OSDN Git Service

702706dfde0c0c342219165108b38a0c4701c3c1
[pettanr/clientJs.git] / 0.6.x / js / 05_util / 01_XNinjaIframe.js
1 /**\r
2  * http://msdn.microsoft.com/ja-jp/library/ie/hh180174%28v=vs.85%29.aspx\r
3  * 孤立するとウィンドウ オブジェクトのプロパティが消去される\r
4  * \r
5  * http://qiita.com/sou/items/3380d4fa9b08b27bb387\r
6  * モバイルブラウザでの iframe の挙動(Mobile Safari, Chrome for Android)\r
7  * \r
8  * @alias X.Util.NinjaIframe\r
9  * @class NinjaIframe 隠し iframe 機能を提供します。\r
10  * @constructs NinjaIframe\r
11  * @extends {Node}\r
12  */\r
13 var X_NinjaIframe = X[ 'Util' ][ 'NinjaIframe' ] = Node[ 'inherits' ](\r
14         'NinjaIframe',\r
15         {\r
16                 autoRefresh  : 0,\r
17                 \r
18                 _iwin        : null,\r
19                 \r
20                 _contentHTML : '',\r
21                 _name        : '',\r
22                 _ready       : false,\r
23                 \r
24                 'Constructor' : function( html ){\r
25                         \r
26                         this._name = 'hidden-iframe-' + X_Timer_now();\r
27                         // https://github.com/polygonplanet/Pot.js/blob/master/src/Worker.js\r
28 \r
29                         X_Node_newByTag = true;\r
30 \r
31                         this[ 'Super' ](\r
32                                 'IFRAME',\r
33                                 {\r
34                                         className         : 'hidden-iframe',\r
35                                         scrolling         : 'no',\r
36                                         allowtransparency : 'no',                                       \r
37                                         frameborder       : 0,\r
38                                         tabindex          : -1,\r
39                                         name              : this._name,\r
40                                         id                : this._name\r
41                                 }\r
42                         );\r
43                         \r
44                         // http://nanto.asablo.jp/blog/2011/12/08/6237308\r
45                         // IE 6/7 で文書間通信を実現するための一案\r
46                         if( X_UA[ 'IE' ] < 9 ){\r
47                                 this[ 'attr' ]( 'src', 'about:blank' );\r
48                         };\r
49                         // Safari 2.0.* bug: iframe's absolute position and src set.\r
50                         if( !X_UA[ 'Webkit' ]  ){\r
51                                 this[ 'css' ]( { position : 'absolute' } );\r
52                         };\r
53                         \r
54                         if( html ) this._contentHTML = html;                    \r
55                         \r
56                         this[ 'appendTo' ]( X_Node_systemNode )\r
57                                 [ 'listenOnce' ]( X_EVENT_KILL_INSTANCE, X_Util_NinjaIframe_handleEvent );\r
58                         \r
59                         X_ViewPort[ 'listenOnce' ]( X_EVENT_AFTER_UPDATE, this, X_Util_NinjaIframe_handleEvent );\r
60                 },\r
61                 \r
62                 'refresh' : function( opt_contentHTML ){\r
63                         var raw = this[ '_rawObject' ],\r
64                                 idoc;\r
65                                 \r
66                         this._ready = false;\r
67                         \r
68                         if( !this._iwin ){\r
69                                 this._contentHTML = opt_contentHTML;\r
70                                 return this;\r
71                         };\r
72                         \r
73                         if( X_UA[ 'IE5x' ] ){\r
74                                 this._iwin.location.href = 'about:blank'; // reload() では、IE5.5(IETester)で2回目移行の操作でerrorが出る(doc取得やopen,writeで)\r
75                         } else {\r
76                                 this._iwin.location.reload();\r
77                         };\r
78                         \r
79                         if( !X_Type_isString( opt_contentHTML ) ) return this;\r
80                         \r
81                         this._contentHTML = opt_contentHTML;\r
82 \r
83                         if( !( X_UA[ 'IE' ] < 9 ) ){\r
84                                 X_Util_NinjaIframe_writeToIframe( this );\r
85                                 //this._ready = true;\r
86                         };\r
87                         \r
88                         return this;\r
89                 }\r
90                 \r
91         }\r
92 );\r
93 \r
94 \r
95 function X_Util_NinjaIframe_handleEvent( e ){\r
96         var raw = this[ '_rawObject' ];\r
97         \r
98         switch( e.type ){\r
99                 case X_EVENT_AFTER_UPDATE :\r
100                         this._iwin = raw.contentWindow || ( raw.contentDocument && raw.contentDocument.parentWindow ) || window.frames[ this._name ];\r
101                         // http://d.hatena.ne.jp/NeoCat/20080921/1221940658\r
102                         // こちらに名前をsetしないとtargetが動作しない\r
103                         if( X_UA[ 'IE' ] ) this._iwin.name = this._name;\r
104                         \r
105                         this[ 'listen' ]( X_UA[ 'IE' ] < 9 ? 'readystatechange' : [ 'load', 'error' ], X_Util_NinjaIframe_handleEvent );\r
106                         \r
107                         if( !( X_UA[ 'IE' ] < 9 ) ){\r
108                                 X_Util_NinjaIframe_writeToIframe( this );\r
109                                 //this._ready = true;\r
110                                 return;\r
111                         };\r
112                         //break; これあると IE8 で駄目!\r
113                         \r
114                 case 'readystatechange' :\r
115                         if( ( raw.readyState !== 'complete' && raw.readyState !== 'loaded' ) ) break;\r
116                         // ie9-\r
117                         if( !this._ready ){\r
118                                 X_Util_NinjaIframe_writeToIframe( this );\r
119                                 //this._ready = true;\r
120                                 break;\r
121                         };\r
122                         // onload\r
123                 case 'load' :\r
124                         console.log( 'iframe load.' );\r
125                         this[ 'asyncDispatch' ]( 'ninjaload' );\r
126                         break;\r
127 \r
128                 case 'error' :\r
129                         this[ 'asyncDispatch' ]( 'ninjaerror' );\r
130                         break;\r
131                 \r
132                 case X_EVENT_KILL_INSTANCE :\r
133                         X_ViewPort[ 'unlisten' ]( X_EVENT_AFTER_UPDATE, this, X_Util_NinjaIframe_handleEvent );\r
134                         this._iwin && this._iwin.close();\r
135                         break;\r
136         };\r
137         \r
138         return X_CALLBACK_STOP_PROPAGATION;\r
139 };\r
140 \r
141 function X_Util_NinjaIframe_writeToIframe( that ){\r
142         var raw  = that[ '_rawObject' ],\r
143                 idoc = raw.contentDocument || that._iwin.document,\r
144                 html = that._contentHTML;\r
145         \r
146         that._ready = true; // これを削除すると ie6,7,8 で Stack overflow at line : 0 意味不明\r
147         delete that._contentHTML;\r
148 \r
149         idoc.open();\r
150         idoc.writeln( html );\r
151         idoc.close();\r
152 };\r
153 \r