var \r
- X_Node_Dirty = {\r
- CLEAN : 0,\r
- CHILD_IS_DIRTY : 1,\r
- ID : 2, // width, height, x, y\r
- CONTENT : 4, // width, height, x, y textNode の内容\r
- CLASSNAME : 8, // X_Node_CSS_getCharSize, width, height, x, y\r
- ATTR : 16, // X_Node_CSS_getCharSize, width, height, x, y\r
- CSS : 32, // X_Node_CSS_getCharSize, width, height, x, y\r
- IE_FILTER : X_UA.IE < 9 && !X_UA.MacIE ? 64 : 0,\r
- UNKNOWN_TAG_FIX : 128,\r
- IE4_TEXTNODE_FIX : 256\r
- },\r
\r
X_Node_State = {\r
- DESTROYED : 0,\r
- EXIST : 1, // XNODE_EXIDT, ELEMENT_EXIST\r
- BELONG_TREE : 2, // HAS_PARENT, HAS_PARENT_ACTUAL, BELONG_TREE, BELONG_TREE_ACTUAL\r
- DISPLAY_NONE : 4, // VISIVILITY_HIDDEN(opacity0), DISPALY_NONE\r
- DISPLAY_BLOCK : 8, // remove\r
- DISPLAY_INLINE : 16,// remove\r
- POSITION_ABSOLUTE : 32,\r
- OVERFLOW_HIDDEN : 64,\r
- HAS_WIDTH_LENGTH : 128,\r
- HAS_WIDTH_PERCENT : 256,\r
- HAS_HEIGHT_LENGTH : 512,\r
- HAS_HEIGHT_PERCENT : 1024,\r
- IE4_ONLY_TEXT : 2048,\r
- IE5_DISPLAY_NONE_FIX : !X_UA.MacIE && X_UA.IE5 ? 4096 : 0 // filterがかかっていると不可? MacIE5.2- は ?\r
+ DESTROYED : 0x0,\r
+ EXIST : 0x1,\r
+ IN_TREE : 0x2, // xnode が(仮想)ツリーに追加されている -> 描画の対象\r
+ \r
+ STYLE_IS_DISPLAY_NONE : 2 << 1, // display : none \r
+ STYLE_IS_INVISIBLE : 2 << 2, // visibility : hidden or opacity : 0\r
+ STYLE_IS_POS_ABSOLUTE : 2 << 3, // position : absolute\r
+ STYLE_IS_NO_OVERFLOW : 2 << 4, // overflow : hidden\r
+ STYLE_IS_WIDTH_LENGTH : 2 << 5, // width : width() のための commitUpdate が不要\r
+ STYLE_IS_WIDTH_PCT : 2 << 6, // width : width() のための commitUpdate が不要かもしれない。(親で LENGTH が指定されているなら)\r
+ STYLE_IS_HEIGHT_LENGTH : 2 << 7, // height :\r
+ STYLE_IS_HEIGHT_PCT : 2 << 8, // height :\r
+ STYLE_IS_FONT_LENGTH : 2 << 9, // fontSize :\r
+ STYLE_IS_FONT_PCT : 2 << 10, // fontSize :\r
+\r
+ DIRTY_POSITION : 2 << 11, // 要素位置の変更が起こった。\r
+ DIRTY_CONTENT : 2 << 12, // width, height, x, y textNode の内容 TODO html と排他なので ID と共通でいい\r
+ DIRTY_ID : 2 << 13, // width, height, x, y\r
+ DIRTY_CLASSNAME : 2 << 14, // X_Node_CSS_getCharSize, width, height, x, y\r
+ DIRTY_ATTR : 2 << 15, // X_Node_CSS_getCharSize, width, height, x, y\r
+ DIRTY_CSS : 2 << 16, // X_Node_CSS_getCharSize, width, height, x, y\r
+ DIRTY_IE_FILTER : X_UA.IE < 10 && X_UA.ActiveX ? 2 << 17 : 0, // \r
+\r
+ \r
+ ELM_NEED_INIT : 2 << 18,\r
+ OLD_ATTRTEXT : 2 << 19,\r
+ OLD_CSSTEXT : 2 << 20,\r
+\r
+ // filter 要素が親子になると不具合が出るのを検出\r
+ IE_FILTER_NOW : 2 << 21,\r
+\r
+ //GPU_WAITING : 2 << 20, // 1:子のGPU解除待\r
+ GPU_RESERVED : 2 << 22, // 2:GPU予約\r
+ GPU_NOW : 2 << 23, // 3:GPU now!\r
+ GPU_RELEASE_RESERVED : 2 << 24, // 4:GPU解除予約\r
+ \r
+ IE4_HAS_TEXTNODE : X_UA.IE4 ? 2 << 22 : 0,\r
+ IE4_HAS_ELEMENT : X_UA.IE4 ? 2 << 23 : 0,\r
+ IE4_DIRTY_CHILDREN : X_UA.IE4 ? 2 << 24 : 0,\r
+ IE4_FIXED : X_UA.IE4 ? 2 << 25 : 0,\r
+ \r
+ IE5_DISPLAY_NONE_FIX : X_UA.IE5 && X_UA.ActiveX ? 2 << 25 : 0\r
},\r
+\r
+ X_Node_BITMASK_RESET_STYLE = ( ( 2 << 29 ) - 1 + ( 2 << 29 ) ) ^ (\r
+ X_Node_State.STYLE_IS_DISPLAY_NONE |\r
+ X_Node_State.STYLE_IS_INVISIBLE |\r
+ X_Node_State.STYLE_IS_POS_ABSOLUTE |\r
+ X_Node_State.STYLE_IS_NO_OVERFLOW |\r
+ X_Node_State.STYLE_IS_WIDTH_LENGTH |\r
+ X_Node_State.STYLE_IS_WIDTH_PCT |\r
+ X_Node_State.STYLE_IS_HEIGHT_LENGTH |\r
+ X_Node_State.STYLE_IS_HEIGHT_PCT |\r
+ X_Node_State.STYLE_IS_FONT_LENGTH |\r
+ X_Node_State.STYLE_IS_FONT_PCT ),\r
+\r
+ X_Node_BitMask_IS_DIRTY = X_Node_State.DIRTY_POSITION | \r
+ X_Node_State.DIRTY_CONTENT | X_Node_State.DIRTY_ID | X_Node_State.DIRTY_CLASSNAME |\r
+ X_Node_State.DIRTY_ATTR | X_Node_State.DIRTY_CSS | X_Node_State.DIRTY_IE_FILTER,\r
+\r
+ X_Node_BitMask_RESET_DIRTY = ( ( 2 << 29 ) - 1 + ( 2 << 29 ) ) ^ X_Node_BitMask_IS_DIRTY,\r
+ \r
+ X_Node_BitMask_RESET_GPU = ( ( 2 << 29 ) - 1 + ( 2 << 29 ) ) ^ ( X_Node_State.GPU_RESERVED | X_Node_State.GPU_NOW | X_Node_State.GPU_RELEASE_RESERVED ),\r
+ \r
+ X_Node_BitMask_IE4_IS_MIX = X_Node_State.IE4_HAS_TEXTNODE | X_Node_State.IE4_HAS_ELEMENT,\r
\r
X_Node_TYPE = {\r
XNODE : 1,\r
IMAGE : 10\r
},\r
\r
- X_Node_strictElmCreation = !X_UA.MacIE && X_UA.IE5678,// && !X_UA.MacIE;\r
+ X_Node_strictElmCreation = !X_UA.MacIE && X_UA.IE5678,// && !X_UA.MacIE;\r
+ \r
+ X_Node_documentFragment = document.createDocumentFragment && ( !X_UA.IE || 5.5 <= X_UA.IE ) && document.createDocumentFragment(),\r
\r
- X_Node_useDocumentFragment = document.createDocumentFragment && ( !X_UA.IE || 5.5 <= X_UA.IE ) && document.createDocumentFragment(),\r
+ // 子の生成後に リアル文書 tree に追加する\r
+ X_Node_addTreeAfterChildren = !( X.UA.IE < 9 ),\r
+ \r
+ X_Node_displayNoneFixForIE5 = !!X_Node_State.IE5_DISPLAY_NONE_FIX,\r
\r
X_Node_newByTag = false,\r
\r
*/ \r
Node = X.Node = X.EventDispatcher.inherits(\r
'XDomNode',\r
- X.Class.POOL_OBJECT,\r
+ X.Class.POOL_OBJECT, // X.Class.FINAL\r
{\r
_uid : 0,\r
- _state : 0,\r
- _dirty : 0,\r
- \r
- _isNew : false, // state にまとめる\r
- \r
+ _flags : X_Node_State.DESTROYED,\r
+\r
_rawObject : null,\r
_rect : null, // \r
+ _fontSize : 0,\r
\r
- _root : null, // xnode が文書ツリーに属しているか?はこれを見る -> state\r
parent : null, // remove された枝も親子構造は維持している。\r
- _xnodes : null,\r
- \r
- _xnodeType : 0,\r
- _tag : null,\r
- _text : null,\r
- _id : null,\r
+ _xnodes : null, // Array.<Node>\r
+\r
+ _tag : '',\r
+ _text : '',\r
+ _id : '',\r
_className : '',\r
\r
_attrs : null, // see X_Node_Attr\r
_newAttrs : null,\r
- _attrText : '', // X_Node_Attr_objToAttrText が必要な場合は false が入っている\r
+ _attrText : '',\r
\r
_css : null, // see X_Node_CSS\r
- _cssText : null,\r
- \r
- _fontSize : 0,\r
+ _cssText : '',\r
\r
- _anime : null,\r
+ _anime : null, // Hash see X_Node_Anime\r
\r
/*\r
* TODO Node の継承ができない!\r
if( X_Node_newByTag ){\r
X_Node_newByTag = false;\r
this._tag = v.toUpperCase();\r
- this._xnodeType = 1;\r
- this._state = X_Node_State.DISPLAY_INLINE; // TODO\r
+ this._flags |= X_Node_State.EXIST;\r
arguments[ 1 ] && this.attr( arguments[ 1 ] );\r
css = arguments[ 2 ];\r
css && this[ X.Type.isString( css ) ? 'cssText' : 'css' ]( css );\r
} else\r
if( X_Node_newByText ){\r
X_Node_newByText = false;\r
- this._text = v;\r
- this._xnodeType = 3;\r
- this._state = X_Node_State.DISPLAY_INLINE;\r
+ this._text = v;\r
+ this._flags |= X_Node_State.EXIST;\r
} else {\r
if( 1 < arguments.length ) return new X_NodeList( arguments );\r
if( X.Type.isArray( v ) && v.length ) return new X_NodeList( v );\r
- //if( !this || this.append !== X_Node_append ){\r
- // return new Node( v );\r
- //};\r
+\r
switch( X_Node_getType( v ) ){\r
case X_Node_TYPE.XNODE :\r
case X_Node_TYPE.XNODE_LIST :\r
return v;\r
+\r
case X_Node_TYPE.RAW_HTML :\r
if( xnode = X_Node_getXNode( v ) ) return xnode;\r
// v.parentNode || v.parentElement : dom1 || dom0\r
this.parent = ( parent = v.parentNode || v.parentElement ) && parent.tagName /* ie7- */ && X_Node_getXNode( parent );\r
- if( this.parent && this.parent._root ) this._root = this.parent._root;\r
+ if( this.parent && ( this.parent._flags & X_Node_State.IN_TREE ) ){\r
+ this._flags |= X_Node_State.IN_TREE;\r
+ };\r
this._rawObject = v;\r
- this._xnodeType = 1;\r
- this._state = X_Node_State.DISPLAY_BLOCK; // TODO\r
+ this._flags |= X_Node_State.EXIST;\r
this._tag = v.tagName.toUpperCase();\r
this._id = v.id;\r
this._className = v.className;\r
+ \r
this.cssText( v.style.cssText );\r
- // X_Node_Dirty.CSS を落とす\r
- this._dirty = 0;\r
+ this._flags &= X_Node_BitMask_RESET_DIRTY; // X_Node_State.DIRTY_CSS を落とす\r
+ \r
// TODO attr の回収は不可能、、、\r
if( X_UA_DOM.IE4 ){\r
v.setAttribute( 'UID', '' + uid );\r
};\r
// childNodes...\r
break;\r
+\r
case X_Node_TYPE.RAW_TEXT :\r
if( xnode = X_Node_getXNode( v ) ) return xnode;\r
this.parent = X_Node_getXNode( v.parentNode );\r
- if( this.parent && this.parent._root ) this._root = this.parent._root;\r
+ if( this.parent && ( this.parent._flags & X_Node_State.IN_TREE ) ){\r
+ this._flags |= X_Node_State.IN_TREE;\r
+ };\r
this._rawObject = v;\r
- this._xnodeType = 3;\r
- this._state = X_Node_State.DISPLAY_INLINE;\r
+ this._flags |= X_Node_State.EXIST;\r
this._text = v.data;\r
v.UID = uid;\r
break;\r
+\r
case X_Node_TYPE.HTML_STRING :\r
case X_Node_TYPE.STRING :\r
if( xnodes = X_HtmlParser_parse( v, true ) && 1 < xnodes.length ) return new X_NodeList( xnodes );\r
if( xnodes.length ) return xnodes[ 0 ];\r
return X_Node_none;\r
- case X_Node_TYPE.IMAGE :\r
- if( xnode = X_Node_getXNode( v ) ) return xnode;\r
- this._rawObject = v;\r
- this._xnodeType = 4;\r
- v.UID = uid;\r
- this._state = X_Node_State.EXIST;\r
- break;\r
- /*\r
- case X_Node_TYPE.WINDOW :\r
- case X_Node_TYPE.DOCUMENT :\r
- if( xnode = X_Node_getXNode( v ) ) return xnode;\r
- this._rawObject = v;\r
- this._xnodeType = 2;\r
- this._state = X_Node_State.DISPLAY_BLOCK;\r
- break; */\r
+\r
default :\r
if( X_Node_none ) return X_Node_none;\r
return;\r
X_Node_CHASHE[ this._uid = uid ] = this;\r
},\r
\r
+ // attr\r
+ // css, cssText\r
+ // find\r
+ // animate, stop\r
+ \r
create : X_Node_create,\r
\r
createAt : X_Node_createAt,\r
\r
before : X_Node_before, // remove\r
\r
- prevNode : X_Node_before, // -> prev\r
+ prev : X_Node_before,\r
\r
after : X_Node_after, // remove\r
\r
- nextNode : X_Node_after, // -> next\r
- \r
- replace : X_Node_replace, // remove\r
+ next : X_Node_after,\r
\r
- swap : X_Node_replace,\r
+ swap : X_Node_swap,\r
\r
remove : X_Node_remove,\r
\r
\r
getChildAt : X_Node_getChildAt,\r
\r
+ numChildren : X_Node_length,\r
+ \r
firstChild : X_Node_firstChild,\r
\r
lastChild : X_Node_lastChild,\r
if( v.constructor === X_NodeList ) return X_Node_TYPE.XNODE_LIST;\r
if( X.Type.isHTMLElement( v ) ) return X_Node_TYPE.RAW_HTML;\r
if( v.nodeType === 3 ) return X_Node_TYPE.RAW_TEXT;\r
- if( X.Type.isImage( v ) ) return X_Node_TYPE.IMAGE;\r
if( X.Type.isString( v ) ){\r
return '<' === v.charAt( 0 ) && v.charAt( v.length - 1 ) === '>' ? X_Node_TYPE.HTML_STRING : X_Node_TYPE.STRING;\r
};\r
- //if( v.nodeType === 11 ) return X_Node_TYPE.DOC_FRAG;\r
return 0;\r
};\r
function X_Node_getXNode( v ){\r
case X_Node_TYPE.XNODE_LIST :\r
return v;\r
case X_Node_TYPE.RAW_HTML :\r
- case X_Node_TYPE.IMAGE :\r
// fake TextNode too.\r
if( X_UA_DOM.IE4 ){\r
uid = v.getAttribute( 'UID' );\r
};\r
};\r
\r
-\r
-X.Doc.create = Node.create = function( tag, opt_attrs, opt_css ){\r
- var list, i;\r
- switch( X_Node_getType( tag ) ){\r
- case X_Node_TYPE.STRING :\r
- X_Node_newByTag = true;\r
- return new Node( tag, opt_attrs, opt_css );\r
- case X_Node_TYPE.HTML_STRING :\r
- list = X_HtmlParser_parse( tag, true );\r
- for( i = list.length; 1 < i; ){\r
- list[ --i ].destroy();\r
- };\r
- return list[ 0 ];\r
- };\r
-};\r
-X.Doc.createText = Node.createText = function( text ){\r
- X_Node_newByText = true;\r
- return new Node( text );\r
-};\r
-\r
-\r
function X_Node_getRoot( xnode ){\r
return X_ViewPort_document;\r
//return X_Node_body._rawObject.documentElement ? node : node.ownerDocument || node.document;\r
};\r
// XMLかどうかを判別する\r
var X_Node_isXmlDocument =\r
- X_UA_DOM.IE4 ?\r
- X.emptyFunction :\r
- (function( root ){\r
- if( X.Type.isBoolean( root.isXML ) ) return root.isXML;\r
- return root.isXML = root._rawObject.createElement( 'p' ).tagName !== root._rawObject.createElement( 'P' ).tagName;\r
- }),\r
+ X_UA_DOM.IE4 ?\r
+ X.emptyFunction :\r
+ (function( root ){\r
+ if( X.Type.isBoolean( root.isXML ) ) return root.isXML;\r
+ return root.isXML = root._rawObject.createElement( 'p' ).tagName !== root._rawObject.createElement( 'P' ).tagName;\r
+ }),\r
X_Node_CHASHE = [],\r
X_Node_none = X_Node_CHASHE[ 0 ] = new Node(),\r
X_Node_html, // = X_Node_CHASHE[ 1 ] <html>\r
X_Node_body, // = X_Node_CHASHE[ 3 ] <body>\r
X_Node_systemNode, // = X_Node_CHASHE[ ? ]\r
X_Node_fontSizeNode,\r
+/*\r
+ * remove :\r
+ * X_Node_reserveRemoval = [] に追加。commitUpdate で remove\r
+ * add :\r
+ * X_Node_reserveRemoval にいたら消す, new_parent._xnodes に挿入\r
+ */\r
X_Node_reserveRemoval = [];\r
\r
\r
var X_Node__ie4getRawNode = X_UA_DOM.IE4 && function ( that ){\r
- var elm = that._rawObject;\r
- return elm ||\r
- ( ( elm = document.all[ 'ie4uid' + that._uid ] ) && ( that._rawObject = elm ) ) ||\r
- ( that._id && ( elm = document.all[ that._id ] ) ) && ( that._rawObject = elm );\r
+ return that._rawObject ||\r
+ ( that._rawObject = document.all[ 'ie4uid' + that._uid ] ) ||\r
+ ( that._id && ( that._rawObject = document.all[ that._id ] ) );\r
};\r
\r
\r
+function X_Node_toggleInTreeFlag( xnodes, flag ){\r
+ var i = xnodes.length, xnode;\r
+ for( ; i; ){\r
+ xnode = xnodes[ --i ];\r
+ flag ? ( xnode._flags |= X_Node_State.IN_TREE | X_Node_State.DIRTY_POSITION ) : ( xnode._flags &= ~X_Node_State.IN_TREE & ~X_Node_State.IE5_DISPLAY_NONE_FIX );\r
+ xnode._xnodes && X_Node_toggleInTreeFlag( xnode._xnodes, flag );\r
+ };\r
+};\r
+\r
/* --------------------------------------\r
* Create\r
*/\r
function X_Node_create( tag, opt_attrs, opt_css ){\r
var xnode;\r
- if( this._xnodeType !== 1 ) return;\r
- if( !this._xnodes ) this._xnodes = [];\r
- \r
- xnode = Node.create( tag, opt_attrs, opt_css );\r
- \r
- xnode.parent = this;\r
- this._xnodes[ this._xnodes.length ] = xnode;\r
- this._root && X_Node_reserveUpdate();\r
+ if( !this._tag ) return;\r
+ this.append( xnode = X_Doc_create( tag, opt_attrs, opt_css ) );\r
return xnode;\r
};\r
function X_Node_createAt( index, tag, opt_attrs, opt_css ){\r
- var xnode = Node.create( tag, opt_attrs, opt_css );\r
- this.appendAt( index, xnode );\r
+ var xnode;\r
+ if( !this._tag ) return;\r
+ this.appendAt( index, xnode = X_Doc_create( tag, opt_attrs, opt_css ) );\r
return xnode;\r
};\r
\r
*/\r
function X_Node_createText( text ){\r
var xnode;\r
- if( this._xnodeType !== 1 ) return;\r
- if( !this._xnodes ) this._xnodes = [];\r
- \r
- X_Node_newByText = true;\r
- xnode = new Node( text );\r
- xnode.parent = this;\r
- \r
- this._root && X_Node_reserveUpdate();\r
- this._xnodes[ this._xnodes.length ] = xnode;\r
+ if( !this._tag ) return;\r
+ this.append( xnode = X_Doc_createText( text ) );\r
return xnode;\r
};\r
function X_Node_createTextAt( index, text ){\r
- var xtext = Node.createText( text );\r
- this.appendAt( index, xtext );\r
- return xtext;\r
+ var xnode;\r
+ if( !this._tag ) return;\r
+ this.appendAt( index, xnode = X_Doc_createText( text ) );\r
+ return xnode;\r
};\r
\r
/* --------------------------------------\r
*/\r
function X_Node_clone( opt_clone_children ){\r
var xnode, xnodes, i, l;\r
- switch( this._xnodeType ){\r
- case 1 :\r
- X_Node_newByTag = true;\r
- xnode = new Node( this._tag, X_Object_clone( this._attrs ), X_Object_clone( this._css ) )\r
- .attr( { 'id' : this._id } )\r
- .className( this._className );\r
- if( opt_clone_children && ( xnodes = this._xnodes ) && ( l = xnodes.length ) ){\r
- for( i = 0; i < l; ++i ){\r
- xnode.append( xnodes[ i ].clone( true ) );\r
- };\r
+ if( this._tag ){\r
+ X_Node_newByTag = true;\r
+ xnode = new Node( this._tag, X_Object_clone( this._attrs ), X_Object_clone( this._css ) )\r
+ .attr( { 'id' : this._id } )\r
+ .className( this._className );\r
+ if( opt_clone_children && ( xnodes = this._xnodes ) && ( l = xnodes.length ) ){\r
+ for( i = 0; i < l; ++i ){\r
+ xnode.append( xnodes[ i ].clone( true ) );\r
};\r
- return xnode;\r
- case 3 :\r
- X_Node_newByText = true;\r
- xnode = new Node( this._text );\r
- return xnode;\r
- \r
- //case 0 :\r
- //case 2 :\r
+ };\r
+ return xnode; \r
};\r
- return this;\r
+ X_Node_newByText = true;\r
+ return new Node( this._text );\r
};\r
\r
/* --------------------------------------\r
*/\r
function X_Node_append( v ){\r
var i, l, xnodes, frg;\r
- if( this._xnodeType !== 1 ) return;\r
+ if( !this._tag ) return;\r
\r
if( 1 < ( l = arguments.length ) ){\r
for( i = 0; i < l; ++i ){\r
case X_Node_TYPE.STRING :\r
return this.append.apply( this, X_HtmlParser_parse( v, true ) );\r
case X_Node_TYPE.XNODE :\r
- if( v._xnodeType !== 1 && v._xnodeType !== 3 ) return this;\r
// 親の xnodes から v を消す\r
- if( v.parent ){\r
- //if( X_UA_DOM.W3C ){\r
- // v.parent._xnodes.splice( v.parent._xnodes.indexOf( v ), 1 );\r
- //} else\r
- //if( X_UA_DOM.IE4 ){\r
- v.remove();\r
- //} else {\r
- \r
- //};\r
- };// else\r
- //if( ( i = X_Node_reserveRemoval.indexOf( v ) ) !== -1 ){\r
- // if( !this._state ) alert( 'xnode already destroyed!' );\r
- // X_Node_reserveRemoval.splice( i, 1 );\r
- //};\r
+ v.parent && v.remove();\r
+ // IE4 でテキストノードの追加、FIXED 済でない場合、親に要素の追加を通知\r
+ if( X_UA.IE4 && !v._tag && ( this._flags & X_Node_State.IE4_FIXED ) === 0 ) this._flags |= X_Node_State.IE4_DIRTY_CHILDREN;\r
break;\r
default :\r
return this;\r
\r
v.parent = this;\r
xnodes[ xnodes.length ] = v;\r
- this._root && X_Node_reserveUpdate();\r
+ if( this._flags & X_Node_State.IN_TREE ){\r
+ v._flags |= X_Node_State.IN_TREE;\r
+ v._xnodes && X_Node_toggleInTreeFlag( v._xnodes, true );\r
+ X_Node_reserveUpdate();\r
+ };\r
return this;\r
};\r
\r
function X_Node_appendAt( start, v ){\r
var xnodes, l, i;\r
\r
- if( this._xnodeType !== 1 ) return this;\r
+ if( !this._tag ) return this;\r
\r
l = arguments.length;\r
if( !( xnodes = this._xnodes ) ) xnodes = this._xnodes = [];\r
};\r
return this;\r
case X_Node_TYPE.XNODE :\r
- if( v._xnodeType !== 1 && v._xnodeType !== 3 ) return this;\r
// 親の xnodes から v を消す\r
- if( v.parent ){\r
- //if( X_UA_DOM.W3C ){\r
- // v.parent._xnodes.splice( v.parent._xnodes.indexOf( v ), 1 );\r
- //} else\r
- //if( X_UA_DOM.IE4 ){\r
- v.remove();\r
- //} else {\r
- \r
- //};\r
- };// else\r
- //if( ( i = X_Node_reserveRemoval.indexOf( v ) ) !== -1 ){\r
- // if( !this._state ) alert( 'xnode already destroyed!' );\r
- // X_Node_reserveRemoval.splice( i, 1 );\r
- //};\r
+ v.parent && v.remove();\r
+ // IE4 でテキストノードの追加、FIXED 済でない場合、親に要素の追加を通知\r
+ if( X_UA.IE4 && !v._tag && ( this._flags & X_Node_State.IE4_FIXED ) === 0 ) this._flags |= X_Node_State.IE4_DIRTY_CHILDREN;\r
break;\r
default :\r
return this;\r
\r
v.parent = this;\r
this._xnodes.splice( start, 0, v );\r
- this._root && X_Node_reserveUpdate();\r
+ if( this._flags & X_Node_State.IN_TREE ){\r
+ v._flags |= X_Node_State.IN_TREE;\r
+ v._xnodes && X_Node_toggleInTreeFlag( v._xnodes, true );\r
+ X_Node_reserveUpdate();\r
+ };\r
return this;\r
};\r
\r
return this;\r
};\r
\r
-function X_Node_replace( v ){\r
+function X_Node_swap( v ){\r
if( !this.parent ) return this;\r
return arguments.length === 1 ? this.before( v ).remove() : this.before.apply( this, arguments ).remove();\r
};\r
* Remove\r
*/\r
function X_Node_remove(){\r
- var parent = this.parent;\r
+ var parent = this.parent,\r
+ elm;\r
\r
if( !parent ) return this;\r
\r
+ delete this.parent;\r
parent._xnodes.splice( parent._xnodes.indexOf( this ), 1 );\r
- if( this._root ){\r
- X_Node_reserveRemoval[ X_Node_reserveRemoval.length ] = this;\r
- X_Node_reserveUpdate();\r
+ \r
+ if( this._flags & X_Node_State.IN_TREE ){\r
+ this._flags &= ~X_Node_State.IN_TREE & ~X_Node_State.IE5_DISPLAY_NONE_FIX;\r
+ this._xnodes && X_Node_toggleInTreeFlag( this._xnodes, false );\r
+\r
+ if( X_UA_DOM.IE4 ){\r
+ elm = this._rawObject || X_Node__ie4getRawNode( this );\r
+ if( elm ){\r
+ X_Node_reserveRemoval[ X_Node_reserveRemoval.length ] = this;\r
+ X_Node_reserveUpdate(); \r
+ } else\r
+ if( !this._tag && ( parent._flags & X_Node_State.IE4_FIXED ) === 0 ){\r
+ parent._flags |= X_Node_State.IE4_DIRTY_CHILDREN;\r
+ };\r
+ } else {\r
+ elm = this._rawObject;\r
+ if( elm && elm.parentNode && elm.parentNode.tagName ){\r
+ X_Node_reserveRemoval[ X_Node_reserveRemoval.length ] = this;\r
+ X_Node_reserveUpdate(); \r
+ };\r
+ };\r
};\r
- delete this.parent;\r
- delete this._root;\r
return this;\r
};\r
\r
};\r
\r
/* --------------------------------------\r
- * destory\r
+ * TODO destory -> kill\r
*/\r
-// Node._destroyChildFlag = false; // TODO\r
\r
function X_Node_destroy( isChild ){\r
var xnodes = this._xnodes, i, elm;\r
\r
- if( !this._state ) return;\r
+ if( !this._flags ) return;\r
\r
elm = this._rawObject || X_UA_DOM.IE4 && X_Node__ie4getRawNode( this );\r
\r
};\r
elm && this._listeners && this.unlisten(); // イベントの退避\r
\r
- delete X_Node_CHASHE[ this._uid ];\r
- delete this._state;\r
- \r
- if( this._root ){\r
+ if( this._flags & X_Node_State.IN_TREE ){\r
!isChild && this.remove();\r
+ delete this._flags;\r
} else {\r
this.parent && this.parent._xnodes.splice( this.parent._xnodes.indexOf( this ), 1 );\r
elm && !isChild && X_Node__actualRemove( this );\r
this.kill();\r
};\r
+ \r
+ delete X_Node_CHASHE[ this._uid ];\r
};\r
\r
+function X_Node_onBeforeKill( e ){\r
+ var xnodes = this._xnodes,\r
+ elm = this._rawObject || X_UA_DOM.IE4 && X_Node__ie4getRawNode( this ),\r
+ i;\r
+ \r
+ if( !this._flags ) return;\r
+ \r
+ delete X_Node_CHASHE[ this._uid ];\r
+ \r
+ if( xnodes && ( i = xnodes.length ) ){\r
+ for( ; i; ){\r
+ X_Node_onBeforeKill.call( xnodes[ --i ] );\r
+ };\r
+ };\r
+\r
+ e && this.remove();\r
+ elm && this._listeners && this.unlisten(); // イベントの退避\r
+ \r
+ if( e && elm && elm.parentNode && elm.parentNode.tagName ){\r
+ delete this._flags;\r
+ return X.Callback.PREVENT_DEFAULT;\r
+ };\r
+};\r
\r
\r
/* --------------------------------------\r
*/\r
function X_Node_contains( v ){\r
var elm, type, xnodes, i;\r
- if( !v || this._xnodeType !== 1 ) return false;\r
+ if( !v || !this._tag || this === v ) return false;\r
// contains ie4+\r
if( ( elm = this._rawObject || X_UA_DOM.IE4 && X_Node__ie4getRawNode( this ) ) && document.contains && ( type = X_Node_getType( v ) ) && ( type === X_Node_TYPE.RAW_HTML || type === X_Node_TYPE.RAW_TEXT ) ){\r
return elm.contains( v ); \r
xnodes = this._xnodes;\r
if( !xnodes || !xnodes.length ) return false;\r
if( xnodes.indexOf( v ) !== -1 ) return true; // fast\r
- if( elm === v.parentNode ) return false;\r
+ if( elm === v.parentNode ) return true;\r
for( i = xnodes.length; i; ){\r
if( xnodes[ --i ].contains( v ) ) return true;\r
};\r
* getChild\r
*/\r
function X_Node_getChildAt( i ){\r
- var xnodes = this._xnodeType === 1 && this._xnodes;\r
+ var xnodes = this._xnodes;\r
return xnodes && 0 <= i && i < xnodes.length && xnodes[ i ];\r
};\r
\r
+function X_Node_length(){\r
+ var xnodes = this._xnodes;\r
+ return xnodes ? xnodes.length : 0;\r
+};\r
\r
/* --------------------------------------\r
* firstChild, lastChild\r
if( this._className === v ) return this;\r
v ? ( this._className = v ) : delete this._className;\r
};\r
- this._dirty |= X_Node_Dirty.CLASSNAME;\r
- this._root && X_Node_reserveUpdate();\r
+ this._flags |= X_Node_State.DIRTY_CLASSNAME;\r
+ this._flags & X_Node_State.IN_TREE && X_Node_reserveUpdate();\r
return this;\r
};\r
function X_Node_addClass( v ){\r
names = v.split( ' ' );\r
for( i = names.length; i; ){\r
name = names[ --i ];\r
- this.hassClass( name ) ? this.removeClass( name ) : this.addClass( name );\r
+ this.hasClass( name ) ? this.removeClass( name ) : this.addClass( name );\r
};\r
return this;\r
};\r
\r
/* --------------------------------------\r
* html, text\r
+ * \r
+ * outerHTML が欲しい場合は、xnode.call('outerHTML') とできる。\r
*/\r
-\r
function X_Node_html( html ){\r
var _ = '', q = '"', xnodes, n, i, l;\r
// setter\r
if( html !== undefined ){ // String 以外に Number や false null なども許可\r
- if( this._xnodeType === 3 ) return this.text( html );\r
+ if( !this._tag ) return this.text( html );\r
return html ? this.empty().append.apply( this, X_HtmlParser_parse( html, true ) ) : this.empty();\r
};\r
\r
// getter\r
- if( this._xnodeType === 3 ){\r
+ if( !this._tag ){\r
return this._text;\r
};\r
\r
- if( this._dirty & X_Node_Dirty.CSS && !( this._cssText = X_Node_CSS_objToCssText( this ) ) ){\r
- delete this._cssText;\r
- };\r
+ this._flags & X_Node_State.OLD_CSSTEXT && X_Node_CSS_objToCssText( this );\r
+\r
html = !X_Node_outerXNode ? [] : [\r
'<', this._tag,\r
this._id ? ' id="' + this._id + q : _,\r
this._className ? ' class="' + this._className + q : _,\r
- this._attrText === false ? ( this._attrText = X_Node_Attr_objToAttrText( this._attrs ) ) : this._attrText,\r
+ this._flags & X_Node_State.OLD_ATTRTEXT ? X_Node_Attr_objToAttrText( this ) : this._attrText,\r
this._cssText ? ' style="' + this._cssText + q : _,\r
'>' ];\r
\r
html[ n ] = xnodes[ i ].html();\r
++n;\r
};\r
- if( X_Node_outerXNode === this ) X_Node_outerXNode = null;\r
+ if( X_Node_outerXNode === this ) X_Node_outerXNode = null;\r
};\r
!X_Node_outerXNode || X_Dom_DTD_EMPTY[ this._tag ] || ( html[ n ] = '<\/' + this._tag + '>' );\r
return html.join( _ );\r
};\r
\r
+/*\r
+ * null が来たら '', 数値等が来たら文字列化\r
+ */\r
function X_Node_text( text ){\r
var xnodes, texts, i, l;\r
// setter\r
if( text !== undefined ){\r
- if( this._xnodeType === 3 ){\r
+ if( text === null ) text = '';\r
+ text += '';\r
+ \r
+ if( !this._tag ){\r
if( this._text !== text ){\r
- text ? ( this._text = text ) : delete this.text;\r
- this._root && X_Node_reserveUpdate();\r
- this._dirty |= X_Node_Dirty.CONTENT;\r
+ text ? ( this._text = text ) : delete this._text;\r
+ this._flags |= X_Node_State.DIRTY_CONTENT; \r
+ this._flags & X_Node_State.IN_TREE && X_Node_reserveUpdate();\r
};\r
return this;\r
};\r
if( !text ) return this.empty();\r
- if( ( xnodes = this._xnodes ) && xnodes.length === 1 && xnodes[ 0 ]._xnodeType === 3 ){\r
+ if( ( xnodes = this._xnodes ) && xnodes.length === 1 && !xnodes[ 0 ]._tag ){\r
xnodes[ 0 ].text( text );\r
return this;\r
};\r
return this;\r
};\r
// getter\r
- if( this._xnodeType === 1 ){\r
+ if( this._tag ){\r
if( ( xnodes = this._xnodes ) && ( l = xnodes.length ) ){\r
for( texts = [], i = 0; i < l; ++i ){\r
texts[ i ] = xnodes[ i ].text();\r
* HTML要素に対して name の関数を実行しその戻り値を返す。関数に渡す引数も任意に設定できる。\r
*/\r
function X_Node_call( name /*, opt_args... */ ){\r
- var raw = this._rawObject || X_UA_DOM.IE4 && X_Node__ie4getRawNode( this ),\r
- l = arguments.length - 1,\r
- func, args, params, i;\r
+ var l = arguments.length - 1,\r
+ raw, func, args, params, i;\r
+ \r
+ X_Node_updateTimerID && X_Node_startUpdate();\r
+ \r
+ switch( name ){\r
+ case 'nodeType' :\r
+ return this._tag ? 1 : 3;\r
+ case 'text' :\r
+ return this.text();\r
+ case 'html' :\r
+ case 'innerHTML' :\r
+ return this.html();\r
+ case 'outerHTML' :\r
+ X_Node_outerXNode = X_Node_body; // == true ならなんでもよい。型を合わすために xbody にしている\r
+ v = this.html();\r
+ X_Node_outerXNode = null;\r
+ return v;\r
+ case 'fontSize' :\r
+ return X_Node_CSS_getCharSize( this );\r
+ case 'inGPU' :\r
+ return !!( this._flags & ( X_Node_State.GPU_NOW | X_Node_State.GPU_RELEASE_RESERVED ) );\r
+ };\r
+ \r
+ raw = this._rawObject || X_UA_DOM.IE4 && X_Node__ie4getRawNode( this );\r
if( !raw ) return;\r
+ \r
func = raw[ name ];\r
if( X.Type.isFunction( func ) ){\r
if( l ){\r
/* --------------------------------------\r
* Async commit update\r
* \r
- * state:\r
- * 0 : no_rawObject\r
- * 1 : no_parent\r
- * 2 : no_root\r
- * 3 : dirty\r
- * 4 : clean\r
- * \r
- * remove :\r
- * root._reserveRemoval = [] に追加。commitUpdate で remove して state は not_added\r
- * add :\r
- * root._reserveRemoval にいたら消す, new_parent._xnodes に挿入 steta は not_added にして commitUpdate を待つ\r
+ * TODO Timer や DOM イベントの呼び出しの最後に、まだ一度も commitUpdate していないなら commitUpdate してしまう。\r
*/\r
\r
function X_Node_reserveUpdate(){\r
if( !X_Node_updateTimerID ) X_Node_updateTimerID = X.Timer.requestFrame( X_Node_startUpdate );\r
};\r
\r
+var X_Node_updateReservedByReleaseGPU = false;\r
+\r
function X_Node_startUpdate( time ){\r
- var removal, i, xnode, tmp;\r
+ var removal, i, xnode;\r
\r
if( !X_Node_updateTimerID || X_ViewPort_readyState < X_TEMP.SYSTEM_EVENT_INIT ){\r
return;\r
};\r
\r
removal = X_Node_reserveRemoval;\r
- \r
- //tmp = X_Node_body._rawObject.style.visibility;\r
- //this._rawObject.style.visibility = 'hidden';\r
-\r
- //console.log( '_actualRemove().' );\r
\r
if( i = removal.length ){\r
for( ; i; ){\r
xnode = removal[ --i ];\r
X_Node__actualRemove( xnode );\r
- !X_Node_body._state && xnode.kill();\r
+ !xnode._flags && xnode.kill();\r
};\r
removal.length = 0;\r
};\r
-\r
- //console.log( 'start _startUpdate().' );\r
-\r
- /* X_Node_html._dirty ? */ X_Node__commitUpdate( X_Node_html ); /* : X_Node__commitUpdate( X_Node_body ); */;\r
\r
- //console.log( 'end of _startUpdate().' );\r
+ if( X_Node_html._flags & X_Node_BitMask_IS_DIRTY ){\r
+ X_Node__commitUpdate( X_Node_html, X_Node_html._rawObject.parentNode, null, X_Node_html._flags );\r
+ } else {\r
+ X_Node__commitUpdate( X_Node_head, X_Node_head._rawObject.parentNode, null, X_Node_head._flags );\r
+ X_Node__commitUpdate( X_Node_body, X_Node_body._rawObject.parentNode, null, X_Node_body._flags );\r
+ };\r
+ \r
+ if( X_Node_updateReservedByReleaseGPU ){\r
+ X_Node_reserveUpdate();\r
+ X_Node_updateReservedByReleaseGPU = false;\r
+ };\r
\r
if( time ){\r
// X.Timer 経由でないと発火しない このイベントでサイズを取ると無限ループに\r
};\r
\r
X_ViewPort._listeners && X_ViewPort._listeners[ X.Event.AFTER_UPDATE ] && X_ViewPort.asyncDispatch( X.Event.AFTER_UPDATE );\r
- //this._rawObject.style.visibility = tmp;\r
};\r
\r
+/*\r
+ * 1. GPU_NOW の場合、これ以下の一切の更新を行わない\r
+ * 2. GPU解放予約 の場合、この要素のみ変更を行う。rAF 後にさらに更新するためフラグを立てる。\r
+ * 3. GPU予約 -> GPU\r
+ * 4. style="display:none" の場合、これ以下の変更を行わない。\r
+ * 5. ie5 非表示フラグが立っていて、親と自身の class・id によって非表示になっていて、親と自身に変更がない。accumulatedFlags を使用。\r
+ * -> TODO これ TREE の変更を検出できない。 remove したときに 子まで X_Node_State.IE5_DISPLAY_NONE_FIXを落とす。\r
+ * 6. 要素の生成\r
+ * 7. 要素の位置のズレを補正\r
+ * 8. 更新の適用\r
+ * 9. ie5 親及び自身へのクラス・id指定で display:none になるケースがありそれを検出。\r
+ * このままでは、生成と破棄が繰り返されてしまうので親と自身のクラス・idが変わった場合、ツリー位置の変化があった場合に再生する。\r
+ */\r
var X_Node__commitUpdate =\r
X_UA_DOM.W3C ?\r
- ( function( that, parentElement, nextElement ){\r
+ ( function( that, parentElement, nextElement, accumulatedFlags ){\r
var elm = that._rawObject,\r
- xnodes, l, i, frg, next, k, v;\r
-\r
- if( that._state & X_Node_State.IE5_DISPLAY_NONE_FIX ){\r
- //alert( that._tag + ' ' + !!elm );\r
- // filter の効いている要素だけdisplay:none が無視される模様。filter を切ればよい?\r
- // 親が、display:none の場合は?\r
- elm && elm.parentNode && X_Node__actualRemove( that );\r
- return nextElement;\r
+ created, xnodes, l, next;\r
+\r
+ // 1. GPU 一切の更新をスキップ\r
+ if( that._flags & X_Node_State.GPU_NOW ){\r
+ console.log( '更新のskip ' + !!( that._flags & X_Node_BitMask_IS_DIRTY ) );\r
+ that._flags & X_Node_BitMask_IS_DIRTY && X_Node__updateRawNode( that, elm );\r
+ return elm;\r
};\r
\r
- if( !elm || ( parentElement && elm.parentNode !== parentElement ) || ( nextElement && elm.nextSibling !== nextElement ) ){\r
- nextElement ?\r
- parentElement.insertBefore( X_Node__actualCreate( that ), nextElement ) :\r
- parentElement.appendChild( X_Node__actualCreate( that ) );\r
- X_Node__afterActualCreate( that );\r
+ // 2. GPU解放予約\r
+ // TODO もしかしたらこのタイミングで更新できるかも。\r
+ if( that._flags & X_Node_State.GPU_RELEASE_RESERVED ){\r
+ console.log( 'GPU 解放 ' );\r
+ //X_Node_updateReservedByReleaseGPU = true;\r
+ //X_Node__updateRawNode( that, elm );\r
+ that._flags &= X_Node_BitMask_RESET_GPU;\r
+ //return elm;\r
+ };\r
\r
- return elm || that._rawObject;\r
- } else\r
- if( ( xnodes = that._xnodes ) && ( l = xnodes.length ) ) {\r
+ // 3. GPU予約 -> GPU\r
+ if( that._flags & X_Node_State.GPU_RESERVED ){\r
+ that._flags &= X_Node_BitMask_RESET_GPU;\r
+ that._flags |= X_Node_State.GPU_NOW;\r
+ };\r
+\r
+ // 4. style="display:none" の場合\r
+ if( that._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ){\r
+ if( X_Node_displayNoneFixForIE5 ){\r
+ // filter の効いている要素を含む要素は display:none が無視される。\r
+ // filter = '' で削除はできるが、再表示時に filter が消える。 -> filter な要素を削除してしまう。 \r
+ if( elm && elm.parentNode ){\r
+ X_Node__actualRemove( that );\r
+ };\r
+ return nextElement;\r
+ };\r
+ elm && ( elm.style.display = 'none' );\r
+ return elm || nextElement;\r
+ }; \r
+ \r
+ // 5. ie5 非表示fixフラグ\r
+ accumulatedFlags |= that._flags;\r
+ \r
+ if( that._flags & X_Node_State.IE5_DISPLAY_NONE_FIX ){\r
+ if( accumulatedFlags & ( X_Node_State.DIRTY_POSITION | X_Node_State.DIRTY_ID | X_Node_State.DIRTY_CLASSNAME ) === 0 ){\r
+ return nextElement;\r
+ };\r
+ };\r
+ \r
+ // 6. 要素の生成\r
+ if( !elm ){\r
+ if( !that._tag ){\r
+ that._flags &= X_Node_BitMask_RESET_DIRTY;\r
+ that._rawObject = elm = document.createTextNode( X_String_chrReferanceTo( that._text ) );\r
+ } else\r
+ if( X_Node_strictElmCreation ){\r
+ that._flags & X_Node_State.DIRTY_CSS && X_Node_CSS_objToCssText( that, true );\r
+ \r
+ that._rawObject = elm =\r
+ document.createElement( [\r
+ '<', that._tag,\r
+ ' UID="', that._uid, '"',\r
+ that._id ? ' id="' + that._id + '"' : '',\r
+ that._className ? ' class="' + that._className + '"' : '',\r
+ that._flags & X_Node_State.OLD_ATTRTEXT ? X_Node_Attr_objToAttrText( that ) : that._attrText,\r
+ that._cssText ? ' style="' + that._cssText + '"' : '',\r
+ '>' ].join( '' ) ); \r
+ } else {\r
+ that._rawObject = elm = document.createElement( that._tag );\r
+ };\r
\r
- /*if( elm.childNodes.length !== l && ( frg = X_Node_useDocumentFragment ) ){\r
- for( i = 0; i < l; ++i ){\r
- frg.appendChild( X_Node__actualCreate( xnodes[ i ], true ) );\r
+ // IE には要素追加のタイミングで起こるメモリリークがありここで追加\r
+ if( !X_Node_addTreeAfterChildren ){\r
+ nextElement ?\r
+ parentElement.insertBefore( elm, nextElement ) :\r
+ parentElement.appendChild( elm );\r
+ //elm.UID = that._uid;\r
+ // src の onload があるので先ではないか?\r
+ // TODO ie の str から要素を作る場合、srcだけ イベント設定後ではないか?\r
+ X_EventDispatcher_toggleAllEvents( that, true );// イベントの復帰\r
+ };\r
+\r
+ if( that._tag ){\r
+ if( X_Node_documentFragment ){\r
+ //( frg = X_Node_documentFragment ).appendChild( elm );\r
};\r
- elm.appendChild( frg );\r
- } else {*/\r
- for( ; l; ){\r
- next = X_Node__commitUpdate( xnodes[ --l ], elm, next );\r
+\r
+ if( X_Node_strictElmCreation ){\r
+ // TODO src 等の設定\r
+ delete that._newAttrs;\r
+ that._flags &= X_Node_BitMask_RESET_DIRTY;\r
+ that._flags |= X_Node_State.DIRTY_IE_FILTER;// doc 追加後に filter を指定しないと有効にならない。\r
+ } else {\r
+ elm.UID = that._uid;\r
+ that._newAttrs = that._attrs;\r
+ that._flags |= X_Node_State.DIRTY_ID | X_Node_State.DIRTY_CLASSNAME | X_Node_State.DIRTY_ATTR | X_Node_State.DIRTY_CSS | X_Node_State.DIRTY_IE_FILTER;\r
+ \r
+ // http://outcloud.blogspot.jp/2010/09/iframe.html\r
+ // この問題は firefox3.6 で確認\r
+ if( X_UA.Gecko ){\r
+ if( that._tag === 'IFRAME' && !that._attrs[ 'src' ] ){\r
+ //elm.contentWindow.location.replace = elm.src = 'about:blank';\r
+ that.attr( 'src', 'about:blank' );\r
+ };\r
+ };\r
};\r
- //};\r
+ };\r
+ \r
+ created = true;\r
+ } else\r
+ // 7. 要素の位置のズレを補正\r
+ if( elm.parentNode !== parentElement || ( nextElement && elm.nextSibling !== nextElement ) ){\r
+ nextElement ?\r
+ parentElement.insertBefore( elm, nextElement ) :\r
+ parentElement.appendChild( elm );\r
+\r
+ if( X_Node_displayNoneFixForIE5 ) that._flags |= X_Node_State.DIRTY_POSITION;\r
+ };\r
+ \r
+ that._flags & X_Node_State.DIRTY_POSITION && X_EventDispatcher_toggleAllEvents( that, true );// イベントの復帰\r
+ that._flags &= ~X_Node_State.DIRTY_POSITION;\r
+ \r
+ // 8. 更新の適用\r
+ if( accumulatedFlags & X_Node_BitMask_IS_DIRTY ) delete that._fontSize;\r
+ \r
+ that._flags & X_Node_BitMask_IS_DIRTY && X_Node__updateRawNode( that, elm );\r
+ \r
+ \r
+ // 9. ie5 only\r
+ // 親及び自身へのクラス・id指定で display : none になるケースがありそれを検出\r
+ // 生成と破棄が繰り返されてしまう、親と自身の id, class が変わった場合だけ再生成。 accumulatedFlags & ( ID | CLASSNAME )\r
+ // currentStyle を観ていたときはエラーで停止する、alert と挟むと正常に動いて支離滅裂\r
+ if( X_Node_displayNoneFixForIE5 && that._tag ){\r
+ if( elm.runtimeStyle.display === 'none' ){\r
+ X_Node__actualRemove( that );\r
+ that._flags |= X_Node_State.IE5_DISPLAY_NONE_FIX;\r
+ return nextElement; \r
+ } else {\r
+ that._flags &= ~X_Node_State.IE5_DISPLAY_NONE_FIX;\r
+ };\r
+ };\r
+ \r
+ // 10. 子要素の更新。\r
+ if( ( xnodes = that._xnodes ) && ( l = xnodes.length ) ) {\r
+ for( ; l; ){\r
+ next = X_Node__commitUpdate( xnodes[ --l ], elm, next, accumulatedFlags );\r
+ };\r
};\r
\r
- delete that._fontSize;\r
- that._dirty && X_Node__updateRawNode( that, elm );\r
- if( that._state & X_Node_State.IE5_DISPLAY_NONE_FIX ){\r
- return nextElement;\r
+ if( created && X_Node_addTreeAfterChildren ){\r
+ nextElement ?\r
+ parentElement.insertBefore( elm, nextElement ) :\r
+ parentElement.appendChild( elm );\r
+ \r
+ X_EventDispatcher_toggleAllEvents( that, true );// イベントの復帰\r
};\r
+\r
return elm;\r
}) :\r
X_UA_DOM.IE4 ? \r
- ( function( that, parentElement, prevElement ){\r
- var elm = that._rawObject || X_Node__ie4getRawNode( that ),\r
- xnodes, l, i, html, text, prev;\r
+ ( function( that, parentElement, prevElement, accumulatedFlags ){\r
+ var elm = that._rawObject || X_Node__ie4getRawNode( that ),\r
+ xnodes, l, i, dirty, mix, html, text, prev;\r
\r
+ if( !that._tag ){\r
+ that._flags & X_Node_State.DIRTY_CONTENT && X_Node__updateRawNode( that, elm );\r
+ return elm;\r
+ };\r
+ \r
+ // 4. style="display:none" の場合\r
+ if( that._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ){\r
+ if( elm ){\r
+ elm.style.display = 'none';\r
+ if( elm.style.display !== 'none' ){ // ie4 の style は currentStyle 相当らしい、、、? div 以外への display:none が効かないので remove する。\r
+ X_Node__actualRemove( that );\r
+ return prevElement;\r
+ };\r
+ };\r
+ return elm || prevElement;\r
+ };\r
+ \r
if( !elm ){\r
prevElement ?\r
- prevElement.insertAdjacentHTML( 'AfterEnd', X_Node__actualCreate( that ) ) :\r
- parentElement.insertAdjacentHTML( 'AfterBegin', X_Node__actualCreate( that ) );\r
+ prevElement.insertAdjacentHTML( 'AfterEnd', X_Node__actualCreate( that, false ) ) :\r
+ parentElement.insertAdjacentHTML( 'AfterBegin', X_Node__actualCreate( that, false ) );\r
X_Node__afterActualCreate( that );\r
return that._rawObject || X_Node__ie4getRawNode( that );\r
};\r
\r
+ accumulatedFlags |= that._flags;\r
+ \r
xnodes = that._xnodes;\r
l = xnodes ? xnodes.length : 0;\r
+ dirty = !!( that._flags & X_Node_State.IE4_DIRTY_CHILDREN );\r
\r
- if( that._dirty & X_Node_Dirty.IE4_TEXTNODE_FIX || ( that._state & X_Node_State.IE4_ONLY_TEXT && ( l !== 1 || xnodes[ 0 ]._xnodeType !== 3 ) ) ){ // 1 < l && elm.children.length === 0\r
+ /*\r
+ * HTML の下に TextNode だけ 。MIX_FIXED でない場合、削除、追加 を親に通知\r
+ * HTML の下に HTML だけ\r
+ * HTML の下は MIX -> TextNode, html の削除、変更、追加\r
+ * HTML の下は MIX_FIXED -> TextNode を <font> に置き換えてあるのでW3C DON 的に触ることができる\r
+ */\r
+ if( dirty ){\r
+ that._flags &= ~X_Node_State.IE4_DIRTY_CHILDREN;\r
+ for( i = 0; i < l; ++i ){\r
+ if( xnodes[ i ]._tag ){\r
+ that._flags |= X_Node_State.IE4_HAS_ELEMENT;\r
+ } else {\r
+ that._flags |= X_Node_State.IE4_HAS_TEXTNODE;\r
+ };\r
+ if( that._flags & X_Node_BitMask_IE4_IS_MIX === X_Node_BitMask_IE4_IS_MIX ){\r
+ mix = true;\r
+ break;\r
+ };\r
+ };\r
+ };\r
+ \r
+ if( that._flags & X_Node_State.IE4_FIXED || that._flags & X_Node_BitMask_IE4_IS_MIX === X_Node_State.IE4_HAS_ELEMENT ){\r
+ for( i = 0; i < l; ++i ){\r
+ prev = X_Node__commitUpdate( xnodes[ i ], elm, prev, accumulatedFlags );\r
+ };\r
+ } else\r
+ if( mix ){\r
html = [];\r
for( i = 0; i < l; ++i ){\r
- html[ i ] = X_Node__actualCreate( xnodes[ i ] );\r
+ html[ i ] = X_Node__actualCreate( xnodes[ i ], false );\r
};\r
elm.innerHTML = html.join( '' );\r
for( i = 0; i < l; ++i ){\r
X_Node__afterActualCreate( xnodes[ i ] );\r
};\r
- that._state &= ~X_Node_State.IE4_ONLY_TEXT;\r
- } else\r
- if( that._state & X_Node_State.IE4_ONLY_TEXT ){ // textNode が swap した場合の検出は、_root で行う\r
- text = xnodes[ 0 ];\r
- if( text._dirty || !text._root ){\r
- elm.innerHTML = text._text;\r
- delete text._dirty;\r
- text._root = that._root; \r
- };\r
+ that._flags |= X_Node_State.IE4_FIXED;\r
} else\r
- if( l ){\r
+ if( that._flags & X_Node_State.IE4_HAS_TEXTNODE ){\r
+ dirty = dirty || false;\r
for( i = 0; i < l; ++i ){\r
- prev = X_Node__commitUpdate( xnodes[ i ], elm, prev );\r
+ text = xnodes[ i ];\r
+ if( text._flags & X_Node_BitMask_IS_DIRTY ){\r
+ text._flags &= X_Node_BitMask_RESET_DIRTY;\r
+ dirty = true;\r
+ };\r
};\r
+ if( dirty ) elm.innerHTML = that.text();\r
};\r
\r
- delete that._fontSize;\r
- that._dirty && X_Node__updateRawNode( that, elm );\r
+ if( accumulatedFlags & X_Node_BitMask_IS_DIRTY ) delete that._fontSize;\r
+ \r
+ that._flags &= ~X_Node_State.DIRTY_POSITION;\r
+ that._flags & X_Node_BitMask_IS_DIRTY && X_Node__updateRawNode( that, elm );\r
return elm;\r
}) :\r
(function(){});\r
\r
+/*\r
+ * TODO IE5 は filter-fix があるため、親から変更を適用し、自信の display:none を調べる\r
+ * GPU レイヤーするブラウザは、子要素から変更を当てていく? <- とりあえず、親要素から。\r
+ */\r
var X_Node__updateRawNode =\r
X_UA_DOM.W3C ?\r
( function( that, elm ){\r
var attrs, rename, k, v;\r
\r
// textNode\r
- if( that._dirty & X_Node_Dirty.CONTENT ){\r
+ if( !that._tag ){\r
elm.data = X_String_chrReferanceTo( that._text );\r
- delete that._dirty;\r
+ that._flags &= X_Node_BitMask_RESET_DIRTY;\r
return;\r
};\r
// id\r
- if( that._dirty & X_Node_Dirty.ID ){\r
+ if( that._flags & X_Node_State.DIRTY_ID ){\r
that._id ? ( elm.id = that._id ) : ( elm.id && elm.removeAttribute( 'id' ) ); \r
};\r
// className\r
- if( that._dirty & X_Node_Dirty.CLASSNAME ){\r
+ if( that._flags & X_Node_State.DIRTY_CLASSNAME ){\r
that._className ? ( elm.className = that._className ) : ( elm.className && elm.removeAttribute( X_UA.IE5678 ? 'className' : 'class' ) ); // className は ie7-? \r
-\r
- // ie5 only\r
- if( X_Node_State.IE5_DISPLAY_NONE_FIX && elm.currentStyle.display === 'none' ){\r
- X_Node__actualRemove( that );\r
- that._state |= X_Node_State.IE5_DISPLAY_NONE_FIX;\r
- return;\r
+ };\r
+ \r
+ // attr\r
+ if( that._flags & X_Node_State.DIRTY_ATTR && ( attrs = that._newAttrs || that._attrs ) ){\r
+ rename = X_Node_Attr_renameForDOM;\r
+ \r
+ for( k in attrs ){\r
+ v = attrs[ k ];\r
+ \r
+ switch( that._tag + k ){\r
+ case 'TEXTAREAvalue' :\r
+ // IETester 5.5 ではエラーが出なかった.MultipulIE5.5 ではエラーが出たので\r
+ if( !X_UA.MacIE && X_UA.IE5x ){\r
+ elm.firstChild ?\r
+ ( elm.firstChild.data = v || '' ) :\r
+ elm.appendChild( document.createTextNode( v || '' ) );\r
+ continue;\r
+ };\r
+ break;\r
+ \r
+ case 'IFRAMEsrc' :\r
+ // http://outcloud.blogspot.jp/2010/09/iframe.html\r
+ // この問題は firefox3.6 で確認\r
+ if( X_UA.Gecko ){\r
+ elm.contentWindow.location.replace = elm.src = v || '';\r
+ continue;\r
+ };\r
+ break;\r
+ \r
+ case 'IFRAMEname' :\r
+ // http://d.hatena.ne.jp/NeoCat/20080921/1221940658\r
+ // こちらに名前をsetしないとtargetが動作しない\r
+ // これってあとから name を変更できないバグでは? itozyun\r
+ // if( X_UA.IE ) elm.name = elm.contentWindow.name = v || '';\r
+ };\r
+ \r
+ //if( X_EMPTY_OBJECT[ k ] ) continue;\r
+ // TODO IE では input, なぜか button, object も type, name の変更が出来ない、同値で置き換えようとしても不可\r
+ v === undefined ?\r
+ elm.removeAttribute( rename[ k ] || k ) :\r
+ ( elm[ rename[ k ] || k ] = X_Node_Attr_noValue[ k ] ? k : v );\r
};\r
+ delete that._newAttrs;\r
};\r
\r
// style\r
- // TODO display:none の場合、更新をスキップ\r
- if( that._dirty & X_Node_Dirty.CSS ){\r
- if( that._cssText !== null || ( that._cssText = X_Node_CSS_objToCssText( that ) ) ){\r
+ if( that._flags & X_Node_State.DIRTY_CSS ){\r
+ if( that._flags & X_Node_State.OLD_CSSTEXT ? X_Node_CSS_objToCssText( that ) : that._cssText ){\r
X_UA.Opera78 || X_UA.NN6 ?\r
elm.setAttribute( 'style', that._cssText ) : // opera8用\r
( elm.style.cssText = that._cssText );\r
elm.removeAttribute( 'style' );\r
delete that._cssText;\r
};\r
- };\r
- \r
- if( that._dirty & X_Node_Dirty.IE_FILTER ){\r
- elm.style.filter = X_Node_CSS_objToIEFilterText( that );;\r
- };\r
- \r
- // attr\r
- // TODO display:none の場合、更新をスキップ\r
- if( that._dirty & X_Node_Dirty.ATTR && ( attrs = that._newAttrs || that._attrs ) ){\r
- rename = X_Node_Attr_renameForDOM;\r
- for( k in attrs ){\r
- if( !X_UA.MacIE && ( X_UA.IE5 || X_UA.IE55 ) ){ // IETester 5.5 ではエラーが出なかった.MultipulIE5.5 ではエラーが出たので\r
- if( that._tag === 'TEXTAREA' && k === 'value' ){\r
- elm.firstChild ?\r
- ( elm.firstChild.data = attrs[ k ] ) :\r
- elm.appendChild( document.createTextNode( attrs[ k ] ) );\r
- continue;\r
- };\r
- };\r
- // TODO IE では input, なぜか buttonも、type の変更が出来ない、object も 同値で置き換えようとしても不可\r
- ( v = attrs[ k ] ) === undefined ?\r
- elm.removeAttribute( rename[ k ] || k ) :\r
- ( elm[ rename[ k ] || k ] = X_Node_Attr_noValue[ k ] ? k : v ); \r
-\r
+ } else\r
+ if( that._flags & X_Node_State.DIRTY_IE_FILTER ){\r
+ v = X_Node_CSS_objToIEFilterText( that );\r
+ if( v ){\r
+ elm.style.filter = v;\r
+ that._flags |= X_Node_State.IE_FILTER_NOW;\r
+ } else {\r
+ elm.style.removeAttribute( 'filter' );\r
+ that._flags &= ~X_Node_State.IE_FILTER_NOW;\r
};\r
- delete that._newAttrs;\r
};\r
\r
- delete that._dirty;\r
+ that._flags &= X_Node_BitMask_RESET_DIRTY;\r
}) :\r
X_UA_DOM.IE4 ? \r
( function( that, elm ){\r
var attrs, rename, k, v;\r
\r
// fake textNode\r
- if( that._dirty & X_Node_Dirty.CONTENT ){\r
+ if( !that._tag ){\r
elm.innerText = that._text;\r
- delete that._dirty;\r
+ that._flags &= X_Node_BitMask_RESET_DIRTY;\r
return;\r
};\r
\r
* title、className、id、lang、language には setAttribute でなく、element.id で直接読み書きできる\r
*/ \r
// id\r
- if( that._dirty & X_Node_Dirty.CONTENT ) elm.setAttribute( 'id', that._id || ( 'ie4uid' + xnode._uid ) );\r
+ if( that._flags & X_Node_State.DIRTY_ID ) elm.setAttribute( 'id', that._id || ( 'ie4uid' + that._uid ) );\r
\r
// className\r
- if( that._dirty & X_Node_Dirty.CLASSNAME ){\r
+ if( that._flags & X_Node_State.DIRTY_CLASSNAME ){\r
that._className ? ( elm.className = that._className ) : elm.removeAttribute( 'class' );\r
};\r
// style\r
- if( that._dirty & X_Node_Dirty.CSS ){\r
- if( that._cssText !== null || ( that._cssText = X_Node_CSS_objToCssText( that ) ) ){\r
+ if( that._flags & X_Node_State.DIRTY_CSS ){\r
+ if( that._flags & X_Node_State.OLD_CSSTEXT ? X_Node_CSS_objToCssText( that ) : that._cssText ){\r
elm.style.cssText = that._cssText;\r
} else {\r
elm.style.cssText = '';\r
elm.removeAttribute( 'style' );\r
delete that._cssText;\r
};\r
- };\r
- \r
- if( that._dirty & X_Node_Dirty.IE_FILTER ){\r
- that._rawObject.style.filter = X_Node_CSS_objToIEFilterText( that );;\r
+ } else\r
+ if( that._flags & X_Node_State.DIRTY_IE_FILTER ){\r
+ v = X_Node_CSS_objToIEFilterText( that );\r
+ if( v ){\r
+ elm.style.filter = v;\r
+ that._flags |= X_Node_State.IE_FILTER_NOW;\r
+ } else {\r
+ elm.style.removeAttribute( 'filter' );\r
+ that._flags &= ~X_Node_State.IE_FILTER_NOW;\r
+ };\r
};\r
\r
// attr\r
- if( that._dirty & X_Node_Dirty.ATTR && ( attrs = that._newAttrs || that._attrs ) ){\r
+ if( that._flags & X_Node_State.DIRTY_ATTR && ( attrs = that._newAttrs || that._attrs ) ){\r
rename = X_Node_Attr_renameForDOM;\r
for( k in attrs ){\r
+ //if( X_EMPTY_OBJECT[ k ] ) continue;\r
( v = attrs[ k ] ) === undefined ?\r
elm.removeAttribute( rename[ k ] || k ) :\r
- //that._tag === 'TEXTAREA' && k === 'value' ?\r
- // ( elm.innerText = v ) :\r
elm.setAttribute( rename[ k ] || k, X_Node_Attr_noValue[ k ] ? k : v );\r
};\r
delete that._newAttrs;\r
};\r
- \r
- delete that._dirty;\r
+\r
+ that._flags &= X_Node_BitMask_RESET_DIRTY;\r
}) :\r
(function(){});\r
\r
* document.createElement of ie4 is only for OPTION & IMAGE.\r
*/\r
var X_Node__actualCreate =\r
- X_UA_DOM.W3C ? (function( that, isChild ){\r
- var elm = that._rawObject,\r
- xnodes, frg, i, l;\r
- \r
- if( that._xnodeType === 3 ){\r
- if( elm ) return elm;\r
- delete that._dirty;\r
- return that._rawObject = document.createTextNode( X_String_chrReferanceTo( that._text ) );\r
- };\r
- \r
- if( !elm ){\r
- if( that._dirty & X_Node_Dirty.CSS && !( that._cssText = X_Node_CSS_objToCssText( that ) ) ){\r
- delete that._cssText;\r
- };\r
- that._isNew = true;\r
- that._rawObject = elm =\r
- X_Node_strictElmCreation ?\r
- document.createElement( [\r
- '<', that._tag,\r
- ' UID="', that._uid, '"',\r
- that._id ? ' id="' + that._id + '"' : '',\r
- that._className ? ' class="' + that._className + '"' : '',\r
- that._attrText === false ? ( that._attrText = X_Node_Attr_objToAttrText( that._attrs ) ) : that._attrText,\r
- that._cssText ? ' style="' + that._cssText + '"' : '',\r
- '>' ].join( '' ) ) :\r
- document.createElement( that._tag );\r
- };\r
- if( X_Node_useDocumentFragment ){\r
- if( ( xnodes = that._xnodes ) && ( l = xnodes.length ) ){\r
- !isChild && ( frg = X_Node_useDocumentFragment ).appendChild( elm );\r
- for( i = 0; i < l; ++i ){\r
- elm.appendChild( X_Node__actualCreate( xnodes[ i ], true ) );\r
- };\r
- return frg || elm;\r
- };\r
- };\r
- \r
- return elm;\r
- }) :\r
- X_UA_DOM.IE4 ? (function( that, isChild ){\r
+ X_UA_DOM.IE4 && (function( that, isChild ){\r
var uid = that._uid,\r
html, xnodes, n, i, l;\r
\r
- if( that._xnodeType === 3 ){\r
+ if( !that._tag ){\r
html = [ '<FONT id=ie4uid', uid, ' UID="', uid, '">', that._text, '</FONT>' ];// fake textNode\r
delete that._rawObject;\r
} else {\r
- if( that._rawObject && !isChild ) X_Node__actualRemove( that, true );\r
+ if( !isChild ) X_Node__actualRemove( that, /* true */ false );\r
\r
- if( that._dirty & X_Node_Dirty.CSS && !( that._cssText = X_Node_CSS_objToCssText( that ) ) ){\r
- delete that._cssText;\r
- };\r
+ that._flags & X_Node_State.DIRTY_CSS && X_Node_CSS_objToCssText( that, true );\r
\r
html = [\r
'<', that._tag, ' id=', ( that._id || ( 'ie4uid' + uid ) ), ' UID="', uid, '"',\r
that._className ? ' class="' + that._className + '"' : '',\r
- that._attrText === false ? ( that._attrText = X_Node_Attr_objToAttrText( that._attrs ) ) : that._attrText,\r
+ that._flags & X_Node_State.OLD_ATTRTEXT ? X_Node_Attr_objToAttrText( that ) : that._attrText,\r
that._cssText ? ' style="' + that._cssText + '"' : '',\r
'>' ];\r
\r
n = html.length;\r
if( ( xnodes = that._xnodes ) && ( l = xnodes.length ) ){\r
- if( l === 1 && xnodes[ 0 ]._xnodeType === 3 ){\r
+ \r
+ that._flags &= ~X_Node_State.IE4_DIRTY_CHILDREN;\r
+ for( i = 0; i < l; ++i ){\r
+ if( xnodes[ i ]._tag ){\r
+ that._flags |= X_Node_State.IE4_HAS_ELEMENT;\r
+ } else {\r
+ that._flags |= X_Node_State.IE4_HAS_TEXTNODE;\r
+ };\r
+ if( that._flags & X_Node_BitMask_IE4_IS_MIX === X_Node_BitMask_IE4_IS_MIX ){\r
+ break;\r
+ };\r
+ };\r
+ \r
+ if( that._flags & X_Node_BitMask_IE4_IS_MIX === X_Node_State.IE4_HAS_TEXTNODE ){\r
// only textnode\r
- html[ n ] = xnodes[ 0 ]._text;\r
+ html[ n ] = that.text();\r
++n;\r
- that._state |= X_Node_State.IE4_ONLY_TEXT;\r
} else {\r
for( i = 0; i < l; ++i ){\r
html[ n ] = X_Node__actualCreate( xnodes[ i ], true );\r
++n;\r
- }; \r
+ };\r
+ that._flags |= X_Node_State.IE4_FIXED;\r
};\r
};\r
X_Dom_DTD_EMPTY[ that._tag ] || ( html[ n ] = '<\/' + that._tag + '>' );\r
};\r
\r
return html.join( '' );\r
- }) :\r
- (function(){});\r
+ });\r
\r
var X_Node__afterActualCreate =\r
- X_UA_DOM.W3C ? (function( that ){\r
- var elm = that._rawObject, xnodes, l, attrs, k, i;\r
-\r
- that._root = that.parent._root;\r
+ X_UA_DOM.IE4 && (function( that ){\r
+ var xnodes, i, v;\r
\r
- if( that._xnodeType === 3 ){\r
- that._dirty && X_Node__updateRawNode( that, elm );\r
- return that;\r
- };\r
- \r
- xnodes = that._xnodes;\r
- l = xnodes && xnodes.length;\r
- \r
- if( that._isNew ){\r
- if( !X_Node_useDocumentFragment && l ){// docFrg が使えない場合、doc 追加後に子を追加\r
- for( i = 0; i < l; ++i ){\r
- elm.appendChild( X_Node__actualCreate( xnodes[ i ], true ) );\r
- };\r
- };\r
- if( X_Node_strictElmCreation ){\r
- if( that._dirty & X_Node_Dirty.IE_FILTER ){\r
- elm.style.filter = X_Node_CSS_objToIEFilterText( that );;\r
- };\r
- delete that._dirty;\r
- } else {\r
- elm.UID = that._uid;\r
- that._newAttrs = that._attrs;\r
- that._dirty = X_Node_Dirty.ID | X_Node_Dirty.CLASSNAME | X_Node_Dirty.CSS | X_Node_Dirty.ATTR | X_Node_Dirty.IE_FILTER;\r
- X_Node__updateRawNode( that, elm );\r
- };\r
- \r
- delete that._isNew;\r
- } else {\r
- that._dirty && X_Node__updateRawNode( that, elm );\r
- };\r
- \r
- for( i = 0; i < l; ++i ){\r
- X_Node__afterActualCreate( xnodes[ i ] );\r
- };\r
- // src の onload があるので先ではないか?\r
- // TODO ie の str から要素を作る場合、srcだけ イベント設定後ではないか?\r
- X_EventDispatcher_toggleAllEvents( that, true );// イベントの復帰\r
- }) :\r
- X_UA_DOM.IE4 ? (function( that ){\r
- var xnodes, i;\r
- that._root = that.parent._root;\r
- \r
- if( that._xnodeType !== 1 ) return that;\r
+ if( !that._tag ) return that;\r
\r
if( ( xnodes = that._xnodes ) && ( i = xnodes.length ) ){\r
for( ; i; ){\r
X_Node__afterActualCreate( xnodes[ --i ] );\r
};\r
};\r
- // textarea への value の適用はここで\r
- if( that._dirty & X_Node_Dirty.IE_FILTER ){\r
- X_Node__ie4getRawNode( that ).style.filter = X_Node_CSS_objToIEFilterText( that );;\r
- };\r
- delete that._dirty;\r
+ that._flags & X_Node_State.DIRTY_IE_FILTER && X_Node__updateRawNode( that, that._rawObject || X_Node__ie4getRawNode( that ) );\r
+ that._flags &= X_Node_BitMask_RESET_DIRTY;\r
X_EventDispatcher_toggleAllEvents( that, true );// イベントの復帰\r
- }) :\r
- (function(){});\r
+ });\r
\r
var X_Node__actualRemove =\r
X_UA_DOM.W3C ?\r
+ // GPUレイヤーにいるうちは remove しない。-> GPU解除してから remove する\r
+ // Firefox34 では遭遇せず、Safari で何度かアニメーションしているうちに発生\r
( function( that, isChild ){\r
var xnodes = that._xnodes,\r
elm = that._rawObject,\r
child, i, l;\r
+\r
if( xnodes && ( l = xnodes.length ) ){\r
for( i = 0; i < l; ++i ){\r
child = xnodes[ i ];\r
- child._xnodeType === 1 && X_Node__actualRemove( child, true );\r
+ child._tag && X_Node__actualRemove( child, true );\r
};\r
};\r
\r
if( !elm ) return;\r
+ \r
that._listeners && X_EventDispatcher_toggleAllEvents( that, false );// イベントの退避\r
+ \r
+ // ie5では filter の効いている要素をremove時に破棄して、再度append 時に新規生成する\r
+ // ちなみに elm.filters に触ると ie8 でなぜかカラム落ちが発生、、、\r
+ if( X_Node_displayNoneFixForIE5 ){\r
+ if( elm.filters && elm.filters.length ){\r
+ //elm.style.removeAttribute( 'filter' );\r
+ isChild = false;\r
+ delete that._rawObject;\r
+ // 破棄前に value を控える TODO checked, selected も!\r
+ if( X_Node_Attr_HAS_VALUE[ that._tag ] && ( !that._newAttrs || !X_Object_inObject( 'value', that._newAttrs ) ) ){\r
+ that._attrs.value = elm.value;\r
+ };\r
+ elm.innerHTML = '';\r
+ };\r
+ };\r
+ \r
if( !X_UA.MacIE ){\r
- // elm.parentNode.tagName for ie7 -> that.state & BELONG_TREE_ACTUAL\r
+ // elm.parentNode.tagName for ie7\r
!isChild && elm.parentNode && elm.parentNode.tagName && elm.parentNode.removeChild( elm );\r
} else {\r
!isChild && elm.parentNode && elm.parentNode.tagName && X_TEMP._fixed_remove( elm, that );\r
if( !elm ) return;\r
that._listeners && X_EventDispatcher_toggleAllEvents( that, false );// イベントの退避\r
\r
+ // 破棄前に value を控える TODO checked, selected も!\r
if( X_Node_Attr_HAS_VALUE[ that._tag ] && ( !that._newAttrs || !X_Object_inObject( 'value', that._newAttrs ) ) ){\r
that._attrs.value = elm.value;\r
};\r