IN_TREE : 0x2, // xnode が(仮想)ツリーに追加されている -> 描画の対象\r
\r
ELM_NEED_INIT : 2 << 1,\r
- ELM_HAS_PARENT : 2 << 1,\r
+ //ELM_HAS_PARENT : 2 << 1,\r
\r
STYLE_IS_DISPLAY_NONE : 2 << 2, // display : none \r
STYLE_IS_INVISIBLE : 2 << 3, // visibility : hidden or opacity : 0\r
OLD_ATTRTEXT : 2 << 18,\r
OLD_CSSTEXT : 2 << 19,\r
\r
+ // filter 要素が親子になると不具合が出るのを検出\r
IE_FILTER_NOW : 2 << 20,\r
\r
- GPU_WAITING : 2 << 20, // 1:子のGPU解除待\r
- GPU_RESERVED : 2 << 21, // 2:GPU予約\r
- GPU_NOW : 2 << 20 | 2 << 21, // 3:GPU now!()\r
- GPU_RELEASE_RESERVED : 2 << 20 | 2 << 21 | 2 << 22, // 4:GPU解除予約\r
+ GPU_WAITING : 2 << 20, // 1:子のGPU解除待\r
+ GPU_RESERVED : 2 << 21, // 2:GPU予約\r
+ GPU_NOW : 2 << 22, // 3:GPU now!\r
+ GPU_RELEASE_RESERVED : 2 << 23, // 4:GPU解除予約\r
\r
- /* 子要素は一つのテキストノード */\r
- IE4_ONLY_TEXT : 2 << 23,\r
- /* 子要素に html要素とテキストノードが混在する */\r
- IE4_TEXTNODE_FIX : 2 << 24,\r
- IE4_TEXTNODE_EXIST : 2 << 25\r
+ IE5_DISPLAY_NONE_FIX : X_UA.IE5 && X_UA.ActiveX ? 2 << 24 : 0,\r
+ \r
+ IE4_HAS_TEXTNODE : X_UA.IE4 ? 2 << 20 : 0,\r
+ IE4_HAS_ELEMENT : X_UA.IE4 ? 2 << 21 : 0,\r
+ IE4_DIRTY_CHILDREN : X_UA.IE4 ? 2 << 22 : 0,\r
+ IE4_FIXED : X_UA.IE4 ? 2 << 23 : 0\r
},\r
\r
X_Node_BITMASK_RESET_STYLE = ( ( 2 << 29 ) - 1 + ( 2 << 29 ) ) ^ (\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
RAW_HTML : 2,\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_useDocumentFragment = document.createDocumentFragment && ( !X_UA.IE || 5.5 <= X_UA.IE ) && document.createDocumentFragment(),\r
+ X_Node_useDocumentFragment = document.createDocumentFragment && ( !X_UA.IE || 5.5 <= X_UA.IE ) && document.createDocumentFragment(),\r
\r
- X_Node_displayNoneFixForIE5 = X_UA.IE5 && X_UA.ActiveX,\r
+ X_Node_displayNoneFixForIE5 = X_Node_State.IE5_DISPLAY_NONE_FIX,\r
\r
X_Node_newByTag = false,\r
\r
\r
nextNode : X_Node_after, // -> next\r
\r
- replace : X_Node_replace, // remove\r
+ replace : X_Node_swap, // remove\r
\r
- swap : X_Node_replace,\r
+ swap : X_Node_swap,\r
\r
remove : X_Node_remove,\r
\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_create( tag, opt_attrs, opt_css ){\r
var xnode;\r
if( !this._tag ) return;\r
- if( !this._xnodes ) this._xnodes = [];\r
- \r
- xnode = X_Doc_create( tag, opt_attrs, opt_css );\r
- \r
- xnode.parent = this;\r
- this._xnodes[ this._xnodes.length ] = xnode;\r
- if( this._flags & X_Node_State.IN_TREE ){\r
- xnode._flags |= X_Node_State.IN_TREE;\r
- xnode._xnodes && X_Node_toggleInTreeFlag( xnode._xnodes, true );\r
- X_Node_reserveUpdate();\r
- };\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 = X_Doc_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
function X_Node_createText( text ){\r
var xnode;\r
if( !this._tag ) return;\r
- if( !this._xnodes ) this._xnodes = [];\r
- \r
- X_Node_newByText = true;\r
- xnode = new Node( text );\r
- xnode.parent = this;\r
- this._xnodes[ this._xnodes.length ] = xnode;\r
- \r
- if( this._flags & X_Node_State.IN_TREE ){\r
- xnode._flags |= X_Node_State.IN_TREE;\r
- xnode._xnodes && X_Node_toggleInTreeFlag( xnode._xnodes, true );\r
- X_Node_reserveUpdate();\r
- };\r
+ this.append( xnode = X_Doc_createText( text ) );\r
return xnode;\r
};\r
function X_Node_createTextAt( index, text ){\r
- var xtext = X_Doc_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
return this.append.apply( this, X_HtmlParser_parse( v, true ) );\r
case X_Node_TYPE.XNODE :\r
// 親の xnodes から v を消す\r
- if( v.parent ){\r
- v.remove();\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
return this;\r
case X_Node_TYPE.XNODE :\r
// 親の xnodes から v を消す\r
- if( v.parent ){\r
- v.remove();\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
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
parent._xnodes.splice( parent._xnodes.indexOf( this ), 1 );\r
\r
if( this._flags & X_Node_State.IN_TREE ){\r
- this._flags &= ~X_Node_State.IN_TREE & ~X_Node_State.IE4_TEXTNODE_EXIST;\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( ( elm = this._rawObject ) && elm.parentNode && elm.parentNode.tagName ){\r
- X_Node_reserveRemoval[ X_Node_reserveRemoval.length ] = this;\r
- X_Node_reserveUpdate(); \r
- //};\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
return this;\r
};\r
};\r
\r
function X_Node_onBeforeKill( e ){\r
- var elm = this._rawObject || X_UA_DOM.IE4 && X_Node__ie4getRawNode( this );\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
- this.remove();\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( elm && elm.parentNode && elm.parentNode.tagName ){\r
+ if( e && elm && elm.parentNode && elm.parentNode.tagName ){\r
delete this._flags;\r
return X.Callback.PREVENT_DEFAULT;\r
};\r
/* --------------------------------------\r
* html, text\r
* \r
- * outerHTML が欲しい場合は、xnode.attr('outerHTML') とできる。\r
+ * outerHTML が欲しい場合は、xnode.call('outerHTML') とできる。\r
*/\r
function X_Node_html( html ){\r
var _ = '', q = '"', xnodes, n, i, l;\r
};\r
\r
/*\r
- * null が来たら '', 数値等が来たら文字烈化\r
+ * null が来たら '', 数値等が来たら文字列化\r
*/\r
function X_Node_text( text ){\r
var xnodes, texts, i, l;\r
case 'innerHTML' :\r
return this.html();\r
case 'outerHTML' :\r
- X_Node_outerXNode = this;\r
+ X_Node_outerXNode = X_Node_body; // == true ならなんでもよい。型を合わすために xbody にしている\r
v = this.html();\r
X_Node_outerXNode = null;\r
return v;\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;\r
\r
for( ; i; ){\r
xnode = removal[ --i ];\r
X_Node__actualRemove( xnode );\r
- X_Node_body._flags && !xnode._flags && xnode.kill();\r
+ !xnode._flags && xnode.kill();\r
};\r
removal.length = 0;\r
};\r
\r
if( X_Node_html._flags & X_Node_BitMask_IS_DIRTY ){\r
- X_Node__commitUpdate( X_Node_html );\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 );\r
- X_Node__commitUpdate( X_Node_body );\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
\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, next;\r
\r
if( X_Node_displayNoneFixForIE5 ){\r
// filter の効いている要素を含む要素は display:none が無視される。\r
- // filter = '' で削除はできるが、再表示時に filter が消える。 -> filter な要素を削除してしまう。\r
+ // filter = '' で削除はできるが、再表示時に filter が消える。 -> filter な要素を削除してしまう。\r
if( that._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ){\r
elm && elm.parentNode && X_Node__actualRemove( that );\r
return nextElement;\r
};\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
- return elm || that._rawObject;\r
- } else\r
- if( ( xnodes = that._xnodes ) && ( l = xnodes.length ) ) {\r
- for( ; l; ){\r
- next = X_Node__commitUpdate( xnodes[ --l ], elm, next );\r
- };\r
+ if( that._flags & X_Node_State.GPU_NOW ){\r
+ // 一切の更新をスキップ\r
+ // return nextElement;\r
};\r
\r
- delete that._fontSize;\r
+ accumulatedFlags |= that._flags;\r
+ \r
+ if( that._flags & X_Node_State.GPU_RELEASE_RESERVED ){\r
+ // 子要素の更新をスキップ\r
+ // 自身の更新のみ -> 更新の予約\r
+ // X_Node_updateReservedByReleaseGPU = true;\r
+ // xnode._flags &= X_Node_BitMask_RESET_GPU;\r
+ } else {\r
+ // ここへ\r
+ };\r
+ \r
+ // 要素が存在しない、または要素の位置のズレを補正\r
+ if( !elm || elm.parentNode !== parentElement || ( nextElement && elm.nextSibling !== nextElement ) ){\r
+ /*\r
+ * if( xnode._flags & X_Node_State.IE5_DISPLAY_NONE_FIX && ( accumulatedFlags & ( X_Node_State.DIRTY_ID | X_Node_State.DIRTY_CLASSNAME ) === 0 ) ) return nextElement;\r
+ */\r
+ nextElement ?\r
+ parentElement.insertBefore( X_Node__actualCreate( that, false ), nextElement ) :\r
+ parentElement.appendChild( X_Node__actualCreate( that, false ) );\r
+ X_Node__afterActualCreate( that );\r
+ return elm || that._rawObject;\r
+ } else\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
+ if( accumulatedFlags & X_Node_BitMask_IS_DIRTY ) delete that._fontSize;\r
+ // ここまで\r
\r
that._flags & X_Node_BitMask_IS_DIRTY && X_Node__updateRawNode( that, elm );\r
\r
+ if( that._flags & X_Node_State.GPU_RESERVED ){\r
+ // xnode._flags &= X_Node_BitMask_RESET_GPU;\r
+ // xnode._flags |= X_Node_State.GPU_NOW;\r
+ };\r
+\r
// ie5 only\r
// 親及び自身へのクラス・id指定で display : none になるケースもある\r
- if( X_Node_displayNoneFixForIE5 && that._tag && elm.currentStyle.display === 'none' ){\r
- X_Node__actualRemove( that );\r
- return nextElement;\r
+ // 生成と破棄が繰り返されてしまう、親と自身の id, class が変わった場合だけ再生成。 accumulatedFlags & ( ID | CLASSNAME )\r
+ if( X_Node_displayNoneFixForIE5 && that._tag ){\r
+ if( elm.currentStyle.display === 'none' ){\r
+ X_Node__actualRemove( that );\r
+ // X_Node_State.IE5_DISPLAY_NONE_FIX -> swap で落とす\r
+ return nextElement; \r
+ } else {\r
+ // xnode._flags &= ~X_Node_State.IE5_DISPLAY_NONE_FIX\r
+ };\r
};\r
+ \r
+ console.log( that.call('outerHTML') );\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_BitMask_IS_DIRTY && X_Node__updateRawNode( that, elm );\r
+ return elm;\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
+ /*\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_ONLY_TEXT && ( l !== 1 || xnodes[ 0 ]._tag ) ) || that._flags & X_Node_State.IE4_TEXTNODE_FIX ){\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._flags &= ~X_Node_State.IE4_TEXTNODE_FIX;\r
- that._flags &= ~X_Node_State.IE4_ONLY_TEXT;\r
- } else\r
- // TODO textNode だけが 2つ以上ある場合\r
- if( that._flags & X_Node_State.IE4_ONLY_TEXT ){\r
- text = xnodes[ 0 ];\r
- if( text._flags & X_Node_State.DIRTY_CONTENT || ( text._flags & X_Node_State.IE4_TEXTNODE_EXIST ) === 0 ){\r
- elm.innerHTML = text._text;\r
- text._flags &= X_Node_BitMask_RESET_DIRTY;\r
- /* if( taht._flags & X_Node_State.IN_TREE ) */ text._flags |= X_Node_State.IE4_TEXTNODE_EXIST;\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
+ 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
return elm;\r
}) :\r
\r
/*\r
* TODO IE5 は filter-fix があるため、親から変更を適用し、自信の display:none を調べる\r
- * GPU レイヤーするブラウザは、子要素から変更を当てていく?\r
+ * GPU レイヤーするブラウザは、子要素から変更を当てていく? <- とりあえず、親要素から。\r
*/\r
var X_Node__updateRawNode =\r
X_UA_DOM.W3C ?\r
\r
// textNode\r
if( !that._tag ){\r
+ console.log( that.parent.call('outerHTML') );\r
elm.data = X_String_chrReferanceTo( that._text );\r
that._flags &= X_Node_BitMask_RESET_DIRTY;\r
return;\r
// style\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
- if( !elm.style ) alert(that.call('outerHTML'));\r
X_UA.Opera78 || X_UA.NN6 ?\r
elm.setAttribute( 'style', that._cssText ) : // opera8用\r
( elm.style.cssText = that._cssText );\r
} else\r
if( that._flags & X_Node_State.DIRTY_IE_FILTER ){\r
elm.style.filter = v = X_Node_CSS_objToIEFilterText( that );\r
- //alert( 'updateraw ' + that.call('outerHTML') );\r
if( v ){\r
that._flags |= X_Node_State.IE_FILTER_NOW;\r
} else {\r
if( !that._tag ){\r
if( elm ) return elm;\r
that._flags &= X_Node_BitMask_RESET_DIRTY;\r
- //console.log( 'create ' + that._text );\r
- console.log( document.createTextNode( X_String_chrReferanceTo( that._text ) ) );\r
return that._rawObject = document.createTextNode( X_String_chrReferanceTo( that._text ) );\r
};\r
\r
if( !elm ){\r
- that._flags & X_Node_State.DIRTY_CSS && X_Node_CSS_objToCssText( that );\r
+ that._flags & X_Node_State.DIRTY_CSS && X_Node_CSS_objToCssText( that, true );\r
\r
that._flags |= X_Node_State.ELM_NEED_INIT;\r
that._rawObject = elm =\r
'>' ].join( '' ) ) :\r
document.createElement( that._tag );\r
};\r
+ \r
if( X_Node_useDocumentFragment ){\r
if( ( xnodes = that._xnodes ) && ( l = xnodes.length ) ){\r
!isChild && ( frg = X_Node_useDocumentFragment ).appendChild( elm );\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( /* that._rawObject && */ !isChild ) X_Node__actualRemove( that, /* true */ false );\r
\r
- that._flags & X_Node_State.DIRTY_CSS && X_Node_CSS_objToCssText( that );\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
\r
n = html.length;\r
if( ( xnodes = that._xnodes ) && ( l = xnodes.length ) ){\r
- if( l === 1 && !xnodes[ 0 ]._tag ){\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._flags |= 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
that._flags & X_Node_BitMask_IS_DIRTY && X_Node__updateRawNode( that, elm );\r
return that;\r
};\r
- \r
+ \r
xnodes = that._xnodes;\r
l = xnodes && xnodes.length;\r
- \r
\r
// src の onload があるので先ではないか?\r
// TODO ie の str から要素を作る場合、srcだけ イベント設定後ではないか?\r
if( !X_Node_useDocumentFragment ){// docFrg が使えない場合、doc 追加後に子を追加 TODO ie の場合この順序(メモリリーク対策)、他のブラウザは 子が先が有利では?\r
for( i = 0; i < l; ++i ){\r
elm.appendChild( X_Node__actualCreate( xnodes[ i ], true ) );\r
- /* X_Node__afterActualCreate( xnodes[ i ] ); */\r
};\r
- /*} else { \r
- for( i = 0; i < l; ++i ){\r
- X_Node__afterActualCreate( xnodes[ i ] );\r
- }; */\r
};\r
\r
if( X_Node_strictElmCreation ){\r
\r
that._flags ^= X_Node_State.ELM_NEED_INIT;\r
} else {\r
- /*\r
- for( i = 0; i < l; ++i ){\r
- X_Node__afterActualCreate( xnodes[ i ] );\r
- }; */\r
- // 親要素の updateRawNode 前に子要素の updateRawNode を行う\r
- // 親要素が GPU レイヤーに転送されるケースがあるので、先に子要素の変更を済ませる <- コレ間違いでは? css 設定後の script 終了後ではないか?\r
that._flags & X_Node_BitMask_IS_DIRTY && X_Node__updateRawNode( that, elm );\r
- }; \r
+ };\r
\r
for( i = 0; i < l; ++i ){\r
X_Node__afterActualCreate( xnodes[ i ] );\r
}) :\r
X_UA_DOM.IE4 ? (function( that ){\r
var xnodes, i, v;\r
- that._flags |= X_Node_State.IE4_TEXTNODE_EXIST;\r
\r
if( !that._tag ) return that;\r
\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
\r
-\r
var\r
ease = {\r
quadratic: {\r
\r
/*\r
* TODO : scale, ActiveX transform, zoom, fontSizeScale\r
- * TODO : rotate, ActiveX transform\r
+ * TODO : rotate, ActiveX transform -> 位置補正のために size 情報が必要なので、commitUpdate 後に計算して適用\r
+ * TODO : matrix\r
+ * TODO : skew\r
*/\r
Node.prototype.animate = function( start, dest, duration, easing, wait ){\r
var isNew = !this._anime,\r
obj.destY = ( dest.y || dest.y === 0 ) ? dest.y : obj.destY || 0;\r
obj.destA = 0 <= dest.opacity && dest.opacity <= 1 ? dest.opacity : obj.destA || 1;\r
\r
+ X_Node_ANIMATIONS.indexOf( this ) === -1 &&\r
+ ( X_Node_ANIMATIONS[ X_Node_ANIMATIONS.length ] = this );\r
+\r
+ \r
if( X_Node_Anime_onTransition ) return this;\r
\r
if( X_Node_Anime_hasTransition ){\r
\r
isNew && this.dispatch( { type : X.Event.ANIME_START, gpu : false } );\r
};\r
-\r
- X_Node_ANIMATIONS.indexOf( this ) === -1 &&\r
- ( X_Node_ANIMATIONS[ X_Node_ANIMATIONS.length ] = this );\r
\r
console.log( 'animate ' + this._id + ' y:' + obj.startX + ' > ' + obj.destX + ' d:' + obj.duration );\r
\r
X_Node_Anime_reserved = true;\r
\r
if( X_Node_updateTimerID ){\r
- //console.log( before ? '> BEFORE_UPDATE' : '> UPDATED' );\r
+ console.log( before ? '> BEFORE_UPDATE' : '> UPDATED' );\r
before = false;\r
X_System.listenOnce( before ? X.Event.BEFORE_UPDATE : X.Event.UPDATED, X_Node_Anime_updateAnimations );\r
} else {\r
- //console.log( '> Timer' );\r
+ console.log( '> Timer' );\r
// Opera12 requestAnimationFrame では transition が動かない、、、\r
X_Node_Anime_updateTimerID =\r
X_UA.Opera ?\r
\r
//console.log( v.type || v );\r
\r
- //console.log( 'updateAnimations ' + i + ' ' + X_Node_Anime_needsDetection );\r
+ //console.log( 'updateAnimations len:' + i + ' time:' + v + ' det:' + X_Node_Anime_needsDetection );\r
\r
if( X_Node_Anime_needsDetection ) X_Node_Anime_detectAnimationLayers();\r
\r
break;\r
case 0 : // 開始位置+アニメーションの設定 \r
case 8 :\r
- xnode.dispatch( { type : X.Event.ANIME_START, gpu : phase === 8 } );\r
X_ViewPort.unlisten( X.Event.AFTER_UPDATE, xnode, X_Node_Anime_gpuReleased );\r
\r
- X_Node_Anime_readyTransition( xnode );\r
+ xnode.css({\r
+ //willChange : X_Node_Anime_transitionProps + ',opacity,width,height',\r
+ backfaceVisibility : 'hidden',\r
+ transitionTimingFunction : obj.easing.style,\r
+ transitionDelay : '0s' // 0.001 にすると transitionend のタイミングが狂う、、、\r
+ });\r
+ \r
X_Node_Anime_updatePosition( xnode, obj.startX, obj.startY, obj.startA, phase === 8 );\r
+ \r
+ xnode.dispatch( { type : X.Event.ANIME_START, gpu : phase === 8 } );\r
++obj.phase;\r
break;\r
case 1 :\r
xnode.listenOnce( 'transitionend', X_Node_Anime_onTransitionEnd );\r
\r
xnode.css({\r
- transitionProperty : X_Node_Anime_transitionProps + ',opacity,width,height', // X_Node_Anime_readyTransitionに移動??\r
- transitionDuration : obj.duration + 'ms'\r
+ transitionProperty : X_Node_Anime_transitionProps + ',opacity,width,height', // X_Node_Anime_readyTransitionに移動??\r
+ transitionDuration : obj.duration + 'ms'\r
});\r
\r
X_Node_Anime_updatePosition( xnode, obj.destX, obj.destY, obj.destA, obj.gpuParent );\r
\r
case 3 : // アニメーションの解除\r
obj.phase = obj.gpuParent ? 10 : 4;\r
- // このタイミングで animation 関連の css を削除したところ、iOS3、4 で再描画忘れが度々起きるように、、、\r
+ // このタイミングで animation 関連の css を削除したところ(X_Node_Anime_clearTransition)、iOS3、4 で再描画忘れが度々起きるように、、、\r
if( !obj.gpuParent ) X_Node_Anime_clearTransition( xnode );\r
xnode.dispatch( { type : X.Event.ANIME_END, gpu : obj.gpuParent } );\r
break;\r
this.dispatch( { type : X.Event.GPU_RELEASED, gpu : true } );\r
};\r
\r
-function X_Node_Anime_readyTransition( xnode ){\r
- xnode.css({\r
- //zIndex : 0,\r
- //willChange : X_Node_Anime_transitionProps + ',opacity,width,height',\r
- backfaceVisibility : 'hidden',\r
- transitionTimingFunction : xnode._anime.easing.style,\r
- transitionDelay : '0s' // 0.001 にすると transitionend のタイミングが狂う、、、\r
- });\r
-};\r
-\r
function X_Node_Anime_clearTransition( xnode ){\r
// 開始座標のセット(新規のみ)\r
// アニメーション指定のセット(または解除)(対象のみ)\r
//xnode.unlisten( 'transitionend', X_Node_Anime_onTransitionEnd );\r
\r
xnode.css({\r
- //zIndex : 1,\r
//willChange : '',\r
backfaceVisibility : '',\r
transitionTimingFunction : '',\r
opacity : opacity\r
});\r
};\r
- // xnode._anime.x, y\r
+\r
+ if( useGPU ){\r
+ if( xnode._flags & X_Node_State.GPU_RELEASE_RESERVED ){\r
+ xnode._flags &= X_Node_BitMask_RESET_GPU;\r
+ xnode._flags |= X_Node_State.GPU_NOW;\r
+ } else\r
+ if( xnode._flags & X_Node_State.GPU_NOW === 0 ){\r
+ xnode._flags &= X_Node_BitMask_RESET_GPU;\r
+ xnode._flags |= X_Node_State.GPU_RESERVED; \r
+ };\r
+ } else {\r
+ if( xnode._flags & X_Node_State.GPU_NOW ){\r
+ xnode._flags &= X_Node_BitMask_RESET_GPU;\r
+ xnode._flags |= X_Node_State.GPU_RELEASE_RESERVED; \r
+ } else\r
+ if( xnode._flags & X_Node_State.GPU_RESERVED ){\r
+ xnode._flags &= X_Node_BitMask_RESET_GPU;\r
+ };\r
+ };\r
+\r
};\r
\r
function X_Node_Anime_updateAnimationsNoTransition(){\r
\r
if( obj.destTime <= now ){\r
X_Node_Anime_updatePosition( xnode, obj.destX, obj.destY, obj.destA, false );\r
- //xnode.asyncDispatch( 'transitionend' );\r
+\r
delete xnode._anime;\r
X_Node_ANIMATIONS.splice( i, 1 );\r
\r