OSDN Git Service

961190005105873276b24128bc6f68936fbfe274
[pettanr/clientJs.git] / 0.6.x / js / 06_net / 04_XNetImage.js
1 //{+netimage"画像の読み込み監視"(Imageの読み込みを監視し画像表示のコントロールを行う)[+net,+utilimage]\r
2 /* \r
3  * original\r
4  *  LICENSE: MIT?\r
5  *  URL: http://d.hatena.ne.jp/uupaa/20080413/1208067631\r
6  *  AUTHOR: uupaa.js@gmail.com\r
7  * \r
8  */\r
9 var X_ImgLoader_image     = window[ 'Image' ] && new Image(),\r
10         // IE では厳密には HTMLImageElement ではなく、appendChild してもサイズが取れず、removeChild に失敗する\r
11         X_ImgLoader_isElement = !( X_UA[ 'IE' ] < 9 ) && X_Type_isHTMLElement( X_ImgLoader_image ),\r
12         // http://uupaa.hatenablog.com/entry/2013/12/17/171809\r
13         // お手軽に画像の読み込みをハンドリングする、今どきな方法\r
14         X_ImgLoader_0forError = !X_UA[ 'IE' ] || X_UA[ 'IE' ] === 11 || X_UA[ 'IEHost' ] === 11;\r
15 \r
16 /*\r
17  * TODO\r
18  * new Image() のときに Image オブジェクトを作るもの(IE8-)と、HTMLImageElement を作るものがある。\r
19  * Image は、X.EventDispatcher で、<img> は X.Node で。 \r
20  */\r
21 \r
22 X_TEMP.X_ImgLoader_init = function(){\r
23         X_ImgLoader = X_Class_override(\r
24                 X_ImgLoader_isElement ? Node( X_ImgLoader_image ) : X_EventDispatcher( X_ImgLoader_image ),\r
25                 X_TEMP.X_ImgLoader_params\r
26         );\r
27         \r
28         X_ImgLoader[ 'listen' ]( [ 'load', 'error' /*, 'abort'*/ ], X_ImgLoader_handleEvent );\r
29         \r
30         delete X_TEMP.X_ImgLoader_init;\r
31         delete X_TEMP.X_ImgLoader_params;\r
32         \r
33         return X_ImgLoader;\r
34 };\r
35 \r
36 X_TEMP.X_ImgLoader_params = {\r
37                 tick       : 0,\r
38                 timerID    : 0,\r
39                 finish     : false,\r
40                 abspath    : '',\r
41                 delay      : 0,\r
42                 timeout    : 0,\r
43                 \r
44                 load : function( data ){\r
45                         this.abspath = X_URL_toAbsolutePath( data[ 'url' ] );\r
46                         this.delay   = data[ 'delay'   ] || 100;\r
47                         this.timeout = data[ 'timeout' ] || 5000;\r
48 \r
49                         this[ '_rawObject' ].src = this.abspath;\r
50 \r
51                         if( X_UA[ 'Opera7' ] && this[ '_rawObject' ].complete ){\r
52                                 this[ 'asyncDispatch' ]( 'load' );\r
53                         } else {\r
54                                 this.timerID = X_Timer_add( this.delay, 0, this, X_ImgLoader_detect );\r
55                         };\r
56                 },\r
57                 \r
58                 cancel : function(){\r
59                         var raw = this[ '_rawObject' ];\r
60                         // abort がある?\r
61                         raw && raw.abort && raw.abort();\r
62                         // this[ '_rawObject' ].src = '';\r
63                         this.finish = true;\r
64                 },\r
65                 \r
66                 reset : function(){\r
67                         //console.log( '/ X.Net.Image:reset ' + this.abspath + ' timerID:' + this.timerID );\r
68                         \r
69                         this.timerID && X_Timer_remove( this.timerID );\r
70                         this.timerID = 0;\r
71                         \r
72                         this.finish  = false;\r
73                         this.abspath = '';                      \r
74                         //X_ImgLoader_isElement ? this[ '_rawObject' ].removeAttribute( 'src' ) : ( this[ '_rawObject' ].src = '' );\r
75                         this[ '_rawObject' ].src = '';\r
76                         \r
77                         //console.log( '\ X.Net.Image:reset ----------- *' );\r
78                 }\r
79         };\r
80 \r
81 function X_ImgLoader_detect(){\r
82         var raw = this[ '_rawObject' ];\r
83         \r
84         if( this.finish ) return;\r
85         \r
86         if( raw && raw.complete ){\r
87                 this.finish = true;\r
88                 //console.log( 'X.Net.Image:detect ' + raw.width );\r
89                 if( raw.width ) return;\r
90                 X_Timer_remove( this.timerID );\r
91                 //console.log( '* X.Net.Image:ERROR @detect(1) ' + this.abspath );\r
92                 this.timerID = this[ 'asyncDispatch' ]( X_EVENT_ERROR );\r
93         } else\r
94         if( this.timeout < ( this.tick += this.delay ) ){\r
95                 this.finish = true;\r
96                 X_Timer_remove( this.timerID );\r
97                 //console.log( '* X.Net.Image:ERROR @detect(2) ' + this.abspath );\r
98                 this.timerID = this[ 'asyncDispatch' ]( { type : X_EVENT_ERROR, 'timeout' : true } );\r
99         };\r
100 };\r
101 \r
102 function X_ImgLoader_handleEvent( e ){\r
103         var raw = this[ '_rawObject' ], size;\r
104         \r
105         // IE11 reset() 時にここに入ってくる...\r
106         if( !this.abspath ) return;\r
107         //console.log( 'X.Net.Image:handleEvent ' + e.type );\r
108         \r
109         switch( e.type ){\r
110                 case 'error' :\r
111                         // ie11(10,9 開発モード)で mineType 不正の場合、画像取得に成功してもエラーイベントが起こるのを無視する。\r
112                         if( X_ImgLoader_0forError && raw.width ) return;\r
113                         if( this.finish ) return;\r
114                         this.finish  = true;\r
115                         this.timerID && X_Timer_remove( this.timerID );\r
116                         //console.log( '* X.Net.Image:ERROR @handle ' + this.abspath + X.Timer.now() );\r
117                         //console.dir( raw );\r
118                         this.timerID = this[ 'asyncDispatch' ]( this.timeout, X_EVENT_ERROR );\r
119                         break;\r
120 \r
121                 case 'load' :\r
122                 // if( finish === true ) return; // これがあると firefox3.6 で駄目、、、\r
123                 // if( timer ) return; // これがあると safari3.2 で駄目、、、\r
124                         this.finish = true;\r
125                         this.timerID && X_Timer_remove( this.timerID );\r
126                         if( X_UA[ 'Opera' ] && !raw.complete ){\r
127                                 this.timerID = this[ 'asyncDispatch' ]( X_EVENT_ERROR );\r
128                                 return;\r
129                         };\r
130 \r
131                         //console.log( '* X.Net.Image:LOAD @handle ' + this.abspath + X.Timer.now() );\r
132                         //console.dir( raw );\r
133                         \r
134                         size = X_Util_Image_getActualDimension( !X_ImgLoader_isElement ? this.abspath : this );\r
135                         this.timerID = this[ 'asyncDispatch' ]( {\r
136                                 'type' : X_EVENT_SUCCESS,\r
137                                 'src'  : this.abspath,\r
138                                 'w'    : size[ 0 ],\r
139                                 'h'    : size[ 1 ]\r
140                                 // TODO feedback net speed\r
141                                 // time , this[ '_rawObject' ].fileSize\r
142                         } );\r
143                         break;\r
144         };\r
145 };\r
146 \r
147 \r
148 // X_ImgLoader_isElement && X_ImgLoader[ 'appendAt' ]( X_Node_systemNode );\r