X.getTime = Date.now ? new Function( 'return Date.now()' ) : new Function( 'return +new Date' );\r
\r
X.emptyFunction = new Function;\r
- \r
+\r
// defer の場合もあるので、document.readyState を見る\r
X.inHead = (function( s ){\r
if( !s ) return false;\r
+ if( !s.length ) return false; // Safari1.3 312.8 でerror\r
s = s[ s.length - 1 ];\r
// Dom0 || Dom1\r
return ( s.parentElement || s.parentNode ).tagName.toLowerCase() === 'head';\r
\r
// bonus: hotfix for IE6 SP1 (bug KB823727)\r
document.execCommand && document.execCommand( 'BackgroundImageCache', false, true );\r
-document.execCommand && document.execCommand( 'LiveResize', false, false );\r
-document.execCommand && document.execCommand( 'SizeToControl', false, false );
\ No newline at end of file
+//document.execCommand && document.execCommand( 'LiveResize', false, false );\r
+//document.execCommand && document.execCommand( 'SizeToControl', false, false );\r
+\r
/*\r
* UA\r
*/\r
-\r
X.UA = (function( n, undefined ){\r
var acme = {},\r
dua = n.userAgent,\r
i = Math.max(dav.indexOf("WebKit"), dav.indexOf("Safari"), 0);\r
if( i && !acme.Chrome ){\r
acme.Safari = parseFloat( dav.split("Version/")[1] );\r
- if( !acme.Safari || parseFloat(dav.substr( i + 7 )) <= 419.3 ){\r
+ i = parseFloat(dav.substr( i + 7 ));\r
+ if( !acme.Safari && i < 100 ){\r
+ acme.Safari = 1;\r
+ };\r
+ if( !acme.Safari && i < 125 ){\r
+ acme.Safari = 1.1;\r
+ };\r
+ if( !acme.Safari && i < 312 ){\r
+ acme.Safari = 1.2;\r
+ };\r
+ if( !acme.Safari && i < 412 ){\r
+ acme.Safari = 1.3;\r
+ };\r
+ if( !acme.Safari && i <= 419.3 ){\r
acme.Safari = 2;\r
};\r
};\r
};\r
return false;\r
}) :\r
- new Function( 'a,b', 'return a in b' );
\ No newline at end of file
+ new Function( 'a,b', 'return a in b' );\r
+ \r
+\r
+// Safari 3.1 未満は開発コンソールがない!\r
+// http://shimax.cocolog-nifty.com/search/2006/09/safarijavascrip_c54d.html\r
+if( X.UA.Safari && X.UA.WebKit < 525.13 ){ \r
+ window.onerror = function( x, y, z ){\r
+ var n = String.fromCharCode( 10 );\r
+ alert('window.onerrorによるエラーの捕捉:' + n + x + n + y + 'の' + z + '行目付近です。');\r
+ return true;\r
+ };\r
+};\r
+\r
+\r
// サブクラスの場合、クラス定義の上書きがなくても作成可能\r
if( !traits ){\r
X.Notification.critical( 'No Class Def!' );\r
- return; \r
+ return;\r
};\r
props = {};\r
} else\r
if( props[ CONSTRUCTOR ] && X.Type.isFunction( props[ CONSTRUCTOR ] ) ){\r
classDef[ CONSTRUCTOR ] = props[ CONSTRUCTOR ];\r
};\r
- \r
+\r
klass = new Function( 'var a=arguments,f=a.callee;if(f.__new)return f.__new(a)' );\r
klass.__new = C;\r
- klass.prototype = X.Class._override( X.Class._override( traits || klass.prototype, props, true ), CommonProps, false );\r
- klass.prototype.constructor = klass;\r
+ if( X.UA.Safari && X.UA.Safari < 2 ){\r
+ traits && X.Class._override( klass.prototype, traits, false );\r
+ X.Class._override( X.Class._override( klass.prototype, CommonProps, false ), props, true );\r
+ } else {\r
+ klass.prototype = X.Class._override( X.Class._override( traits || klass.prototype, props, true ), CommonProps, false );\r
+ klass.prototype.constructor = klass;\r
+ };\r
klass.name = displayName;\r
\r
if( opt_abstract === true ){\r
},\r
/* over のプロパティを target にコピーする.ただし target の プロパティが優先, force で解除 */\r
_override : function ( target, src, force ){\r
- for( var p in src ){\r
+ var p;\r
+ for( p in src ){\r
if( p === 'Super' || p === 'SuperConstructor' ){\r
X.Notification.critical( 'Super & SuperConstructor is reserved!' );\r
return;\r
};\r
- if( force === true || target[ p ] === void 0 ){\r
+ if( force || target[ p ] === void 0 ){\r
target[ p ] = src[ p ];\r
};\r
};\r
info サーバ情報\r
debug デバック用の情報\r
*/\r
+\r
Node._systemNode = Node.create( 'div', { 'class' : 'hidden-system-node' } ),\r
Node._fontSizeNode = Node.create( 'div', { 'class' : 'hidden-system-node' } ).cssText( 'line-height:1;height:1em;' ).text( 'X' )\r
)._startUpdate();\r
- \r
+\r
X.Dom.asyncDispatch( 0, { type : X.Dom.Event.DOM_INIT } );\r
} );\r
\r
.listen( 'beforeunload', X.Dom )\r
.listenOnce( 'unload', X.Dom );\r
\r
+//ブラウザの戻るボタンで戻ったときに呼ばれるイベントとかキャッシュとかそこらへんのこと\r
+//http://d.hatena.ne.jp/koumiya/20080916/1221580149\r
+\r
if( document[ 'hidden' ] !== undefined ) {// iOS 7+\r
Node._document.listen( 'visibilitychange', X.Dom );\r
} else\r
} ) :\r
( function(){\r
Node.root._updateTimerID && Node.root._startUpdate();\r
- return[ X.Dom._root.scrollLeft, X.Dom._root.scrollTop ];\r
+ // body は Safari2-\r
+ return[ X.Dom._root.scrollLeft || document.body.scrollLeft, X.Dom._root.scrollTop || document.body.scrollTop ];\r
} ),\r
\r
getScrollbarSize : function(){\r
// X.Dom.Dirty.CSS を落とす\r
this._dirty = 0;\r
// attr の回収は不可能、、、\r
- if( X.UA.IE && X.UA.IE < 5 ){\r
+ if( X.Dom.DOM_IE4 ){\r
v.setAttribute( 'UID', '' + uid );\r
} else {\r
v.UID = uid;\r
return Node.none;\r
case Node.IS_IMAGE :\r
v.UID = uid;\r
+ this._isImage = true;\r
case Node.IS_WINDOW :\r
case Node.IS_DOCUMENT :\r
+ if( xnode = Node._getXNode( v ) ) return xnode;\r
this._rawNode = v;\r
this._xnodeType = 2;\r
this._state = X.Dom.State.DISPLAY_BLOCK;\r
if( v === window ) return Node.IS_WINDOW;\r
if( v === document ) return Node.IS_DOCUMENT;\r
if( v.constructor === window.Image ) return Node.IS_IMAGE;\r
+ if( X.UA.Safari && X.UA.Safari < 3 ){\r
+ if( v.src !== undefined && v.onload !== undefined && X.Type.isNumber( v.height ) && X.Type.isNumber( v.width ) && X.Type.isBoolean( v.complete ) ){\r
+ return Node.IS_IMAGE;\r
+ };\r
+ }; \r
if( v.constructor === Node ) return Node.IS_XNODE;\r
if( v.constructor === X.Dom.NodeList ) return Node.IS_XNODE_LIST;\r
if( v.tagName ) return Node.IS_RAW_HTML;\r
case Node.IS_RAW_HTML :\r
case Node.IS_IMAGE :\r
// fake TextNode too.\r
- if( X.UA.IE && X.UA.IE < 5 ){\r
+ if( X.Dom.DOM_IE4 ){\r
uid = v.getAttribute( 'UID' );\r
return uid && Node._chashe[ uid ];\r
};\r
};\r
// XMLかどうかを判別する\r
Node.isXmlDocument =\r
- X.UA.IE && X.UA.IE < 5 ?\r
+ X.Dom.DOM_IE4 ?\r
X.emptyFunction :\r
(function( root ){\r
return root._rawNode.createElement( 'p' ).tagName !== root._rawNode.createElement( 'P' ).tagName;\r
xnodes[ i ]._afterActualCreate();\r
};\r
};\r
- \r
+ // src の onload があるので先ではないか?\r
+ // ie の str から要素を作る場合、srcだけ イベント設定後ではないか?\r
this._restoreEvent();// イベントの復帰\r
}) :\r
X.Dom.DOM_IE4 ? (function(){\r
this.type = X.Dom.Event.RenameTo[ e.type ] || e.type;\r
\r
//http://www.quirksmode.org/js/events_properties.html\r
- this.target = Node._getXNode( e.target.nodeType === 3 ? e.target.parentNode : e.target );// defeat Safari bug // xnode\r
+ if( e.target ){\r
+ this.target = Node._getXNode( e.target.nodeType === 3 ? e.target.parentNode : e.target );// defeat Safari bug // xnode\r
+ };\r
+ if( e.relatedTarget ){\r
+ this.relatedTarget = Node._getXNode( e.relatedTarget.nodeType === 3 ? e.relatedTarget.parentNode : e.relatedTarget ); // xnode\r
+ };\r
\r
this.currentTarget = xnode; // xnode\r
- this.relatedTarget = Node._getXNode( e.relatedTarget ); // xnode\r
this.eventPhase = e.eventPhase;\r
\r
this.clientX = e.clientX;\r
\r
if( this._xnodeType === 0 || this._xnodeType === 3 || !arg1 ) return this;\r
\r
- ( !this._listeners || !this._listeners[ type ] ) && this._addEvent( type );\r
+ ( !this._listeners || !this._listeners[ type ] ) && X.Type.isString( type ) && this._addEvent( type );\r
\r
return typeof arg1 === 'function' ?\r
X.EventDispatcher.prototype.listen.call( this, type, this, arg1, arg2 ) :\r
};\r
\r
X.Dom.Node.prototype._addEvent =\r
+ // Days on the Moon DOM Events とブラウザの実装 \r
+ // http://nanto.asablo.jp/blog/2007/03/23/1339502\r
+ // Safari 2 では関数オブジェクトしか EventListener として使えませんが、Safari のナイトリービルドでは handleEvent メソッドを持つオブジェクトも EventListener として使えるようです。\r
+ X.Dom.EVENT_W3C && X.UA.Safari && X.UA.Safari < 3 ?\r
+ (function( type ){\r
+ var raw = this._rawNode;\r
+ if( !raw ) return;\r
+ this._handleEvent = this._handleEvent || X.Callback.create( this );\r
+ if( this._isImage ){\r
+ raw[ 'on' + type ] = this._handleEvent;\r
+ } else {\r
+ raw.addEventListener( type, this._handleEvent, false );\r
+ };\r
+ }) :\r
X.Dom.EVENT_W3C ?\r
(function( type ){\r
this._rawNode && this._rawNode.addEventListener( X.Dom.Event.Rename[ type ] || type, this, false );\r
\r
X.EventDispatcher.prototype.unlisten.apply( this, arguments );\r
\r
- l && !list[ type ] && this._removeEvent( type );\r
+ l && !list[ type ] && X.Type.isString( type ) && this._removeEvent( type );\r
\r
return this;\r
};\r
\r
X.Dom.Node.prototype._removeEvent =\r
+ X.Dom.EVENT_W3C && X.UA.Safari && X.UA.Safari < 3 ?\r
+ (function( type ){\r
+ var raw = this._rawNode;\r
+ if( !raw ) return;\r
+ \r
+ if( raw.constructor === Image ){\r
+ raw[ 'on' + type ] = '';\r
+ } else {\r
+ raw.removeEventListener( type, this._handleEvent, false );\r
+ };\r
+ if( !this._listeners ){\r
+ X.Callback._correct( this._handleEvent );\r
+ delete this._handleEvent;\r
+ };\r
+ }) :\r
X.Dom.EVENT_W3C ?\r
(function( type ){\r
var elm = this._rawNode;\r
};\r
});\r
\r
+// Is this in regard to the Safari 1.x preventDefault bug on click/dblclick?\r
+// https://groups.google.com/forum/#!msg/comp.lang.javascript/uYEuCHjHxnw/yKoHtZJPa1QJ\r
\r
X.Dom.Node.prototype.handleEvent =\r
X.Dom.EVENT_W3C ?\r
(function( e ){\r
var ret = X.EventDispatcher.prototype.dispatch.call( this, new X.Dom.Event( e, this ) );\r
-\r
+ \r
if( ret & X.Callback.STOP_PROPAGATION ){\r
e.stopPropagation();\r
};\r
if( ret & X.Callback.PREVENT_DEFAULT ){\r
this._tag === 'A' && this._rawNode.blur();\r
e.preventDefault();\r
+ if( X.UA.Safari && X.UA.Safari < 3 ){\r
+ if( e.type === 'click' || e.type === 'dbclick' ){\r
+ X.Dom._safariPreventDefault = true;\r
+ };\r
+ };\r
return false;\r
};\r
}) :\r
};\r
};\r
\r
-\r
-\r
/* -----------------------------------------------\r
* Document Ready\r
* Dean Edwards/Matthias Miller/John Resig\r
*/\r
+\r
+// SafariでJavaScriptのデバッグをする方法\r
+// safari1.3 可\r
+// http://shimax.cocolog-nifty.com/search/2006/09/safarijavascrip_c54d.html\r
+\r
+// Re: onLoad doesn't work with Safari?\r
+// http://lists.apple.com/archives/web-dev/2003/Oct/msg00036.html\r
+if( X.UA.Safari && X.UA.Safari < 3 ){\r
+ X.Timer.add( 10, function(){\r
+ if( !X.Dom._init ) return X.Callback.UN_LISTEN;\r
+ if( 'loaded|complete'.indexOf( document.readyState ) !== -1 ) return X.Dom._init();\r
+ } );\r
+} else\r
+\r
/* for ie9+/Mozilla/Opera9 */\r
if( X.Dom.DOM_W3C ){\r
- X.Dom.Node._document.listenOnce( 'DOMContentLoaded', X.Dom._init );\r
+ Node._document.listenOnce( 'DOMContentLoaded', X.Dom._init );\r
} else\r
if( 5 <= X.UA.IE && X.inHead ){\r
// if this script in Head\r
if( 'loaded|complete'.indexOf( document.readyState ) !== -1 ) return X.Dom._init();\r
});\r
};\r
+ /* for other browsers */\r
+ Node._window.listenOnce( 'load', X.Dom._init ); \r
+\r
+\r
\r
-/* for other browsers */\r
-X.Dom.Node._window.listenOnce( 'load', X.Dom._init );\r
\r
//\r
-X.Dom.listenOnce( X.Dom.Event.XDOM_READY, function(e){ console.log( 'X.Dom XDomReady ' + X.Dom.readyState ); } );\r
+X.Dom.listenOnce( X.Dom.Event.XDOM_READY, function(e){\r
+ console.log( 'X.Dom XDomReady ' + X.Dom.readyState );\r
+} );\r
+\r
+if( X.UA.Safari && X.UA.Safari < 3 ){\r
+ document.documentElement.onclick =\r
+ document.documentElement.ondbclick = function( e ){\r
+ if( X.Dom._safariPreventDefault ){\r
+ X.Dom._safariPreventDefault = false;\r
+ e.preventDefault();\r
+ return false;\r
+ };\r
+ };\r
+};\r
\r
X.Dom.listenOnce( X.Dom.Event.VIEW_RESIZED, function(e){ console.log( 'X.Dom VIEW_RESIZED ' + e.w + 'x' + e.h ); } );\r
\r
for( i = list.length; i; ){
unit = list[ --i ];
- output[ unit ] = xnode.css( 'width', 100 + unit ).width() / 100;
+ output[ unit ] = xnode.css( 'width', 10 + unit ).width() / 10;
};
output = X.Dom.Style._FONT_SIZE_RATIO = {},
};\r
if( ret = X.Dom.Image._actualSize[ img.src ] ) return ret;\r
};\r
- \r
+\r
// for Firefox, Safari, Google Chrome\r
if( img.naturalWidth ) return [ img.naturalWidth, img.naturalHeight ];\r
\r
// restore\r
run.height = memH;\r
} else {// for Opera and Other\r
- \r
- memW = img.width;\r
- memH = img.height;\r
- // keep current style\r
- img.removeAttribute( 'width' );\r
- img.removeAttribute( 'height' );\r
- w = img.width;\r
- h = img.height;\r
- img.width = memW;\r
- // restore\r
- img.height = memH;\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
delay : null,\r
timeout : 0,\r
Constructor : function( abspath, delay, timeout ){\r
- var img;\r
+ var img, s, p;\r
\r
this.abspath = abspath;\r
this.delay = delay || 100;\r
this.timeout = timeout || 10000;\r
this.xnode =\r
(\r
- window.Image ?\r
+ window[ 'Image' ] ?\r
X.Dom.Node( img = new Image() ) :\r
X.Dom.Node._systemNode.create( 'img', { src : abspath } )\r
)\r
.listen( 'abort', this )\r
.listen( X.Dom.Event.LOAD_ASSET_COMPLETE, this )\r
.listen( X.Dom.Event.LOAD_ASSET_ERROR, this );\r
- \r
img && ( img.src = abspath );\r
-\r
this._detect();\r
},\r
handleEvent : function( e ){\r
}, \r
_detect : function(){\r
if( this.finish === true ) return;\r
- if( this.xnode._rawNode.complete ){\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.Dom.Event.LOAD_ASSET_ERROR } );\r
};\r
if( ( this.tick += this.delay ) > this.timeout ){\r
this.finish = true;\r
- this.timerID = this.asyncDispatch( 0, { type : X.Dom.Event.LOAD_ASSET_ERROR } );\r
+ this.timerID = this.asyncDispatch( 0, { type : X.Dom.Event.LOAD_ASSET_ERROR, msg : 'timeout' } );\r
return;\r
};\r
this.timerID = X.Timer.once( this.delay, this, this._detect );\r
// textarea の内容を控えて、消す。xnode tree 構築後に復帰。でないと、html パースでこける\r
\r
// cleanup tree \r
- (function cleanUpTree( elm, skip, head ){\r
+ (function/*cleanUpTree*/( elm, skip, head ){\r
var moveToHead = 'style,bgsound,area,base,meta'.split( ',' ),\r
remove = 'script,noscript,noframes,comment,!,noembed,nolayer'.split( ',' ),\r
noncleanup = 'pre,textarea,code,kbd,samp,xmp,plaintext,listing'.split( ',' ),\r
continue;\r
} else {\r
// pre タグ以下はスペースの置換は行わない\r
- node.childNodes && node.childNodes.length && cleanUpTree( node, skip || noncleanup.indexOf( tag ) !== -1, head );\r
+ node.childNodes && node.childNodes.length && /*cleanUpTree*/arguments.callee( node, skip || noncleanup.indexOf( tag ) !== -1, head );\r
};\r
textNode = null;\r
break;\r