OSDN Git Service

Version 0.6.77, add X.Util & X.Net. enjoy!
authoritozyun <itozyun@user.sourceforge.jp>
Thu, 11 Sep 2014 11:43:34 +0000 (20:43 +0900)
committeritozyun <itozyun@user.sourceforge.jp>
Thu, 11 Sep 2014 11:43:34 +0000 (20:43 +0900)
0.6.x/js/00_core/06_XEventDispatcher.js
0.6.x/js/03_util/00_XUtil.js [new file with mode: 0644]
0.6.x/js/03_util/01_XNinjaIframe.js [new file with mode: 0644]
0.6.x/js/03_util/02_XJSON.js [new file with mode: 0644]
0.6.x/js/04_net/00_XNet.js [new file with mode: 0644]
0.6.x/js/04_net/01_XNetXHR.js [new file with mode: 0644]
0.6.x/js/04_net/02_XNetJSONP.js [new file with mode: 0644]

index 7a4ca75..f9fa5c1 100644 (file)
@@ -25,12 +25,14 @@ X.Event = {
        BEFORE_CANCEL : 5,\r
        CANCELED      : 6,\r
        TIMEOUT       : 7,\r
-       // INSTANCE_KILLED\r
+       // BEFORE_KILL_INSTANCE\r
        // KILL_INSTANCE_CANCELED\r
        _LAST_EVENT   : 7\r
 };\r
 \r
-// --- define / local variables ----------------------------\r
+// ------------------------------------------------------------------------- //\r
+// --- define / local variables -------------------------------------------- //\r
+// ------------------------------------------------------------------------- //\r
 var x_eventdispatcher_once       = false,\r
        x_eventdispatcher_needsIndex = false,\r
        x_eventdispatcher_temp       = {};\r
@@ -101,7 +103,7 @@ X.EventDispatcher =
                 * @private\r
                 * @type {Object}\r
                 */\r
-                       _rawObject      : null,\r
+                       _rawObject    : null,\r
                        _handleEvent  : null,\r
                        \r
                        _dispatching  : 0,     // dispatch 中の unlisten で使用\r
diff --git a/0.6.x/js/03_util/00_XUtil.js b/0.6.x/js/03_util/00_XUtil.js
new file mode 100644 (file)
index 0000000..896284e
--- /dev/null
@@ -0,0 +1 @@
+X.Util = {};\r
diff --git a/0.6.x/js/03_util/01_XNinjaIframe.js b/0.6.x/js/03_util/01_XNinjaIframe.js
new file mode 100644 (file)
index 0000000..9978da2
--- /dev/null
@@ -0,0 +1,136 @@
+X.Util.NinjaIframe = X.EventDispatcher.inherits(\r
+       'NinjaIframe',\r
+       {\r
+               autoRefresh  : 0,\r
+               \r
+               xnodeIframe  : null,\r
+               \r
+               _iwin         : null,\r
+               \r
+               _html        : null,\r
+               _name        : null,\r
+               _ready       : false,\r
+               \r
+               Constructor : function( html ){\r
+                       \r
+                       this._name = 'hidden-iframe-' + X.getTime();\r
+                       // https://github.com/polygonplanet/Pot.js/blob/master/src/Worker.js\r
+\r
+                       this.xnodeIframe = X.Dom.Node._body.create(\r
+                               'iframe',\r
+                               {\r
+                                       className         : 'hidden-iframe',\r
+                                       scrolling         : 'no',\r
+                                       frameborder       : 0,\r
+                                       allowtransparency : 'no',\r
+                                       name              : this._name,\r
+                                       id                : this._name\r
+                               }\r
+                       );\r
+                       \r
+                       X.Dom.listenOnce( X.Dom.Event.AFTER_UPDATE, this );\r
+                       \r
+                       // http://nanto.asablo.jp/blog/2011/12/08/6237308\r
+                       // IE 6/7 で文書間通信を実現するための一案\r
+                       if( X.UA.IE < 9 ){\r
+                               this.xnodeIframe.attr( 'src', 'about:blank' );\r
+                       };\r
+                       // Safari 2.0.* bug: iframe's absolute position and src set.\r
+                       if( !X.UA.Webkit ){\r
+                               this.xnodeIframe.css( { position : 'absolute' } );\r
+                       };\r
+                       \r
+                       if( html ) this._html = html;\r
+               },\r
+               \r
+               handleEvent : function( e ){\r
+                       var raw = this.xnodeIframe._rawObject,\r
+                               html, idoc;\r
+                       \r
+                       switch( e.type ){\r
+                               case X.Dom.Event.AFTER_UPDATE :\r
+                                       //\r
+                                       console.log( 'X.Dom.Event.AFTER_UPDATE' );\r
+                                       this._iwin = raw.contentWindow || raw.contentDocument && raw.contentDocument.parentWindow || window.frames[ this._name ];\r
+                                       \r
+                                       this.xnodeIframe.listen( X.UA.IE < 9 ? [ 'readystatechange', 'error' ] : [ 'load', 'error' ], this );\r
+                                       \r
+                                       if( !( X.UA.IE < 9 ) ){\r
+                                               this._html && X_Util_NinjaIframe_writeToIframe( this );\r
+                                               this._ready = true;\r
+                                               return;\r
+                                       };\r
+                                       \r
+                               case 'readystatechange' :\r
+                                       //alert( 'iframe readystatechange. ' + raw.readyState );\r
+                                       \r
+                                       if( ( raw.readyState !== 'complete' && raw.readyState !== 'loaded' ) ) return X.Callback.STOP_PROPAGATION;\r
+                                       // ie9-\r
+                                       if( !this._ready ){\r
+                                               this._html && X_Util_NinjaIframe_writeToIframe( this );\r
+                                               this._ready = true;\r
+                                               return;                 \r
+                                       };\r
+                                       // onload\r
+                               case 'load' :\r
+                                       console.log( 'iframe load.' );\r
+                                       this.asyncDispatch( 0, X.Event.SUCCESS );\r
+                                       break;\r
+                               case 'error' :\r
+                                       this.asyncDispatch( 0, X.Event.ERROR );\r
+                                       break;\r
+                       };\r
+                       \r
+                       return X.Callback.STOP_PROPAGATION;                     \r
+               },\r
+               \r
+               refresh : function( opt_html ){\r
+                       var raw = this.xnodeIframe._rawObject,\r
+                               idoc;\r
+                               \r
+                       this._ready = false;\r
+                       \r
+                       if( !this._iwin ){\r
+                               this._html = opt_html;\r
+                               return this;\r
+                       };\r
+                       \r
+                       this._iwin.location.reload();\r
+                       \r
+                       if( !opt_html ) return this;\r
+                       \r
+                       if( X.UA.IE < 9 ){\r
+                       //if( 7 < X.UA.IE ){\r
+                               this._html = opt_html;\r
+                       //};                            \r
+                       } else {\r
+                               this._html = opt_html;\r
+                               X_Util_NinjaIframe_writeToIframe( this );\r
+                       };\r
+                       return this;\r
+               },\r
+               \r
+               close : function(){\r
+                       X.Dom.unlisten( X.Dom.Event.AFTER_UPDATE, this );\r
+                       this.xnodeIframe.call( 'close' );\r
+                       this.xnodeIframe.destroy();\r
+               }\r
+               \r
+       }\r
+);\r
+\r
+function X_Util_NinjaIframe_writeToIframe( that ){\r
+var raw = that.xnodeIframe._rawObject,\r
+       idoc = raw.contentDocument || that._iwin.document,\r
+       html = that._html;\r
+       \r
+       delete that._html;\r
+       that._ready = true;\r
+       \r
+       console.log( 'iframe import. ' + html );\r
+       \r
+       idoc.open();\r
+       idoc.writeln( html ); // ここで script を書き出すので2度呼ばれる?\r
+       idoc.close();\r
+};\r
+\r
diff --git a/0.6.x/js/03_util/02_XJSON.js b/0.6.x/js/03_util/02_XJSON.js
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/0.6.x/js/04_net/00_XNet.js b/0.6.x/js/04_net/00_XNet.js
new file mode 100644 (file)
index 0000000..a60ee42
--- /dev/null
@@ -0,0 +1,102 @@
+// TODO  onlineevent offlineevent, netspeed\r
+X.Net = {\r
+\r
+       get : function( url ){\r
+               return new X_NET_Queue( X_NET_TYPE_XHR, { get : url } );\r
+       },\r
+       \r
+       post : function( url ){\r
+               return new X_NET_Queue( X_NET_TYPE_XHR, { post : url } );\r
+       },\r
+       \r
+       // TODO chashe\r
+       jsonp : function( url ){\r
+               return new X_NET_Queue( X_NET_TYPE_JSONP, url );\r
+       }\r
+\r
+};\r
+\r
+var X_NET_TYPE_XHR   = 1,\r
+       X_NET_TYPE_JSONP = 2,\r
+       X_NET_TYPE_FORM  = 3,\r
+\r
+       X_NET_QUEUE_LIST = [],\r
+\r
+       X_NET_XHRWrapper,\r
+       X_NET_JSONPWrapper,\r
+       X_NET_FORMWrapper,\r
+\r
+       X_NET_currentWrapper,\r
+       X_NET_currentQueue,\r
+\r
+       X_NET_Queue = X.EventDispatcher.inherits(\r
+               'XNetQueue',\r
+               X.Class.POOL_OBJECT,\r
+               {\r
+                       type : 0,\r
+                       data : null,\r
+                       \r
+                       Constructor : function( type, data ){\r
+                               this.type = type;\r
+                               this.data = data;                               \r
+                               \r
+                               X_NET_QUEUE_LIST[ X_NET_QUEUE_LIST.length ] = this;\r
+                               !X_NET_currentQueue && X_NET_shiftQueue();\r
+                       },\r
+                       \r
+                       cancel : function(){\r
+                               var i = X_NET_QUEUE_LIST.indexOf( this );\r
+                               if( i !== -1 ){\r
+                                       X_NET_QUEUE_LIST.splice( i, 1 );\r
+                               } else\r
+                               if( this === X_NET_currentQueue ){\r
+                                       X_NET_currentWrapper.cancel();\r
+                               };\r
+                       }\r
+               }\r
+       );\r
+\r
+function X_NET_proxyDispatch( e ){\r
+       switch( e.type ){\r
+               case X.Event.SUCCESS :\r
+               case X.Event.ERROR :\r
+                       this.asyncDispatch( 0, e );\r
+                       //this.kill();\r
+                       X_NET_shiftQueue();\r
+                       break;\r
+               case X.Event.PROGRESS :\r
+                       this.dispatch( 0, e );\r
+       };\r
+};\r
+\r
+function X_NET_shiftQueue(){\r
+       var queue;\r
+       \r
+       if( X_NET_currentQueue ){\r
+               if( X_NET_currentWrapper._busy ) return;\r
+               X_NET_currentWrapper.unlisten( [ X.Event.SUCCESS, X.Event.ERROR, X.Event.PROGRESS ], X_NET_currentQueue, X_NET_proxyDispatch );\r
+       };\r
+       \r
+       if( !X_NET_QUEUE_LIST.length ){\r
+               X_NET_currentQueue = X_NET_currentWrapper = null;\r
+               return;\r
+       };\r
+       queue = X_NET_QUEUE_LIST.shift();\r
+       \r
+       switch( queue.type ){\r
+               case X_NET_TYPE_XHR :\r
+                       X_NET_currentWrapper = X_NET_XHRWrapper;\r
+                       break;\r
+               case X_NET_TYPE_JSONP :\r
+                       X_NET_currentWrapper = X_NET_JSONPWrapper;\r
+                       break;\r
+               case X_NET_TYPE_FORM :\r
+                       X_NET_currentWrapper = X_NET_FORMWrapper;\r
+                       break;\r
+       };\r
+       \r
+       X_NET_currentWrapper.listen( [ X.Event.SUCCESS, X.Event.ERROR, X.Event.PROGRESS ], X_NET_currentQueue = queue, X_NET_proxyDispatch );\r
+       \r
+       X_NET_currentWrapper.load( queue.data );\r
+};\r
+\r
diff --git a/0.6.x/js/04_net/01_XNetXHR.js b/0.6.x/js/04_net/01_XNetXHR.js
new file mode 100644 (file)
index 0000000..7f6c38f
--- /dev/null
@@ -0,0 +1,285 @@
+// https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest\r
+// https://web.archive.org/web/20071101021832/http://web.paulownia.jp/script/ajax/xmlhttp4.html\r
+\r
+var X_Net_XHR_W3C      = window[ 'XMLHttpRequest' ] && new XMLHttpRequest(),\r
+       X_Net_XHR_X_DOMAIN = window[ 'XDomainRequest' ] && new XDomainRequest(),\r
+       X_Net_XHR_MSXML_VERSION = 0,\r
+       X_Net_XHR_ACTIVE_X = 5 <= X.UA.IE && X.UA.IE < 8 && X.UA.ActiveX && ( new Function( [\r
+               'var x=".XMLHTTP",',\r
+                       'm="MSXML2"+x,',\r
+                       'v=[m+".6.0",m+".3.0",m,"Microsoft"+x,m+".4.0"],',\r
+                       'i=-1;',\r
+               'for(;i<3;){',\r
+                       'try{',\r
+                               'return new ActiveXObject(v[++i]);',\r
+                       '}catch(e){}',\r
+               '}'\r
+       ].join( '' ) ) )();\r
+\r
+X.Net.XHR = {\r
+       // Opera7.6+, Safari1.2+, khtml3+, Gecko0.9.7+\r
+       W3C      : !!X_Net_XHR_W3C,\r
+\r
+       X_DOMAIN : !!X_Net_XHR_X_DOMAIN,\r
+\r
+       ACTIVE_X : !!X_Net_XHR_ACTIVE_X,\r
+\r
+// ie7 ではローカルリソースには ActiveX の XHR を使う\r
+\r
+// https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest\r
+// Progress Events     Chrome7, firefox3.5, ie10, opera12, Safari?, Chrome for Android 0.16\r
+       PROGRESS    : false, //\r
+\r
+       UL_PROGRESS : false,\r
+\r
+       CANCELABLE  : false,\r
+       \r
+       TIMEOUT     : false\r
+\r
+};\r
+\r
+if( X.Net.XHR.W3C || X_Net_XHR_ACTIVE_X ){\r
+       \r
+       X_NET_XHRWrapper = X.Class._override(\r
+               new X.EventDispatcher(),\r
+               {\r
+                                               \r
+                       _rawObject    : X_Net_XHR_W3C || X_Net_XHR_ACTIVE_X,\r
+                       _isXHR        : true,\r
+                       \r
+                       _method       : null,\r
+                       _type         : null,\r
+                       _busy         : false,\r
+                       _canceled     : false,\r
+                       _lastProgress : 0,\r
+                       \r
+                       load : function( obj ){\r
+                               var raw      = X_NET_XHRWrapper._rawObject,\r
+                                       method   = obj[ 'get' ] ? 'GET' : 'POST',\r
+                                       url      = obj[ 'get' ] || obj[ 'post' ],\r
+                                       async    = obj[ 'async' ],\r
+                                       user     = obj[ 'user' ],\r
+                                       password = obj[ 'password' ],\r
+                                       headers  = obj[ 'headers' ],\r
+                                       postbody = obj[ 'postbody' ],\r
+                                       timeout  = obj[ 'timeout' ];\r
+\r
+                               if( X_Net_XHR_X_DOMAIN ){\r
+                                       if( false /* isXDomain( url ) */ ){ // isXDomain\r
+                                               //if( raw !== X_Net_XHR_X_DOMAIN ){\r
+                                                       X_NET_XHRWrapper._migrateEvent();\r
+                                                       X_NET_XHRWrapper._rawObject = X_Net_XHR_X_DOMAIN;\r
+                                                       X_NET_XHRWrapper._restoreEvent();\r
+                                               //};\r
+                                       } else {\r
+                                               //if( raw === X_Net_XHR_X_DOMAIN ){\r
+                                                       X_NET_XHRWrapper._migrateEvent();\r
+                                                       X_NET_XHRWrapper._rawObject = X_Net_XHR_W3C || X_Net_XHR_ACTIVE_X;\r
+                                                       X_NET_XHRWrapper._restoreEvent();\r
+                                               //};\r
+                                       };\r
+                               };\r
+                               //if( raw.timeout !== undefined ) raw.timeout = timeout || -1;\r
+                               raw.open( method, url, false );\r
+                               \r
+                               // http://www.quirksmode.org/blog/archives/2005/09/xmlhttp_notes_r_1.html\r
+                               // raw.overrideMimeType()\r
+                               if( !X_Net_XHR_ACTIVE_X && X.Type.isFunction( raw.setRequestHeader ) ){\r
+                                       for( p in headers ){\r
+                                               raw.setRequestHeader( p, headers[ p ] ); // Opera8.01+, MSXML3+\r
+                                       };              \r
+                               };\r
+                               \r
+                               // http://allabout.co.jp/gm/gc/24097/#1\r
+                               // sendをonreadystatechangeの前に記述すると、ieでは動作しなくなります、、、。\r
+                               // konquerorでエラーが発生するのでここでは、とりあえず、send('') としました。\r
+                               raw.send( postbody || '' );\r
+                               \r
+                               this._busy = true;\r
+                       },\r
+                       \r
+                       cancel : X.Net.XHR.CANCELABLE ?\r
+                               function(){\r
+                                       //X_NET_XHRWrapper._rawObject.abort()\r
+                               } :\r
+                               function(){\r
+                                       this._canceled = true;\r
+                               },\r
+                       \r
+                       reset : function(){\r
+                               this._method       = this._type = null;\r
+                               this._canceled     = false;\r
+                               this._busy         = false;\r
+                               this._lastProgress = 0;\r
+                       },\r
+                       \r
+                       handleEvent : function( e ){\r
+                               var raw  = X_NET_XHRWrapper._rawObject,\r
+                                       live = !this._canceled,\r
+                                       status, data;\r
+                               console.log( '-- ' + e.type );\r
+                               switch( e.type ){\r
+                                       /*\r
+                                        * http://memopad.bitter.jp/w3c/ajax/ajax_xmlhttprequest_onreadystatechange.html\r
+                                       readyState      XMLHttpRequest のステータスを保持する。0 から 4 までに変化する:\r
+                                       0: リクエストは初期化されていない\r
+                                       1: サーバ接続は確立した\r
+                                       2: リクエストを受信した\r
+                                       3: リクエストの処理中\r
+                                       4: リクエストは終了してレスポンスの準備が完了\r
+                                       status  200: "OK"\r
+                                       404: Page not found\r
+                                       \r
+                                       If-Modified-Sinceヘッダを利用してWebページのキャッシュを行うXMLHttpRequestラッパー\r
+                                       http://www.semblog.org/msano/archives/000407.html\r
+                                       * */            \r
+                                       case 'readystatechange' :\r
+                                               if( !X.Net.XHR.PROGRESS ){\r
+                                                       switch( raw.readyState ){\r
+                                                               case 0 :\r
+                                                               case 1 :\r
+                                                                       return;\r
+                                                               case 2 : // 0.01%\r
+                                                                       live && this.asyncDispatch( 0, { type : X.Event.PROGRESS, percent : 0.01 } );\r
+                                                                       return;\r
+                                                               case 3 :\r
+                                                                       live && this.asyncDispatch( 0, { type : X.Event.PROGRESS, percent : this._lastProgress < 99.9 ? 99.9 : ( this._lastProgress + 100 ) / 2 } );\r
+                                                                       // 99.9%\r
+                                                                       return;\r
+                                                               case 4 :\r
+                                                                       if( this._lastProgress === 100 ) return; // Opera8 readystatechange が2重に発生\r
+                                                                       // 100%\r
+                                                                       break; // load へ\r
+                                                               default :\r
+                                                                       // error\r
+                                                                       return;\r
+                                                       };                                              \r
+                                               };\r
+       \r
+                                       case 'load' :\r
+                                               \r
+                                               if( !live ){\r
+                                                       // this.reset();\r
+                                               };\r
+                                               if( this._lastProgress === 100 ) return;\r
+                                               \r
+                                               \r
+                                               this._lastProgress = 100;\r
+                                               \r
+                                               \r
+                                               status = raw.status;\r
+                                               \r
+                                               // https://code.google.com/p/fakeworker-js/source/browse/src/javascript/fakeworker.js\r
+                                               if(\r
+                                                       ( !status && location.protocol === 'file:' ) ||\r
+                                           ( 200 <= status && status < 300 ) ||\r
+                                           status === 304 ||\r
+                                           status === 1223 ||\r
+                                           ( X.UA.Webkit && status == undefined ) // safari: /webkit/.test(userAgent)\r
+                                               ){\r
+                                                       \r
+                                               } else {\r
+                                                       console.log( 'status ' + status );\r
+                                                       //console.dir( raw );\r
+                                                       live && this.asyncDispatch( 0, { type : X.Event.ERROR, status : raw.status || 0, percent : 100 } );\r
+                                                       this.reset();\r
+                                                       return;\r
+                                               };\r
+\r
+                                               \r
+                                               /*\r
+                                                * opera8, safari2, khtml3 で utf8 日本語文字列の文字化け\r
+                                                */\r
+                                               raw.getAllResponseHeaders();\r
+                                               \r
+                                               // parse json, html, xml, text, script, css\r
+                                               switch( this._type ){\r
+                                                       case null :\r
+                                                       case 'text' :\r
+                                                               data = raw[ 'responseText' ];\r
+                                                               break;\r
+                                                       case 'json' :\r
+                                                       case 'moz-json' :\r
+                                                       case 'document' :\r
+                                                       case 'blob' :\r
+                                                       case 'arraybuffer' :\r
+                                               };\r
+                                               \r
+                                                       console.log( 'status ' + status );\r
+                                                       //console.dir( raw );\r
+                                               this._busy = false;\r
+                                               this.asyncDispatch( 0, { type : X.Event.SUCCESS, status : status || 200, data : data } );\r
+                                               \r
+                                               break;\r
+                                       \r
+                                       case 'progress' :\r
+                                               if( e.lengthComputable ){\r
+                                                       this._lastProgress = e.loaded / e.total;\r
+                                                       live && this.asyncDispatch( 0, { type : X.Event.PROGRESS, percent : this._lastProgress } );\r
+                                               };\r
+                                               break;\r
+                                       \r
+                                       case 'error' :\r
+                                       //console.dir( e );\r
+                                               live && this.asyncDispatch( 0, { type : X.Event.ERROR, status : raw.status } );\r
+                                               this.reset();\r
+                                               break;\r
+                                       \r
+                                       //case 'abort' :\r
+                                       //      this.asyncDispatch( 0, { type : X.Event.ERROR, status : raw.status } );\r
+                                       //      break;\r
+                                       case 'timeout' : // Gecko 12.0 https://developer.mozilla.org/ja/docs/XMLHttpRequest/Synchronous_and_Asynchronous_Requests\r
+                                               live && this.asyncDispatch( 0, { type : X.Event.ERROR, status : raw.status } );\r
+                                               this.reset();\r
+                                               break;\r
+                                               \r
+                                       case 'loadend' :\r
+                                               break;\r
+                               };\r
+                       },\r
+                       \r
+                       onUploadProgress : X.Net.XHR.UL_PROGRESS && function( e ){\r
+                               var raw  = X_NET_XHRWrapper._rawObject.upload,\r
+                                       live = !this._canceled,\r
+                                       states, data;\r
+                       }\r
+               },\r
+               true\r
+       );\r
+       // 同期リクエストでなければならない場合, unload, beforeunload時\r
+\r
+\r
+       // ie8 では timeout が有効\r
+       if( X.UA.IE8 ){\r
+               X_NET_XHRWrapper.listen( [ 'readystatechange', 'error','abort', 'timeout' ] );\r
+       } else\r
+       if( X.UA.IE7 ){\r
+               X_NET_XHRWrapper.listen( [ 'readystatechange', 'error' ] );\r
+       } else\r
+       if( X_Net_XHR_ACTIVE_X ){ // win ie5-6\r
+               X_NET_XHRWrapper.listen( [ 'readystatechange' ] );\r
+       } else \r
+       if( X.Net.XHR.PROGRESS ){\r
+               X_NET_XHRWrapper.listen( [ 'load', 'progress', 'error', 'abort', 'timeout' ] );\r
+       } else {\r
+               X_NET_XHRWrapper.listen( [ 'load', 'readystatechange', 'error', 'abort', 'timeout' ] );\r
+       };\r
+       \r
+       if( X.Net.XHR.UL_PROGRESS ){\r
+               X_NET_XHRWrapper._rawObject.upload.addEventListener( 'progress', X.Net.XHR.xhr.onUploadProgress );\r
+       };\r
+       \r
+       \r
+       var X_NET_XHR_lastReadyState = 0;\r
+       \r
+       function X_NET_XHR_checkReadyStateTimer(){\r
+               //console.log( '-' );\r
+               if( X_NET_XHR_lastReadyState < X_NET_XHRWrapper._rawObject.readyState ){\r
+                       X_NET_XHR_lastReadyState = X_NET_XHRWrapper._rawObject.readyState;\r
+                       X_NET_XHRWrapper.dispatch( { type : 'readystatechange' } );\r
+                       console.log( '- ' + X_NET_XHR_lastReadyState );\r
+                       if( 4 <= X_NET_XHR_lastReadyState ) return X.Callback.UN_LISTEN;\r
+               };\r
+       };\r
+};\r
+\r
diff --git a/0.6.x/js/04_net/02_XNetJSONP.js b/0.6.x/js/04_net/02_XNetJSONP.js
new file mode 100644 (file)
index 0000000..76948b8
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * Operaでも非同期リクエストが並列処理できる img-JSONP
+ * http://developer.cybozu.co.jp/takesako/2007/06/opera_img-jsonp.html
+ * 
+ * IE9でiframe内で遷移した場合window.parentのメソッドを呼べない 
+ * http://kozo002.blogspot.jp/2012/07/ie9iframewindowparent.html
+ */
+
+X.Net.JSONP = {
+       cb : function( accessKey, jsonString, time, opt_json2FileSize ){
+                       if( accessKey !== X_NET_JSONP_ACCESS_KEY ) return;
+                       
+                       X_NET_JSONPWrapper
+                               .asyncDispatch( 0, {
+                                       type : jsonString ? X.Event.SUCCESS : X.Event.ERROR,
+                                       data : jsonString //eval( jsonString )
+                               } );
+                       X_NET_JSONPWrapper.cleanup();
+                       
+                       console.log( 'ms : ' + time + ' speed : ' + ( ( jsonString.length + ( opt_json2FileSize || 0 ) ) / time * 1000 ) + ' バイト/秒.' );
+               }
+};
+
+var X_NET_JSONP_ACCESS_KEY = Math.random(),
+       
+       X_NET_JSONP_NinjaIframe,
+       
+       X_NET_JSONP_imageFixListener = X.UA.Opera && function( e ){
+               switch( e.type ){
+                       case X.Event.SUCCESS :
+                       case X.Event.ERROR :
+                               X_NET_JSONP_loadScriptInNinjaIframe( e.src );
+                       case X.Event.TIMEOUT :
+                       case X.Event.CANCELED :
+               };
+       };
+
+function X_NET_JSONP_loadScriptInNinjaIframe( url ){
+       X_NET_JSONP_NinjaIframe || ( X_NET_JSONP_NinjaIframe = new X.Util.NinjaIframe() );
+       
+       var json2Path     = '../js/libs/json2.js',
+               json2FileSize = 18103,
+               html;
+       
+       if( X.UA.IE8 ){
+               html = [
+                       // http://blog.livedoor.jp/dankogai/archives/51503830.html              
+                       // Ajax - IE8にもJSON入ってます。使えるとは限らないけど
+                       // Compatibility mode (別名Quirks mode) では、JSONオブジェクトは無効になります。iframeもだめです
+                       /* 以下のコードは XP ie8 では動くけど、win8 IE11(8モード)で動かない 開発の便宜を取って,setTimeout を挟む
+                       '<script>',
+                               'function cb(o){window.parent.X.Net.JSONP.cb(' + X_NET_JSONP_ACCESS_KEY + ',window.parent.JSON.stringify(o))}',
+                       '</script>',
+                       '<script src="', url, '"></script>' */
+                       '<script id="jp"></script>',
+                       '<script>',
+                               'function cb(o){nw-=+new Date;parent.X.Net.JSONP.cb(' + X_NET_JSONP_ACCESS_KEY + ',parent.JSON.stringify(o),-nw)}',
+                               'function tm(){jp.src="', url ,'";nw=+new Date}',
+                               'setTimeout(tm,16);',
+                       '</script>'
+               ];
+       } else
+       if( X.UA.IE9 ){
+               html = [
+                       '<script id="jp"></script>',
+                       '<script>',
+                               'function cb(o){nw-=+new Date;parent.X.Net.JSONP.cb(' + X_NET_JSONP_ACCESS_KEY + ',JSON.stringify(o),-nw)}',
+                               'function tm(){jp.src="', url ,'";nw=+new Date}',
+                               'setTimeout(tm,16);',
+                       '</script>'
+               ];
+       } else
+       if( window[ 'JSON' ] ){
+               html = [        
+                       '<script>',
+                               'nw=+new Date;',
+                               'function cb(o){nw-=+new Date;parent.X.Net.JSONP.cb(' + X_NET_JSONP_ACCESS_KEY + ',JSON.stringify(o),-nw)}',
+                       '</script>',
+                       '<script src="', url, '"></script>'
+               ];
+       } else
+       if( X.UA.IE < 5 || X.UA.MacIE ){
+               html = [
+                       '<script id="jn"></script>',
+                       '<script id="jp"></script>',
+                       '<script>',
+                               'function cb(o){nw-=new Date;parent.X.Net.JSONP.cb(' + X_NET_JSONP_ACCESS_KEY + ',JSON.stringify(o),-nw-16,', json2FileSize, ')}',
+                               'function t1(){document.all.jn.src="', json2Path ,'";setTimeout("t2()",16);nw=+new Date}',
+                               'setTimeout("t1()",16);',
+                               'function t2(){if(window.JSON){document.all.jp.src="', url ,'"}else{setTimeout("t2()",16)}}',
+                       '</script>'
+               ];
+       } else
+       if( X.UA.IE < 8 ){ // ie5-7
+               html = [
+                       '<script id="jn"></script>',
+                       '<script id="jp"></script>',
+                       '<script>',
+                               'function cb(o){nw-=new Date;parent.X.Net.JSONP.cb(' + X_NET_JSONP_ACCESS_KEY + ',JSON.stringify(o),-nw-16,', json2FileSize, ')}',
+                               'function t1(){jn.src="', json2Path ,'";setTimeout(t2,16);nw=+new Date}',
+                               'setTimeout(t1,16);',
+                               'function t2(){if(window.JSON){jp.src="', url ,'"}else{setTimeout(t2,16)}}',
+                       '</script>'
+               ];
+       } else {
+               html = [
+                       '<script>',
+                               'function cb(o){nw-=new Date;parent.X.Net.JSONP.cb(' + X_NET_JSONP_ACCESS_KEY + ',JSON.stringify(o),-nw,', json2FileSize, ')}',
+                               'nw=+new Date;',
+                       '</script>',
+                       '<script src="', json2Path, '"></script>',
+                       '<script src="', url, '"></script>'
+               ];
+       };
+       
+       X_NET_JSONP_NinjaIframe
+               .refresh( html.join( '' ) )
+               .listen( [ X.Event.SUCCESS, X.Event.ERROR ], X_NET_JSONPWrapper, X_NET_JSONP_iframeListener );
+};
+
+
+function X_NET_JSONP_iframeListener( e ){
+       switch( e.type ){
+               case X.Event.SUCCESS :
+                       console.log( 'iframe onload' );
+
+                       break;
+               case X.Event.ERROR :
+                       console.log( 'iframe onerror' );
+                       X_NET_JSONPWrapper.asyncDispatch( 0, X.Event.ERROR );
+                       break;
+       };
+};
+
+
+X_NET_JSONPWrapper = X.Class._override(
+       new X.EventDispatcher(),
+       {
+
+               _operaImage   : null, // X.Dom.Image.Loader();
+               _busy         : false,
+               _canceled     : false,
+               
+               load : function( url, data, timeout ){
+                       
+                       //createURL
+                       if( X_NET_JSONP_imageFixListener ){
+                               this._operaImage = X.Dom.Image.Loader( url )
+                                       .listenOnce( [ X.Event.SUCCESS, X.Event.ERROR ], X_NET_JSONP_imageFixListener );
+                       } else {
+                               X_NET_JSONP_loadScriptInNinjaIframe( url );
+                       };
+                                               
+                       this._budy = true;
+               },
+               
+               cancel : function(){
+                       if( this._operaImage ){
+                               this._operaImage
+                                       .unlisten()
+                                       .abort();
+                               delete this._operaImage;
+                       } else {
+                               this._canceled = true;
+                       };
+               },
+               
+               reset : function(){
+                       this._budy = this._canceled = false;
+               },
+               
+               cleanup : function(){
+                       this._budy = this._canceled = false;
+               }
+       }
+);
+