OSDN Git Service

Fix the bug of X.NodeAnime.
[pettanr/clientJs.git] / 0.6.x / js / 02_dom / 20_XNode.js
index b7f8ce9..8ed979d 100644 (file)
@@ -8,8 +8,7 @@
  */
 var    Node = X[ 'Node' ] = X_EventDispatcher[ 'inherits' ](
        'X.Node',
-       X_Class.POOL_OBJECT,
-       
+       X_Class.NONE,
        {
                /**
                 * 要素に振られるユニークID
@@ -152,10 +151,12 @@ var       Node = X[ 'Node' ] = X_EventDispatcher[ 'inherits' ](
         * 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;
                        
-                       if( X_Node_newByTag ){
+                       // TODO 継承クラスで this.Super('DIV') ができない! -> サブクラスから呼ばれた場合も
+                       if( X_Node_newByTag || this.constructor !== Node ){
                                X_Node_newByTag = false;
                                this[ '_tag' ]  = v.toUpperCase();
                                arguments[ 1 ] && this[ 'attr' ]( arguments[ 1 ] );
@@ -223,6 +224,7 @@ var Node = X[ 'Node' ] = X_EventDispatcher[ 'inherits' ](
                        X_Node_CHASHE[ this[ '_uid' ] = uid ] = this;
                },
                
+               // TODO .mesure() -> X.Event.MESURED
                'width'          : X_Node_width,
                'height'         : X_Node_height,
                'clientWidth'    : X_Node_clientWidth,
@@ -253,6 +255,8 @@ var Node = X[ 'Node' ] = X_EventDispatcher[ 'inherits' ](
                
                'createTextAt'   : X_Node_createTextAt,
                
+               'createRange'    : X_Node_createRange,
+               
                'clone'          : X_Node_clone,
                
                'append'         : X_Node_append,
@@ -289,7 +293,7 @@ var Node = X[ 'Node' ] = X_EventDispatcher[ 'inherits' ](
                'toggleClass'    : X_Node_toggleClass,
                'hasClass'       : X_Node_hasClass,
                
-               'html'           : X_Node_html,
+               'html'           : X_Node__html,
                'text'           : X_Node_text,
                'call'           : X_Node_call,
                'each'           : X_Node_each
@@ -360,6 +364,7 @@ function X_Node_getType( v ){
        if( X_Type_isString( v ) ){
                return '<' === v.charAt( 0 ) && v.charAt( v.length - 1 ) === '>' ? X_NodeType_HTML_STRING : X_NodeType_STRING;
        };
+       // Node サブクラスのインスタンス
        if( v[ 'instanceOf' ] && v[ 'instanceOf' ]( Node ) ) return X_NodeType_XNODE;
        return 0;
 };
@@ -383,7 +388,7 @@ function X_Node_getXNode( v ){
                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;
                        };
        };
 };
@@ -394,11 +399,10 @@ function X_Node_getRoot( 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' ] ] );
        };
 
 
@@ -446,6 +450,7 @@ function X_Node_toggleInGPUFlag( gpuRoot, xnodes, flag ){
  */
 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;
@@ -494,6 +499,15 @@ function X_Node_createTextAt( index, text ){
 };
 
 /**
+ * 選択されたテキストへの参照やテキスト座標情報
+ * @alias Node.prototype.createRange
+ * @return {TextRange} 新規作成されたテキストレンジ
+ */
+function X_Node_createRange( a, b, c ){
+       return X_TextRange( this, a, b, c );
+};
+
+/**
  * Node のクローンを作成し返す。id もクローンされる点に注意。イベントリスナはクローンされない。
  * http://d.hatena.ne.jp/think49/20110724/1311472811
  * http://d.hatena.ne.jp/uupaa/20100508/1273299874
@@ -560,9 +574,10 @@ function X_Node_append( v ){
                        return X_Node_append.apply( this, X_HtmlParser_parse( v, true ) );
                case X_NodeType_XNODE :
                        // 親の xnodes から v を消す
-                       v.parent && v[ 'remove' ]();
+               if( v.parent === this && xnodes[ xnodes.length - 1 ] === v ) return this;
+                       v[ 'remove' ]();
                        // IE4 でテキストノードの追加、FIXED 済でない場合、親に要素の追加を通知
-                       if( X_UA[ 'IE4' ] && !v[ '_tag' ] && ( this[ '_flags' ] & X_NodeFlags_IE4_FIXED ) === 0 ) this[ '_flags' ] |= X_NodeFlags_IE4_DIRTY_CHILDREN;
+                       if( X_UA[ 'IE4' ] && !v[ '_tag' ] && ( ( this[ '_flags' ] & X_NodeFlags_IE4_FIXED ) === 0 ) ) this[ '_flags' ] |= X_NodeFlags_IE4_DIRTY_CHILDREN;
                        break;
                default :
                        return this;
@@ -638,7 +653,7 @@ function X_Node_appendAt( start, v ){
                                v[ 'remove' ]();
                        };
                        // IE4 でテキストノードの追加、FIXED 済でない場合、親に要素の追加を通知
-                       if( X_UA[ 'IE4' ] && !v[ '_tag' ] && ( this[ '_flags' ] & X_NodeFlags_IE4_FIXED ) === 0 ) this[ '_flags' ] |= X_NodeFlags_IE4_DIRTY_CHILDREN;
+                       if( X_UA[ 'IE4' ] && !v[ '_tag' ] && ( ( this[ '_flags' ] & X_NodeFlags_IE4_FIXED ) === 0 ) ) this[ '_flags' ] |= X_NodeFlags_IE4_DIRTY_CHILDREN;
                        break;
                default :
                        return this;
@@ -768,10 +783,11 @@ function X_Node_swap( v ){
 };
 
 /**
- * 要素を抜く。
+ * 要素を親要素から抜く。jQuery の remove と異なり、インスタンスは破壊(kill)されず、再び別の親に挿入等できる
  * @alias Node.prototype.remove
  * @return {Node} 自身。チェインメソッド
  * @example node.remove();
+ * parent.append( node ); 新しい親に追加できる
  */
 function X_Node_remove(){
        var parent = this.parent,
@@ -779,6 +795,14 @@ function X_Node_remove(){
        
        if( !parent ) return this;
 
+       // stop() ->
+       if( this[ '_anime' ] && this[ '_anime' ].phase ){
+               console.log( 'Animation 中の REMOVE' );
+               X_NodeAnime_stopNow( this );
+       };
+       // 子孫にアニメーション中の要素が要る
+       // 先祖に GPU 化した要素が要る
+
        delete this.parent;
        parent[ '_xnodes' ].splice( parent[ '_xnodes' ].indexOf( this ), 1 );
        
@@ -787,12 +811,11 @@ function X_Node_remove(){
                this[ '_xnodes' ] && X_Node_toggleInTreeFlag( this[ '_xnodes' ], false );
 
                if( X_UA_DOM.IE4 ){
-                       elm = this[ '_rawObject' ] || X_Node__ie4getRawNode( this );
-                       if( elm ){
+                       if( elm = this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ){
                                X_Node_reserveRemoval[ X_Node_reserveRemoval.length ] = this;
-                               X_Node_reserveUpdate();                 
+                               X_Node_reserveUpdate();
                        } else
-                       if( !this[ '_tag' ] && ( parent[ '_flags' ] & X_NodeFlags_IE4_FIXED ) === 0 ){
+                       if( !this[ '_tag' ] && ( ( parent[ '_flags' ] & X_NodeFlags_IE4_FIXED ) === 0 ) ){
                                parent[ '_flags' ] |= X_NodeFlags_IE4_DIRTY_CHILDREN;
                        };
                } else {
@@ -802,6 +825,14 @@ function X_Node_remove(){
                                X_Node_reserveUpdate();                 
                        };
                };
+       } else {
+               if( !X_UA_DOM.IE4 ){
+                       elm = this[ '_rawObject' ];
+                       if( elm && elm.parentNode && elm.parentNode.tagName ){
+                               X_Node_reserveRemoval[ X_Node_reserveRemoval.length ] = this;
+                               X_Node_reserveUpdate();                 
+                       };
+               };
        };
        return this;
 };
@@ -814,7 +845,9 @@ function X_Node_remove(){
  */
 function X_Node_empty(){
        var xnodes = this[ '_xnodes' ], i;
+       
        if( xnodes && ( i = xnodes.length ) ){
+               delete this[ '_xnodes' ];
                for( ; i; ){
                        xnodes[ --i ][ 'kill' ]();
                };
@@ -829,31 +862,38 @@ function X_Node_onKill( that ){
        
        if( ( that[ '_flags' ] & X_NodeFlags_EXIST ) === 0 ) return;
        
-       parent && 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 ); // イベントの退避
+       parent && parent[ '_xnodes' ] && parent[ '_xnodes' ].splice( parent[ '_xnodes' ].indexOf( that ), 1 );
 
        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 ] はまずい!
+
+       if( that[ '_anime' ] && that[ '_anime' ].phase ){
+               console.log( 'Animation 中の KILL' );
+               X_NodeAnime_stopNow( that );
+       };
+
+       elm = that[ '_rawObject' ] || X_UA_DOM.IE4 && X_Node__ie4getRawNode( that );
+
 // remove _xnodes
        if( X_UA_DOM.IE4 ){
                if( elm ){
                        X_Node_reserveRemoval[ X_Node_reserveRemoval.length ] = elm;
                        X_Node_reserveUpdate();                 
                } else
-               if( !that[ '_tag' ] && ( parent[ '_flags' ] & X_NodeFlags_IE4_FIXED ) === 0 ){
+               if( !that[ '_tag' ] && ( ( parent[ '_flags' ] & X_NodeFlags_IE4_FIXED ) === 0 ) ){
                        parent[ '_flags' ] |= X_NodeFlags_IE4_DIRTY_CHILDREN;
                };
        } else {
                if( elm && elm.parentNode && elm.parentNode.tagName ){
                        X_Node_reserveRemoval[ X_Node_reserveRemoval.length ] = elm;
-                       X_Node_reserveUpdate();         
+                       X_Node_reserveUpdate();
                };
        };
 };
@@ -869,21 +909,15 @@ function X_Node_onKill( that ){
  * @example node.contains( testNode );
  */
 function X_Node_contains( v ){
-       var elm, type, xnodes, i;
+       var xnodes;
+       
        if( !v || !this[ '_tag' ] || this === v ) return false;
-       // contains ie4+
-       if( ( elm = this[ '_rawObject' ] || X_UA_DOM.IE4 && X_Node__ie4getRawNode( this ) ) && document.contains && ( type = X_Node_getType( v ) ) && ( type === X_NodeType_RAW_HTML || type === X_NodeType_RAW_TEXT ) ){
-               return elm.contains( v );
-       };
 
-       //if( document.compareDocumentPosition ){
-       //      
-       //};
        xnodes = this[ '_xnodes' ];
        if( !xnodes || !xnodes.length ) return false;
-       if( xnodes.indexOf( v ) !== -1 ) return true; // fast
-       for( i = xnodes.length; i; ){
-               if( xnodes[ --i ][ 'contains' ]( v ) ) return true;
+
+       while( v = v[ 'parent' ] ){
+               if( this === v ) return true;
        };
        return false;
 };
@@ -1083,12 +1117,17 @@ function X_Node_hasClass( v ){
  * @return {string|Node} 
  * @example node.html( '<img>' );
  */
-function X_Node_html( html ){
+function X_Node__html( html ){
        var _ = '', q = '"', xnodes, n, i, l;
        // 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
@@ -1177,7 +1216,7 @@ function X_Node_call( name /*, opt_args... */ ){
        var args = arguments,
                l    = args.length - 1,
                v, raw, parent, body,
-               childX, childY, childW, childH,
+               child, childX, childY, childW, childH,
                parentW, parentH,
                parentSX, parentSY, parentSW, parentSH,
                visibleX, visibleY, visibleW, visibleH,
@@ -1198,9 +1237,26 @@ function X_Node_call( name /*, opt_args... */ ){
                case 'treeIsDirty' :
                        return !!X_Node_updateTimerID;
                case 'fontSize' :
-                       return X_Node_CSS_getCharSize( this );
+                       return ( this[ '_flags' ] & X_NodeFlags_IN_TREE ) ? X_Node_CSS_getCharSize( this ) : 0;
                case 'inGPU' :
                        return !!( this[ '_flags' ] & ( X_NodeFlags_GPU_NOW | X_NodeFlags_GPU_RELEASE_RESERVED ) );
+               case 'isGPUChild' :
+                       if( this[ '_flags' ] & X_NodeFlags_IN_TREE ){
+                               parent = this;
+                               while( parent = parent.parent ){
+                                       if( parent[ '_flags' ] & ( X_NodeFlags_GPU_NOW | X_NodeFlags_GPU_RELEASE_RESERVED ) ) return true;
+                               };
+                       };
+                       return false;
+               case 'containGPU' :
+                       
+                       return false;
+               case 'canAnimateNow' :
+                       return ( this[ '_flags' ] & X_NodeFlags_IN_TREE ) && X_NodeAnime_detectWaitAnimation( this, true, true ) === 6;
+               case 'animeState' :
+                       return this[ '_anime' ] ? this[ '_anime' ].phase : 0;
+               case 'animeProgress' :
+                       return this[ '_anime' ] && this[ '_anime' ].phase === 7 ? this[ '_anime' ].progress : 0;
        };
        
        X_Node_updateTimerID && X_Node_startUpdate();
@@ -1216,7 +1272,8 @@ function X_Node_call( name /*, opt_args... */ ){
        };
        
        if( name === 'inView' ){
-               body   = document.body;
+               if( !( this[ '_flags' ] & X_NodeFlags_IN_TREE ) ) return { 'isInView' : false };
+               body   = X_elmBody;
                child  = raw;
                visibleX = visibleY = visibleW = visibleH = 0;
                while( child !== body ){
@@ -1325,7 +1382,7 @@ function X_Node_reserveUpdate(){
 var X_Node_updateReservedByReleaseGPU = false;
 
 function X_Node_startUpdate( time ){
-       var removal, i, xnodeOrElm;
+       var removal, i, xnodeOrElm, xnodesIEFilterFixAfter, xnode, active;
        
        if( !X_Node_updateTimerID || X_ViewPort_readyState < X_EVENT_INIT ){
                return;
@@ -1345,6 +1402,7 @@ function X_Node_startUpdate( time ){
                for( ; i; ){
                        xnodeOrElm = removal[ --i ];
                        // TODO GPU レイヤーの子の場合、remove をスキップする。 非GPU レイヤーへ apppend される場合、clone する?
+                       // GPU レイヤーを削除する場合、cssText = '' して GPU レイヤーを解除する
                        if( !xnodeOrElm[ 'instanceOf' ] ){
                                if( X_UA_DOM.IE4 ){
                                        xnodeOrElm.removeAttribute( 'id' ); // ?
@@ -1364,11 +1422,23 @@ function X_Node_startUpdate( time ){
                removal.length = 0;
        };
        
+       // 強制的に再描画を起こす, 但し activeElement からフォーカスが外れるため復帰する
+       // IE5mode win10 で 確認
+       if( X_UA[ 'IE5' ] ){
+               active = FocusUtility_getFocusedElement();
+               X_elmBody.style.visibility = 'hidden';
+       };
+
        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, xnodesIEFilterFixAfter = [] );
        } 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, xnodesIEFilterFixAfter = [] );
+               X_Node__commitUpdate( X_Node_body, X_Node_body[ '_rawObject' ].parentNode, null, X_Node_body[ '_flags' ], 1, xnodesIEFilterFixAfter = [] );
+       };
+
+       if( X_UA[ 'IE5' ] ){
+               X_elmBody.style.visibility = '';
+               active && active.parentNode && FocusUtility_setTemporarilyFocus( active );
        };
        
        if( X_Node_updateReservedByReleaseGPU ){
@@ -1376,12 +1446,16 @@ function X_Node_startUpdate( time ){
                X_Node_updateReservedByReleaseGPU = false;
        };
        
-       if( time ){
-               // X.Timer 経由でないと発火しない このイベントでサイズを取ると無限ループに
-               X_System[ '_listeners' ] && X_System[ '_listeners' ][ X_EVENT_UPDATED ] && X_System[ 'dispatch' ]( X_EVENT_UPDATED );   
-       } else {
-               X_System[ '_listeners' ] && X_System[ '_listeners' ][ X_EVENT_UPDATED ] && X_System[ 'asyncDispatch' ]( X_EVENT_UPDATED );
+       if( X_NodeFlags_IE_FILTER_FIX_AFTER && xnodesIEFilterFixAfter.length ){
+               for( i = 0; xnode = xnodesIEFilterFixAfter[ i ]; ++i ){
+                       xnode[ '_flags' ] &= ~X_NodeFlags_IE_FILTER_FIX_AFTER;
+                       X_Node_CSS_onAfterUpdateIEFilterFix( xnode );
+               };
        };
+
+       // time を視て X.Timer 経由の場合、即座に発火する。
+       // width() 等で強制的にツリーを構築している場合、UPDATE イベントのコールバックで要素を変更しサイズを取ると無限ループになる,これを防ぐため asyncDispatch とする
+       X_System[ '_listeners' ] && X_System[ '_listeners' ][ X_EVENT_UPDATED ] && X_System[ time ? 'dispatch' : 'asyncDispatch' ]( X_EVENT_UPDATED );
        
        X_ViewPort[ '_listeners' ] && X_ViewPort[ '_listeners' ][ X_EVENT_AFTER_UPDATE ] && X_ViewPort[ 'asyncDispatch' ]( X_EVENT_AFTER_UPDATE );
 };
@@ -1401,28 +1475,28 @@ function X_Node_startUpdate( time ){
  */
 var X_Node__commitUpdate =
        X_UA_DOM.W3C ?
-               ( function( that, parentElement, nextElement, accumulatedFlags ){
+               ( function( that, parentElement, nextElement, accumulatedFlags, ie8AccumulatedOpcity, xnodesIEFilterFixAfter ){
                        var elm = that[ '_rawObject' ],
-                               created, xnodes, l, next;
+                               created, xnodes, l, next, anime, v, currentOpcity;
 
                        // 1. GPU 一切の更新をスキップ
                        if( that[ '_flags' ] & X_NodeFlags_GPU_NOW ){
-                               console.log( '更新のskip ' + !!( that[ '_flags' ] & X_Node_BitMask_IS_DIRTY ) );
+                               console.log( '更新のskip ' + that[ '_className' ] + !!( that[ '_flags' ] & X_Node_BitMask_IS_DIRTY ) );
                                that[ '_flags' ] & X_Node_BitMask_IS_DIRTY && X_Node__updateRawNode( that, elm );
                                return elm;
                        };
 
                        // 2. GPU解放予約
                        if( that[ '_flags' ] & X_NodeFlags_GPU_RELEASE_RESERVED ){
-                               // console.log( 'GPU 解放 ' );
+                               console.log( 'GPU 解放 ' );
                                //X_Node_updateReservedByReleaseGPU = true;
-                               //X_Node__updateRawNode( that, elm );
                                that[ '_flags' ] &= X_Node_BitMask_RESET_GPU;
-                               //return elm;// TODO もしかしたらこのタイミングで更新できるかも
+                               //return elm;// このタイミングで更新できるっぽい
                        };
 
                        // 3. GPU予約 -> GPU
                        if( that[ '_flags' ] & X_NodeFlags_GPU_RESERVED ){
+                               // TODO size 取得のための update の場合、GPU化をスキップ
                                that[ '_flags' ] &= X_Node_BitMask_RESET_GPU;
                                that[ '_flags' ] |= X_NodeFlags_GPU_NOW;
                        };
@@ -1431,7 +1505,8 @@ var X_Node__commitUpdate =
                        if( that[ '_flags' ] & X_NodeFlags_STYLE_IS_DISPLAY_NONE ){
                                if( X_Node_displayNoneFixForIE5 ){
                                        // filter の効いている要素を含む要素は display:none が無視される。
-                                       // filter = '' で削除はできるが、再表示時に filter が消える。 -> filter な要素を削除してしまう。                                         
+                                       // filter = '' で削除はできるが、再表示時に filter が消える。 -> filter な要素を削除してしまう。 
+                                       // TODO filters[0].enabled = false なんてどう?                                     
                                        if( elm && elm.parentNode ){
                                                X_Node__actualRemove( that );
                                        };
@@ -1445,7 +1520,7 @@ var X_Node__commitUpdate =
                        accumulatedFlags |= that[ '_flags' ];
                        
                        if( that[ '_flags' ] & X_NodeFlags_IE5_DISPLAY_NONE_FIX ){
-                               if( accumulatedFlags & ( X_NodeFlags_DIRTY_POSITION | X_NodeFlags_DIRTY_ID | X_NodeFlags_DIRTY_CLASSNAME ) === 0 ){
+                               if( ( accumulatedFlags & ( X_NodeFlags_DIRTY_POSITION | X_NodeFlags_DIRTY_ID | X_NodeFlags_DIRTY_CLASSNAME ) ) === 0 ){
                                        return nextElement;
                                };
                        };
@@ -1454,7 +1529,12 @@ var X_Node__commitUpdate =
                        if( !elm ){
                                if( !that[ '_tag' ] ){
                                        that[ '_flags' ] &= X_Node_BitMask_RESET_DIRTY;
-                                       that[ '_rawObject' ] = elm = document.createTextNode( X_String_chrReferanceTo( that[ '_text' ] ) );
+                                       if( X_UA[ 'IE' ] < 8 ){
+                                               // \n -> \r\n に変換しないと pre タグで改行されない  win10ie7(ie11 emu) で確認
+                                               elm = document.createTextNode( X_String_chrReferanceTo( that[ '_text' ] ).split( '\n' ).join( X_String_CRLF ) );
+                                       } else {
+                                               elm = document.createTextNode( X_String_chrReferanceTo( that[ '_text' ] ) );
+                                       };
                                        if( !X_UA[ 'IE' ] ){
                                                elm[ 'UID' ] = that[ '_uid' ];
                                        };
@@ -1462,7 +1542,7 @@ var X_Node__commitUpdate =
                                if( X_Node_strictElmCreation ){
                                        that[ '_flags' ] & X_NodeFlags_OLD_CSSTEXT && X_Node_CSS_objToCssText( that, true ); // OLD_CSSTEXT ??
                
-                                       that[ '_rawObject' ] = elm =
+                                       elm =
                                                document.createElement( [
                                                        '<', that[ '_tag' ],
                                                                ' UID="', that[ '_uid' ], '"',
@@ -1471,14 +1551,17 @@ var X_Node__commitUpdate =
                                                                X_Node_Attr_objToAttrText( that, true ),
                                                                that[ '_cssText' ] ? ' style="' + that[ '_cssText' ] + '"' : '',
                                                        '>' ].join( '' ) );
+                               } else
+                               if( that[ '_flags' ] & X_NodeFlags_IS_SVG ){
+                                       elm = document.createElementNS( 'http://www.w3.org/2000/svg', that[ '_tag' ].toLowerCase() );
+                                       
+                                       // TODO math http://www.w3.org/1998/Math/MathML
                                } else {
-                                       if( that[ '_flags' ] & X_NodeFlags_IS_SVG ){
-                                               that[ '_rawObject' ] = elm = document.createElementNS( 'http://www.w3.org/2000/svg', that[ '_tag' ].toLowerCase() );
-                                       } else {
-                                               that[ '_rawObject' ] = elm = document.createElement( that[ '_tag' ] );
-                                       };
+                                       elm = document.createElement( that[ '_tag' ] );
                                };
                                
+                               that[ '_rawObject' ] = elm;
+                               
                                // IE には要素追加のタイミングで起こるメモリリークがありここで追加
                                if( !X_Node_addTreeAfterChildren ){
                                        nextElement ?
@@ -1490,10 +1573,10 @@ var X_Node__commitUpdate =
                                        X_EventDispatcher_toggleAllEvents( that, true );// イベントの復帰                                
                                        that[ '_flags' ] |= X_NodeFlags_ACTUAL_LISTENING;
                                        
-                                       if( X_Node_documentFragment ){
+                                       //if( X_Node_documentFragment ){
                                                //( frg = X_Node_documentFragment ).appendChild( elm );
                                                // 連続する要素の差し替えの場合に有効
-                                       };
+                                       //};
 
                                        if( X_Node_strictElmCreation ){
                                                that[ '_flags' ] &= X_Node_BitMask_RESET_DIRTY;
@@ -1526,15 +1609,19 @@ var X_Node__commitUpdate =
                                        parentElement.appendChild( elm );
                        };
                        
-                       if( that[ '_listeners' ] && ( that[ '_flags' ] & X_NodeFlags_ACTUAL_LISTENING ) === 0 ){
+                       if( that[ '_listeners' ] && ( ( that[ '_flags' ] & X_NodeFlags_ACTUAL_LISTENING ) === 0 ) ){
                                X_EventDispatcher_toggleAllEvents( that, true );// イベントの退避
                                that[ '_flags' ] |= X_NodeFlags_ACTUAL_LISTENING;
                        };
                        
+                       // ie8 では子要素に opacity が反映されないため、親要素の opacity を積算する
+                       currentOpcity = that[ '_css' ] && 0 <= that[ '_css' ].opacity && that[ '_css' ].opacity;
+                       ie8AccumulatedOpcity = ie8AccumulatedOpcity * ( currentOpcity || 1 );
+                       
                        // 8. 更新の適用
                        if( accumulatedFlags & X_Node_BitMask_IS_DIRTY ){
                                delete that[ '_fontSize' ];
-                               X_Node__updateRawNode( that, elm );
+                               X_Node__updateRawNode( that, elm, currentOpcity, ie8AccumulatedOpcity, accumulatedFlags );
                        };
 
                        // 9. ie5 only
@@ -1551,10 +1638,14 @@ var X_Node__commitUpdate =
                                };
                        };
                        
+                       if( that[ '_flags' ] & X_NodeFlags_IE_FILTER_FIX_AFTER ){
+                               xnodesIEFilterFixAfter[ xnodesIEFilterFixAfter.length ] = that;
+                       };
+                       
                        // 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, ie8AccumulatedOpcity, xnodesIEFilterFixAfter );
                                };
                        };
 
@@ -1569,12 +1660,34 @@ var X_Node__commitUpdate =
                                };
                        };
 
+/*
+ *                     if( ( anime = that[ '_anime' ] ) && 6 <= anime.phase && anime.doScroll ){
+                               if( anime.phase === 6 ){
+                                       v = anime.fromScrollX;
+                                       if( v === v ){
+                                               elm.scrollLeft = v;
+                                       } else {
+                                               anime.fromScrollX = elm.scrollLeft;
+                                       };
+                                       v = anime.fromScrollY;
+                                       if( v === v ){
+                                               elm.scrollTop = v;
+                                       } else {
+                                               anime.fromScrollY = elm.scrollTop;
+                                       };
+                               } else {
+                                       elm.scrollLeft = anime.scrollX;
+                                       elm.scrollTop  = anime.scrollY;
+                               };
+                       };
+ */
+
                        return elm;
                }) :
        X_UA_DOM.IE4 ? 
                ( function( that, parentElement, prevElement, accumulatedFlags ){
                        var elm = that[ '_rawObject' ] || X_Node__ie4getRawNode( that ),
-                               xnodes, l, i, dirty, mix, html, text, prev;
+                               xnodes, l, i, dirty, mix, html, text, prev, anime, v;
 
                        if( !that[ '_tag' ] ){
                                that[ '_flags' ] & X_NodeFlags_DIRTY_CONTENT && X_Node__updateRawNode( that, elm );
@@ -1598,68 +1711,90 @@ var X_Node__commitUpdate =
                                        prevElement.insertAdjacentHTML( 'AfterEnd', X_Node__actualCreate( that, false ) ) :
                                        parentElement.insertAdjacentHTML( 'AfterBegin', X_Node__actualCreate( that, false ) );
                                X_Node__afterActualCreate( that );
-                               return that[ '_rawObject' ] || X_Node__ie4getRawNode( that );
-                       };
-                       
-                       accumulatedFlags |= that[ '_flags' ];
-                       
-                       xnodes = that[ '_xnodes' ];
-                       l      = xnodes ? xnodes.length : 0;
-                       dirty  = !!( that[ '_flags' ] & X_NodeFlags_IE4_DIRTY_CHILDREN );
-                       
-                       /*
-                        * HTML の下に TextNode だけ 。MIX_FIXED でない場合、削除、追加 を親に通知
-                        * HTML の下に HTML だけ
-                        * HTML の下は MIX -> TextNode, html の削除、変更、追加
-                        * HTML の下は MIX_FIXED -> TextNode を <font> に置き換えてあるのでW3C DON 的に触ることができる
-                        */
-                       if( dirty ){
-                               that[ '_flags' ] &= ~X_NodeFlags_IE4_DIRTY_CHILDREN;
-                               for( i = 0; i < l; ++i ){
-                                       if( xnodes[ i ][ '_tag' ] ){
-                                               that[ '_flags' ] |= X_NodeFlags_IE4_HAS_ELEMENT;
-                                       } else {
-                                               that[ '_flags' ] |= X_NodeFlags_IE4_HAS_TEXTNODE;
+                               
+                               elm = that[ '_rawObject' ] || X_Node__ie4getRawNode( that );
+                       } else {
+                               accumulatedFlags |= that[ '_flags' ];
+                               
+                               xnodes = that[ '_xnodes' ];
+                               l      = xnodes ? xnodes.length : 0;
+                               dirty  = !!( that[ '_flags' ] & X_NodeFlags_IE4_DIRTY_CHILDREN );
+                               
+                               /*
+                                * HTML の下に TextNode だけ 。MIX_FIXED でない場合、削除、追加 を親に通知
+                                * HTML の下に HTML だけ
+                                * HTML の下は MIX -> TextNode, html の削除、変更、追加
+                                * HTML の下は MIX_FIXED -> TextNode を <font> に置き換えてあるのでW3C DON 的に触ることができる
+                                */
+                               if( dirty ){
+                                       that[ '_flags' ] &= ~X_NodeFlags_IE4_DIRTY_CHILDREN;
+                                       for( i = 0; i < l; ++i ){
+                                               if( xnodes[ i ][ '_tag' ] ){
+                                                       that[ '_flags' ] |= X_NodeFlags_IE4_HAS_ELEMENT;
+                                               } else {
+                                                       that[ '_flags' ] |= X_NodeFlags_IE4_HAS_TEXTNODE;
+                                               };
+                                               if( that[ '_flags' ] & X_Node_BitMask_IE4_IS_MIX === X_Node_BitMask_IE4_IS_MIX ){
+                                                       mix = true;
+                                                       break;
+                                               };
                                        };
-                                       if( that[ '_flags' ] & X_Node_BitMask_IE4_IS_MIX === X_Node_BitMask_IE4_IS_MIX ){
-                                               mix = true;
-                                               break;
+                               };
+                               
+                               if( that[ '_flags' ] & X_NodeFlags_IE4_FIXED || that[ '_flags' ] & X_Node_BitMask_IE4_IS_MIX === X_NodeFlags_IE4_HAS_ELEMENT ){
+                                       for( i = 0; i < l; ++i ){
+                                               prev = X_Node__commitUpdate( xnodes[ i ], elm, prev, accumulatedFlags );
+                                       };
+                               } else
+                               if( mix ){
+                                       html = [];
+                                       for( i = 0; i < l; ++i ){
+                                               html[ i ] = X_Node__actualCreate( xnodes[ i ], false );
+                                       };
+                                       elm.innerHTML = html.join( '' );
+                                       for( i = 0; i < l; ++i ){
+                                               X_Node__afterActualCreate( xnodes[ i ] );
+                                       };
+                                       that[ '_flags' ] |= X_NodeFlags_IE4_FIXED;
+                               } else
+                               if( that[ '_flags' ] & X_NodeFlags_IE4_HAS_TEXTNODE ){
+                                       dirty = dirty || false;
+                                       for( i = 0; i < l; ++i ){
+                                               text = xnodes[ i ];
+                                               if( text[ '_flags' ] & X_Node_BitMask_IS_DIRTY ){
+                                                       text[ '_flags' ] &= X_Node_BitMask_RESET_DIRTY;
+                                                       dirty = true;
+                                               };
                                        };
+                                       if( dirty ) elm.innerHTML = that[ 'text' ]();
                                };
+                               
+                               if( accumulatedFlags & X_Node_BitMask_IS_DIRTY ) delete that[ '_fontSize' ];
+                               
+                               that[ '_flags' ] &= ~X_NodeFlags_DIRTY_POSITION;
+                               that[ '_flags' ] & X_Node_BitMask_IS_DIRTY && X_Node__updateRawNode( that, elm );                               
                        };
                        
-                       if( that[ '_flags' ] & X_NodeFlags_IE4_FIXED || that[ '_flags' ] & X_Node_BitMask_IE4_IS_MIX === X_NodeFlags_IE4_HAS_ELEMENT ){
-                               for( i = 0; i < l; ++i ){
-                                       prev = X_Node__commitUpdate( xnodes[ i ], elm, prev, accumulatedFlags );
-                               };
-                       } else
-                       if( mix ){
-                               html = [];
-                               for( i = 0; i < l; ++i ){
-                                       html[ i ] = X_Node__actualCreate( xnodes[ i ], false );
-                               };
-                               elm.innerHTML = html.join( '' );
-                               for( i = 0; i < l; ++i ){
-                                       X_Node__afterActualCreate( xnodes[ i ] );
-                               };
-                               that[ '_flags' ] |= X_NodeFlags_IE4_FIXED;
-                       } else
-                       if( that[ '_flags' ] & X_NodeFlags_IE4_HAS_TEXTNODE ){
-                               dirty = dirty || false;
-                               for( i = 0; i < l; ++i ){
-                                       text = xnodes[ i ];
-                                       if( text[ '_flags' ] & X_Node_BitMask_IS_DIRTY ){
-                                               text[ '_flags' ] &= X_Node_BitMask_RESET_DIRTY;
-                                               dirty = true;
+                       if( ( anime = that[ '_anime' ] ) && 6 <= anime.phase && anime.doScroll ){
+                               if( anime.phase === 6 ){
+                                       v = anime.fromScrollX;
+                                       if( v === v ){
+                                               elm.scrollLeft = v;
+                                       } else {
+                                               anime.fromScrollX = elm.scrollLeft;
                                        };
+                                       v = anime.fromScrollY;
+                                       if( v === v ){
+                                               elm.scrollTop = v;
+                                       } else {
+                                               anime.fromScrollY = elm.scrollTop;
+                                       };
+                               } else {
+                                       elm.scrollLeft = anime.scrollX;
+                                       elm.scrollTop  = anime.scrollY;
                                };
-                               if( dirty ) elm.innerHTML = that[ 'text' ]();
                        };
-                       
-                       if( accumulatedFlags & X_Node_BitMask_IS_DIRTY ) delete that[ '_fontSize' ];
-                       
-                       that[ '_flags' ] &= ~X_NodeFlags_DIRTY_POSITION;
-                       that[ '_flags' ] & X_Node_BitMask_IS_DIRTY && X_Node__updateRawNode( that, elm );
+
                        return elm;
                }) :
                (function(){});
@@ -1669,15 +1804,22 @@ var X_Node__commitUpdate =
  */
 var X_Node__updateRawNode =
        X_UA_DOM.W3C ?
-               ( function( that, elm ){
-                       var attrs, rename, k, v;
+               ( function( that, elm, currentOpcity, ie8AccumulatedOpcity, accumulatedFlags ){
+                       var // flags = that[ '_flags' ],
+                               attrs, rename, k, v, f;
 
                        // textNode
                        if( !that[ '_tag' ] ){
-                               elm.data = X_String_chrReferanceTo( that[ '_text' ] );
+                               if( X_UA[ 'IE' ] < 8 ){
+                                       // \n -> \r\n に変換しないと pre タグで改行されない  win10ie7(ie11 emu) で確認
+                                       elm.data = X_String_chrReferanceTo( that[ '_text' ] ).split( '\n' ).join( X_String_CRLF );
+                               } else {
+                                       elm.data = X_String_chrReferanceTo( that[ '_text' ] );
+                               };
                                that[ '_flags' ] &= X_Node_BitMask_RESET_DIRTY;
                                return;
                        };
+                       
                        // id
                        if( that[ '_flags' ] & X_NodeFlags_DIRTY_ID ){
                                that[ '_id' ] ?
@@ -1694,7 +1836,7 @@ var X_Node__updateRawNode =
                                                elm.setAttribute( 'class', that[ '_className' ] ) :
                                                ( elm.className = that[ '_className' ] )
                                        ) :
-                                       ( elm.className && elm.removeAttribute( X_UA[ 'IE' ] < 8 ? 'className' : 'class' ) ); // className は ie7-                     
+                                       ( elm.className && elm.removeAttribute( X_UA[ 'IE' ] < 8 ? 'className' : 'class' ) ); // className は ie7-             
                        };
                        
                        // attr
@@ -1744,6 +1886,19 @@ var X_Node__updateRawNode =
                                delete that[ '_newAttrs' ];
                        };
                        
+                       if( accumulatedFlags & X_NodeFlags_IE8_OPACITY_FIX ){
+                               if( 0 <= currentOpcity ){
+                                       f = true;
+                                       that[ '_css' ].opacity = ie8AccumulatedOpcity;
+                                       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' ] ){
@@ -1766,6 +1921,15 @@ var X_Node__updateRawNode =
                                };
                        };
                        
+                       /*
+                        * http://jsdo.it/esukei/imOL
+                        * IE8でのfilter:alpha継承
+                        * IE8でfilter:alphaの指定がposition:relative,position:absoluteの子要素に継承されない問題
+                        */
+                       if( f ){
+                               that[ '_css' ].opacity = currentOpcity;
+                       };
+                       
                        that[ '_flags' ] &= X_Node_BitMask_RESET_DIRTY;
                }) :
        X_UA_DOM.IE4 ? 
@@ -1940,7 +2104,7 @@ var X_Node__actualRemove =
                                that[ '_listeners' ] && X_EventDispatcher_toggleAllEvents( that, false );// イベントの退避
                                that[ '_flags' ] &= ~X_NodeFlags_ACTUAL_LISTENING;
                        };
-                       
+
                        // ie5では filter の効いている要素をremove時に破棄して、再度append 時に新規生成する
                        // ちなみに elm.filters に触ると ie8 でなぜかカラム落ちが発生、、、
                        if( X_Node_displayNoneFixForIE5 ){
@@ -1960,7 +2124,7 @@ var X_Node__actualRemove =
                                                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;
                                        };
@@ -2003,7 +2167,7 @@ var X_Node__actualRemove =
                                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;
                        };