--- /dev/null
+\r
+X.Dom.Image = {\r
+ _actualSize : {},\r
+ \r
+/*\r
+ * original\r
+ * LICENSE: MIT\r
+ * AUTHOR: uupaa.js@gmail.com\r
+ */ \r
+ getActualDimension : function( XnodeOrImageElemOrSrc ){\r
+ var xnode, img, remove, ret, run, memW, memH, w, h;\r
+ \r
+ if( X.Type.isString( XnodeOrImageElemOrSrc ) ){\r
+ if( ret = X.Dom.Image._actualSize[ X.Dom.getAbsolutePath( XnodeOrImageElemOrSrc ) ] ) return ret;\r
+ \r
+ xnode = X.Dom.Node._systemNode.create(\r
+ 'img',\r
+ {\r
+ src : XnodeOrImageElemOrSrc\r
+ },\r
+ {\r
+ position : 'absolute'\r
+ }\r
+ );\r
+ Node._body._startUpdate();\r
+ img = xnode._ie4getRawNode ? xnode._ie4getRawNode() : xnode._rawNode;\r
+ remove = true;\r
+ } else {\r
+ if( XnodeOrImageElemOrSrc.constructor === X.Dom.Node ){\r
+ xnode = XnodeOrImageElemOrSrc;\r
+ img = xnode._ie4getRawNode ? xnode._ie4getRawNode() : xnode._rawNode;\r
+ } else\r
+ if( X.Type.isHTMLElement( XnodeOrImageElemOrSrc ) ){\r
+ img = XnodeOrImageElemOrSrc;\r
+ } else {\r
+ return;\r
+ };\r
+ if( ret = X.Dom.Image._actualSize[ img.src ] ) return ret;\r
+ };\r
+\r
+ // for Firefox, Safari, Google Chrome\r
+ if( img.naturalWidth ) return [ img.naturalWidth, img.naturalHeight ];\r
+ \r
+ if( X.UA.IE && 5 <= X.UA.IE ){// for IE\r
+ run = img.runtimeStyle;\r
+ memW = run.width;\r
+ memH = run.height;\r
+ \r
+ // keep runtimeStyle\r
+ run.width = 'auto';\r
+ // override\r
+ run.height = 'auto';\r
+ w = img.width;\r
+ h = img.height;\r
+ run.width = memW;\r
+ // restore\r
+ run.height = memH;\r
+ } else {// for Opera and Other\r
+ \r
+ memW = w = img.width;\r
+ memH = h = img.height;\r
+ \r
+ if( img.removeAttribute ){ // Safari1.3 の Image は removeAttribute がない\r
+ // keep current style\r
+ img.removeAttribute( 'width' );\r
+ img.removeAttribute( 'height' );\r
+ \r
+ w = img.width;\r
+ h = img.height;\r
+ \r
+ // restore\r
+ img.width = memW;\r
+ img.height = memH;\r
+ };\r
+ };\r
+ \r
+ ret = X.Dom.Image._actualSize[ img.src ] = [ w, h ];\r
+ \r
+ remove && xnode.destroy();\r
+ \r
+ return ret;\r
+ },\r
+ \r
+ /* \r
+ * original\r
+ * LICENSE: MIT?\r
+ * URL: http://d.hatena.ne.jp/uupaa/20080413/1208067631\r
+ * AUTHOR: uupaa.js@gmail.com\r
+ * \r
+ */\r
+ Loader : X.EventDispatcher.inherits(\r
+ 'ImageLoader',\r
+ X.Class.POOL_OBJECT,\r
+ {\r
+ xnode : null,\r
+ size : null,\r
+ tick : 0,\r
+ timerID : 0,\r
+ finish : false,\r
+ abspath : null,\r
+ delay : null,\r
+ timeout : 0,\r
+ Constructor : function( abspath, delay, timeout ){\r
+ var img;\r
+ \r
+ this.abspath = abspath;\r
+ this.delay = delay || 100;\r
+ this.timeout = timeout || 10000;\r
+ this.xnode =\r
+ (\r
+ window[ 'Image' ] ?\r
+ X.Dom.Node( img = new Image() ) :\r
+ X.Dom.Node._systemNode.create( 'img', { src : abspath } )\r
+ )\r
+ .listen( [ 'load', 'error', 'abort', X.Event.SUCCESS, X.Event.ERROR ], this );\r
+ img && ( img.src = abspath );\r
+ this._detect();\r
+ },\r
+ handleEvent : function( e ){\r
+ var size;\r
+ switch( e.type ){\r
+ case 'error' :\r
+ case 'abort' :\r
+ if( this.finish ) return;\r
+ this.finish = true;\r
+ this.timerID = this.asyncDispatch( 0, { type : X.Event.ERROR } );\r
+ break;\r
+ case 'load' :\r
+ // if( finish === true ) return; // これがあると firefox3.6 で駄目、、、\r
+ // if( timer ) return; // これがあると safari3.2 で駄目、、、\r
+ this.finish = true;\r
+ this.timerID && X.Timer.remove( this.timerID );\r
+ if( window.opera && !this.xnode._rawNode.complete ){\r
+ this.timerID = this.asyncDispatch( 0, { type : X.Event.ERROR } );\r
+ return;\r
+ };\r
+ size = X.Dom.Image.getActualDimension( X.UA.IE && X.UA.IE < 9 && window.Image ? this.abspath : this.xnode );\r
+ this.timerID = this.asyncDispatch( 0, {\r
+ type : X.Event.SUCCESS,\r
+ src : this.abspath,\r
+ w : size[ 0 ],\r
+ h : size[ 1 ]\r
+ } );\r
+ break;\r
+ case X.Event.SUCCESS :\r
+ case X.Event.ERROR :\r
+ delete this.timerID;\r
+ X.Timer.once( 0, this, this.kill );\r
+ break;\r
+ };\r
+ }, \r
+ _detect : function(){\r
+ if( this.finish === true ) return;\r
+ if( this.xnode._rawNode && this.xnode._rawNode.complete ){\r
+ this.finish = true;\r
+ if( this.xnode._rawNode.width ) return;\r
+ this.timerID = this.asyncDispatch( 0, { type : X.Event.ERROR } );\r
+ return;\r
+ };\r
+ if( ( this.tick += this.delay ) > this.timeout ){\r
+ this.finish = true;\r
+ this.timerID = this.asyncDispatch( 0, { type : X.Event.ERROR, msg : 'timeout' } );\r
+ return;\r
+ };\r
+ this.timerID = X.Timer.once( this.delay, this, this._detect );\r
+ },\r
+ stop : function(){\r
+ // if( this.dispatch( { type : X.Event.BEFORE_CANCEL } ) & X.Callback.CANCEL_NOW ) return;\r
+ \r
+ // this.dispacth( { type : X.Event.CANCELED } );\r
+ this.kill();\r
+ },\r
+ onKill : function(){\r
+ this.timerID && X.Timer.remove( this.timerID );\r
+ this.xnode.destroy();\r
+ this.unlisten();\r
+ }\r
+ }\r
+ )\r
+};\r