var Node = X[ 'Node' ] = X_EventDispatcher[ 'inherits' ](
'X.Node',
X_Class.POOL_OBJECT,
-
{
/**
* 要素に振られるユニークID
* TODO Node の継承ができない!
*/
'Constructor' : function( v ){
+ // TODO uid = X_Node_CHASHE.indexOf( null ), uid === -1 ? X_Node_CHASHE.length : uid;
var uid = X_Node_CHASHE.length,
css, xnodes, xnode, parent;
case X_NodeType_RAW_TEXT :
if( v[ 'UID' ] ) return X_Node_CHASHE[ v[ 'UID' ] ];
for( chashe = X_Node_CHASHE, i = chashe.length; i; ){
- if( ( xnode = X_Node_CHASHE[ --i ] ) && ( xnode[ '_rawObject' ] === v ) ) return xnode;
+ if( ( xnode = chashe[ --i ] ) && ( xnode[ '_rawObject' ] === v ) ) return xnode;
};
};
};
};
-
+// TODO document.all[ uid ] -> document[ uid ]
var X_Node__ie4getRawNode = X_UA_DOM.IE4 && function ( that ){
return that[ '_rawObject' ] ||
- ( that[ '_rawObject' ] = document.all[ 'ie4uid' + that[ '_uid' ] ] ) ||
- ( that[ '_id' ] && ( that[ '_rawObject' ] = document.all[ that[ '_id' ] ] ) );
+ ( that[ '_rawObject' ] = document.all[ 'ie4uid' + that[ '_uid' ] ] || that[ '_id' ] && document.all[ that[ '_id' ] ] );
};
*/
function X_Node_create( tag, opt_attrs, opt_css ){
var xnode;
+
if( !this[ '_tag' ] ) return;
this[ 'append' ]( xnode = X_Doc_create( tag, opt_attrs, opt_css ) );
return xnode;
};
/**
- * 要素を抜く。
+ * 要素を親要素から抜く。jQuery の remove と異なり、インスタンスは破壊(kill)されず、再び別の親に挿入等できる
* @alias Node.prototype.remove
* @return {Node} 自身。チェインメソッド
* @example node.remove();
+ * parent.append( node ); 新しい親に追加できる
*/
function X_Node_remove(){
var parent = this.parent,
*/
function X_Node_empty(){
var xnodes = this[ '_xnodes' ], i;
+
if( xnodes && ( i = xnodes.length ) ){
+ delete this[ '_xnodes' ];
for( ; i; ){
xnodes[ --i ][ 'kill' ]();
};
if( ( that[ '_flags' ] & X_NodeFlags_EXIST ) === 0 ) return;
- parent && parent[ '_xnodes' ].splice( parent[ '_xnodes' ].indexOf( that ), 1 );
+ parent && parent[ '_xnodes' ] && parent[ '_xnodes' ].splice( parent[ '_xnodes' ].indexOf( that ), 1 );
elm = that[ '_rawObject' ] || X_UA_DOM.IE4 && X_Node__ie4getRawNode( that );
- // elm && that[ '_listeners' ] && X_EventDispatcher_unlistenAll( that ); // イベントの退避
if( xnodes && ( i = xnodes.length ) ){
+ delete that[ '_xnodes' ];
for( ; i; ){
xnodes[ --i ][ 'kill' ]();
};
+ xnodes.length = 0;
};
- delete X_Node_CHASHE[ that[ '_uid' ] ];
+ X_Node_CHASHE[ that[ '_uid' ] ] = null; // array に対して delete X_Node_CHASHE[ uid ] はまずい!
+
// remove _xnodes
if( X_UA_DOM.IE4 ){
if( elm ){
} else {
if( elm && elm.parentNode && elm.parentNode.tagName ){
X_Node_reserveRemoval[ X_Node_reserveRemoval.length ] = elm;
- X_Node_reserveUpdate();
+ X_Node_reserveUpdate();
};
};
};
// setter
if( html !== undefined ){ // String 以外に Number や false null なども許可
if( !this[ '_tag' ] ) return this[ 'text' ]( html );
- return html ? this[ 'empty' ]()[ 'append' ].apply( this, X_HtmlParser_parse( html, true ) ) : this[ 'empty' ]();
+
+ this[ 'empty' ]();
+ if( html ){
+ X_Node_append.apply( this, X_HtmlParser_parse( html, true ) );
+ };
+ return this;
};
// getter
case 'treeIsDirty' :
return !!X_Node_updateTimerID;
case 'fontSize' :
- return X_Node_CSS_getCharSize( this );
+ return this.parent ? X_Node_CSS_getCharSize( this ) : 0;
case 'inGPU' :
return !!( this[ '_flags' ] & ( X_NodeFlags_GPU_NOW | X_NodeFlags_GPU_RELEASE_RESERVED ) );
};
};
if( X_Node_html[ '_flags' ] & X_Node_BitMask_IS_DIRTY ){
- X_Node__commitUpdate( X_Node_html, X_Node_html[ '_rawObject' ].parentNode, null, X_Node_html[ '_flags' ] );
+ X_Node__commitUpdate( X_Node_html, X_Node_html[ '_rawObject' ].parentNode, null, X_Node_html[ '_flags' ], 1 );
} else {
- X_Node__commitUpdate( X_Node_head, X_Node_head[ '_rawObject' ].parentNode, null, X_Node_head[ '_flags' ] );
- X_Node__commitUpdate( X_Node_body, X_Node_body[ '_rawObject' ].parentNode, null, X_Node_body[ '_flags' ] );
+ X_Node__commitUpdate( X_Node_head, X_Node_head[ '_rawObject' ].parentNode, null, X_Node_head[ '_flags' ], 1 );
+ X_Node__commitUpdate( X_Node_body, X_Node_body[ '_rawObject' ].parentNode, null, X_Node_body[ '_flags' ], 1 );
};
if( X_Node_updateReservedByReleaseGPU ){
*/
var X_Node__commitUpdate =
X_UA_DOM.W3C ?
- ( function( that, parentElement, nextElement, accumulatedFlags ){
+ ( function( that, parentElement, nextElement, accumulatedFlags, ie8opacity ){
var elm = that[ '_rawObject' ],
created, xnodes, l, next;
// 1. GPU 一切の更新をスキップ
if( that[ '_flags' ] & X_NodeFlags_GPU_NOW ){
- console.log( '更新のskip ' + !!( that[ '_flags' ] & X_Node_BitMask_IS_DIRTY ) );
+ //console.log( '更新のskip ' + !!( that[ '_flags' ] & X_Node_BitMask_IS_DIRTY ) );
that[ '_flags' ] & X_Node_BitMask_IS_DIRTY && X_Node__updateRawNode( that, elm );
return elm;
};
if( that[ '_flags' ] & X_NodeFlags_GPU_RELEASE_RESERVED ){
// console.log( 'GPU 解放 ' );
//X_Node_updateReservedByReleaseGPU = true;
- //X_Node__updateRawNode( that, elm );
that[ '_flags' ] &= X_Node_BitMask_RESET_GPU;
//return elm;// TODO もしかしたらこのタイミングで更新できるかも。
};
that[ '_flags' ] |= X_NodeFlags_ACTUAL_LISTENING;
};
+ ie8opacity = ie8opacity * ( that[ '_css' ] && 0 <= that[ '_css' ].opacity ? that[ '_css' ].opacity : 1 );
+
// 8. 更新の適用
if( accumulatedFlags & X_Node_BitMask_IS_DIRTY ){
delete that[ '_fontSize' ];
- X_Node__updateRawNode( that, elm );
+ X_Node__updateRawNode( that, elm, ie8opacity, accumulatedFlags );
};
// 9. ie5 only
// 10. 子要素の更新。
if( ( xnodes = that[ '_xnodes' ] ) && ( l = xnodes.length ) ) {
for( ; l; ){
- next = X_Node__commitUpdate( xnodes[ --l ], elm, next, accumulatedFlags );
+ next = X_Node__commitUpdate( xnodes[ --l ], elm, next, accumulatedFlags, ie8opacity );
};
};
*/
var X_Node__updateRawNode =
X_UA_DOM.W3C ?
- ( function( that, elm ){
- var attrs, rename, k, v;
+ ( function( that, elm, ie8opacity, accumulatedFlags ){
+ var attrs, rename, k, v, memory, f;
// textNode
if( !that[ '_tag' ] ){
delete that[ '_newAttrs' ];
};
+ if( accumulatedFlags & X_NodeFlags_IE8_OPACITY_FIX ){
+ memory = that[ '_css' ] && that[ '_css' ].opacity;
+ if( f = true ){
+ if( !that[ '_css' ] ) that[ '_css' ] = {};
+ that[ '_css' ].opacity = ie8opacity;
+ if( that[ '_flags' ] & X_NodeFlags_DIRTY_CSS ){
+ that[ '_flags' ] |= X_NodeFlags_OLD_CSSTEXT;
+ } else
+ if( !( that[ '_flags' ] & X_NodeFlags_DIRTY_IE_FILTER ) ){
+ that[ '_flags' ] |= X_NodeFlags_DIRTY_IE_FILTER;
+ };
+ };
+ };
+
// style
if( that[ '_flags' ] & X_NodeFlags_DIRTY_CSS ){
if( that[ '_flags' ] & X_NodeFlags_OLD_CSSTEXT ? X_Node_CSS_objToCssText( that ) : that[ '_cssText' ] ){
};
};
+ if( f ){
+ if( 0 <= memory ){
+ that[ '_css' ].opacity = memory;
+ } else {
+ delete that[ '_css' ].opacity;
+ if( X_Object_isEmpty( that[ '_css' ] ) ) delete that[ '_css' ];
+ };
+ };
+
that[ '_flags' ] &= X_Node_BitMask_RESET_DIRTY;
}) :
X_UA_DOM.IE4 ?
that[ '_listeners' ] && X_EventDispatcher_toggleAllEvents( that, false );// イベントの退避
that[ '_flags' ] &= ~X_NodeFlags_ACTUAL_LISTENING;
};
-
+
// ie5では filter の効いている要素をremove時に破棄して、再度append 時に新規生成する
// ちなみに elm.filters に触ると ie8 でなぜかカラム落ちが発生、、、
if( X_Node_displayNoneFixForIE5 ){
if( !that[ '_attrs' ] ) that[ '_attrs' ] = {};
that[ '_attrs' ].selectedIndex = elm.selectedIndex;
};
- if( that[ '_tag' ] === 'INPUT' && that._attr && ( that._attr.type === 'checkbox' || that._attr.type === 'radio' ) && ( !that[ '_newAttrs' ] || !X_Object_inObject( 'checked', that[ '_newAttrs' ] ) ) ){
+ if( that[ '_tag' ] === 'INPUT' && that[ '_attrs' ] && ( that[ '_attrs' ].type === 'checkbox' || that[ '_attrs' ].type === 'radio' ) && ( !that[ '_newAttrs' ] || !X_Object_inObject( 'checked', that[ '_newAttrs' ] ) ) ){
if( !that[ '_attrs' ] ) that[ '_attrs' ] = {};
that[ '_attrs' ].checked = elm.checked;
};
if( !that[ '_attrs' ] ) that[ '_attrs' ] = {};
that[ '_attrs' ].selectedIndex = elm.selectedIndex;
};
- if( that[ '_tag' ] === 'INPUT' && that._attr && ( that._attr.type === 'checkbox' || that._attr.type === 'radio' ) && ( !that[ '_newAttrs' ] || !X_Object_inObject( 'checked', that[ '_newAttrs' ] ) ) ){
+ if( that[ '_tag' ] === 'INPUT' && that[ '_attrs' ] && ( that[ '_attrs' ].type === 'checkbox' || that[ '_attrs' ].type === 'radio' ) && ( !that[ '_newAttrs' ] || !X_Object_inObject( 'checked', that[ '_newAttrs' ] ) ) ){
if( !that[ '_attrs' ] ) that[ '_attrs' ] = {};
that[ '_attrs' ].checked = elm.checked;
};