From d46b3c051de91e296153c953c17d3ac5032ef1b7 Mon Sep 17 00:00:00 2001 From: itozyun Date: Fri, 30 Jan 2015 17:37:05 +0900 Subject: [PATCH] Version 0.6.128, creanup commitUpdate(). --- 0.6.x/js/02_dom/02_XNode.js | 269 ++++++++++++++++-------------------- 0.6.x/js/02_dom/05_XNodeAttr.js | 9 ++ 0.6.x/js/05_util/01_XNinjaIframe.js | 2 +- 3 files changed, 126 insertions(+), 154 deletions(-) diff --git a/0.6.x/js/02_dom/02_XNode.js b/0.6.x/js/02_dom/02_XNode.js index e4c32c6..9c6d66d 100644 --- a/0.6.x/js/02_dom/02_XNode.js +++ b/0.6.x/js/02_dom/02_XNode.js @@ -85,7 +85,7 @@ var X_Node_documentFragment = document.createDocumentFragment && ( !X_UA.IE || 5.5 <= X_UA.IE ) && document.createDocumentFragment(), // 子の生成後に リアル文書 tree に追加する - X_Node_addTreeAfterChildren = false, + X_Node_addTreeAfterChildren = !( X.UA.IE < 9 ), X_Node_displayNoneFixForIE5 = !!X_Node_State.IE5_DISPLAY_NONE_FIX, @@ -1079,7 +1079,7 @@ var X_Node__commitUpdate = X_UA_DOM.W3C ? ( function( that, parentElement, nextElement, accumulatedFlags ){ var elm = that._rawObject, - xnodes, l, next; + created, xnodes, l, next; // 1. GPU 一切の更新をスキップ if( that._flags & X_Node_State.GPU_NOW ){ @@ -1119,24 +1119,84 @@ var X_Node__commitUpdate = // 5. ie5 非表示fixフラグ accumulatedFlags |= that._flags; - if( that._flags & X_Node_State.IE5_DISPLAY_NONE_FIX && ( accumulatedFlags & ( X_Node_State.DIRTY_POSITION | X_Node_State.DIRTY_ID | X_Node_State.DIRTY_CLASSNAME ) === 0 ) ) return nextElement; - + if( that._flags & X_Node_State.IE5_DISPLAY_NONE_FIX ){ + if( accumulatedFlags & ( X_Node_State.DIRTY_POSITION | X_Node_State.DIRTY_ID | X_Node_State.DIRTY_CLASSNAME ) === 0 ){ + return nextElement; + }; + + }; // 6. 要素の生成 if( !elm ){ - nextElement ? - parentElement.insertBefore( X_Node__actualCreate( that, false ), nextElement ) : - parentElement.appendChild( X_Node__actualCreate( that, false ) ); - return X_Node__afterActualCreate( that ) || X_Node_displayNoneFixForIE5 && nextElement; // ie5 だけこの位置で _rawObject が空の場合がある - // X_Node__actualCreate, X_Node__afterActualCreate の処理をこちら側に。 - }; - + if( !that._tag ){ + that._flags &= X_Node_BitMask_RESET_DIRTY; + that._rawObject = elm = document.createTextNode( X_String_chrReferanceTo( that._text ) ); + } else + if( X_Node_strictElmCreation ){ + that._flags & X_Node_State.DIRTY_CSS && X_Node_CSS_objToCssText( that, true ); + + that._rawObject = elm = + document.createElement( [ + '<', that._tag, + ' UID="', that._uid, '"', + that._id ? ' id="' + that._id + '"' : '', + that._className ? ' class="' + that._className + '"' : '', + that._flags & X_Node_State.OLD_ATTRTEXT ? X_Node_Attr_objToAttrText( that ) : that._attrText, + that._cssText ? ' style="' + that._cssText + '"' : '', + '>' ].join( '' ) ); + } else { + that._rawObject = elm = document.createElement( that._tag ); + }; + + // IE には要素追加のタイミングで起こるメモリリークがありここで追加 + if( !X_Node_addTreeAfterChildren ){ + nextElement ? + parentElement.insertBefore( elm, nextElement ) : + parentElement.appendChild( elm ); + //elm.UID = that._uid; + // src の onload があるので先ではないか? + // TODO ie の str から要素を作る場合、srcだけ イベント設定後ではないか? + X_EventDispatcher_toggleAllEvents( that, true );// イベントの復帰 + }; + + if( that._tag ){ + if( X_Node_documentFragment ){ + //( frg = X_Node_documentFragment ).appendChild( elm ); + }; + + if( X_Node_strictElmCreation ){ + // TODO src 等の設定 + delete that._newAttrs; + that._flags &= X_Node_BitMask_RESET_DIRTY; + that._flags |= X_Node_State.DIRTY_IE_FILTER;// doc 追加後に filter を指定しないと有効にならない。 + } else { + elm.UID = that._uid; + that._newAttrs = that._attrs; + 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; + + // http://outcloud.blogspot.jp/2010/09/iframe.html + // この問題は firefox3.6 で確認 + if( X_UA.Gecko ){ + if( that._tag === 'IFRAME' && !that._attrs[ 'src' ] ){ + //elm.contentWindow.location.replace = elm.src = 'about:blank'; + that.attr( 'src', 'about:blank' ); + }; + }; + }; + }; + + created = true; + } else // 7. 要素の位置のズレを補正 if( elm.parentNode !== parentElement || ( nextElement && elm.nextSibling !== nextElement ) ){ nextElement ? parentElement.insertBefore( elm, nextElement ) : parentElement.appendChild( elm ); + + if( X_Node_displayNoneFixForIE5 ) that._flags |= X_Node_State.DIRTY_POSITION; }; + + that._flags & X_Node_State.DIRTY_POSITION && X_EventDispatcher_toggleAllEvents( that, true );// イベントの復帰 that._flags &= ~X_Node_State.DIRTY_POSITION; // 8. 更新の適用 @@ -1165,6 +1225,14 @@ var X_Node__commitUpdate = }; }; + if( created && X_Node_addTreeAfterChildren ){ + nextElement ? + parentElement.insertBefore( elm, nextElement ) : + parentElement.appendChild( elm ); + + X_EventDispatcher_toggleAllEvents( that, true );// イベントの復帰 + }; + return elm; }) : X_UA_DOM.IE4 ? @@ -1272,30 +1340,42 @@ var X_Node__updateRawNode = that._className ? ( elm.className = that._className ) : ( elm.className && elm.removeAttribute( X_UA.IE5678 ? 'className' : 'class' ) ); // className は ie7-? }; - that._tag === 'TEXTAREA' && console.log( that.call('outerHTML') ); - // attr if( that._flags & X_Node_State.DIRTY_ATTR && ( attrs = that._newAttrs || that._attrs ) ){ rename = X_Node_Attr_renameForDOM; - - // IETester 5.5 ではエラーが出なかった.MultipulIE5.5 ではエラーが出たので - if( !X_UA.MacIE && X_UA.IE5x && that._tag === 'TEXTAREA' && ( ( v = attrs[ 'value' ] ) || X_Object_inObject( 'value', attrs ) ) ){ - delete attrs[ 'value' ]; - elm.firstChild ? - ( elm.firstChild.data = v || '' ) : - elm.appendChild( document.createTextNode( v || '' ) ); - }; - // http://outcloud.blogspot.jp/2010/09/iframe.html - // この問題は firefox3.6 で確認 - if( X_UA.Gecko && that._tag === 'IFRAME' && ( ( v = attrs[ 'src' ] ) || X_Object_inObject( 'src', attrs ) ) ){ - elm.contentWindow.location.replace = elm.src = v || ''; - delete attrs[ 'src' ]; - }; for( k in attrs ){ + v = attrs[ k ]; + + switch( that._tag + k ){ + case 'TEXTAREAvalue' : + // IETester 5.5 ではエラーが出なかった.MultipulIE5.5 ではエラーが出たので + if( !X_UA.MacIE && X_UA.IE5x ){ + elm.firstChild ? + ( elm.firstChild.data = v || '' ) : + elm.appendChild( document.createTextNode( v || '' ) ); + continue; + }; + break; + + case 'IFRAMEsrc' : + // http://outcloud.blogspot.jp/2010/09/iframe.html + // この問題は firefox3.6 で確認 + if( X_UA.Gecko ){ + elm.contentWindow.location.replace = elm.src = v || ''; + continue; + }; + break; + + case 'IFRAMEname' : + // http://d.hatena.ne.jp/NeoCat/20080921/1221940658 + // こちらに名前をsetしないとtargetが動作しない + // if( X_UA.IE ) elm.name = elm.contentWindow.name = v || ''; + }; + //if( X_EMPTY_OBJECT[ k ] ) continue; // TODO IE では input, なぜか button, object も type, name の変更が出来ない、同値で置き換えようとしても不可 - ( v = attrs[ k ] ) === undefined ? + v === undefined ? elm.removeAttribute( rename[ k ] || k ) : ( elm[ rename[ k ] || k ] = X_Node_Attr_noValue[ k ] ? k : v ); }; @@ -1315,10 +1395,12 @@ var X_Node__updateRawNode = }; } else if( that._flags & X_Node_State.DIRTY_IE_FILTER ){ - elm.style.filter = v = X_Node_CSS_objToIEFilterText( that ); + v = X_Node_CSS_objToIEFilterText( that ); if( v ){ + elm.style.filter = v; that._flags |= X_Node_State.IE_FILTER_NOW; } else { + elm.style.removeAttribute( 'filter' ); that._flags &= ~X_Node_State.IE_FILTER_NOW; }; }; @@ -1359,10 +1441,12 @@ var X_Node__updateRawNode = }; if( that._flags & X_Node_State.DIRTY_IE_FILTER ){ - that._rawObject.style.filter = v = X_Node_CSS_objToIEFilterText( that ); + v = X_Node_CSS_objToIEFilterText( that ); if( v ){ + elm.style.filter = v; that._flags |= X_Node_State.IE_FILTER_NOW; } else { + elm.style.removeAttribute( 'filter' ); that._flags &= ~X_Node_State.IE_FILTER_NOW; }; }; @@ -1402,47 +1486,7 @@ var X_Node__updateRawNode = */ var X_Node__actualCreate = X_UA_DOM.W3C ? (function( that, isChild ){ - var elm = that._rawObject, xnodes, frg, i, l; - - if( !that._tag ){ - if( elm ){ - that._flags & X_Node_BitMask_IS_DIRTY && ( elm.data = X_String_chrReferanceTo( that._text ) ); - that._flags &= X_Node_BitMask_RESET_DIRTY; - return elm; - }; - that._flags &= X_Node_BitMask_RESET_DIRTY; - return that._rawObject = document.createTextNode( X_String_chrReferanceTo( that._text ) ); - }; - - if( !elm ){ - that._flags & X_Node_State.DIRTY_CSS && X_Node_CSS_objToCssText( that, true ); - that._rawObject = elm = - X_Node_strictElmCreation ? - document.createElement( [ - '<', that._tag, - ' UID="', that._uid, '"', - that._id ? ' id="' + that._id + '"' : '', - that._className ? ' class="' + that._className + '"' : '', - that._flags & X_Node_State.OLD_ATTRTEXT ? X_Node_Attr_objToAttrText( that ) : that._attrText, - that._cssText ? ' style="' + that._cssText + '"' : '', - '>' ].join( '' ) ) : - document.createElement( that._tag ); - - that._flags |= X_Node_State.ELM_NEED_INIT; - }; - - if( X_Node_documentFragment ){ - if( ( xnodes = that._xnodes ) && ( l = xnodes.length ) ){ - !isChild && ( frg = X_Node_documentFragment ).appendChild( elm ); - for( i = 0; i < l; ++i ){ - elm.appendChild( X_Node__actualCreate( xnodes[ i ], true ) ); - }; - return frg || elm; - }; - }; - - return elm; }) : X_UA_DOM.IE4 ? (function( that, isChild ){ var uid = that._uid, @@ -1452,7 +1496,7 @@ var X_Node__actualCreate = html = [ '', that._text, '' ];// fake textNode delete that._rawObject; } else { - if( /* that._rawObject && */ !isChild ) X_Node__actualRemove( that, /* true */ false ); + if( !isChild ) X_Node__actualRemove( that, /* true */ false ); that._flags & X_Node_State.DIRTY_CSS && X_Node_CSS_objToCssText( that, true ); @@ -1501,81 +1545,7 @@ var X_Node__actualCreate = var X_Node__afterActualCreate = X_UA_DOM.W3C ? (function( that ){ - var elm = that._rawObject, xnodes, l, i, v; - - if( !that._tag ){ - elm.UID = that._uid; - return elm; - }; - - xnodes = that._xnodes; - l = xnodes && xnodes.length; - - that._flags &= ~X_Node_State.DIRTY_POSITION; - - // ie5 では、documentFragment が無いため、この位置で要素はこれのみ。 - if( X_Node_displayNoneFixForIE5 ){ - that._flags & X_Node_State.ELM_NEED_INIT || ( that._flags & X_Node_BitMask_IS_DIRTY && X_Node__updateRawNode( that, elm ) ); - - if( elm.currentStyle.display === 'none' ){ - X_Node__actualRemove( that ); - that._flags |= X_Node_State.IE5_DISPLAY_NONE_FIX; - return; - } else { - that._flags &= ~X_Node_State.IE5_DISPLAY_NONE_FIX; - }; - }; - - // src の onload があるので先ではないか? - // TODO ie の str から要素を作る場合、srcだけ イベント設定後ではないか? - X_EventDispatcher_toggleAllEvents( that, true );// イベントの復帰 - if( that._flags & X_Node_State.ELM_NEED_INIT ){ - that._flags ^= X_Node_State.ELM_NEED_INIT; - - if( !X_Node_documentFragment ){// docFrg が使えない場合、doc 追加後に子を追加 TODO ie の場合この順序(メモリリーク対策)、他のブラウザは 子が先が有利では? - for( i = 0; i < l; ++i ){ - elm.appendChild( X_Node__actualCreate( xnodes[ i ], true ) ); - }; - }; - - if( X_Node_strictElmCreation ){ - // TODO src 等の設定 - if( that._flags & X_Node_State.DIRTY_IE_FILTER ){ - // doc 追加後に filter を指定しないと有効にならない。 - elm.style.filter = v = X_Node_CSS_objToIEFilterText( that ); - if( v ){ - that._flags |= X_Node_State.IE_FILTER_NOW; - } else { - that._flags &= ~X_Node_State.IE_FILTER_NOW; - }; - }; - delete that._newAttrs; - that._flags &= X_Node_BitMask_RESET_DIRTY; - } else { - console.log(); - elm.UID = that._uid; - that._newAttrs = that._attrs; - 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; - X_Node__updateRawNode( that, elm ); - - // http://outcloud.blogspot.jp/2010/09/iframe.html - // この問題は firefox3.6 で確認 - if( X_UA.Gecko && that._tag === 'IFRAME' ){ - if( !that._attrs[ 'src' ] ){ - elm.contentWindow.location.replace = elm.src = 'about:blank'; - }; - }; - }; - } else { - that._flags & X_Node_BitMask_IS_DIRTY && X_Node__updateRawNode( that, elm ); - }; - - for( i = 0; i < l; ++i ){ - X_Node__afterActualCreate( xnodes[ i ] ); - }; - - return elm; }) : X_UA_DOM.IE4 ? (function( that ){ var xnodes, i, v; @@ -1587,14 +1557,7 @@ var X_Node__afterActualCreate = X_Node__afterActualCreate( xnodes[ --i ] ); }; }; - if( that._flags & X_Node_State.DIRTY_IE_FILTER ){ - X_Node__ie4getRawNode( that ).style.filter = v = X_Node_CSS_objToIEFilterText( that ); - if( v ){ - that._flags |= X_Node_State.IE_FILTER_NOW; - } else { - that._flags &= ~X_Node_State.IE_FILTER_NOW; - }; - }; + that._flags & X_Node_State.DIRTY_IE_FILTER && X_Node__updateRawNode( that, that._rawObject || X_Node__ie4getRawNode( that ) ); that._flags &= X_Node_BitMask_RESET_DIRTY; X_EventDispatcher_toggleAllEvents( that, true );// イベントの復帰 }) : diff --git a/0.6.x/js/02_dom/05_XNodeAttr.js b/0.6.x/js/02_dom/05_XNodeAttr.js index 20e915b..cd9a1ff 100644 --- a/0.6.x/js/02_dom/05_XNodeAttr.js +++ b/0.6.x/js/02_dom/05_XNodeAttr.js @@ -180,6 +180,15 @@ Node.prototype.attr = function( nameOrObj /* v */ ){ case 'cssText' : return this.cssText(); + case 'src' : // src は遷移して変化する, name も? + if( this._tag !== 'IFRAME' ) break; + if( this._newAttrs && X_Object_inObject( nameOrObj, this._newAttrs ) ) return this._newAttrs[ nameOrObj ]; + if( elm = X_UA_DOM.IE4 ? this._rawObject || X_Node__ie4getRawNode( this ) : this._rawObject ){ + if( !attrs ) attrs = this._attrs = {}; + return attrs[ nameOrObj ] = elm[ nameOrObj ]; // getAttribute( nameOrObj )? + }; + break; + case 'selected' : // kquery.js : safariのバグ対策 // if ($.browser.safari && key === "selected" && tmp) tmp.selectedIndex; diff --git a/0.6.x/js/05_util/01_XNinjaIframe.js b/0.6.x/js/05_util/01_XNinjaIframe.js index 6be609a..0973350 100644 --- a/0.6.x/js/05_util/01_XNinjaIframe.js +++ b/0.6.x/js/05_util/01_XNinjaIframe.js @@ -58,7 +58,7 @@ X.Util.NinjaIframe = X.EventDispatcher.inherits( this._iwin = raw.contentWindow || ( raw.contentDocument && raw.contentDocument.parentWindow ) || window.frames[ this._name ]; // http://d.hatena.ne.jp/NeoCat/20080921/1221940658 // こちらに名前をsetしないとtargetが動作しない - this._iwin.name = this._name; + if( X_UA.IE ) this._iwin.name = this._name; this.xnodeIframe.listen( [ X_UA.IE < 9 ? 'readystatechange' : 'load', 'error' ], this ); -- 2.11.0