OSDN Git Service

f1f65cbc4de161c61b1a7c2a9ce9a6cb23e685c8
[pettanr/clientJs.git] / 0.6.x / js / 04_net / 02_XNetJSONP.js
1 /*
2  * Operaでも非同期リクエストが並列処理できる img-JSONP
3  * http://developer.cybozu.co.jp/takesako/2007/06/opera_img-jsonp.html
4  * 
5  * iframe を使った jsonp の読み込みエラー判定の記事、
6  * JSONPのエラーを判断する は web archive でも観れない
7  * http://d.hatena.ne.jp/yuushimizu/20090128/1233146321
8  * TODO JSONPの動的取得+エラー処理
9  * http://d.hatena.ne.jp/NeoCat/20110206/1296934235
10  * 
11  * IE9でiframe内で遷移した場合window.parentのメソッドを呼べない 
12  * http://kozo002.blogspot.jp/2012/07/ie9iframewindowparent.html
13  * 
14  * IE6(IETester,localhost) で動かない,
15  * 
16  * TODO postMessage
17  */
18
19 X.Net.JSONP = {
20         cb : function( accessKey, jsonString, time, opt_json2FileSize ){
21                         if( accessKey !== X_NET_JSONP_ACCESS_KEY || !X_NET_JSONPWrapper._busy ) return;
22                         
23                         X_NET_JSONPWrapper._busy = false;
24                         
25                         X_NET_JSONPWrapper
26                                 .asyncDispatch( 0, {
27                                         type : jsonString ? X.Event.SUCCESS : X.Event.ERROR,
28                                         data : jsonString //eval( jsonString )
29                                 } );
30                         
31                         console.log( 'ms : ' + time + ' speed : ' + ( ( jsonString.length + ( opt_json2FileSize || 0 ) ) / time * 1000 ) + ' バイト/秒.' );
32                 }
33 };
34
35 var X_NET_JSONP_ACCESS_KEY = Math.random(),
36         
37         X_NET_JSONP_NinjaIframe;
38
39
40 function X_NET_JSONP_loadScriptInNinjaIframe( url ){
41         var json2Path     = 'js/libs/json2.js',
42                 json2FileSize = 18103,
43                 html;
44         
45         X_NET_JSONP_NinjaIframe || ( X_NET_JSONP_NinjaIframe = new X.Util.NinjaIframe() );
46         
47         // TODO '<scr'+'ipt> 化 恐らくアンチウイルスソフトが反応しないための対策
48         
49         if( X.UA.IE8 ){
50                 html = [
51                         // http://blog.livedoor.jp/dankogai/archives/51503830.html              
52                         // Ajax - IE8にもJSON入ってます。使えるとは限らないけど
53                         // Compatibility mode (別名Quirks mode) では、JSONオブジェクトは無効になります。iframeもだめです
54                         /* 以下のコードは XP ie8 では動くけど、win8 IE11(8モード)で動かない 開発の便宜を取って,setTimeout を挟む
55                         '<script>',
56                                 'function cb(o){window.parent.X.Net.JSONP.cb(' + X_NET_JSONP_ACCESS_KEY + ',window.parent.JSON.stringify(o))}',
57                         '</script>',
58                         '<script src="', url, '"></script>' */
59                         '<script id="jp"></script>',
60                         '<script>',
61                                 'nw=0;', // なぜか必要,,,
62                                 'function cb(o){nw-=+new Date;parent.X.Net.JSONP.cb(' + X_NET_JSONP_ACCESS_KEY + ',parent.JSON.stringify(o),-nw)}',
63                                 'function tm(){jp.src="', url ,'";nw=+new Date}',
64                                 'setTimeout(tm,16);',
65                         '</script>'
66                 ];
67         } else
68         if( X.UA.IE9 ){
69                 html = [
70                         '<script id="jp"></script>',
71                         '<script>',
72                                 'function cb(o){nw-=+new Date;parent.X.Net.JSONP.cb(' + X_NET_JSONP_ACCESS_KEY + ',JSON.stringify(o),-nw)}',
73                                 'function tm(){jp.src="', url ,'";nw=+new Date}',
74                                 'setTimeout(tm,16);',
75                         '</script>'
76                 ];
77         } else
78         if( window[ 'JSON' ] ){
79                 html = [        
80                         '<script>',
81                                 'nw=+new Date;',
82                                 'function cb(o){if(nw){nw-=+new Date;parent.X.Net.JSONP.cb(' + X_NET_JSONP_ACCESS_KEY + ',JSON.stringify(o),-nw);nw=0}}',
83                         '</script>',
84                         '<script src="', url, '"></script>'
85                 ];
86         } else
87         if( X.UA.IE4 || X.UA.MacIE ){
88                 html = [
89                         '<script id="jn"></script>',
90                         '<script id="jp"></script>',
91                         '<script>',
92                                 'function cb(o){nw-=new Date;parent.X.Net.JSONP.cb(' + X_NET_JSONP_ACCESS_KEY + ',JSON.stringify(o),-nw-16,', json2FileSize, ')}',
93                                 'function t1(){document.all.jn.src="', json2Path ,'";setTimeout("t2()",16);nw=+new Date}',
94                                 'setTimeout("t1()",16);',
95                                 'function t2(){if(window.JSON){document.all.jp.src="', url ,'"}else{setTimeout("t2()",16)}}',
96                         '</script>'
97                 ];
98         } else
99         if( X.UA.IE < 8 ){ // ie5-7
100                 html = [
101                         '<script id="jn"></script>',
102                         '<script id="jp"></script>',
103                         '<script>',
104                                 'function cb(o){nw-=new Date;parent.X.Net.JSONP.cb(' + X_NET_JSONP_ACCESS_KEY + ',JSON.stringify(o),-nw-16,', json2FileSize, ')}',
105                                 'function t1(){jn.src="', json2Path ,'";setTimeout(t2,16);nw=+new Date}',
106                                 'setTimeout(t1,16);',
107                                 'function t2(){if(window.JSON){jp.src="', url ,'"}else{setTimeout(t2,16)}}',
108                         '</script>'
109                 ];
110         } else {
111                 html = [
112                         '<script>',
113                                 'function cb(o){if(nw){nw-=new Date;parent.X.Net.JSONP.cb(' + X_NET_JSONP_ACCESS_KEY + ',JSON.stringify(o),-nw,', json2FileSize, ');nw=0}}',
114                                 'nw=+new Date;',
115                         '</script>',
116                         '<script src="', json2Path, '"></script>',
117                         '<script src="', url, '"></script>'
118                 ];
119         };
120         
121         X_NET_JSONP_NinjaIframe
122                 .refresh( html.join( '' ) )
123                 .listen( [ X.Event.SUCCESS, X.Event.ERROR ], X_NET_JSONPWrapper, X_NET_JSONP_iframeListener );
124 };
125
126
127 function X_NET_JSONP_iframeListener( e ){
128         switch( e.type ){
129                 case X.Event.SUCCESS :
130                         console.log( 'iframe onload' );
131
132                         break;
133                 case X.Event.ERROR :
134                         console.log( 'iframe onerror' );
135                         X_NET_JSONPWrapper.asyncDispatch( 0, X.Event.ERROR );
136                         break;
137         };
138 };
139
140
141 X_NET_JSONPWrapper = X.Class._override(
142         new X.EventDispatcher(),
143         {
144
145                 _operaImage   : null, // X.Net.Image();
146                 _busy         : false,
147                 _canceled     : false,
148                 
149                 load : function( url, data, timeout ){
150                         //createURL
151                         if( X_NET_JSONP_operaImageHandleEvent ){
152                                 this._operaImage = X.Net.Image( url )
153                                         .listenOnce( [ X.Event.SUCCESS, X.Event.ERROR, X.Event.TIMEOUT ], X_NET_JSONP_operaImageHandleEvent );
154                         } else {
155                                 X_NET_JSONP_loadScriptInNinjaIframe( url );
156                         };
157                                                 
158                         this._busy = true;
159                 },
160                 
161                 cancel : function(){
162                         if( this._operaImage ){
163                                 this._operaImage
164                                         .unlisten( [ X.Event.SUCCESS, X.Event.ERROR, X.Event.TIMEOUT ], X_NET_JSONP_operaImageHandleEvent )
165                                         .abort();
166                                 delete this._operaImage;
167                         } else {
168                                 this._canceled = true;
169                         };
170                 },
171                 
172                 reset : function(){
173                         this._busy = this._canceled = false;
174                 }
175         }
176 );
177
178 function X_NET_JSONP_operaImageHandleEvent( e ){
179         switch( e.type ){
180                 case X.Event.SUCCESS :
181                 case X.Event.ERROR :
182                         X_NET_JSONP_loadScriptInNinjaIframe( e.src );
183                         break;
184                 case X.Event.TIMEOUT :
185                         X_NET_JSONPWrapper._operaImage
186                                 .unlisten( [ X.Event.SUCCESS, X.Event.ERROR, X.Event.TIMEOUT ], X_NET_JSONP_operaImageHandleEvent )
187                                 .reset();
188                         X_NET_JSONPWrapper.asyncDispatch( 0, X.Event.ERROR );
189                         break;
190         };
191 };
192 if( !X.UA.Opera ) X_NET_JSONP_operaImageHandleEvent = null;