OSDN Git Service

9e3e810c4f4f0dd81be9f4fa8af3e34b7c39f87d
[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 \r
9 // TODO Node.inherits\r
10 X[ 'Util' ][ 'NinjaIframe' ] = Node[ 'inherits' ](\r
11         'NinjaIframe',\r
12         {\r
13                 autoRefresh  : 0,\r
14                 \r
15                 _iwin        : null,\r
16                 \r
17                 _contentHTML : '',\r
18                 _name        : '',\r
19                 _ready       : false,\r
20                 \r
21                 'Constructor' : function( html ){\r
22                         \r
23                         this._name = 'hidden-iframe-' + X_Timer_now();\r
24                         // https://github.com/polygonplanet/Pot.js/blob/master/src/Worker.js\r
25 \r
26                         X_Node_newByTag = true;\r
27 \r
28                         this[ 'Super' ](\r
29                                 'IFRAME',\r
30                                 {\r
31                                         className         : 'hidden-iframe',\r
32                                         scrolling         : 'no',\r
33                                         allowtransparency : 'no',                                       \r
34                                         frameborder       : 0,\r
35                                         tabindex          : -1,\r
36                                         name              : this._name,\r
37                                         id                : this._name\r
38                                 }\r
39                         );\r
40                         \r
41                         // http://nanto.asablo.jp/blog/2011/12/08/6237308\r
42                         // IE 6/7 で文書間通信を実現するための一案\r
43                         if( X_UA[ 'IE' ] < 9 ){\r
44                                 this[ 'attr' ]( 'src', 'about:blank' );\r
45                         };\r
46                         // Safari 2.0.* bug: iframe's absolute position and src set.\r
47                         if( !X_UA[ 'Webkit' ]  ){\r
48                                 this[ 'css' ]( { position : 'absolute' } );\r
49                         };\r
50                         \r
51                         if( html ) this._contentHTML = html;                    \r
52                         \r
53                         this[ 'appendTo' ]( X_Node_body /* X_Node_systemNode */ );\r
54                         \r
55                         X_ViewPort[ 'listenOnce' ]( X_EVENT_AFTER_UPDATE, this, X_Util_NinjaIframe_handleEvent );\r
56                 },\r
57                 \r
58                 'refresh' : function( opt_contentHTML ){\r
59                         var raw = this[ '_rawObject' ],\r
60                                 idoc;\r
61                                 \r
62                         this._ready = false;\r
63                         \r
64                         if( !this._iwin ){\r
65                                 this._contentHTML = opt_contentHTML;\r
66                                 return this;\r
67                         };\r
68                         \r
69                         if( X_UA[ 'IE5x' ] ){\r
70                                 this._iwin.location.href = 'about:blank'; // reload() では、IE5.5(IETester)で2回目移行の操作でerrorが出る(doc取得やopen,writeで)\r
71                         } else {\r
72                                 this._iwin.location.reload();\r
73                         };\r
74                         \r
75                         if( !opt_contentHTML && opt_contentHTML !== '' ) return this;\r
76                         \r
77                         this._contentHTML = opt_contentHTML;\r
78                         X_UA[ 'IE' ] < 9 || X_Util_NinjaIframe_writeToIframe( this );\r
79                         \r
80                         return this;\r
81                 },\r
82                 \r
83                 // TODO close -> kill\r
84                 'close' : function(){\r
85                         X_ViewPort[ 'unlisten' ]( X_EVENT_AFTER_UPDATE, this, X_Util_NinjaIframe_handleEvent );\r
86                         this.call( 'close' );\r
87                         this[ 'kill' ]();\r
88                 }\r
89                 \r
90         }\r
91 );\r
92 \r
93 \r
94 function X_Util_NinjaIframe_handleEvent( e ){\r
95         var raw = this[ '_rawObject' ];\r
96         \r
97         switch( e.type ){\r
98                 case X_EVENT_AFTER_UPDATE :\r
99                         this._iwin = raw.contentWindow || ( raw.contentDocument && raw.contentDocument.parentWindow ) || window.frames[ this._name ];\r
100                         // http://d.hatena.ne.jp/NeoCat/20080921/1221940658\r
101                         // こちらに名前をsetしないとtargetが動作しない\r
102                         if( X_UA[ 'IE' ] ) this._iwin.name = this._name;\r
103                         \r
104                         this[ 'listen' ]( [ X_UA[ 'IE' ] < 9 ? 'readystatechange' : 'load', 'error' ], this, X_Util_NinjaIframe_handleEvent );\r
105                         \r
106                         if( !( X_UA[ 'IE' ] < 9 ) ){\r
107                                 ( this._contentHTML || this._contentHTML === '' ) && X_Util_NinjaIframe_writeToIframe( this );\r
108                                 this._ready = true;\r
109                                 return;\r
110                         };\r
111                         //break; これあると IE8 で駄目!\r
112                         \r
113                 case 'readystatechange' :\r
114                         if( ( raw.readyState !== 'complete' && raw.readyState !== 'loaded' ) ) break;\r
115                         // ie9-\r
116                         if( !this._ready ){\r
117                                 ( this._contentHTML || this._contentHTML === '' ) && X_Util_NinjaIframe_writeToIframe( this );\r
118                                 this._ready = true;\r
119                                 break;\r
120                         };\r
121                         // onload\r
122                 case 'load' :\r
123                         console.log( 'iframe load.' );\r
124                         this[ 'asyncDispatch' ]( 'ninjaload' );\r
125                         break;\r
126 \r
127                 case 'error' :\r
128                         this[ 'asyncDispatch' ]( 'ninjaerror' );\r
129                         break;\r
130         };\r
131         \r
132         return X_Callback_STOP_PROPAGATION;\r
133 };\r
134 \r
135 function X_Util_NinjaIframe_writeToIframe( that ){\r
136         var raw  = that[ '_rawObject' ],\r
137                 idoc = raw.contentDocument || that._iwin.document,\r
138                 html = that._contentHTML;\r
139                 \r
140         delete that._contentHTML;\r
141         that._ready = true;\r
142 \r
143         idoc.open();\r
144         idoc.writeln( html );\r
145         idoc.close();\r
146 };\r
147 \r