OSDN Git Service

d65f2c0a6015d22bbc0af0904a9d895f83da76a4
[pettanr/clientJs.git] / 0.6.x / js / 06_net / 05_XXHRGadget.js
1 //{+xhrgadget"OpenSocialガジェット通信プロキシ"(Xドメインは元よりXプロトコルな擬似xhr通信を可能にする)[+xhr]\r
2 \r
3 /*\r
4  * gadgets.io.makeRequest\r
5  * \r
6  * 1. gadget-iframe を作る。指示を # で渡す。 元文書は frame 内の images の監視を開始する。\r
7  *  1. 通信用 img の src\r
8  *\r
9  * 2. gadget-iframe が 通信用 img を作る。#ready\r
10  * \r
11  * 3. 元文書が #ready を受け取ったら、iframe の # を書き換えて指示を送る。指示が長い場合、分割して送る。\r
12  * \r
13  * 4. gadget-iframe は 通信用 img の # に結果を書く。コンテンツが長い場合、分割する。\r
14  * \r
15  * 5. 元文書は結果を受け取ったことを gadget-iframe の # に書いて伝える。\r
16  * \r
17  * \r
18  */\r
19 \r
20 var X_NET_GIMR_canUse         = 5.5 <= X_UA[ 'IE' ] || !X_UA[ 'IE' ],\r
21         \r
22         X_NET_GIMR_iframeName     = 'gadgetProxy_' + ( Math.random() * 100000 | 0 ),\r
23         \r
24         X_NET_GIMR_GADGET_XML_URL = 'http://googledrive.com/host/0B4Y86MXyTfuoVUkwTE54T3V1V1U',\r
25         \r
26         // https://kldleov8fp2dl82hphfmor8riij82tof-a-sites-opensocial.googleusercontent.com/gadgets/ifr\r
27         X_NET_GIMR_GADGET_URL     = 'http://www.ig.gmodules.com/gadgets/ifr?url=' + encodeURIComponent( X_NET_GIMR_GADGET_XML_URL ) + '&nocache=1',\r
28         \r
29         X_NET_GIMR_IMAGE_URL      = 'img/opacity0.gif',\r
30         \r
31         // https://code.google.com/p/xssinterface/source/browse/trunk/js/xssinterface.js\r
32         X_NET_GIMR_maxQueryLength = X_UA[ 'IE' ] ? 2000 : 6000,\r
33         \r
34         X_NET_GIMR_detection      = new Function( 'f,j,i', 'for(j=f.length;j;)try{i=f[--j];return i.location.hash}catch(e){}' ),\r
35         \r
36         X_NET_GIMR_requestBatches,\r
37         \r
38         X_NET_GIMR_requestOriginal,\r
39         \r
40         X_NET_GIMR_timerID,\r
41         \r
42         X_NET_GIMR_phase = 0,\r
43         \r
44         X_NET_GIMR_lastHashString,\r
45         \r
46         X_NET_GIMR_isReceiveBatches, X_NET_GIMR_receivedString = '';\r
47 \r
48 \r
49 function X_NET_GIMR_detectImageOverIframe(){\r
50         var raw = this[ '_rawObject' ],\r
51                 iwin, ret, n, error, data = null, zero, e;\r
52         \r
53         if( raw ){\r
54                 iwin = raw.contentWindow || ( raw.contentDocument && raw.contentDocument.parentWindow ) || window.frames[ X_NET_GIMR_iframeName ];\r
55                 \r
56                 if( iwin && iwin.frames && iwin.frames.length ){\r
57                         ret = X_NET_GIMR_detection( iwin.frames );\r
58                         if( ret && ret !== X_NET_GIMR_lastHashString ){\r
59                                 X_NET_GIMR_lastHashString = ret;\r
60                                 //console.log( ret.length );\r
61                                 //console.log( '' + ret );\r
62                                 \r
63                                 switch( X_NET_GIMR_phase ){\r
64                                         case 0 : // makeRequest\r
65                                                 iwin.location.href = X_NET_GIMR_GADGET_URL + '#' + X_NET_GIMR_requestBatches.shift();\r
66                                                 if( X_NET_GIMR_requestBatches.length ) return; //TODO boost\r
67                                                 break;\r
68                                                 \r
69                                         case 1 : // after makeRequest > :ok 待ち\r
70                                                 iwin.location.href = X_NET_GIMR_GADGET_URL + '#_waiting_';\r
71                                                 break;\r
72 \r
73                                         case 2 : // _waiting_ 通信結果待ち\r
74                                                 // 分割受信モードか?\r
75                                                 ret = ret.substr( 1 );\r
76                                                 n   = parseInt( ret );\r
77                                                 \r
78                                                 if( X_NET_GIMR_isReceiveBatches ){\r
79                                                         X_NET_GIMR_receivedString += X_Net_GIMR_decodeLocationHash( ret );                                              \r
80                                                         if( --X_NET_GIMR_isReceiveBatches ){\r
81                                                                 iwin.location.href = X_NET_GIMR_GADGET_URL + '#_recived_' + X_NET_GIMR_isReceiveBatches;\r
82                                                                 return;\r
83                                                         };\r
84                                                 } else\r
85                                                 if( 1 < n ){\r
86                                                         ret = ret.substr( ( n + ':' ).length );\r
87                                                         X_NET_GIMR_receivedString   = X_Net_GIMR_decodeLocationHash( ret );\r
88                                                         X_NET_GIMR_isReceiveBatches = --n;\r
89                                                         iwin.location.href = X_NET_GIMR_GADGET_URL + '#_recived_' + X_NET_GIMR_isReceiveBatches;\r
90                                                         // speedup\r
91                                                         X_NET_GIMR_timerID = X_Timer_add( 16, 0, this, X_NET_GIMR_detectImageOverIframe );\r
92                                                         return X_Callback_UN_LISTEN;\r
93                                                 } else {\r
94                                                         X_NET_GIMR_receivedString = X_Net_GIMR_decodeLocationHash( ret );\r
95                                                 };\r
96 \r
97                                                 ret = X_String_parseTrustedJsonString( X_NET_GIMR_receivedString );\r
98                                                 \r
99                                                 \r
100                                                 X_NET_GIMR_receivedString = '';\r
101                                                 \r
102                                                 error = ret[ 'errors' ] && ret[ 'errors' ].length;\r
103                                                 \r
104                                                 switch( !error && X_NET_GIMR_requestOriginal[ 'dataType' ] ){\r
105                                                         case 'json' :\r
106                                                                 data = X_String_parseTrustedJsonString( ret[ 'json' ] || ret[ 'text' ] || '' );\r
107                                                                 break;\r
108                                                 };\r
109                                                 \r
110                                                 //console.dir( data || ret );\r
111                                                 \r
112                                                 X_NET_GIMRWrapper._busy = false;\r
113                                                 \r
114                                                 if( error || ret[ 'rc' ] < 200 || 400 < ret[ 'rc' ] ){\r
115                                                         e = {\r
116                                                                 type      : X_EVENT_ERROR,\r
117                                                                 status    : ret[ 'rc' ] || ret[ 'code' ] || 400,\r
118                                                                 'message' : error && ret[ 'errors' ].join( '\n' )\r
119                                                         };\r
120                                                 } else {\r
121                                                         e = {\r
122                                                                 type      : X_EVENT_SUCCESS,\r
123                                                                 status    : ret[ 'rc' ] || 200,\r
124                                                                 response  : data\r
125                                                         };\r
126                                                 };\r
127                                                 \r
128                                                 e[ 'headers' ] = ret[ 'headers' ];\r
129                                                 \r
130                                                 X_NET_GIMRWrapper[ 'asyncDispatch' ]( e );\r
131                                                 \r
132                                                 //console.dir( e );\r
133 \r
134                                                 X_NET_GIMR_timerID = X_NET_GIMR_phase = 0;\r
135                                                 X_NET_GIMR_lastHashString = '';                                                 \r
136                                                 iwin.location.href = X_NET_GIMR_GADGET_URL + '#_recived_';\r
137                                                 \r
138                                                 return X_Callback_UN_LISTEN;\r
139                                 };\r
140                                 ++X_NET_GIMR_phase;\r
141                         };\r
142                 };\r
143         };\r
144 };\r
145 \r
146 // http://outcloud.blogspot.jp/2015/06/gecko-location-hash.html\r
147 function X_Net_GIMR_decodeLocationHash( str ){\r
148         return X_UA[ 'Gecko' ] ? unescape( str ) : decodeURIComponent( str );\r
149 };\r
150 \r
151 X_TEMP.X_Net_GIMR_init = function(){\r
152         X_NET_GIMRWrapper = X_Class_override(\r
153                         X_Node_systemNode\r
154                                 .create( 'iframe', {\r
155                                         className         : 'hidden-iframe',\r
156                                         name              : X_NET_GIMR_iframeName,\r
157                                         id                : X_NET_GIMR_iframeName,\r
158                                         src               : X_NET_GIMR_GADGET_URL + '#' + encodeURIComponent(\r
159                                                         X_JSON_stringify( {\r
160                                                                 'img'  : X_URL_toAbsolutePath( X_NET_GIMR_IMAGE_URL ),\r
161                                                                 'len'  : X_NET_GIMR_maxQueryLength,\r
162                                                                 'itvl' : 333,\r
163                                                                 'gck'  : X_UA[ 'Gecko' ] ? 1 : 0\r
164                                                         } )\r
165                                                 ),\r
166                                         scrolling         : 'no',\r
167                                         allowtransparency : 'no',                                       \r
168                                         frameborder       : 0,\r
169                                         tabindex          : -1\r
170                                         }),\r
171                         X_TEMP.X_Net_GIMR_props );\r
172         \r
173         delete X_TEMP.X_Net_GIMR_init;\r
174         delete X_TEMP.X_Net_GIMR_props; \r
175         \r
176         X_NET_GIMR_requestBatches = [];\r
177         \r
178         return X_NET_GIMRWrapper;\r
179 };\r
180 \r
181 X_TEMP.X_Net_GIMR_props = {\r
182 \r
183                 _busy         : false,\r
184                 _canceled     : false,\r
185                 _onloadCount  : 0,\r
186                 \r
187                 load : function( obj ){\r
188                         var req = {},\r
189                                 k, max, sendStr, l, str;\r
190                         //createURL\r
191 \r
192                         X_NET_GIMR_requestOriginal = obj;\r
193                         \r
194                         for( k in obj ){\r
195                                 switch( k ){\r
196                                         case 'url' :\r
197                                         case 'postdata' :\r
198                                         case 'method' :\r
199                                         case 'dataType' :\r
200                                         case 'headers' :\r
201                                         case 'cashe' :\r
202                                                 req[ k ] = obj[ k ];\r
203                                                 break;\r
204                                 };\r
205                         };\r
206                         \r
207                         max = X_NET_GIMR_maxQueryLength - X_NET_GIMR_GADGET_URL.length - 5;\r
208                         \r
209                         sendStr = X_JSON_stringify( req );\r
210                         \r
211                         while( sendStr.length ){\r
212                                 l   = max;\r
213                                 str = encodeURIComponent( sendStr.substr( 0, l ) );\r
214                                 while( max < str.length ){\r
215                                         l   = l * ( 2 + l / str.length ) / 3 | 0;\r
216                                         str = encodeURIComponent( sendStr.substr( 0, l ) );\r
217                                         //console.log( l );\r
218                                 };\r
219                                 X_NET_GIMR_requestBatches.push( str );\r
220                                 sendStr = sendStr.substr( l );\r
221                                 str = '';\r
222                         };\r
223                         \r
224                         sendStr = '';\r
225                         \r
226                         if( 1 < X_NET_GIMR_requestBatches.length ){\r
227                                 X_NET_GIMR_requestBatches[ 0 ] = X_NET_GIMR_requestBatches.length + ':' + X_NET_GIMR_requestBatches[ 0 ];       \r
228                         };\r
229                         \r
230                         X_NET_GIMR_timerID = X_Timer_add( 333, 0, this, X_NET_GIMR_detectImageOverIframe );\r
231                         \r
232                         this._busy = true;\r
233                 },\r
234                 \r
235                 cancel : function(){\r
236                         this._canceled = true;\r
237                 },\r
238                 \r
239                 reset : function(){\r
240                         this._busy = this._canceled = false;\r
241                         this._onloadCount = 0;\r
242                 }\r
243         };\r
244 \r
245 //}+xhrgadget