OSDN Git Service

Version 0.6.119, add ended event to X.Audio.Sprite & GPU layer off.
[pettanr/clientJs.git] / 0.6.x / js / 02_dom / 02_XNode.js
index 233ee62..9c44e1d 100644 (file)
@@ -4,9 +4,9 @@ var
                CHILD_IS_DIRTY   :  1,\r
                ID               :  2, // width, height, x, y\r
                CONTENT          :  4, // width, height, x, y textNode の内容\r
-               CLASSNAME        :  8, // _getCharSize, width, height, x, y\r
-               ATTR             : 16, // _getCharSize, width, height, x, y\r
-               CSS              : 32, // _getCharSize, width, height, x, y\r
+               CLASSNAME        :  8, // X_Node_CSS_getCharSize, width, height, x, y\r
+               ATTR             : 16, // X_Node_CSS_getCharSize, width, height, x, y\r
+               CSS              : 32, // X_Node_CSS_getCharSize, width, height, x, y\r
                IE_FILTER        : X_UA.IE < 9 && !X_UA.MacIE ? 64 : 0,\r
                UNKNOWN_TAG_FIX  : 128,\r
                IE4_TEXTNODE_FIX : 256\r
@@ -15,8 +15,8 @@ var
        X_Node_State = {\r
                DESTROYED          : 0,\r
                EXIST              : 1, // XNODE_EXIDT, ELEMENT_EXIST\r
-               BELONG_TREE        : 2, // HAS_PARENT, BELONG_TREE_XNODE, BELONG_TREE_ELEMENT\r
-               DISPLAY_NONE       : 4, // VISIVILITY_HIDDEN & DISPALY_NONE\r
+               BELONG_TREE        : 2, // HAS_PARENT, HAS_PARENT_ACTUAL, BELONG_TREE, BELONG_TREE_ACTUAL\r
+               DISPLAY_NONE       : 4, // VISIVILITY_HIDDEN(opacity0), DISPALY_NONE\r
                DISPLAY_BLOCK      : 8, // remove\r
                DISPLAY_INLINE     : 16,// remove\r
                POSITION_ABSOLUTE  : 32,\r
@@ -46,11 +46,13 @@ var
        \r
        X_Node_useDocumentFragment = document.createDocumentFragment && ( !X_UA.IE || 5.5 <= X_UA.IE ) && document.createDocumentFragment(),\r
        \r
-       X_Node_newByTag  = false,\r
+       X_Node_newByTag      = false,\r
        \r
-       X_Node_newByText = false,\r
+       X_Node_newByText     = false,\r
        \r
-       X_Node_outerXNode = null,\r
+       X_Node_outerXNode    = null,\r
+       \r
+       X_Node_updateTimerID = 0,\r
 /*\r
  * Node( rawElement | rawTextnode | htmlString | textString )\r
  */    \r
@@ -105,15 +107,13 @@ var
                        } else\r
                        if( X_Node_newByText ){\r
                                X_Node_newByText = false;\r
-                               this._text      = v;\r
-                               this._xnodeType = 3;\r
-                               this._state     = X_Node_State.DISPLAY_INLINE;\r
+                               this._text       = v;\r
+                               this._xnodeType  = 3;\r
+                               this._state      = X_Node_State.DISPLAY_INLINE;\r
                        } else {\r
                                if( 1 < arguments.length ) return new X_NodeList( arguments );\r
                                if( X.Type.isArray( v ) && v.length ) return new X_NodeList( v );\r
-                               //if( !this || this.append !== X_Node_append ){\r
-                               //       return new Node( v );\r
-                               //};\r
+\r
                                switch( X_Node_getType( v ) ){\r
                                        case X_Node_TYPE.XNODE :\r
                                        case X_Node_TYPE.XNODE_LIST :\r
@@ -155,20 +155,13 @@ var
                                                if( xnodes = X_HtmlParser_parse( v, true ) && 1 < xnodes.length ) return new X_NodeList( xnodes );\r
                                                if( xnodes.length ) return xnodes[ 0 ];\r
                                                return X_Node_none;\r
+                                       /*\r
                                        case X_Node_TYPE.IMAGE :\r
                                                if( xnode = X_Node_getXNode( v ) ) return xnode;\r
                                                this._rawObject = v;\r
                                                this._xnodeType = 4;\r
                                                v.UID           = uid;\r
                                                this._state     = X_Node_State.EXIST;\r
-                                               break;\r
-                                       /*\r
-                                       case X_Node_TYPE.WINDOW :\r
-                                       case X_Node_TYPE.DOCUMENT :\r
-                                               if( xnode = X_Node_getXNode( v ) ) return xnode;\r
-                                               this._rawObject = v;\r
-                                               this._xnodeType = 2;\r
-                                               this._state     = X_Node_State.DISPLAY_BLOCK;\r
                                                break; */\r
                                        default :\r
                                                if( X_Node_none ) return X_Node_none;\r
@@ -219,6 +212,8 @@ var
                \r
                getChildAt     : X_Node_getChildAt,\r
                \r
+               numChildren    : X_Node_length,\r
+               \r
                firstChild     : X_Node_firstChild,\r
                \r
                lastChild      : X_Node_lastChild,\r
@@ -248,7 +243,7 @@ function X_Node_getType( v ){
        if( v.constructor === X_NodeList ) return X_Node_TYPE.XNODE_LIST;\r
        if( X.Type.isHTMLElement( v ) ) return X_Node_TYPE.RAW_HTML;\r
        if( v.nodeType === 3 ) return X_Node_TYPE.RAW_TEXT;\r
-       if( X.Type.isImage( v ) ) return X_Node_TYPE.IMAGE;\r
+       //if( X.Type.isImage( v ) ) return X_Node_TYPE.IMAGE;\r
        if( X.Type.isString( v ) ){\r
                return '<' === v.charAt( 0 ) && v.charAt( v.length - 1 ) === '>' ? X_Node_TYPE.HTML_STRING : X_Node_TYPE.STRING;\r
        };\r
@@ -262,7 +257,7 @@ function X_Node_getXNode( v ){
                case X_Node_TYPE.XNODE_LIST :\r
                        return v;\r
                case X_Node_TYPE.RAW_HTML :\r
-               case X_Node_TYPE.IMAGE :\r
+               //case X_Node_TYPE.IMAGE :\r
                        // fake TextNode too.\r
                        if( X_UA_DOM.IE4 ){\r
                                uid = v.getAttribute( 'UID' );\r
@@ -270,7 +265,7 @@ function X_Node_getXNode( v ){
                        };\r
                        return v.UID && X_Node_CHASHE[ v.UID ];\r
                case X_Node_TYPE.WINDOW :\r
-                       return X.ViewPort;\r
+                       return X_ViewPort;\r
                case X_Node_TYPE.DOCUMENT :\r
                        return X_ViewPort_document;\r
                case X_Node_TYPE.RAW_TEXT :\r
@@ -281,39 +276,18 @@ function X_Node_getXNode( v ){
        };\r
 };\r
 \r
-\r
-X.Doc.create = Node.create = function( tag, opt_attrs, opt_css ){\r
-       var list, i;\r
-       switch( X_Node_getType( tag ) ){\r
-               case X_Node_TYPE.STRING :\r
-                       X_Node_newByTag = true;\r
-                       return new Node( tag, opt_attrs, opt_css );\r
-               case X_Node_TYPE.HTML_STRING :\r
-                       list = X_HtmlParser_parse( tag, true );\r
-                       for( i = list.length; 1 < i; ){\r
-                               list[ --i ].destroy();\r
-                       };\r
-                       return list[ 0 ];\r
-       };\r
-};\r
-X.Doc.createText = Node.createText = function( text ){\r
-       X_Node_newByText = true;\r
-       return new Node( text );\r
-};\r
-\r
-\r
 function X_Node_getRoot( xnode ){\r
        return X_ViewPort_document;\r
        //return X_Node_body._rawObject.documentElement ? node : node.ownerDocument || node.document;\r
 };\r
        // XMLかどうかを判別する\r
 var X_Node_isXmlDocument =\r
-       X_UA_DOM.IE4 ?\r
-               X.emptyFunction :\r
-               (function( root ){\r
-                       if( X.Type.isBoolean( root.isXML ) ) return root.isXML;\r
-                       return root.isXML = root._rawObject.createElement( 'p' ).tagName !== root._rawObject.createElement( 'P' ).tagName;\r
-               }),\r
+               X_UA_DOM.IE4 ?\r
+                       X.emptyFunction :\r
+                       (function( root ){\r
+                               if( X.Type.isBoolean( root.isXML ) ) return root.isXML;\r
+                               return root.isXML = root._rawObject.createElement( 'p' ).tagName !== root._rawObject.createElement( 'P' ).tagName;\r
+                       }),\r
        X_Node_CHASHE     = [],\r
        X_Node_none  = X_Node_CHASHE[ 0 ] = new Node(),\r
        X_Node_html, // = X_Node_CHASHE[ 1 ] <html>\r
@@ -340,7 +314,7 @@ function X_Node_create( tag, opt_attrs, opt_css ){
        if( this._xnodeType !== 1 ) return;\r
        if( !this._xnodes ) this._xnodes = [];\r
        \r
-       xnode = Node.create( tag, opt_attrs, opt_css );\r
+       xnode = X_Doc_create( tag, opt_attrs, opt_css );\r
        \r
        xnode.parent = this;\r
        this._xnodes[ this._xnodes.length ] = xnode;\r
@@ -348,7 +322,7 @@ function X_Node_create( tag, opt_attrs, opt_css ){
        return xnode;\r
 };\r
 function X_Node_createAt( index, tag, opt_attrs, opt_css ){\r
-       var xnode = Node.create( tag, opt_attrs, opt_css );\r
+       var xnode = X_Doc_create( tag, opt_attrs, opt_css );\r
        this.appendAt( index, xnode );\r
        return xnode;\r
 };\r
@@ -370,7 +344,7 @@ function X_Node_createText( text ){
        return xnode;\r
 };\r
 function X_Node_createTextAt( index, text ){\r
-       var xtext = Node.createText( text );\r
+       var xtext = X_Doc_createText( text );\r
        this.appendAt( index, xtext );\r
        return xtext;\r
 };\r
@@ -706,6 +680,10 @@ function X_Node_getChildAt( i ){
        return xnodes && 0 <= i && i < xnodes.length && xnodes[ i ];\r
 };\r
 \r
+function X_Node_length(){\r
+       var xnodes = this._xnodes;\r
+       return xnodes ? xnodes.length : 0;\r
+};\r
 \r
 /* --------------------------------------\r
  *  firstChild, lastChild\r
@@ -792,7 +770,7 @@ function X_Node_toggleClass( v, opt_toggle ){
        names = v.split( ' ' );\r
        for( i = names.length; i; ){\r
                name = names[ --i ];\r
-               this.hassClass( name ) ? this.removeClass( name ) : this.addClass( name );\r
+               this.hasClass( name ) ? this.removeClass( name ) : this.addClass( name );\r
        };\r
        return this;\r
 };\r
@@ -831,7 +809,7 @@ function X_Node_html( html ){
                return this._text;\r
        };\r
        \r
-       if( this._dirty & X_Node_Dirty.CSS && !( this._cssText = X_Node_CSS_objToCssText( this._css ) ) ){\r
+       if( this._dirty & X_Node_Dirty.CSS && !( this._cssText = X_Node_CSS_objToCssText( this ) ) ){\r
                delete this._cssText;\r
        };\r
        html = !X_Node_outerXNode ? [] : [\r
@@ -855,10 +833,16 @@ function X_Node_html( html ){
        return html.join( _ );\r
 };\r
 \r
+/*\r
+ * null が来たら '', 数値等が来たら文字烈化\r
+ */\r
 function X_Node_text( text ){\r
        var xnodes, texts, i, l;\r
        // setter\r
        if( text !== undefined ){\r
+               if( text === null ) text = '';\r
+               text += '';\r
+               \r
                if( this._xnodeType === 3 ){\r
                        if( this._text !== text ){\r
                                text ? ( this._text = text ) : delete this.text;\r
@@ -892,10 +876,14 @@ function X_Node_text( text ){
  * HTML要素に対して name の関数を実行しその戻り値を返す。関数に渡す引数も任意に設定できる。\r
  */\r
 function X_Node_call( name /*, opt_args... */ ){\r
-       var raw  = this._rawObject || X_UA_DOM.IE4 && X_Node__ie4getRawNode( this ),\r
-               l    = arguments.length - 1,\r
-               func, args, params, i;\r
+       var l = arguments.length - 1,\r
+               raw, func, args, params, i;\r
+               \r
+       X_Node_updateTimerID && X_Node_startUpdate();\r
+       \r
+       raw  = this._rawObject || X_UA_DOM.IE4 && X_Node__ie4getRawNode( this );\r
        if( !raw ) return;\r
+       \r
        func = raw[ name ];\r
        if( X.Type.isFunction( func ) ){\r
                if( l ){\r
@@ -960,23 +948,23 @@ function X_Node_each( func /*, opt_args */ ){
  */\r
        \r
 function X_Node_reserveUpdate(){\r
-       var root = X_Node_body;\r
-       if( root && !root._updateTimerID ) root._updateTimerID = X.Timer.requestFrame( X_Node_startUpdate );\r
+       if( !X_Node_updateTimerID ) X_Node_updateTimerID = X.Timer.requestFrame( X_Node_startUpdate );\r
 };\r
 \r
-function X_Node_startUpdate(){\r
+function X_Node_startUpdate( time ){\r
        var removal, i, xnode, tmp;\r
-       if( X_ViewPort_readyState < X_TEMP.SYSTEM_EVENT_INIT ){\r
+       \r
+       if( !X_Node_updateTimerID || X_ViewPort_readyState < X_TEMP.SYSTEM_EVENT_INIT ){\r
                return;\r
        };\r
-       if( X_Node_body._updateTimerID ){\r
-               X.Timer.cancelFrame( X_Node_body._updateTimerID );\r
-               X_Node_body._updateTimerID = 0;\r
-       } else {\r
-               return;\r
+\r
+       X.Timer.cancelFrame( X_Node_updateTimerID );\r
+       X_Node_updateTimerID = 0;\r
+\r
+       if( time ){\r
+               // X.Timer 経由でないと発火しない このイベントでサイズを取ると無限ループに\r
+               X_System._listeners && X_System._listeners[ X.Event.BEFORE_UPDATE ] && X_System.dispatch( X.Event.BEFORE_UPDATE );\r
        };\r
-       // このイベントでサイズを取ると無限ループに\r
-       // X_ViewPort._listeners && X_ViewPort._listeners[ X.Event.BEFORE_UPDATE ] && X_ViewPort.dispatch( X.Dom.Event.BEFORE_UPDATE );\r
 \r
        removal = X_Node_reserveRemoval;\r
        \r
@@ -1000,6 +988,11 @@ function X_Node_startUpdate(){
        \r
        //console.log( 'end of _startUpdate().' );\r
        \r
+       if( time ){\r
+               // X.Timer 経由でないと発火しない このイベントでサイズを取ると無限ループに\r
+               X_System._listeners && X_System._listeners[ X.Event.UPDATED ] && X_System.dispatch( X.Event.UPDATED );  \r
+       };\r
+       \r
        X_ViewPort._listeners && X_ViewPort._listeners[ X.Event.AFTER_UPDATE ] && X_ViewPort.asyncDispatch( X.Event.AFTER_UPDATE );\r
        //this._rawObject.style.visibility = tmp;\r
 };\r
@@ -1033,9 +1026,6 @@ var X_Node__commitUpdate =
                                                frg.appendChild( X_Node__actualCreate( xnodes[ i ], true ) );\r
                                        };\r
                                        elm.appendChild( frg );\r
-                                       for( i = 0; i < l; ++i ){\r
-                                               X_Node__actualCreate( xnodes[ i ], true );\r
-                                       };\r
                                } else {*/\r
                                        for( ; l; ){\r
                                                next = X_Node__commitUpdate( xnodes[ --l ], elm, next );\r
@@ -1123,10 +1113,11 @@ var X_Node__updateRawNode =
                                        return;\r
                                };\r
                        };\r
+                       \r
                        // style\r
                        // TODO display:none の場合、更新をスキップ\r
                        if( that._dirty & X_Node_Dirty.CSS ){\r
-                               if( that._cssText !== null || ( that._cssText = X_Node_CSS_objToCssText( that._css ) ) ){\r
+                               if( that._cssText !== null || ( that._cssText = X_Node_CSS_objToCssText( that ) ) ){\r
                                        X_UA.Opera78 || X_UA.NN6 ?\r
                                                elm.setAttribute( 'style', that._cssText ) : // opera8用\r
                                                ( elm.style.cssText = that._cssText );\r
@@ -1138,7 +1129,7 @@ var X_Node__updateRawNode =
                        };\r
                        \r
                        if( that._dirty & X_Node_Dirty.IE_FILTER ){\r
-                               elm.style.filter = X_Node_CSS_SPECIAL_FIX( that._css );\r
+                               elm.style.filter = X_Node_CSS_objToIEFilterText( that );;\r
                        };\r
                        \r
                        // attr\r
@@ -1189,7 +1180,7 @@ var X_Node__updateRawNode =
                        };\r
                        // style\r
                        if( that._dirty & X_Node_Dirty.CSS ){\r
-                               if( that._cssText !== null || ( that._cssText = X_Node_CSS_objToCssText( that._css ) ) ){\r
+                               if( that._cssText !== null || ( that._cssText = X_Node_CSS_objToCssText( that ) ) ){\r
                                        elm.style.cssText = that._cssText;\r
                                } else {\r
                                        elm.style.cssText = '';\r
@@ -1199,7 +1190,7 @@ var X_Node__updateRawNode =
                        };\r
                        \r
                        if( that._dirty & X_Node_Dirty.IE_FILTER ){\r
-                               that._rawObject.style.filter = X_Node_CSS_SPECIAL_FIX( that._css );\r
+                               that._rawObject.style.filter = X_Node_CSS_objToIEFilterText( that );;\r
                        };\r
                        \r
                        // attr\r
@@ -1208,9 +1199,9 @@ var X_Node__updateRawNode =
                                for( k in attrs ){\r
                                        ( v = attrs[ k ] ) === undefined ?\r
                                                elm.removeAttribute( rename[ k ] || k ) :\r
-                                       that._tag === 'TEXTAREA' && k === 'value' ?\r
-                                               ( elm.innerText = v ) :\r
-                                               elm.setAttribute( rename[ k ] || k, X_Node_Attr_noValue[ k ] ? k : v ); // TODO X_Node_Attr_noValue[ k ] ? k : v\r
+                                       //that._tag === 'TEXTAREA' && k === 'value' ?\r
+                                       //      ( elm.innerText = v ) :\r
+                                               elm.setAttribute( rename[ k ] || k, X_Node_Attr_noValue[ k ] ? k : v );\r
                                };\r
                                delete that._newAttrs;\r
                        };\r
@@ -1248,7 +1239,7 @@ var X_Node__actualCreate =
                };\r
                \r
                if( !elm ){\r
-                       if( that._dirty & X_Node_Dirty.CSS && !( that._cssText = X_Node_CSS_objToCssText( that._css ) ) ){\r
+                       if( that._dirty & X_Node_Dirty.CSS && !( that._cssText = X_Node_CSS_objToCssText( that ) ) ){\r
                                delete that._cssText;\r
                        };\r
                        that._isNew = true;\r
@@ -1286,7 +1277,7 @@ var X_Node__actualCreate =
                } else {\r
                        if( that._rawObject && !isChild ) X_Node__actualRemove( that, true );\r
                        \r
-                       if( that._dirty & X_Node_Dirty.CSS && !( that._cssText = X_Node_CSS_objToCssText( that._css ) ) ){\r
+                       if( that._dirty & X_Node_Dirty.CSS && !( that._cssText = X_Node_CSS_objToCssText( that ) ) ){\r
                                delete that._cssText;\r
                        };\r
                        \r
@@ -1342,7 +1333,7 @@ var X_Node__afterActualCreate =
                        };\r
                        if( X_Node_strictElmCreation ){\r
                                if( that._dirty & X_Node_Dirty.IE_FILTER ){\r
-                                       elm.style.filter = X_Node_CSS_SPECIAL_FIX( that._css );\r
+                                       elm.style.filter = X_Node_CSS_objToIEFilterText( that );;\r
                                };\r
                                delete that._dirty;\r
                        } else {\r
@@ -1361,7 +1352,7 @@ var X_Node__afterActualCreate =
                        X_Node__afterActualCreate( xnodes[ i ] );\r
                };\r
                // src の onload があるので先ではないか?\r
-               // ie の str から要素を作る場合、srcだけ イベント設定後ではないか?\r
+               // TODO ie の str から要素を作る場合、srcだけ イベント設定後ではないか?\r
                X_EventDispatcher_toggleAllEvents( that, true );// イベントの復帰\r
        }) :\r
        X_UA_DOM.IE4 ? (function( that ){\r
@@ -1377,7 +1368,7 @@ var X_Node__afterActualCreate =
                };\r
                // textarea への value の適用はここで\r
                if( that._dirty & X_Node_Dirty.IE_FILTER ){\r
-                       X_Node__ie4getRawNode( that ).style.filter = X_Node_CSS_SPECIAL_FIX( that._css );\r
+                       X_Node__ie4getRawNode( that ).style.filter = X_Node_CSS_objToIEFilterText( that );;\r
                };\r
                delete that._dirty;\r
                X_EventDispatcher_toggleAllEvents( that, true );// イベントの復帰\r
@@ -1386,6 +1377,8 @@ var X_Node__afterActualCreate =
 \r
 var X_Node__actualRemove =\r
        X_UA_DOM.W3C ?\r
+               // GPUレイヤーにいるうちは remove しない。-> GPU解除してから remove する\r
+               // Firefox34 では遭遇せず、Safari で何度かアニメーションしているうちに発生\r
                ( function( that, isChild ){\r
                        var xnodes = that._xnodes,\r
                                elm    = that._rawObject,\r
@@ -1398,9 +1391,9 @@ var X_Node__actualRemove =
                        };\r
 \r
                        if( !elm ) return;\r
-                       that._xnodeType === 1 && X_EventDispatcher_toggleAllEvents( that, false );// イベントの退避\r
-                       // elm.parentNode.tagName for ie7\r
+                       that._listeners && X_EventDispatcher_toggleAllEvents( that, false );// イベントの退避\r
                        if( !X_UA.MacIE ){\r
+                               // elm.parentNode.tagName for ie7 -> that.state & BELONG_TREE_ACTUAL\r
                                !isChild && elm.parentNode && elm.parentNode.tagName && elm.parentNode.removeChild( elm );\r
                        } else {\r
                                !isChild && elm.parentNode && elm.parentNode.tagName && X_TEMP._fixed_remove( elm, that );\r
@@ -1418,7 +1411,7 @@ var X_Node__actualRemove =
                        };\r
 \r
                        if( !elm ) return;\r
-                       that._xnodeType === 1 && X_EventDispatcher_toggleAllEvents( that, false );// イベントの退避\r
+                       that._listeners && X_EventDispatcher_toggleAllEvents( that, false );// イベントの退避\r
                        \r
                        if( X_Node_Attr_HAS_VALUE[ that._tag ] && ( !that._newAttrs || !X_Object_inObject( 'value', that._newAttrs ) ) ){\r
                                that._attrs.value = elm.value;\r
@@ -1429,3 +1422,6 @@ var X_Node__actualRemove =
                        delete that._rawObject;\r
                }) :\r
                (function(){});\r
+\r
+X_ViewPort.listenOnce( X.Event.UNLOAD, X_Node__actualRemove, [ X_Node_html, true ] );\r
+\r