1 //{+xhrgadget"OpenSocialガジェット通信プロキシ"(Xドメインは元よりXプロトコルな擬似xhr通信を可能にする)[+xhr]
\r
4 * gadgets.io.makeRequest
\r
6 * 1. gadget-iframe を作る。指示を # で渡す。 元文書は frame 内の images の監視を開始する。
\r
9 * 2. gadget-iframe が 通信用 img を作る。#ready
\r
11 * 3. 元文書が #ready を受け取ったら、iframe の # を書き換えて指示を送る。指示が長い場合、分割して送る。
\r
13 * 4. gadget-iframe は 通信用 img の # に結果を書く。コンテンツが長い場合、分割する。
\r
15 * 5. 元文書は結果を受け取ったことを gadget-iframe の # に書いて伝える。
\r
20 var X_GadgetXHR_canUse = 5.5 <= X_UA[ 'IE' ] || !X_UA[ 'IE' ],
\r
22 X_GadgetXHR_iframeName = 'gadgetProxy_' + ( Math.random() * 100000 | 0 ),
\r
24 X_GadgetXHR_GADGET_XML_URL = 'http://googledrive.com/host/0B4Y86MXyTfuoVUkwTE54T3V1V1U',
\r
26 // https://kldleov8fp2dl82hphfmor8riij82tof-a-sites-opensocial.googleusercontent.com/gadgets/ifr
\r
27 X_GadgetXHR_GADGET_URL = 'http://www.ig.gmodules.com/gadgets/ifr?url=' + encodeURIComponent( X_GadgetXHR_GADGET_XML_URL ) + '&nocache=1',
\r
29 X_GadgetXHR_IMAGE_URL = 'img/opacity0.gif',
\r
31 // https://code.google.com/p/xssinterface/source/browse/trunk/js/xssinterface.js
\r
32 X_GadgetXHR_maxQueryLength = X_UA[ 'IE' ] ? 2000 : 6000,
\r
34 X_GadgetXHR_requestBatches,
\r
36 X_GadgetXHR_requestOriginal,
\r
38 X_GadgetXHR_timerID,
\r
40 X_GadgetXHR_phase = 0,
\r
42 X_GadgetXHR_lastHashString,
\r
44 X_GadgetXHR_isReceiveBatches, X_GadgetXHR_receivedString = '';
\r
47 function X_GadgetXHR_detectImageOverIframe(){
\r
48 var raw = X_GadgetXHR[ '_rawObject' ],
\r
49 iwin, frames, i, ret, n;
\r
52 iwin = raw.contentWindow || ( raw.contentDocument && raw.contentDocument.parentWindow ) || window.frames[ X_GadgetXHR_iframeName ];
\r
54 if( iwin && ( frames = iwin.frames ) && ( i = frames.length ) ){
\r
56 if( ret = X_Script_try( X_Object_find, [ frames[ --i ], 'location>hash' ] ) ) break;
\r
58 if( ret && ret !== X_GadgetXHR_lastHashString ){
\r
59 X_GadgetXHR_lastHashString = ret;
\r
60 //console.log( ret.length );
\r
61 //console.log( '' + ret );
\r
63 switch( X_GadgetXHR_phase ){
\r
64 case 0 : // makeRequest
\r
65 iwin.location.href = X_GadgetXHR_GADGET_URL + '#' + X_GadgetXHR_requestBatches.shift();
\r
66 if( X_GadgetXHR_requestBatches.length ) return; //TODO boost
\r
69 case 1 : // after makeRequest > :ok 待ち
\r
70 iwin.location.href = X_GadgetXHR_GADGET_URL + '#_waiting_';
\r
73 case 2 : // _waiting_ 通信結果待ち
\r
75 ret = ret.substr( 1 );
\r
76 n = parseFloat( ret );
\r
78 if( X_GadgetXHR_isReceiveBatches ){
\r
79 X_GadgetXHR_receivedString += X_GadgetXHR_decodeLocationHash( ret );
\r
80 if( --X_GadgetXHR_isReceiveBatches ){
\r
81 iwin.location.href = X_GadgetXHR_GADGET_URL + '#_recived_' + X_GadgetXHR_isReceiveBatches;
\r
86 ret = ret.substr( ( n + ':' ).length );
\r
87 X_GadgetXHR_receivedString = X_GadgetXHR_decodeLocationHash( ret );
\r
88 X_GadgetXHR_isReceiveBatches = --n;
\r
89 iwin.location.href = X_GadgetXHR_GADGET_URL + '#_recived_' + X_GadgetXHR_isReceiveBatches;
\r
91 X_GadgetXHR_timerID = X_Timer_add( 16, 0, X_GadgetXHR_detectImageOverIframe );
\r
92 return X_CALLBACK_UN_LISTEN;
\r
94 X_GadgetXHR_receivedString = X_GadgetXHR_decodeLocationHash( ret );
\r
97 X_GadgetXHR[ 'asyncDispatch' ]( X_JSON_parseTrustableString( X_GadgetXHR_receivedString ) );
\r
98 X_GadgetXHR_receivedString = '';
\r
101 X_GadgetXHR._busy = false;
\r
102 X_GadgetXHR_timerID = X_GadgetXHR_phase = 0;
\r
104 X_GadgetXHR_lastHashString = '';
\r
105 iwin.location.href = X_GadgetXHR_GADGET_URL + '#_recived_';
\r
107 return X_CALLBACK_UN_LISTEN;
\r
109 ++X_GadgetXHR_phase;
\r
115 // http://outcloud.blogspot.jp/2015/06/gecko-location-hash.html
\r
116 function X_GadgetXHR_decodeLocationHash( str ){
\r
117 return X_UA[ 'Gecko' ] ? unescape( str ) : decodeURIComponent( str );
\r
120 X_TEMP.X_GadgetXHR_init = function(){
\r
121 X_GadgetXHR = X_Class_override(
\r
123 .create( 'iframe', {
\r
124 className : 'hidden-iframe',
\r
125 name : X_GadgetXHR_iframeName,
\r
126 id : X_GadgetXHR_iframeName,
\r
127 src : X_GadgetXHR_GADGET_URL + '#' + encodeURIComponent(
\r
128 X_JSON_stringify( {
\r
129 'img' : X_URL_toAbsolutePath( X_GadgetXHR_IMAGE_URL ),
\r
130 'len' : X_GadgetXHR_maxQueryLength,
\r
132 'gck' : X_UA[ 'Gecko' ] ? 1 : 0,
\r
133 'err' : X_EVENT_ERROR,
\r
134 'suc' : X_EVENT_SUCCESS
\r
138 allowtransparency : 'no',
\r
142 X_TEMP.X_GadgetXHR_props );
\r
144 delete X_TEMP.X_GadgetXHR_init;
\r
145 delete X_TEMP.X_GadgetXHR_props;
\r
147 X_GadgetXHR_requestBatches = [];
\r
149 return X_GadgetXHR;
\r
152 X_TEMP.X_GadgetXHR_props = {
\r
158 load : function( obj ){
\r
160 k, max, sendStr, l, str;
\r
163 X_GadgetXHR_requestOriginal = obj;
\r
173 req[ k ] = obj[ k ];
\r
178 max = X_GadgetXHR_maxQueryLength - X_GadgetXHR_GADGET_URL.length - 5;
\r
180 sendStr = X_JSON_stringify( req );
\r
182 while( sendStr.length ){
\r
184 str = encodeURIComponent( sendStr.substr( 0, l ) );
\r
185 while( max < str.length ){
\r
186 l = l * ( 2 + l / str.length ) / 3 | 0;
\r
187 str = encodeURIComponent( sendStr.substr( 0, l ) );
\r
188 //console.log( l );
\r
190 X_GadgetXHR_requestBatches.push( str );
\r
191 sendStr = sendStr.substr( l );
\r
197 if( 1 < X_GadgetXHR_requestBatches.length ){
\r
198 X_GadgetXHR_requestBatches[ 0 ] = X_GadgetXHR_requestBatches.length + ':' + X_GadgetXHR_requestBatches[ 0 ];
\r
201 X_GadgetXHR_timerID = X_Timer_add( 333, 0, X_GadgetXHR_detectImageOverIframe );
\r
203 X_GadgetXHR._busy = true;
\r
206 cancel : function(){
\r
207 X_GadgetXHR._canceled = true;
\r
210 reset : function(){
\r
211 X_GadgetXHR._busy = X_GadgetXHR._canceled = false;
\r
212 X_GadgetXHR._onloadCount = 0;
\r