OSDN Git Service

Version 0.6.138, working X.UI.ScrollBox!, fix Node.prev & Node.next.
authoritozyun <itozyun@user.sourceforge.jp>
Thu, 16 Apr 2015 13:01:49 +0000 (22:01 +0900)
committeritozyun <itozyun@user.sourceforge.jp>
Thu, 16 Apr 2015 13:01:49 +0000 (22:01 +0900)
19 files changed:
0.6.x/js/01_core/03_XType.js
0.6.x/js/01_core/06_XURL.js
0.6.x/js/02_dom/02_XNode.js
0.6.x/js/02_dom/09_XHTMLParser.js
0.6.x/js/02_dom/10_XNodeAnime.js
0.6.x/js/06_net/00_XNet.js
0.6.x/js/06_net/01_XNetXHR.js
0.6.x/js/20_ui/00_XUI.js
0.6.x/js/20_ui/02_XUI_Attr.js
0.6.x/js/20_ui/04_XUI_Event.js
0.6.x/js/20_ui/05_XUI_Gesture.js
0.6.x/js/20_ui/06_AbstractUINode.js
0.6.x/js/20_ui/08_Box.js
0.6.x/js/20_ui/11_VBox.js
0.6.x/js/20_ui/12_HBox.js
0.6.x/js/20_ui/13_TileBox.js
0.6.x/js/20_ui/14_ChromeBox.js
0.6.x/js/20_ui/15_ScrollBox.js
0.6.x/js/20_ui/20_PageRoot.js

index fdf181c..a7a78aa 100644 (file)
@@ -56,10 +56,11 @@ X[ 'Type' ] = {
 \r
        /**\r
         * Object か?判定する。typeof null === 'object' に対策済なので null は Object ではない。\r
+        * new String(), new Number(), new Boolean() も typeof object なので対策\r
         * @alias X.Type.isObject\r
         */\r
        function X_Type_isObject( v ){\r
-               return v && typeof v === 'object'; // typeof null === 'object' に対策\r
+               return v && typeof v === 'object'; // && ( v !== v + '' && v !== v + 0 && v !== true ) ; // typeof null === 'object' に対策\r
        };\r
        /**\r
         * Function か?判定する。\r
index 9d2dd87..39951cb 100644 (file)
@@ -48,13 +48,13 @@ var X_URL_BASE_URL = ( function( parts ){
  */\r
 X[ 'URL' ] = {\r
 \r
-       'BASE_URL' : X_URL_BASE_URL,\r
+       'BASE_URL'       : X_URL_BASE_URL,\r
        \r
-       'IS_FILE'  : X_URL_IS_FILE,\r
+       'IS_FILE'        : X_URL_IS_FILE,\r
        \r
-       'IS_LOCAL' : X_URL_IS_LOCAL,\r
+       'IS_LOCAL'       : X_URL_IS_LOCAL,\r
        \r
-       'PARAMS'   : X_URL_PARAMS,\r
+       'PARAMS'         : X_URL_PARAMS,\r
        \r
        'toAbsolutePath' : X_URL_toAbsolutePath,\r
        \r
index ab3d01c..c0bb170 100644 (file)
@@ -142,7 +142,6 @@ var Node = X[ 'Node' ] = X_EventDispatcher[ 'inherits' ](
                /**\r
                 * NodeList と動作を一致させるためのプロパティ。常に 1。\r
                 * @type {number}\r
-                * @private\r
                 * @alias Node.prototype.length\r
                 */\r
                length       : 1,\r
@@ -150,7 +149,6 @@ var Node = X[ 'Node' ] = X_EventDispatcher[ 'inherits' ](
                /**\r
                 * 親 Node。\r
                 * @type {Node}\r
-                * @private\r
                 * @alias Node.prototype.parent\r
                 */\r
                parent       : null, // remove された枝も親子構造は維持している。\r
@@ -671,7 +669,14 @@ function X_Node_appendAt( start, v ){
                        return this;\r
                case X_Node_TYPE.XNODE :\r
                        // 親の xnodes から v を消す\r
-                       v.parent && v[ 'remove' ]();\r
+                       if( v.parent ){\r
+                               if( v.parent === this ){\r
+                                       i = v[ 'getOrder' ]();\r
+                                       if( i === start ) return this;\r
+                                       if( i < start ) --start;\r
+                               };\r
+                               v[ 'remove' ]();\r
+                       };\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
@@ -716,14 +721,14 @@ function X_Node_appendTo( parent, opt_index ){
 \r
 \r
 /**\r
- * ノードの直前の要素を取得。または直前に挿入。\r
+ * ノードの直前の要素を取得。または直前に挿入。挿入する要素が先にいる兄弟でも正しく動作する。\r
  * @alias Node.prototype.prev\r
- * @param {Node|string|HTMLElement|TextNode} [v] HTMLElement と TextNode は内部のみ。\r
+ * @param {Node|string|HTMLElement|TextNode} [...v] HTMLElement と TextNode は内部のみ。\r
  * @return {Node} 自身。チェインメソッド\r
  * @example childNode.prev( prevNode );\r
  */\r
 function X_Node_prev( v ){\r
-       var parent = this.parent, xnodes, i, l, start;\r
+       var parent = this.parent, xnodes, i, l;\r
        \r
        // getter\r
        if( v === undefined ){\r
@@ -736,19 +741,18 @@ function X_Node_prev( v ){
        if( !parent ) return this;\r
        \r
        l = arguments.length;\r
-       start = this[ 'getOrder' ]();\r
        if( 1 < l ){\r
-               for( ; l; ){\r
-                       parent[ 'appendAt' ]( start, arguments[ --l ] );\r
+               for( i = 0; l; ++i ){\r
+                       parent[ 'appendAt' ]( this[ 'getOrder' ]() - i, arguments[ --l ] );\r
                };\r
                return this;\r
        };\r
-       parent[ 'appendAt' ]( start, v );\r
+       parent[ 'appendAt' ]( this[ 'getOrder' ](), v );\r
        return this;\r
 };\r
 \r
 /**\r
- * ノードの直後の要素を取得。または直後に挿入。\r
+ * ノードの直後の要素を取得。または直後に挿入。挿入する要素が先にいる兄弟でも正しく動作する。\r
  * @alias Node.prototype.next\r
  * @param {Node|string|HTMLElement|TextNode} [v] HTMLElement と TextNode は内部のみ。\r
  * @return {Node} 自身。チェインメソッド\r
@@ -769,23 +773,19 @@ function X_Node_next( v ){
        \r
        l = arguments.length;\r
        start = this[ 'getOrder' ]() + 1;\r
+       \r
        if( parent[ '_xnodes' ].length <= start ){\r
-               if( 1 < l ){\r
-                       for( i = 0; i < l; ++i ){\r
-                               parent[ 'append' ]( arguments[ i ] );\r
-                       };\r
-                       return this;\r
+               for( i = 0; i < l; ++i ){\r
+                       parent[ 'append' ]( arguments[ i ] );\r
                };\r
-               parent[ 'append' ]( v );\r
-               return this;\r
-       };\r
+       } else\r
        if( 1 < l ){\r
                for( ; l; ){\r
-                       parent[ 'appendAt' ]( start, arguments[ --l ] );\r
+                       parent[ 'appendAt' ]( this[ 'getOrder' ]() + 1, arguments[ --l ] );\r
                };\r
-               return this;\r
+       } else {\r
+               parent[ 'appendAt' ]( start, v );\r
        };\r
-       parent[ 'appendAt' ]( start, v );\r
        return this;\r
 };\r
 \r
@@ -1213,6 +1213,9 @@ function X_Node_call( name /*, opt_args... */ ){
                        return v;\r
                case 'fontSize' :\r
                        return X_Node_CSS_getCharSize( this );\r
+               case 'GPU' :\r
+                       return this[ '_flags' ] & X_Node_State.GPU_NOW ? 'NOW' :\r
+                               this[ '_flags' ] & X_Node_State.GPU_RELEASE_RESERVED ? '解除予約' : '';\r
                case 'inGPU' :\r
                        return !!( this[ '_flags' ] & ( X_Node_State.GPU_NOW | X_Node_State.GPU_RELEASE_RESERVED ) );\r
        };\r
@@ -1359,13 +1362,12 @@ var X_Node__commitUpdate =
                        };\r
 \r
                        // 2. GPU解放予約\r
-                       // TODO もしかしたらこのタイミングで更新できるかも。\r
                        if( that[ '_flags' ] & X_Node_State.GPU_RELEASE_RESERVED ){\r
-                               console.log( 'GPU 解放 ' );\r
+                               // console.log( 'GPU 解放 ' );\r
                                //X_Node_updateReservedByReleaseGPU = true;\r
                                //X_Node__updateRawNode( that, elm );\r
                                that[ '_flags' ] &= X_Node_BitMask_RESET_GPU;\r
-                               //return elm;\r
+                               //return elm;// TODO もしかしたらこのタイミングで更新できるかも。\r
                        };\r
 \r
                        // 3. GPU予約 -> GPU\r
index 60b6d27..764ce5f 100644 (file)
@@ -8,7 +8,7 @@
 var X_HTMLParser_CHARS = {\r
                'A':1,'B':1,'C':1,'D':1,'E':1,'F':1,'G':1,'H':1,'I':1,'J':1,'K':1,'L':1,'M':1,'N':1,'O':1,'P':1,'Q':1,'R':1,'S':1,'T':1,'U':1,'V':1,'W':1,'X':1,'Y':1,'Z':1,\r
                'a':2,'b':2,'c':2,'d':2,'e':2,'f':2,'g':2,'h':2,'i':2,'j':2,'k':2,'l':2,'m':2,'n':2,'o':2,'p':2,'q':2,'r':2,'s':2,'t':2,'u':2,'v':2,'w':2,'x':2,'y':2,'z':2,\r
-               // "0" ': 4, "1" : 4, "2" : 4, "3" : 4, "4" : 4, "5" : 4, "6" : 4, "7" : 4, "8" : 4, "9" : 4, closure compiler で minify すると ie4 で error、eval使う\r
+               '!':1,// "0" ': 4, "1" : 4, "2" : 4, "3" : 4, "4" : 4, "5" : 4, "6" : 4, "7" : 4, "8" : 4, "9" : 4, closure compiler で minify すると ie4 で error、eval使う\r
                \r
                '\t' : 16, '\r\n' : 16, '\r' : 16, '\n' : 16, '\f' : 16, '\b' : 16, ' ' : 16\r
        },\r
@@ -55,8 +55,6 @@ var X_HTMLParser_CHARS = {
                var special        = X_HTMLParser_special,\r
                        //plainText      = X_HTMLParser_plainText,\r
                        startTime      = async && X_Timer_now(),\r
-                       _parseStartTag = X_HTMLParser__parseStartTag,\r
-                       _parseEndTag   = X_HTMLParser__parseEndTag,\r
                        stack          = async ? async[ 1 ] : [],\r
                        lastHtml       = html,\r
                        chars, last, text, index;\r
@@ -66,10 +64,10 @@ var X_HTMLParser_CHARS = {
                        last  = stack[ stack.length - 1 ];\r
                        \r
                        // Make sure we're not in a script or style element\r
-                       if ( last && special[ last ] === 1 ) {\r
-                               if( 0 <= ( index = html.toUpperCase().indexOf( '</' + last ) ) ){\r
+                       if ( last && special[ handler.isXML ? last.toUpperCase() : last ] === 1 ) {\r
+                               if( 0 <= ( index = html.toUpperCase().indexOf( '</' + ( handler.isXML ? last.toUpperCase() : last ) ) ) ){\r
                                        handler.chars( html.substring( 0, index ) );\r
-                                       if( index = _parseEndTag( stack, handler, html ) ){\r
+                                       if( index = X_HTMLParser__parseEndTag( stack, handler, html ) ){\r
                                                html = html.substring( index );\r
                                        } else {\r
                                                handler.chars( html );\r
@@ -90,14 +88,14 @@ var X_HTMLParser_CHARS = {
        \r
                                // end tag\r
                                } else if ( html.indexOf("</") === 0 ) {\r
-                                       if ( 2 < ( index = _parseEndTag( stack, handler, html ) ) ) {\r
+                                       if ( 2 < ( index = X_HTMLParser__parseEndTag( stack, handler, html ) ) ) {\r
                                                html = html.substring( index );\r
                                                chars = false;\r
                                        };\r
        \r
                                // start tag\r
                                } else if ( html.indexOf("<") === 0 ) {\r
-                                       if( index = _parseStartTag( stack, last, handler, html ) ){\r
+                                       if( index = X_HTMLParser__parseStartTag( stack, last, handler, html ) ){\r
                                                html  = html.substring( index );\r
                                                chars = false;\r
                                        } else\r
@@ -147,7 +145,7 @@ var X_HTMLParser_CHARS = {
                        i     = 0,\r
                        attrs = [],\r
                        tagName, empty = false,\r
-                       chr, start, attrName, quot, escape;\r
+                       chr, start, attrName, quot, escape, tagUpper;\r
                \r
                while( i < l && phase < 9 ){\r
                        chr = html.charAt( i );\r
@@ -209,7 +207,24 @@ var X_HTMLParser_CHARS = {
                };\r
                if( phase === 9 ){\r
                        if( empty ) ++i;\r
-                       if( X_HTMLParser_parseStartTag( stack, last, handler, tagName.toUpperCase(), attrs, empty, i ) === false ) return false;\r
+                       //if( X_HTMLParser_parseStartTag( stack, last, handler, tagName, attrs, empty, i ) === false ) return false;\r
+                       \r
+                       tagUpper = tagName.toUpperCase();\r
+                       \r
+                       if( !X_HTMLParser_skipFixNesting && X_HTMLParser_block[ tagUpper ] === 1 ){\r
+                               while( last && X_HTMLParser_inline[ handler.isXML ? last.toUpperCase() : last ] === 1 ){\r
+                                       X_HTMLParser_parseEndTag( stack, handler, last );\r
+                                       last = stack[ stack.length - 1 ];\r
+                               };\r
+                       };\r
+                       last && X_HTMLParser_closeSelf[ tagUpper ] === 1 &&\r
+                               ( last === tagName || ( X_HTMLParser_sisters[ tagUpper ] && X_HTMLParser_sisters[ tagUpper ][ handler.isXML ? last.toUpperCase() : last ] === 1 ) ) &&\r
+                                       X_HTMLParser_parseEndTag( stack, handler, last );\r
+                       empty = empty || X_Dom_DTD_EMPTY[ tagUpper ];\r
+                       !empty && ( stack[ stack.length ] = handler.isXML ? tagName : tagUpper );\r
+                       \r
+                       if( handler.start( handler.isXML ? tagName : tagUpper, attrs, empty, i ) === false ) return false;\r
+                       \r
                        return i;\r
                };\r
                return 0; // error\r
@@ -245,7 +260,7 @@ var X_HTMLParser_CHARS = {
                        ++i;\r
                };\r
                if( phase === 9 ){\r
-                       X_HTMLParser_parseEndTag( stack, handler, tagName.toUpperCase() );\r
+                       X_HTMLParser_parseEndTag( stack, handler, handler.isXML ? tagName : tagName.toUpperCase() );\r
                        return i;\r
                };\r
                return 0; // error\r
@@ -264,23 +279,6 @@ var X_HTMLParser_CHARS = {
                };\r
        };\r
 \r
-       function X_HTMLParser_parseStartTag( stack, last, handler, tagName, attrs, empty, index ) {\r
-               var inline   = X_HTMLParser_inline,\r
-                       parseEndTag = X_HTMLParser_parseEndTag,\r
-                       sisters  = X_HTMLParser_sisters;\r
-               if( !X_HTMLParser_skipFixNesting && X_HTMLParser_block[ tagName ] === 1 ){\r
-                       while( last && inline[ last ] === 1 ){\r
-                               parseEndTag( stack, handler, last );\r
-                               last = stack[ stack.length - 1 ];\r
-                       };\r
-               };\r
-               last && X_HTMLParser_closeSelf[ tagName ] === 1 && ( last === tagName || ( sisters[ tagName ] && sisters[ tagName ][ last ] === 1 ) ) && parseEndTag( stack, handler, last );\r
-               empty = empty || X_Dom_DTD_EMPTY[ tagName ];\r
-               !empty && ( stack[ stack.length ] = tagName );\r
-               \r
-               return handler.start( tagName, attrs, empty, index );\r
-       };\r
-\r
        function X_HTMLParser_parseEndTag( stack, handler, tagName ) {\r
                var pos = 0, i = stack.length;\r
                // If no tag name is provided, clean shop\r
@@ -304,6 +302,7 @@ var X_HTMLParser_CHARS = {
 var X_HTMLParser_htmlStringToXNode = {\r
        flat : null,\r
        nest : [],\r
+       isXML : false,\r
        err : function( html ){\r
                X_HTMLParser_htmlStringToXNode.flat.length = 0;\r
                !X_HTMLParser_htmlStringToXNode.ignoreError && X.Logger.warn( 'X_Dom_Parser() error ' + html );\r
@@ -361,6 +360,7 @@ function X_HtmlParser_parse( html, ignoreError ){
 };\r
 \r
 var X_HTMLParser_asyncHtmlStringToXNode = {\r
+       isXML : false,\r
        err : function( html ){\r
                X_HTMLParser_htmlStringToXNode.err( html );\r
                this[ 'asyncDispatch' ]( X_EVENT_ERROR );\r
index ebdb856..e68b852 100644 (file)
@@ -129,14 +129,16 @@ Node.prototype[ 'animate' ] = function( start, dest, duration, easing, wait ){
                isNew && this[ 'dispatch' ]( { type : X_EVENT_ANIME_START, gpu : false } );\r
        };\r
        \r
-       console.log( 'animate ' + this[ '_id' ] + ' y:' + obj.startX + ' > ' + obj.destX + ' d:' + obj.duration );\r
+       // console.log( 'animate() ' + this[ '_id' ] + ' y:' + obj.startY + ' > ' + obj.destY + ' d:' + obj.duration );\r
        \r
        return this;\r
 };\r
 \r
 Node.prototype[ 'stop' ] = function(){\r
        var obj = this[ '_anime' ];\r
-       if( !obj ) return;\r
+       \r
+       if( !obj ) return this;\r
+       \r
        if( X_Node_Anime_hasTransition ){\r
                obj.phase = 100;\r
                X_Node_Anime_needsDetection = true;\r
@@ -154,24 +156,26 @@ function X_Node_Anime_reserveUpdate( before ){
                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
                                        X_Timer_once( 0, X_Node_Anime_updateAnimations ) :\r
-                                       X_Timer_requestFrame( X_Node_Anime_updateAnimations );                  \r
+                                       X_Timer_requestFrame( X_Node_Anime_updateAnimations );\r
                };\r
+       } else {\r
+               // console.log( ' X_Node_Anime_reserved 済、予約なし' );\r
        };\r
 };\r
 \r
 function X_Node_Anime_updateAnimations( v, updateNow ){\r
        var i = X_Node_ANIMATIONS.length, ret, c = false;\r
        \r
-       //console.log( v.type || v );\r
+       // console.log( v.type || v );\r
        \r
        //console.log( 'updateAnimations len:' + i + ' time:' + v + ' det:' + X_Node_Anime_needsDetection );\r
        \r
@@ -287,7 +291,7 @@ function X_Node_Anime_updateAnimation( xnode ){
                                transitionDelay          : '0s' // 0.001 にすると transitionend のタイミングが狂う、、、\r
                        });\r
                        \r
-                       console.log( '開始位置 ' + phase );\r
+                       //console.log( '開始位置 ' + phase );\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
@@ -304,12 +308,12 @@ function X_Node_Anime_updateAnimation( xnode ){
                                        transitionDuration : obj.duration + 'ms'\r
                                });\r
                                \r
-                               console.log( '修了位置 ' + phase );\r
+                               //console.log( '修了位置 ' + phase );\r
                                X_Node_Anime_updatePosition( xnode, obj.destX, obj.destY, obj.destA, obj.gpuParent );\r
                                obj.phase = 2;\r
                                break;\r
                        };\r
-                       console.log( 'duration = 0 の場合、アニメーションの解除' );\r
+                       //console.log( 'duration = 0 の場合、アニメーションの解除' );\r
                        // duration = 0 の場合、アニメーションの解除\r
                        \r
                case 3 : // アニメーションの解除\r
@@ -367,7 +371,7 @@ function X_Node_Anime_updateAnimation( xnode ){
                case 15 :\r
                        // GPU有効で停止(待機)している xnode の解除\r
                        //console.log( 'GPU有効で停止(待機)している xnode の解除' + xnode[ '_tag' ] + xnode[ 'getOrder' ]() );\r
-                       console.log( 'GPU有効で停止(待機)している xnode のGPU解除' );\r
+                       // console.log( 'GPU有効で停止(待機)している xnode のGPU解除' );\r
                        X_Node_Anime_clearTransition( xnode );\r
                        X_Node_Anime_updatePosition( xnode, obj.destX, obj.destY, obj.destA, false );\r
                        obj.gpuTimerID && X_Timer_remove( obj.gpuTimerID );\r
@@ -376,7 +380,7 @@ function X_Node_Anime_updateAnimation( xnode ){
                \r
                case 100 : // stop() : アニメーションを中断して削除\r
                        //console.log( 'stop() gpu:' + obj.gpuParent );\r
-                       console.log( 'アニメーションを中断して削除' );\r
+                       // console.log( 'アニメーションを中断して削除' );\r
                        current = X_Node_Anime_getComputedPosition( xnode );\r
                                                \r
                        X_Node_Anime_clearTransition( xnode );\r
@@ -404,10 +408,15 @@ function X_Node_Anime_getComputedPosition( that ) {
 };\r
 \r
 function X_Node_Anime_onTransitionEnd( e ){\r
-       if( !this[ '_anime' ] || this[ '_anime' ].phase !== 2 ) return X_Callback_PREVENT_DEFAULT | X_Callback_STOP_PROPAGATION;\r
-       this[ '_anime' ].phase = 3;\r
+       // console.log( 'アニメ終了[onTransitionEnd] ' + ( this[ '_anime' ] && this[ '_anime' ].phase ) );\r
        \r
-       console.log( 'トランジション終了' );\r
+       if( !this[ '_anime' ] || this[ '_anime' ].phase !== 2 ){\r
+               // ここで return してしまうと、view の更新イベント待ちの場合、アニメが止まる\r
+               X_Node_Anime_reserved && !X_Node_Anime_updateTimerID && !X_Node_updateTimerID && X_Node_Anime_reserveUpdate( X_Node_Anime_reserved = false );\r
+               return X_Callback_PREVENT_DEFAULT | X_Callback_STOP_PROPAGATION;\r
+       };\r
+       \r
+       this[ '_anime' ].phase = 3;\r
        \r
        X_Node_Anime_onTransition = true;\r
        this[ 'dispatch' ]( { type : X_EVENT_ANIME_END, gpu : this[ '_anime' ].gpuParent } );\r
@@ -424,7 +433,7 @@ function X_Node_Anime_onTransitionEnd( e ){
 function X_Node_Anime_releaseGPULayer(){\r
        var obj = this[ '_anime' ], tmp;\r
        if( !obj ){\r
-               console.log( '_anime無' );\r
+               // console.log( '_anime無' );\r
                return;\r
        };\r
        X_Node_Anime_clearTransition( this );\r
@@ -432,13 +441,13 @@ function X_Node_Anime_releaseGPULayer(){
        X_Node_ANIMATIONS.splice( X_Node_ANIMATIONS.indexOf( this ), 1 );\r
        delete obj.gpuTimerID;\r
        delete this[ '_anime' ];\r
-       console.log( 'GPUレイヤーの破棄を指示' );\r
+       //console.log( 'GPUレイヤーの破棄を指示' );\r
        \r
        X_ViewPort[ 'listenOnce' ]( X_EVENT_AFTER_UPDATE, this, X_Node_Anime_gpuReleased );\r
 };\r
 \r
 function X_Node_Anime_gpuReleased(){\r
-       console.log( 'GPU レイヤーが解放されました' );\r
+       //console.log( 'GPU レイヤーが解放されました' );\r
        this[ 'dispatch' ]( { type : X_EVENT_GPU_RELEASED, gpu : true } );\r
 };\r
 \r
@@ -458,7 +467,7 @@ function X_Node_Anime_clearTransition( xnode ){
 };\r
 \r
 function X_Node_Anime_updatePosition( xnode, x, y, opacity, useGPU ){\r
-       //console.log( 'y : ' + y + ' gpu : ' + !!useGPU );\r
+       // console.log( 'updatePosition y:' + y + ' gpu:' + !!useGPU );\r
        if( X_Node_Anime_hasTransform ){\r
                xnode[ 'css' ]({\r
                        transform : 'translate(' + ( x | 0 ) + 'px,' + ( y | 0 ) + 'px)' + ( useGPU ? X_Node_Anime_translateZ : '' ),\r
index 30779d1..8e1e63d 100644 (file)
@@ -104,7 +104,7 @@ var X_NET_Queue = X_EventDispatcher[ 'inherits' ](
                        \r
                        'Constructor' : function( type, data ){\r
                                this.type = type;\r
-                               this.data = data;                               \r
+                               this.data = data;\r
                                \r
                                //this[ 'listenOnce' ]( X_EVENT_COMPLETE, X_NET_proxyDispatch );\r
                                X_EventDispatcher_systemListen( this, X_EVENT_COMPLETE, X_NET_proxyDispatch );\r
index 4ca0b62..4eb6988 100644 (file)
@@ -68,8 +68,9 @@ X[ 'Net' ][ 'XHR' ] = {
 // Progress Events     Chrome7, firefox3.5, ie10, opera12, Safari?, Chrome for Android 0.16\r
        'PROGRESS'    : false, //\r
 \r
-       'UL_PROGRESS' : false\r
+       'UL_PROGRESS' : false,\r
 \r
+       'CORS'        : X_Net_XHR_X_DOMAIN || ( X_Net_XHR_W3C && X_Net_XHR_W3C.withCredentials !== undefined )\r
 };\r
 \r
 if( X_Net_XHR_W3C || X_Net_XHR_ACTIVE_X ){\r
index 878677a..4212773 100644 (file)
@@ -31,21 +31,6 @@ X.UI = {
                CONTENT : 4  // コンテンツが変更された\r
        },\r
        \r
-       Util : {\r
-               createChecker : function( str ){\r
-                       var ret = {},\r
-                               ary = str.split( ',' ),\r
-                               l   = ary.length,\r
-                               i   = 0, v;\r
-                       for( ; i < l; ){\r
-                               v = ary[ i ];\r
-                               ret[ v ] = ++i;\r
-                               ret[ i ] = v;\r
-                       };\r
-                       return ret;\r
-               }\r
-       },\r
-       \r
        currentRootData : null,\r
        \r
        Layout : {\r
@@ -63,3 +48,26 @@ X.UI = {
        }\r
 };\r
 \r
+/*\r
+ * 'none,chrome,container' を受け取ったら、\r
+ * {\r
+ *     'none' : 1,\r
+ *  'chrome' : 2,\r
+ *  'container' : 3,\r
+ *  1 : 'none',\r
+ *  2 : 'chrome',\r
+ *  3 : 'container'\r
+ * } こんな object を返す。\r
+ */\r
+function XUI_createChecker( str ){\r
+       var ret = {},\r
+               ary = str.split( ',' ),\r
+               l   = ary.length,\r
+               i   = 0, v;\r
+       for( ; i < l; ){\r
+               v = ary[ i ];\r
+               ret[ v ] = ++i;\r
+               ret[ i ] = v;\r
+       };\r
+       return ret;\r
+};\r
index 0ae487f..846a2e2 100644 (file)
@@ -4,61 +4,36 @@ X.UI.Attr = {
        \r
        USER : {\r
                XNODE  : 0,\r
-               UINODE : 1,\r
+               UINODE : 1, // 値は _uinode にコピーされます。\r
                LAYOUT : 2\r
        },\r
        \r
        Type : {\r
-               LIST              :    0,\r
-               LENGTH            :    1, // '1.5em'\r
-               MINUS_LENGTH      :    2,\r
-               PERCENT           :    4, // '90%', 0.0 ~ 1.0 こういう指定はできない!\r
-               MINUS_PERCENT     :    8,\r
-               NUMERICAL         :   16, // 1.1 (lineHeight only)\r
-               AUTO              :   32, // 'auto'\r
-               COLOR             :   64, // 0x000000 ~ 0xFFFFFF, RED, #000000 ~ #FFFFFF, #000 ~ #FFF\r
-               URL               :  128,\r
-               STRING            :  128,\r
-               FONT_NAME         :  256,\r
-               BOOLEAN           :  512,\r
-               COMBI             : 1024,\r
-               QUARTET           : 2048,\r
-               DEFAULT_ONLY      : 4096,\r
-               INIT_ONLY         : 8192\r
+               LIST              : 16384,\r
+               LENGTH            :     1, // '1.5em'\r
+               MINUS_LENGTH      :     2,\r
+               PERCENT           :     4, // '90%', 0.0 ~ 1.0 こういう指定はできない!\r
+               MINUS_PERCENT     :     8,\r
+               NUMERICAL         :    16, // 1.1 (lineHeight only)\r
+               AUTO              :    32, // 'auto'\r
+               COLOR             :    64, // 0x000000 ~ 0xFFFFFF, RED, #000000 ~ #FFFFFF, #000 ~ #FFF\r
+               URL               :   128,\r
+               STRING            :   128,\r
+               FONT_NAME         :   256,\r
+               BOOLEAN           :   512,\r
+               COMBI             :  1024,\r
+               QUARTET           :  2048,\r
+               DEFAULT_ONLY      :  4096,\r
+               INIT_ONLY         :  8192\r
        },\r
        \r
        Option : {\r
-               BORDER_STYLE      : X.UI.Util.createChecker( 'none,hidden,dotted,dashed,solid,double,groove,ridge,inset,outset' ),\r
-               ALIGN             : X.UI.Util.createChecker( 'left,center,right,justify' ),\r
-               TEXT_DECORATION   : X.UI.Util.createChecker( 'none,underline,overline,line-through,blink' ),\r
-               TEXT_TRANSFORM    : X.UI.Util.createChecker( 'none,capitalize,lowercase,uppercase' ),\r
-               BOX_SIZING        : X.UI.Util.createChecker( 'content,padding,border' ),\r
-               CURSOR            : X.UI.Util.createChecker( 'pointer,wait' )\r
-       },\r
-       \r
-       createAttrDef : function( base, defs ){\r
-               var F = base ? X_Object_clone( base ) : {},\r
-                       z = base ? base._last : 0,\r
-                       n = 1,\r
-                       p, def;\r
-               \r
-               // 属性定義の上書き\r
-               for( p in defs ){\r
-                       if( X_EMPTY_OBJECT[ p ] ) continue;\r
-                       if( p === '_last' ) continue;\r
-                       if( !X_Type_isArray( def = defs[ p ] ) ) continue;\r
-                       F[ p ] = def;\r
-                       if( !base || !X_Type_isArray( base[ p ] ) ){\r
-                               def.No = z += n;\r
-                               // add\r
-                               n = def[ 3 ] & X.UI.Attr.Type.QUARTET ? 4 :\r
-                                   def[ 3 ] & X.UI.Attr.Type.COMBI   ? 2 : 1;\r
-                       } else {\r
-                               def.No = base[ p ].No;\r
-                       };\r
-               };\r
-               F._last = z;\r
-               return F;\r
+               BORDER_STYLE      : 'none,hidden,dotted,dashed,solid,double,groove,ridge,inset,outset',\r
+               ALIGN             : 'left,center,right,justify',\r
+               TEXT_DECORATION   : 'none,underline,overline,line-through,blink',\r
+               TEXT_TRANSFORM    : 'none,capitalize,lowercase,uppercase',\r
+               BOX_SIZING        : 'content,padding,border',\r
+               CURSOR            : 'pointer,wait'\r
        },\r
        \r
        CSS3 : {\r
@@ -84,6 +59,34 @@ X.UI.Attr = {
        }\r
 };\r
 \r
+       function XUI_Attr_createAttrDef( base, defs ){\r
+               var F = base ? X_Object_clone( base ) : {},\r
+                       z = base ? base._last : 0,\r
+                       n = 1,\r
+                       p, def;\r
+               \r
+               // 属性定義の上書き\r
+               for( p in defs ){\r
+                       if( X_EMPTY_OBJECT[ p ] ) continue;\r
+                       if( p === '_last' ) continue;\r
+                       if( !X_Type_isArray( def = defs[ p ] ) ) continue;\r
+                       F[ p ] = def;\r
+                       if( !base || !X_Type_isArray( base[ p ] ) ){\r
+                               def.No = z += n;\r
+                               // add\r
+                               n = def[ 3 ] & X.UI.Attr.Type.QUARTET ? 4 :\r
+                                   def[ 3 ] & X.UI.Attr.Type.COMBI   ? 2 : 1;\r
+                       } else {\r
+                               def.No = base[ p ].No;\r
+                       };\r
+                       if( def[ 3 ] & X.UI.Attr.Type.LIST && X_Type_isString( def[ 4 ] ) ){\r
+                               def[ 4 ] = XUI_createChecker( def[ 4 ] );\r
+                       };\r
+               };\r
+               F._last = z;\r
+               return F;\r
+       };\r
+\r
 /*\r
  * 0: 初期値 : undefined は不可!\r
  * 1: dirty\r
@@ -91,20 +94,20 @@ X.UI.Attr = {
  * 3: 受け付けるデータ型\r
  * 4: 選択方式の場合、その候補\r
  */\r
-X.UI.Attr.Support = X.UI.Attr.createAttrDef( false,\r
+X.UI.Attr.Support = XUI_Attr_createAttrDef( 0,\r
 {\r
        className         : [ null,           X.UI.Dirty.CLEAN,  X.UI.Attr.USER.UINODE, X.UI.Attr.Type.DEFAULT_ONLY | X.UI.Attr.Type.STRING ],\r
        pointerHoverClass : [ null,           X.UI.Dirty.CLEAN,  X.UI.Attr.USER.UINODE, X.UI.Attr.Type.DEFAULT_ONLY | X.UI.Attr.Type.STRING ],\r
        pointerDownClass  : [ null,           X.UI.Dirty.CLEAN,  X.UI.Attr.USER.UINODE, X.UI.Attr.Type.DEFAULT_ONLY | X.UI.Attr.Type.STRING ],\r
        invalidLayoutColor: [ null,           X.UI.Dirty.CLEAN,  X.UI.Attr.USER.UINODE, X.UI.Attr.Type.DEFAULT_ONLY | X.UI.Attr.Type.COLOR ],\r
        \r
-       role              : [ 0,              X.UI.Dirty.CLEAN,  X.UI.Attr.USER.UINODE, X.UI.Attr.Type.INIT_ONLY | X.UI.Attr.Type.LIST, 'none,chrome' ],\r
+       role              : [ 1,              X.UI.Dirty.CLEAN,  X.UI.Attr.USER.UINODE, X.UI.Attr.Type.INIT_ONLY | X.UI.Attr.Type.LIST, 'none,chrome' ],\r
        selectable        : [ false,          X.UI.Dirty.CLEAN,  X.UI.Attr.USER.UINODE, X.UI.Attr.Type.INIT_ONLY | X.UI.Attr.Type.BOOLEAN ],\r
        \r
        visible           : [ true,           X.UI.Dirty.LAYOUT, X.UI.Attr.USER.UINODE, X.UI.Attr.Type.BOOLEAN ],\r
        pointerEnabled    : [ false,          X.UI.Dirty.CLEAN,  X.UI.Attr.USER.UINODE, X.UI.Attr.Type.BOOLEAN ],\r
        pointerChildren   : [ true,           X.UI.Dirty.CLEAN,  X.UI.Attr.USER.UINODE, X.UI.Attr.Type.BOOLEAN ],\r
-       cursor            : [ null,           X.UI.Dirty.CLEAN,  X.UI.Attr.USER.UINODE, X.UI.Attr.Type.LIST, X.UI.Attr.Option.CURSOR ],\r
+       cursor            : [ 1,              X.UI.Dirty.CLEAN,  X.UI.Attr.USER.UINODE, X.UI.Attr.Type.LIST, X.UI.Attr.Option.CURSOR ],\r
        tooltip           : [ null,           X.UI.Dirty.CLEAN,  X.UI.Attr.USER.UINODE, X.UI.Attr.Type.STRING ],\r
        \r
        borderWidth       : [ 0,              X.UI.Dirty.LAYOUT, X.UI.Attr.USER.LAYOUT, X.UI.Attr.Type.QUARTET | X.UI.Attr.Type.LENGTH | X.UI.Attr.Type.PERCENT  ], // em [ top, right, bottom, left ]\r
@@ -116,14 +119,14 @@ X.UI.Attr.Support = X.UI.Attr.createAttrDef( false,
        height            : [ X.UI.Attr.AUTO, X.UI.Dirty.LAYOUT, X.UI.Attr.USER.LAYOUT, X.UI.Attr.Type.LENGTH | X.UI.Attr.Type.PERCENT | X.UI.Attr.Type.AUTO ],\r
        minHeight         : [ 0,              X.UI.Dirty.LAYOUT, X.UI.Attr.USER.LAYOUT, X.UI.Attr.Type.LENGTH | X.UI.Attr.Type.PERCENT ],\r
        maxHeight         : [ X.UI.Attr.AUTO, X.UI.Dirty.LAYOUT, X.UI.Attr.USER.LAYOUT, X.UI.Attr.Type.LENGTH | X.UI.Attr.Type.PERCENT | X.UI.Attr.Type.AUTO ],\r
-       sizing            : [ 0,              X.UI.Dirty.LAYOUT, X.UI.Attr.USER.LAYOUT, X.UI.Attr.Type.LIST, X.UI.Attr.Option.BOX_SIZING ],\r
+       sizing            : [ 1,              X.UI.Dirty.LAYOUT, X.UI.Attr.USER.LAYOUT, X.UI.Attr.Type.LIST, X.UI.Attr.Option.BOX_SIZING ],\r
        left              : [ null,           X.UI.Dirty.LAYOUT, X.UI.Attr.USER.LAYOUT, X.UI.Attr.Type.LENGTH | X.UI.Attr.Type.PERCENT | X.UI.Attr.Type.MINUS_LENGTH | X.UI.Attr.Type.MINUS_PERCENT ],\r
        top               : [ null,           X.UI.Dirty.LAYOUT, X.UI.Attr.USER.LAYOUT, X.UI.Attr.Type.LENGTH | X.UI.Attr.Type.PERCENT | X.UI.Attr.Type.MINUS_LENGTH | X.UI.Attr.Type.MINUS_PERCENT ],\r
        bottom            : [ null,           X.UI.Dirty.LAYOUT, X.UI.Attr.USER.LAYOUT, X.UI.Attr.Type.LENGTH | X.UI.Attr.Type.PERCENT | X.UI.Attr.Type.MINUS_LENGTH | X.UI.Attr.Type.MINUS_PERCENT ],\r
        right             : [ null,           X.UI.Dirty.LAYOUT, X.UI.Attr.USER.LAYOUT, X.UI.Attr.Type.LENGTH | X.UI.Attr.Type.PERCENT | X.UI.Attr.Type.MINUS_LENGTH | X.UI.Attr.Type.MINUS_PERCENT ],  \r
 \r
        borderColor       : [ 0x0,            X.UI.Dirty.PAINT,  X.UI.Attr.USER.XNODE,  X.UI.Attr.Type.QUARTET | X.UI.Attr.Type.COLOR   ], // color [ top, right, bottom, left ]\r
-       borderStyle       : [ 0,              X.UI.Dirty.PAINT,  X.UI.Attr.USER.XNODE,  X.UI.Attr.Type.QUARTET | X.UI.Attr.Type.LIST, X.UI.Attr.Option.BORDER_STYLE ], // string [ top, right, bottom, left ]\r
+       borderStyle       : [ 1,              X.UI.Dirty.PAINT,  X.UI.Attr.USER.XNODE,  X.UI.Attr.Type.QUARTET | X.UI.Attr.Type.LIST, X.UI.Attr.Option.BORDER_STYLE ], // string [ top, right, bottom, left ]\r
        bgColor           : [ 0xFFFFFF,       X.UI.Dirty.PAINT,  X.UI.Attr.USER.XNODE,  X.UI.Attr.Type.COLOR     ], // color, none\r
 \r
        fontColor         : [ 0x0,            X.UI.Dirty.PAINT,  X.UI.Attr.USER.XNODE, X.UI.Attr.Type.COLOR     ],\r
@@ -135,9 +138,9 @@ X.UI.Attr.Support = X.UI.Attr.createAttrDef( false,
        lineHeight        : [ 1,              X.UI.Dirty.FONT,   X.UI.Attr.USER.XNODE, X.UI.Attr.Type.NUMERICAL ], // percent\r
        letterSpacing     : [ 0,              X.UI.Dirty.FONT,   X.UI.Attr.USER.XNODE, X.UI.Attr.Type.LENGTH    ],\r
        wordSpacing       : [ 0,              X.UI.Dirty.FONT,   X.UI.Attr.USER.XNODE, X.UI.Attr.Type.LENGTH    ],\r
-       textAlign         : [ 0,              X.UI.Dirty.FONT,   X.UI.Attr.USER.XNODE, X.UI.Attr.Type.LIST, X.UI.Attr.Option.ALIGN           ],\r
-       textDecoration    : [ 0,              X.UI.Dirty.FONT,   X.UI.Attr.USER.XNODE, X.UI.Attr.Type.LIST, X.UI.Attr.Option.TEXT_DECORATION ],\r
-       textTransform     : [ 0,              X.UI.Dirty.FONT,   X.UI.Attr.USER.XNODE, X.UI.Attr.Type.LIST, X.UI.Attr.Option.TEXT_TRANSFORM  ]\r
+       textAlign         : [ 1,              X.UI.Dirty.FONT,   X.UI.Attr.USER.XNODE, X.UI.Attr.Type.LIST, X.UI.Attr.Option.ALIGN           ],\r
+       textDecoration    : [ 1,              X.UI.Dirty.FONT,   X.UI.Attr.USER.XNODE, X.UI.Attr.Type.LIST, X.UI.Attr.Option.TEXT_DECORATION ],\r
+       textTransform     : [ 1,              X.UI.Dirty.FONT,   X.UI.Attr.USER.XNODE, X.UI.Attr.Type.LIST, X.UI.Attr.Option.TEXT_TRANSFORM  ]\r
 }\r
 );\r
 \r
index 893359f..8f38aae 100644 (file)
@@ -6,6 +6,9 @@ X.UI.Event = {
        CREATION_COMPLETE : ++X_Event_last,\r
        REMOVED           : ++X_Event_last,\r
 \r
+       LAYOUT_BEFORE     : ++X_Event_last,\r
+       LAYOUT_COMPLETE   : ++X_Event_last,\r
+\r
        // http://d.hatena.ne.jp/edvakf/20100205/1265338487\r
        // http://d.hatena.ne.jp/uupaa/20100401/1270097629\r
        ENTER_VIEW        : ++X_Event_last, // 要素が視界に入った\r
index 9fd95b8..1f7bd1f 100644 (file)
@@ -91,7 +91,7 @@
                                };\r
                                numTouches = touches.length;\r
                                \r
-                               console.log( 'numTouches ' + numTouches );\r
+                               ///console.log( 'numTouches ' + numTouches );\r
                        } else\r
                        // touch\r
                        if ( type & TOUCH ){ //sourceEventType.match(/touch/)) {\r
index 13af1bc..f649cd5 100644 (file)
@@ -17,7 +17,7 @@ X.UI._AbstractUINode = X_EventDispatcher[ 'inherits' ](
                attrObject        : null,\r
                unverifiedAttrs   : null,\r
                \r
-               role              : null,\r
+               role              : 1,\r
                pointerDisabled   : false,\r
                hoverClassName    : null,\r
                hovering          : false,\r
@@ -30,8 +30,8 @@ X.UI._AbstractUINode = X_EventDispatcher[ 'inherits' ](
                \r
                boxX              : 0,\r
                boxY              : 0,\r
-               scrollWidth       : 0,\r
-               scrollHeight      : 0,          \r
+               scrollWidth       : 0, // remove?\r
+               scrollHeight      : 0, // remove?\r
                boxWidth          : X.UI.Attr.AUTO,\r
                minBoxWidth       : 0,\r
                maxBoxWidth       : X.UI.Attr.AUTO,     \r
@@ -133,6 +133,7 @@ X.UI._AbstractUINode = X_EventDispatcher[ 'inherits' ](
                                } else\r
                                if( list && ( _v = list[ v ] ) ){\r
                                        // good\r
+                                       console.log( v + ' ' + _v );\r
                                        v = _v;\r
                                } else\r
                                if( ( percent || minusPct ) && v.lastIndexOf( '%' ) !== -1 && isFinite( _v = parseFloat( v ) ) && v === _v + '%' ){\r
@@ -216,8 +217,8 @@ X.UI._AbstractUINode = X_EventDispatcher[ 'inherits' ](
                                };\r
 \r
                                if( !X.UI.attrClassProto && user === X.UI.Attr.USER.XNODE && this.xnode ){\r
-                                       this.xnode[ 'css' ]( X.UI.Attr.Rename[ name ] || name, this._createCssText( name ) );\r
-                                       //console.log( ( X.UI.Attr.Rename[ name ] || name ) + ' ' + this._createCssText( name ) + ' ' + propID + ' ' + attrs[ propID ] );\r
+                                       this.xnode[ 'css' ]( X.UI.Attr.Rename[ name ] || name, XUI_AbstractUINode_createCssText( this, name ) );\r
+                                       //console.log( ( X.UI.Attr.Rename[ name ] || name ) + ' ' + XUI_AbstractUINode_createCssText( this, name ) + ' ' + propID + ' ' + attrs[ propID ] );\r
                                };\r
                                return;\r
                        };\r
@@ -260,87 +261,15 @@ X.UI._AbstractUINode = X_EventDispatcher[ 'inherits' ](
                                        attrs[ propID ] = v;\r
                                };\r
                                \r
+                               if( name && user === X.UI.Attr.USER.UINODE ){\r
+                                       this[ name ] = v;\r
+                               };\r
+                               \r
                                if( name && user === X.UI.Attr.USER.XNODE && this.xnode ){\r
-                                       this.xnode[ 'css' ]( X.UI.Attr.Rename[ name ] || name, this._createCssText( name ) );\r
-                                       //console.log( ( X.UI.Attr.Rename[ name ] || name ) + ' ' + this._createCssText( name ) + ' ' + propID + ' ' + attrs[ propID ] );\r
+                                       this.xnode[ 'css' ]( X.UI.Attr.Rename[ name ] || name, XUI_AbstractUINode_createCssText( this, name ) );\r
+                                       //console.log( ( X.UI.Attr.Rename[ name ] || name ) + ' ' + XUI_AbstractUINode_createCssText( this, name ) + ' ' + propID + ' ' + attrs[ propID ] );\r
                                } else\r
-                               if( this.dirty < dirty ) this.dirty = dirty;                                                    \r
-                       };\r
-               },\r
-\r
-               _createCssText : function( name ){\r
-                       var attrs      = this.attrObject || this.attrClass.prototype || X.UI.AttrClass,\r
-                               def        = this.supportAttrs[ name ],\r
-                               no         = def.No,\r
-                               v          = attrs[ def.No ],\r
-                               type       = def[ 3 ],\r
-                               list       = def[ 4 ],\r
-                               flag       = !!( type & X.UI.Attr.Type.BOOLEAN ),\r
-                               combi      = !!( type & X.UI.Attr.Type.COMBI   ),\r
-                               quartet    = !!( type & X.UI.Attr.Type.QUARTET );\r
-\r
-                       if( quartet ){\r
-                               if( attrs[ no + 1 ] === attrs[ no + 3 ] ){\r
-                                       if( v === attrs[ no + 2 ] ){\r
-                                               if( v === attrs[ no + 1 ] ){\r
-                                                       return this._createCssValue( v, type, list );\r
-                                               };\r
-                                               return [\r
-                                                       this._createCssValue( v, type, list ),\r
-                                                       this._createCssValue( attrs[ no + 1 ], type, list )\r
-                                               ].join( ' ' );\r
-                                       };\r
-                                       return [\r
-                                               this._createCssValue( v, type, list ),\r
-                                               this._createCssValue( attrs[ no + 1 ], type, list ),\r
-                                               this._createCssValue( attrs[ no + 2 ], type, list )\r
-                                       ].join( ' ' );\r
-                               };\r
-                               return [\r
-                                       this._createCssValue( v, type, list ),\r
-                                       this._createCssValue( attrs[ no + 1 ], type, list ),\r
-                                       this._createCssValue( attrs[ no + 2 ], type, list ),\r
-                                       this._createCssValue( attrs[ no + 3 ], type, list )\r
-                               ].join( ' ' );\r
-                       } else\r
-                       if( combi ){\r
-                               return [\r
-                                       this._createCssValue( v, type, list ),\r
-                                       this._createCssValue( attrs[ no + 1 ], type, list )\r
-                               ].join( ' ' );\r
-                       } else\r
-                       if( flag ){\r
-                               return v ? list : 'normal'; // \r
-                       };\r
-                       return this._createCssValue( v, type, list );\r
-               },\r
-\r
-               _createCssValue : function( v, type, list ){\r
-                       var length     = !!( type & X.UI.Attr.Type.LENGTH        ),\r
-                               minusLen   = !!( type & X.UI.Attr.Type.MINUS_LENGTH  ),\r
-                               percent    = !!( type & X.UI.Attr.Type.PERCENT       ),\r
-                               minusPct   = !!( type & X.UI.Attr.Type.MINUS_PERCENT ),\r
-                               numerical  = !!( type & X.UI.Attr.Type.NUMERICAL     ),\r
-                               auto       = !!( type & X.UI.Attr.Type.AUTO          ),\r
-                               color      = !!( type & X.UI.Attr.Type.COLOR         ),\r
-                               url        = !!( type & X.UI.Attr.Type.URL           ),\r
-                               fontName   = !!( type & X.UI.Attr.Type.FONT_NAME     );\r
-                       \r
-                       if( X_Type_isNumber( v ) ){\r
-                               if( auto && v === X.UI.Attr.AUTO ) return 'auto';\r
-                               if( length || minusLen ) return v + 'em';\r
-                               if( numerical ) return v;\r
-                               if( list && list[ v ] ) return list[ v ];\r
-                               if( color ){\r
-                                       if( v < 0x100000 ){\r
-                                               v = '00000' + v.toString( 16 );\r
-                                               return '#' + v.substr( v.length - 6 );\r
-                                       };\r
-                                       return '#' + v.toString( 16 );\r
-                               };\r
-                       };\r
-                       if( X_Type_isString( v ) ){\r
-                               if( percent || minusPct || url || fontName ) return v;\r
+                               if( this.dirty < dirty ) this.dirty = dirty;\r
                        };\r
                },\r
 \r
@@ -420,10 +349,10 @@ X.UI._AbstractUINode = X_EventDispatcher[ 'inherits' ](
                        this.xnode\r
                                [ 'css' ]( 'left',        x ? x + 'em' : 0 )\r
                                [ 'css' ]( 'top',         y ? y + 'em' : 0 )\r
-                               [ 'css' ]( 'width',       this.contentWidth  ? X.UI._AbstractUINode.ceil( this.contentWidth  ) + 'em' : 0 )\r
-                               [ 'css' ]( 'height',      this.contentHeight ? X.UI._AbstractUINode.ceil( this.contentHeight ) + 'em' : 0 )\r
-                               [ 'css' ]( 'padding',     this._createCssText( 'padding' ) )\r
-                               [ 'css' ]( 'borderWidth', this._createCssText( 'borderWidth' ) );\r
+                               [ 'css' ]( 'width',       this.contentWidth  ? XUI_AbstractUINode_ceil( this.contentWidth  ) + 'em' : 0 )\r
+                               [ 'css' ]( 'height',      this.contentHeight ? XUI_AbstractUINode_ceil( this.contentHeight ) + 'em' : 0 )\r
+                               [ 'css' ]( 'padding',     XUI_AbstractUINode_createCssText( this, 'padding' ) )\r
+                               [ 'css' ]( 'borderWidth', XUI_AbstractUINode_createCssText( this, 'borderWidth' ) );\r
                },\r
 \r
                /*\r
@@ -431,7 +360,6 @@ X.UI._AbstractUINode = X_EventDispatcher[ 'inherits' ](
                 */\r
                preMesure : function( allowedW, allowedH ){\r
                        var attrs = this.attrObject || this.attrClass.prototype || X.UI.AttrClass,\r
-                               calc  = X.UI._AbstractUINode.calcValue,\r
                                box   = attrs[ X.UI.Attr.Support.sizing.No ],\r
                                min, max,\r
                                boxL, boxT, boxR, boxB,\r
@@ -443,10 +371,10 @@ X.UI._AbstractUINode = X_EventDispatcher[ 'inherits' ](
                        // 自身が constraintW の場合 親が AUTO ではない\r
                        // 自身が constraintW でない場合自身が  AUTO はなくかつ親 が AUTO の場合 or 自身は % でない\r
                        \r
-                       paddingR = calc( attrs[ X.UI.Attr.Support.padding.No + 1 ], allowedW );\r
-                       paddingL = calc( attrs[ X.UI.Attr.Support.padding.No + 3 ], allowedW );\r
-                       borderR  = calc( attrs[ X.UI.Attr.Support.borderWidth.No + 1 ], allowedW );\r
-                       borderL  = calc( attrs[ X.UI.Attr.Support.borderWidth.No + 3 ], allowedW );\r
+                       paddingR = XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.padding.No + 1 ], allowedW );\r
+                       paddingL = XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.padding.No + 3 ], allowedW );\r
+                       borderR  = XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.borderWidth.No + 1 ], allowedW );\r
+                       borderL  = XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.borderWidth.No + 3 ], allowedW );\r
                        boxMinus = 0;\r
                        switch( box ){\r
                                case 3 : // border-box\r
@@ -460,9 +388,9 @@ X.UI._AbstractUINode = X_EventDispatcher[ 'inherits' ](
                        \r
                        if( this.constraintW ? allowedW !== X.UI.Attr.AUTO : !this.autoWidth && ( allowedW !== X.UI.Attr.AUTO || !this.percentWidth ) ){\r
                                if( this.constraintW ){ // 制約レイアウト\r
-                                       contentW = allowedW - ( boxL = calc( attrs[ X.UI.Attr.Support.left.No ], allowedW ) ) - ( boxR = calc( attrs[ X.UI.Attr.Support.right.No ], allowedW ) );\r
+                                       contentW = allowedW - ( boxL = XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.left.No ], allowedW ) ) - ( boxR = XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.right.No ], allowedW ) );\r
                                } else {\r
-                                       contentW = X.UI._AbstractUINode.finalValue( attrs[ X.UI.Attr.Support.width.No ], attrs[ X.UI.Attr.Support.minWidth.No ], attrs[ X.UI.Attr.Support.maxWidth.No ], allowedW );                                    \r
+                                       contentW = XUI_AbstractUINode_calcFinalValue( attrs[ X.UI.Attr.Support.width.No ], attrs[ X.UI.Attr.Support.minWidth.No ], attrs[ X.UI.Attr.Support.maxWidth.No ], allowedW );                                  \r
                                };\r
                                this.contentWidth = contentW + boxMinus;\r
                                this.scrollWidth  = this.contentWidth + this.contentL + this.contentR;\r
@@ -473,8 +401,8 @@ X.UI._AbstractUINode = X_EventDispatcher[ 'inherits' ](
                                delete this.minBoxWidth;\r
                                delete this.maxBoxWidth;\r
                        } else {        \r
-                               this.minContentWidth = calc( attrs[ X.UI.Attr.Support.minWidth.No ], allowedW ) + boxMinus;\r
-                               this.maxContentWidth = calc( attrs[ X.UI.Attr.Support.maxWidth.No ], allowedW ) + boxMinus;\r
+                               this.minContentWidth = XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.minWidth.No ], allowedW ) + boxMinus;\r
+                               this.maxContentWidth = XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.maxWidth.No ], allowedW ) + boxMinus;\r
                                this.scrollWidth     = this.contentWidth + this.contentL + this.contentR;\r
                                this.minBoxWidth     = this.minContentWidth - boxMinus + this.contentL + this.contentR;\r
                                this.maxBoxWidth     = this.maxContentWidth - boxMinus + this.contentL + this.contentR;\r
@@ -484,10 +412,10 @@ X.UI._AbstractUINode = X_EventDispatcher[ 'inherits' ](
                                //delete this.boxSizingOffsetLR;\r
                        };\r
                        \r
-                       paddingT  = calc( attrs[ X.UI.Attr.Support.padding.No + 0 ], allowedH );// paddingTRBL の % 指定は 最大幅に対して TB でも幅に対して\r
-                       paddingB  = calc( attrs[ X.UI.Attr.Support.padding.No + 2 ], allowedH );\r
-                       borderT   = calc( attrs[ X.UI.Attr.Support.borderWidth.No  + 0 ], allowedH );\r
-                       borderB   = calc( attrs[ X.UI.Attr.Support.borderWidth.No  + 2 ], allowedH );\r
+                       paddingT  = XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.padding.No + 0 ], allowedH );// paddingTRBL の % 指定は 最大幅に対して TB でも幅に対して\r
+                       paddingB  = XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.padding.No + 2 ], allowedH );\r
+                       borderT   = XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.borderWidth.No  + 0 ], allowedH );\r
+                       borderB   = XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.borderWidth.No  + 2 ], allowedH );\r
                        boxMinus = 0;\r
                        switch( box ){\r
                                case 3 : // border-box\r
@@ -502,9 +430,9 @@ X.UI._AbstractUINode = X_EventDispatcher[ 'inherits' ](
                        // Height\r
                        if( this.constraintH ? allowedH !== X.UI.Attr.AUTO : !this.autoHeight && ( allowedH !== X.UI.Attr.AUTO || !this.percentHeight ) ){\r
                                if( this.constraintH ){ // 制約レイアウト\r
-                                       contentH = allowedH - ( boxT = calc( attrs[ X.UI.Attr.Support.top.No ], allowedH ) ) - ( boxB = calc( attrs[ X.UI.Attr.Support.bottom.No ], allowedH ) );\r
+                                       contentH = allowedH - ( boxT = XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.top.No ], allowedH ) ) - ( boxB = XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.bottom.No ], allowedH ) );\r
                                } else {\r
-                                       contentH = X.UI._AbstractUINode.finalValue( attrs[ X.UI.Attr.Support.height.No ], attrs[ X.UI.Attr.Support.minHeight.No ], attrs[ X.UI.Attr.Support.maxHeight.No ], allowedH );\r
+                                       contentH = XUI_AbstractUINode_calcFinalValue( attrs[ X.UI.Attr.Support.height.No ], attrs[ X.UI.Attr.Support.minHeight.No ], attrs[ X.UI.Attr.Support.maxHeight.No ], allowedH );\r
                                };                      \r
                                this.contentHeight = contentH + boxMinus;\r
                                this.scrollHeight  = this.contentHeight + this.contentT + this.contentB;\r
@@ -515,8 +443,8 @@ X.UI._AbstractUINode = X_EventDispatcher[ 'inherits' ](
                                delete this.minBoxHeight;\r
                                delete this.maxBoxHeight;\r
                        } else {\r
-                               this.minContentHeight = calc( attrs[ X.UI.Attr.Support.minHeight.No ], allowedH ) + boxMinus;\r
-                               this.maxContentHeight = calc( attrs[ X.UI.Attr.Support.maxHeight.No ], allowedH ) + boxMinus;                           \r
+                               this.minContentHeight = XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.minHeight.No ], allowedH ) + boxMinus;\r
+                               this.maxContentHeight = XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.maxHeight.No ], allowedH ) + boxMinus;                           \r
                                this.minBoxHeight = this.minContentHeight - boxMinus + this.contentT + this.contentB;\r
                                this.maxBoxHeight = this.maxContentHeight - boxMinus + this.contentT + this.contentB;\r
                \r
@@ -528,12 +456,12 @@ X.UI._AbstractUINode = X_EventDispatcher[ 'inherits' ](
                        \r
                        if( this.parentData && this.parentData.layout.overrideAttrsForChild.left ){\r
                                if( this.constraintW ){\r
-                                       this.boxX = ( boxL || boxL === 0 ) ? boxL : calc( attrs[ X.UI.Attr.Support.left.No ], allowedW );\r
+                                       this.boxX = ( boxL || boxL === 0 ) ? boxL : XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.left.No ], allowedW );\r
                                } else\r
                                if( attrs[ X.UI.Attr.Support.right.No ] === null ){\r
-                                       this.boxX = ( boxL || boxL === 0 ) ? boxL : calc( attrs[ X.UI.Attr.Support.left.No ], allowedW );\r
+                                       this.boxX = ( boxL || boxL === 0 ) ? boxL : XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.left.No ], allowedW );\r
                                } else {\r
-                                       this.boxX = alllowW - this.boxWidth - ( ( boxR || boxR === 0 ) ? boxR : calc( attrs[ X.UI.Attr.Support.right.No ], allowedW ) );\r
+                                       this.boxX = alllowW - this.boxWidth - ( ( boxR || boxR === 0 ) ? boxR : XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.right.No ], allowedW ) );\r
                                };\r
                        } else {\r
                                delete this.boxX;\r
@@ -541,12 +469,12 @@ X.UI._AbstractUINode = X_EventDispatcher[ 'inherits' ](
                        \r
                        if( this.parentData && this.parentData.layout.overrideAttrsForChild.top ){\r
                                if( this.constraintH ){\r
-                                       this.boxY = ( boxT || boxT === 0 ) ? boxT : calc( attrs[ X.UI.Attr.Support.top.No ], allowedH );\r
+                                       this.boxY = ( boxT || boxT === 0 ) ? boxT : XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.top.No ], allowedH );\r
                                } else\r
                                if( attrs[ X.UI.Attr.Support.bottom.No ] === null ){\r
-                                       this.boxY = ( boxT || boxT === 0 ) ? boxT : calc( attrs[ X.UI.Attr.Support.top.No ], allowedH );\r
+                                       this.boxY = ( boxT || boxT === 0 ) ? boxT : XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.top.No ], allowedH );\r
                                } else {\r
-                                       this.boxY = allowedH - this.boxHeight - ( ( boxB || boxB === 0 ) ? boxB : calc( attrs[ X.UI.Attr.Support.bottom.No ], allowedH ) );\r
+                                       this.boxY = allowedH - this.boxHeight - ( ( boxB || boxB === 0 ) ? boxB : XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.bottom.No ], allowedH ) );\r
                                };\r
                        } else {\r
                                delete this.boxY;\r
@@ -608,7 +536,7 @@ X.UI._AbstractUINode = X_EventDispatcher[ 'inherits' ](
                                                        if( w - this.boxSizingOffsetLR < this.minContentWidth ) this.contentWidth = this.minContentWidth + this.boxSizingOffsetLR;\r
                                                        this.lastContentWidth = this.contentWidth;\r
                                                        \r
-                                                       w !== this.contentWidth && xnode[ 'css' ]( 'width', X.UI._AbstractUINode.ceil( this.contentWidth ) + 'em' );\r
+                                                       w !== this.contentWidth && xnode[ 'css' ]( 'width', XUI_AbstractUINode_ceil( this.contentWidth ) + 'em' );\r
                                                        \r
                                                        if( h === X.UI.Attr.AUTO ){\r
                                                                this.contentHeight = h = xnode[ 'css' ]( 'height', 'auto' )[ 'scrollHeight' ]() / X_Node_CSS_getCharSize( xnode ); // scrollHeight() ??\r
@@ -623,7 +551,7 @@ X.UI._AbstractUINode = X_EventDispatcher[ 'inherits' ](
                                                } else\r
                                                if( h === X.UI.Attr.AUTO ){\r
                                                        if( w !== this.lastContentWidth ){\r
-                                                               xnode[ 'css' ]( 'width', X.UI._AbstractUINode.ceil( w ) + 'em' );\r
+                                                               xnode[ 'css' ]( 'width', XUI_AbstractUINode_ceil( w ) + 'em' );\r
                                                                \r
                                                                this.lastContentWidth  = w;\r
                                                                this.contentHeight = h = xnode[ 'css' ]( 'height', 'auto' )[ 'scrollHeight' ]() / X_Node_CSS_getCharSize( xnode );\r
@@ -666,7 +594,6 @@ X.UI._AbstractUINode = X_EventDispatcher[ 'inherits' ](
                 */\r
                postMesure : function(){\r
                        var     attrs = this.attrObject || this.attrClass.prototype || X.UI.AttrClass,\r
-                               calc  = X.UI._AbstractUINode.calcValue,\r
                                box   = attrs[ X.UI.Attr.Support.sizing.No ],\r
                                contentW, contentH,\r
                                contentPlus,\r
@@ -677,10 +604,10 @@ X.UI._AbstractUINode = X_EventDispatcher[ 'inherits' ](
                        // Width\r
                        if( this.boxWidth === X.UI.Attr.AUTO ){\r
                                contentW = this.contentWidth;\r
-                               paddingR = calc( attrs[ X.UI.Attr.Support.padding.No + 1 ], contentW );                                 \r
-                               paddingL = calc( attrs[ X.UI.Attr.Support.padding.No + 3 ], contentW );                                 \r
-                               borderR  = calc( attrs[ X.UI.Attr.Support.borderWidth.No + 1 ], contentW );\r
-                               borderL  = calc( attrs[ X.UI.Attr.Support.borderWidth.No + 3 ], contentW );\r
+                               paddingR = XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.padding.No + 1 ], contentW );                                 \r
+                               paddingL = XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.padding.No + 3 ], contentW );                                 \r
+                               borderR  = XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.borderWidth.No + 1 ], contentW );\r
+                               borderL  = XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.borderWidth.No + 3 ], contentW );\r
                                contentPlus = 0;\r
                                switch( box ){\r
                                        case 3 : // border-box\r
@@ -692,8 +619,8 @@ X.UI._AbstractUINode = X_EventDispatcher[ 'inherits' ](
                                \r
                                if( !this.constraintW ){\r
                                        contentW += contentPlus;\r
-                                       min = calc( attrs[ X.UI.Attr.Support.minWidth.No ], contentW );\r
-                                       max = calc( attrs[ X.UI.Attr.Support.maxWidth.No ], contentW );\r
+                                       min = XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.minWidth.No ], contentW );\r
+                                       max = XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.maxWidth.No ], contentW );\r
                                        if( contentW < min && contentPlus < min ){\r
                                                this.contentWidth = min - contentPlus;\r
                                        } else\r
@@ -708,10 +635,10 @@ X.UI._AbstractUINode = X_EventDispatcher[ 'inherits' ](
                        // Height\r
                        if( this.boxHeight === X.UI.Attr.AUTO ){\r
                                contentH    = this.contentHeight;\r
-                               paddingT    = calc( attrs[ X.UI.Attr.Support.padding.No + 0 ], contentH );// paddingTRBL の % 指定は 最大幅に対して TB でも幅に対して\r
-                               paddingB    = calc( attrs[ X.UI.Attr.Support.padding.No + 2 ], contentH );\r
-                               borderT     = calc( attrs[ X.UI.Attr.Support.borderWidth.No  + 0 ], contentH );\r
-                               borderB     = calc( attrs[ X.UI.Attr.Support.borderWidth.No  + 2 ], contentH );\r
+                               paddingT    = XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.padding.No + 0 ], contentH );// paddingTRBL の % 指定は 最大幅に対して TB でも幅に対して\r
+                               paddingB    = XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.padding.No + 2 ], contentH );\r
+                               borderT     = XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.borderWidth.No  + 0 ], contentH );\r
+                               borderB     = XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.borderWidth.No  + 2 ], contentH );\r
                                contentPlus = 0;\r
                                switch( box ){\r
                                        case 3 : // border-box\r
@@ -722,8 +649,8 @@ X.UI._AbstractUINode = X_EventDispatcher[ 'inherits' ](
                                };\r
                                if( !this.constraintH ){\r
                                        contentH += contentPlus;\r
-                                       min = calc( attrs[ X.UI.Attr.Support.minHeight.No ], contentH );\r
-                                       max = calc( attrs[ X.UI.Attr.Support.maxHeight.No ], contentH );\r
+                                       min = XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.minHeight.No ], contentH );\r
+                                       max = XUI_AbstractUINode_calcValue( attrs[ X.UI.Attr.Support.maxHeight.No ], contentH );\r
                                        if( contentH < min && contentPlus < min ){\r
                                                this.contentHeight = min - contentPlus;\r
                                        } else\r
@@ -750,7 +677,9 @@ X.UI._AbstractUINode = X_EventDispatcher[ 'inherits' ](
                        };\r
                },\r
                \r
-               \r
+               /*\r
+                * context を明示しない場合、User が context になる!\r
+                */\r
                listen : function( type, arg1, arg2, arg3 ){\r
                        var root, events, counter, f;\r
                        if( X.UI.Event._START_POINTER <= type && type <= X.UI.Event._END_POINTER ){\r
@@ -777,7 +706,7 @@ X.UI._AbstractUINode = X_EventDispatcher[ 'inherits' ](
                                        };\r
                                };\r
                        };\r
-                       f = X_Callback_classifyCallbackArgs( arg1, arg2, arg3 );\r
+                       arg1 && arg1.kind ? ( f = arg1 ) : ( f = X_Callback_classifyCallbackArgs( arg1, arg2, arg3 ) );\r
                        if( !f.kind ){\r
                                return X_EventDispatcher_listen.call( this, type, this.User, f );\r
                        } else\r
@@ -814,7 +743,7 @@ X.UI._AbstractUINode = X_EventDispatcher[ 'inherits' ](
                                        };\r
                                };\r
                        };\r
-                       f = X_Callback_classifyCallbackArgs( arg1, arg2, arg3 );\r
+                       arg1 && arg1.kind ? ( f = arg1 ) : ( f = X_Callback_classifyCallbackArgs( arg1, arg2, arg3 ) );\r
                        if( !f.kind ){\r
                                return X_EventDispatcher_unlisten.apply( this, [ type, this.User, f ] );\r
                        } else\r
@@ -843,7 +772,83 @@ X.UI._AbstractUINode = X_EventDispatcher[ 'inherits' ](
        }\r
 );\r
 \r
-X.UI._AbstractUINode.calcValue = function( styleValue, srcValue ){\r
+function XUI_AbstractUINode_createCssText( that, name ){\r
+       var attrs      = that.attrObject || that.attrClass.prototype || X.UI.AttrClass,\r
+               def        = that.supportAttrs[ name ],\r
+               no         = def.No,\r
+               v          = attrs[ def.No ],\r
+               type       = def[ 3 ],\r
+               list       = def[ 4 ],\r
+               flag       = !!( type & X.UI.Attr.Type.BOOLEAN ),\r
+               combi      = !!( type & X.UI.Attr.Type.COMBI   ),\r
+               quartet    = !!( type & X.UI.Attr.Type.QUARTET );\r
+\r
+       if( quartet ){\r
+               if( attrs[ no + 1 ] === attrs[ no + 3 ] ){\r
+                       if( v === attrs[ no + 2 ] ){\r
+                               if( v === attrs[ no + 1 ] ){\r
+                                       return XUI_AbstractUINode_createCssValue( v, type, list );\r
+                               };\r
+                               return [\r
+                                       XUI_AbstractUINode_createCssValue( v, type, list ),\r
+                                       XUI_AbstractUINode_createCssValue( attrs[ no + 1 ], type, list )\r
+                               ].join( ' ' );\r
+                       };\r
+                       return [\r
+                               XUI_AbstractUINode_createCssValue( v, type, list ),\r
+                               XUI_AbstractUINode_createCssValue( attrs[ no + 1 ], type, list ),\r
+                               XUI_AbstractUINode_createCssValue( attrs[ no + 2 ], type, list )\r
+                       ].join( ' ' );\r
+               };\r
+               return [\r
+                       XUI_AbstractUINode_createCssValue( v, type, list ),\r
+                       XUI_AbstractUINode_createCssValue( attrs[ no + 1 ], type, list ),\r
+                       XUI_AbstractUINode_createCssValue( attrs[ no + 2 ], type, list ),\r
+                       XUI_AbstractUINode_createCssValue( attrs[ no + 3 ], type, list )\r
+               ].join( ' ' );\r
+       } else\r
+       if( combi ){\r
+               return [\r
+                       XUI_AbstractUINode_createCssValue( v, type, list ),\r
+                       XUI_AbstractUINode_createCssValue( attrs[ no + 1 ], type, list )\r
+               ].join( ' ' );\r
+       } else\r
+       if( flag ){\r
+               return v ? list : 'normal'; // \r
+       };\r
+       return XUI_AbstractUINode_createCssValue( v, type, list );\r
+};\r
+\r
+function XUI_AbstractUINode_createCssValue( v, type, list ){\r
+       var length     = !!( type & X.UI.Attr.Type.LENGTH        ),\r
+               minusLen   = !!( type & X.UI.Attr.Type.MINUS_LENGTH  ),\r
+               percent    = !!( type & X.UI.Attr.Type.PERCENT       ),\r
+               minusPct   = !!( type & X.UI.Attr.Type.MINUS_PERCENT ),\r
+               numerical  = !!( type & X.UI.Attr.Type.NUMERICAL     ),\r
+               auto       = !!( type & X.UI.Attr.Type.AUTO          ),\r
+               color      = !!( type & X.UI.Attr.Type.COLOR         ),\r
+               url        = !!( type & X.UI.Attr.Type.URL           ),\r
+               fontName   = !!( type & X.UI.Attr.Type.FONT_NAME     );\r
+       \r
+       if( X_Type_isNumber( v ) ){\r
+               if( auto && v === X.UI.Attr.AUTO ) return 'auto';\r
+               if( length || minusLen ) return v + 'em';\r
+               if( numerical ) return v;\r
+               if( list && list[ v ] ) return list[ v ];\r
+               if( color ){\r
+                       if( v < 0x100000 ){\r
+                               v = '00000' + v.toString( 16 );\r
+                               return '#' + v.substr( v.length - 6 );\r
+                       };\r
+                       return '#' + v.toString( 16 );\r
+               };\r
+       };\r
+       if( X_Type_isString( v ) ){\r
+               if( percent || minusPct || url || fontName ) return v;\r
+       };\r
+};\r
+\r
+function XUI_AbstractUINode_calcValue( styleValue, srcValue ){\r
        /*\r
         * String の場合は必ず %\r
         */     \r
@@ -854,14 +859,13 @@ X.UI._AbstractUINode.calcValue = function( styleValue, srcValue ){
        return styleValue;\r
 };\r
 \r
-X.UI._AbstractUINode.finalValue = function( styleValue, styleMin, styleMax, srcValue ){\r
-       var calc = X.UI._AbstractUINode.calcValue,\r
-               v    = calc( styleValue, srcValue ),\r
-               min  = calc( styleMin, srcValue ),\r
-               max  = calc( styleMax, srcValue );\r
+function XUI_AbstractUINode_calcFinalValue( styleValue, styleMin, styleMax, srcValue ){\r
+       var v    = XUI_AbstractUINode_calcValue( styleValue, srcValue ),\r
+               min  = XUI_AbstractUINode_calcValue( styleMin, srcValue ),\r
+               max  = XUI_AbstractUINode_calcValue( styleMax, srcValue );\r
        return v <= min ? min : max <= v ? max : v;\r
 };\r
-X.UI._AbstractUINode.ceil = function( v ){\r
+function XUI_AbstractUINode_ceil( v ){\r
        if( 0 <= v ){\r
                return ( v * 10 + 0.999 | 0 ) / 10;\r
        };\r
@@ -939,10 +943,10 @@ X.UI.AbstractUINode = X_Class_create(
                        return X_Class_getPrivate( this )[ 'dispatch' ]( e );\r
                },\r
                        \r
-               getNextNode : function(){\r
+               nextNode : function(){\r
                        \r
                },\r
-               getPrevNode : function(){\r
+               prevNode : function(){\r
                        \r
                },\r
                nodeIndex : function( v ){\r
@@ -979,23 +983,6 @@ X.UI.AbstractUINode = X_Class_create(
                getHeight : function(){\r
                        // dirty の場合、rootData.calculate\r
                        return X_Class_getPrivate( this ).boxHeight;\r
-               },\r
-               scrollTo : function( x, y ){\r
-                       X_Class_getPrivate( this ).scrollTo( x, y );\r
-               },\r
-               getScrollX : function( v ){\r
-                       // dirty の場合、rootData.calculate\r
-                       return X_Class_getPrivate( this ).scrollX( v );\r
-               },\r
-               getScrollY : function( v ){\r
-                       // dirty の場合、rootData.calculate\r
-                       return X_Class_getPrivate( this ).scrollY( v );\r
-               },\r
-               disabled : function( v ){\r
-                       return X_Class_getPrivate( this ).disabled( v );\r
-               },\r
-               cursor : function( v ){\r
-                       return X_Class_getPrivate( this ).cursor( v );\r
                }\r
        }\r
 );\r
index e90abdd..dfe2e15 100644 (file)
@@ -53,6 +53,8 @@ X.UI._Box = X.UI._AbstractUINode.inherits(
        'X.UI._Box',\r
        X_Class.PRIVATE_DATA | X_Class.SUPER_ACCESS, // 現状 super 指定がないとconstructor未定擬時に親のconstructor が使われない\r
        {\r
+               supportAttrs    : XUI_Attr_createAttrDef( X.UI._AbstractUINode.prototype.supportAttrs, X.UI.Layout.Canvas.overrideAttrsForSelf ),\r
+               \r
                layout          : null,\r
                uinodes         : null,\r
                xnodes          : null,\r
@@ -66,9 +68,11 @@ X.UI._Box = X.UI._AbstractUINode.inherits(
 \r
                Constructor : function( layout, args ){\r
                        var i = 0,\r
-                               l = args.length,\r
+                               l = args.length || 1,\r
                                j = -1,\r
-                               uinodes, arg, _data, attrs, support;\r
+                               uinodes, arg, _data, attrs, support, p;\r
+                       \r
+                       //if( !args.length ) args = [ args ];\r
                        \r
                        if( !this.User[ 'instanceOf' ]( X.UI.Box ) ){\r
                                //throw new Error( 'Box を継承したインスタンスだけが _Box のオーナーになれます' );\r
@@ -373,13 +377,13 @@ X.UI.Box.presets = function(){
        };\r
        \r
        if( privateKlass ){\r
-               supports = X.UI.Attr.createAttrDef( privateKlass.prototype.supportAttrs, layout.overrideAttrsForSelf );\r
+               supports = XUI_Attr_createAttrDef( privateKlass.prototype.supportAttrs, layout.overrideAttrsForSelf );\r
                \r
                klass = this.inherits( privateKlass );\r
                privateKlass.prototype.supportAttrs = supports,\r
                privateKlass.prototype.attrClass    = X.UI.Attr.preset( privateKlass.prototype.attrClass, supports, attrs );\r
        } else {\r
-               supports = X.UI.Attr.createAttrDef( shadow.prototype.supportAttrs, layout.overrideAttrsForSelf );\r
+               supports = XUI_Attr_createAttrDef( shadow.prototype.supportAttrs, layout.overrideAttrsForSelf );\r
                \r
                klass = this.inherits(\r
                        boxName,\r
index 14febc5..00b706a 100644 (file)
@@ -5,6 +5,8 @@ X.UI.Layout.Vertical = X.UI.Layout.create( {
        overrideAttrsForSelf : {\r
                selectable  : false,\r
                role        : [ 0,              X.UI.Dirty.CLEAN,  X.UI.Attr.USER.UINODE, X.UI.Attr.Type.INIT_ONLY | X.UI.Attr.Type.LIST, 'none,chrome,container' ],\r
+               width       : [ '100%',         X.UI.Dirty.LAYOUT, X.UI.Attr.USER.LAYOUT, X.UI.Attr.Type.LENGTH | X.UI.Attr.Type.PERCENT | X.UI.Attr.Type.AUTO ],\r
+               height      : [ X.UI.Attr.AUTO, X.UI.Dirty.LAYOUT, X.UI.Attr.USER.LAYOUT, X.UI.Attr.Type.LENGTH | X.UI.Attr.Type.PERCENT | X.UI.Attr.Type.AUTO ],\r
                childWidth  : [ X.UI.Attr.AUTO, X.UI.Dirty.LAYOUT, X.UI.Attr.USER.LAYOUT, X.UI.Attr.Type.LENGTH | X.UI.Attr.Type.PERCENT | X.UI.Attr.Type.AUTO ],\r
                childHeight : [ X.UI.Attr.AUTO, X.UI.Dirty.LAYOUT, X.UI.Attr.USER.LAYOUT, X.UI.Attr.Type.LENGTH | X.UI.Attr.Type.PERCENT | X.UI.Attr.Type.AUTO ],\r
                gapY        : [ 0,              X.UI.Dirty.LAYOUT, X.UI.Attr.USER.LAYOUT, X.UI.Attr.Type.LENGTH ]\r
@@ -34,9 +36,9 @@ X.UI.Layout.Vertical = X.UI.Layout.create( {
                autoW          = contentW === X.UI.Attr.AUTO;\r
                autoH          = contentH === X.UI.Attr.AUTO;\r
                detectionPhase = autoW || autoH;\r
-               gapY           = X.UI._AbstractUINode.calcValue( attrs[ data.supportAttrs.gapY.No ], contentH );\r
-               childW         = X.UI._AbstractUINode.calcValue( attrs[ data.supportAttrs.childWidth.No ], contentW );\r
-               childH         = X.UI._AbstractUINode.calcValue( attrs[ data.supportAttrs.childHeight.No ], contentH );\r
+               gapY           = XUI_AbstractUINode_calcValue( attrs[ data.supportAttrs.gapY.No ], contentH );\r
+               childW         = XUI_AbstractUINode_calcValue( attrs[ data.supportAttrs.childWidth.No ], contentW );\r
+               childH         = XUI_AbstractUINode_calcValue( attrs[ data.supportAttrs.childHeight.No ], contentH );\r
                _x             = data.contentL;\r
                _y             = data.contentT;\r
 \r
index 0fea3ea..52b9bdf 100644 (file)
@@ -4,6 +4,8 @@ X.UI.Layout.Horizontal = X.UI.Layout.create( {
        overrideAttrsForSelf : {\r
                selectable  : false,\r
                role        : [ 0,              X.UI.Dirty.CLEAN,  X.UI.Attr.USER.UINODE, X.UI.Attr.Type.INIT_ONLY | X.UI.Attr.Type.LIST, 'none,chrome,container' ],\r
+               width       : [ '100%',         X.UI.Dirty.LAYOUT, X.UI.Attr.USER.LAYOUT, X.UI.Attr.Type.LENGTH | X.UI.Attr.Type.PERCENT | X.UI.Attr.Type.AUTO ],\r
+               height      : [ X.UI.Attr.AUTO, X.UI.Dirty.LAYOUT, X.UI.Attr.USER.LAYOUT, X.UI.Attr.Type.LENGTH | X.UI.Attr.Type.PERCENT | X.UI.Attr.Type.AUTO ],\r
                childWidth  : [ X.UI.Attr.AUTO, X.UI.Dirty.LAYOUT, X.UI.Attr.USER.LAYOUT, X.UI.Attr.Type.LENGTH | X.UI.Attr.Type.PERCENT | X.UI.Attr.Type.AUTO ],\r
                childHeight : [ X.UI.Attr.AUTO, X.UI.Dirty.LAYOUT, X.UI.Attr.USER.LAYOUT, X.UI.Attr.Type.LENGTH | X.UI.Attr.Type.PERCENT | X.UI.Attr.Type.AUTO ],\r
                gapX        : [ 0,              X.UI.Dirty.LAYOUT, X.UI.Attr.USER.LAYOUT, X.UI.Attr.Type.LENGTH ]\r
@@ -32,9 +34,9 @@ X.UI.Layout.Horizontal = X.UI.Layout.create( {
                autoW          = contentW === X.UI.Attr.AUTO;\r
                autoH          = contentH === X.UI.Attr.AUTO;\r
                detectionPhase = autoW || autoH;\r
-               gapX           = X.UI._AbstractUINode.calcValue( attrs[ data.supportAttrs.gapX.No ], contentW );\r
-               childW         = X.UI._AbstractUINode.calcValue( attrs[ data.supportAttrs.childWidth.No ], contentW );\r
-               childH         = X.UI._AbstractUINode.calcValue( attrs[ data.supportAttrs.childHeight.No ], contentH );\r
+               gapX           = XUI_AbstractUINode_calcValue( attrs[ data.supportAttrs.gapX.No ], contentW );\r
+               childW         = XUI_AbstractUINode_calcValue( attrs[ data.supportAttrs.childWidth.No ], contentW );\r
+               childH         = XUI_AbstractUINode_calcValue( attrs[ data.supportAttrs.childHeight.No ], contentH );\r
                _x             = data.contentL;\r
                _y             = data.contentT;         \r
 \r
index d118565..3856e9c 100644 (file)
@@ -35,10 +35,10 @@ X.UI.Layout.Tile = X.UI.Layout.create( {
                        _x      = data.contentL;\r
                        _y      = data.contentT;\r
                        _w      = data.contentWidth;\r
-                       gapX    = X.UI._AbstractUINode.calcValue( attrs[ data.supportAttrs.gapX.No ], contentW );\r
-                       gapY    = X.UI._AbstractUINode.calcValue( attrs[ data.supportAttrs.gapY.No ], contentH );\r
-                       childW  = X.UI._AbstractUINode.calcValue( attrs[ data.supportAttrs.childWidth.No ], contentW );\r
-                       childH  = X.UI._AbstractUINode.calcValue( attrs[ data.supportAttrs.childHeight.No ], contentH );\r
+                       gapX    = XUI_AbstractUINode_calcValue( attrs[ data.supportAttrs.gapX.No ], contentW );\r
+                       gapY    = XUI_AbstractUINode_calcValue( attrs[ data.supportAttrs.gapY.No ], contentH );\r
+                       childW  = XUI_AbstractUINode_calcValue( attrs[ data.supportAttrs.childWidth.No ], contentW );\r
+                       childH  = XUI_AbstractUINode_calcValue( attrs[ data.supportAttrs.childHeight.No ], contentH );\r
                        numH    = X.UI.Attr.FLOOR( ( _w + gapX ) / ( childW + gapX ) );\r
                        numV    = l % numH ? X.UI.Attr.FLOOR( l / numH ) + 1 : l / numH;\r
                        _h      = _y + data.contentB + ( childH + gapY ) * numH - gapY;\r
index 2fc9bc5..ed1cd7e 100644 (file)
@@ -15,13 +15,14 @@ X.UI._ChromeBox = X.UI._Box.inherits(
 \r
                        for( ; i; ){\r
                                node = uinodes[ --i ];\r
-                               if( node.forContainer === true ){\r
+                               if( node.role === 3 ){\r
                                        if( this.containerNode ){\r
                                                //throw new Error( 'ContainerNode が複数設定されています!ContainerNode はクロームボックスにひとつ、生成時に設定できます ' + node );\r
                                        };\r
-                                       this.containerNode = node;\r
+                                       this.containerNode = node.User;\r
+                                       this._containerNode = node;\r
                                } else {\r
-                                       if( !this.chromeNodes  ) this.chromeNodes = [];\r
+                                       if( !this.chromeNodes ) this.chromeNodes = [];\r
                                        this.chromeNodes[ this.chromeNodes.length ] = node;\r
                                };\r
                        };\r
index 03de673..0191bb0 100644 (file)
@@ -30,14 +30,16 @@ function X_UI_ScrollBox_momentum( current, start, time, lowerMargin, wrapperSize
 \r
 var X_UI_ScrollBox_SUPPORT_ATTRS = {\r
                // スクロール開始するために必要な移動距離、縦か横、どちらか制限する場合、より重要\r
-               directionLockThreshold : [   10, X.UI.Dirty.CLEAN, X.UI.Attr.USER.UINODE, X.UI.Attr.Type.LENGTH ],\r
-               scrollX                : [ true, X.UI.Dirty.CLEAN, X.UI.Attr.USER.UINODE, X.UI.Attr.Type.BOOLEAN ],\r
-               scrollY                : [ true, X.UI.Dirty.CLEAN, X.UI.Attr.USER.UINODE, X.UI.Attr.Type.BOOLEAN ],\r
-               enabled                : [ true, X.UI.Dirty.CLEAN, X.UI.Attr.USER.UINODE, X.UI.Attr.Type.BOOLEAN ],\r
-               bounce                 : [ true, X.UI.Dirty.CLEAN, X.UI.Attr.USER.UINODE, X.UI.Attr.Type.BOOLEAN ],\r
-               bounceTime             : [  600, X.UI.Dirty.CLEAN, X.UI.Attr.USER.UINODE, X.UI.Attr.Type.TIME ],\r
-               useWheel               : [ true, X.UI.Dirty.CLEAN, X.UI.Attr.USER.UINODE, X.UI.Attr.Type.BOOLEAN ],\r
-               useKey                 : [ true, X.UI.Dirty.CLEAN, X.UI.Attr.USER.UINODE, X.UI.Attr.Type.BOOLEAN ],\r
+               directionLockThreshold : [     10, X.UI.Dirty.CLEAN, X.UI.Attr.USER.UINODE, X.UI.Attr.Type.LENGTH ],\r
+               scrollXEnabled         : [   true, X.UI.Dirty.CLEAN, X.UI.Attr.USER.UINODE, X.UI.Attr.Type.BOOLEAN ],\r
+               scrollYEnabled         : [   true, X.UI.Dirty.CLEAN, X.UI.Attr.USER.UINODE, X.UI.Attr.Type.BOOLEAN ],\r
+               scrollEnabled          : [   true, X.UI.Dirty.CLEAN, X.UI.Attr.USER.UINODE, X.UI.Attr.Type.BOOLEAN ],\r
+               bounceEnabled          : [   true, X.UI.Dirty.CLEAN, X.UI.Attr.USER.UINODE, X.UI.Attr.Type.BOOLEAN ],\r
+               bounceTime             : [    600, X.UI.Dirty.CLEAN, X.UI.Attr.USER.UINODE, X.UI.Attr.Type.TIME ],\r
+               useWheel               : [   true, X.UI.Dirty.CLEAN, X.UI.Attr.USER.UINODE, X.UI.Attr.Type.BOOLEAN ],\r
+               useKey                 : [   true, X.UI.Dirty.CLEAN, X.UI.Attr.USER.UINODE, X.UI.Attr.Type.BOOLEAN ],\r
+               hasScrollShadow        : [   true, X.UI.Dirty.CLEAN, X.UI.Attr.USER.UINODE, X.UI.Attr.Type.BOOLEAN ],\r
+               scrollShadowColor      : [ '#000', X.UI.Dirty.CLEAN, X.UI.Attr.USER.UINODE, X.UI.Attr.Type.COLOR ]\r
        };\r
 \r
 \r
@@ -49,28 +51,30 @@ X.UI._ScrollBox = X.UI._ChromeBox.inherits(
                //elmScroller   : null,\r
                //elmScrollbar  : null,\r
                \r
-               supportAttrs   : X.UI.Attr.createAttrDef( X.UI.Attr.Support, X_UI_ScrollBox_SUPPORT_ATTRS ),\r
+               directionLockThreshold : 10,\r
+               scrollXEnabled         : true,\r
+               scrollYEnabled         : true,\r
+               scrollEnabled          : true,\r
+               bounceEnabled          : true,\r
+               momentumEnabled        : true,\r
+               bounceTime             : 600,\r
+               useWheel               : true,\r
+               useKey                 : true,\r
+               hasScrollShadow        : true,\r
+               scrollShadowColor      : '#000',\r
                \r
-               scrolling      : false,\r
+               supportAttrs    : XUI_Attr_createAttrDef( X.UI.Attr.Support, X_UI_ScrollBox_SUPPORT_ATTRS ),\r
+               \r
+               scrolling       : false,\r
                \r
                initiated       : '',\r
                moved               : false,\r
-               distX               : 0,\r
-               distY               : 0,\r
-               directionX      : 0,\r
-               directionY      : 0,\r
                directionLocked : '',\r
                startTime       : 0,\r
                endTime         : 0,\r
                isAnimating     : false,\r
-               startX          : 0,\r
-               startY          : 0,\r
-               absStartX       : 0,\r
-               absStartY       : 0,\r
-               pointX          : 0,\r
-               pointY          : 0,\r
-               maxScrollX      : 0,\r
-               maxScrollY      : 0,\r
+               isInTransition  : false,\r
+\r
                hasHScroll      : false,\r
                hasVScroll      : false,\r
 \r
@@ -78,9 +82,23 @@ X.UI._ScrollBox = X.UI._ChromeBox.inherits(
                wheelTimeout    : 0,\r
                requestFrameID  : 0,\r
                \r
-               _scrollX        : 0,\r
-               _scrollY        : 0,\r
-               scrollXPercent  : 0,\r
+               fontSize        : 0,\r
+               \r
+               scrollX         : 0, // px\r
+               scrollY         : 0, // px\r
+               maxScrollX      : 0, // px\r
+               maxScrollY      : 0, // px\r
+               startX          : 0, // px\r
+               startY          : 0, // px\r
+               absStartX       : 0, // px\r
+               absStartY       : 0, // px\r
+               pointX          : 0, // px\r
+               pointY          : 0, // px\r
+               distX               : 0, // px\r
+               distY               : 0, // px\r
+               directionX      : 0, // px\r
+               directionY      : 0, // px      \r
+               scrollXPercent  : 0, // この値は scroll 不要になっても保持される。 scroll 必要時に参照される\r
                scrollYPercent  : 0,\r
                \r
                lastScrollWidth  : 0,\r
@@ -94,97 +112,49 @@ X.UI._ScrollBox = X.UI._ChromeBox.inherits(
                Constructor : function( layout, args ){\r
                        this[ 'Super' ]( layout, args );\r
                        this._containerNode = X_Class_getPrivate( this.containerNode );\r
+                       this._containerXNode = this._containerNode.xnode[ 'className' ]( 'ScrollSlider' ).listen( X_EVENT_ANIME_END, this, X_UI_ScrollBox_onAnimeEnd );\r
+                       this.xnode[ 'className' ]( 'ScrollBox' );\r
                },\r
                \r
                creationComplete : function(){\r
                        X.UI._Box.prototype.creationComplete.apply( this, arguments );\r
                        this.scrollManager;\r
-                       this._check();\r
                },\r
                \r
                calculate : function(){\r
-                       this.lastScrollWidth  = this.scrollWidth;\r
-                       this.lastScrollHeight = this.scrollHeight;\r
+                       this.lastScrollWidth  = this._containerNode.boxWidth;\r
+                       this.lastScrollHeight = this._containerNode.boxHeight;\r
                        this.lastBoxWidth     = this.boxWidth;\r
                        this.lastBoxHeight    = this.boxHeight;\r
                        \r
                        X.UI._Box.prototype.calculate.apply( this, arguments );\r
                        \r
+                       // TODO root の layout_complete 後に。\r
+                       // TODO calculate 前に scroll の解放。\r
+                       \r
                        if(\r
-                                       this.lastScrollWidth !== this.scrollWidth || this.lastScrollHeight !== this.scrollHeight ||\r
+                                       this.lastScrollWidth  !== this._containerNode.boxWidth ||\r
+                                       this.lastScrollHeight !== this._containerNode.boxHeight ||\r
                                        this.lastBoxWidth    !== this.boxWidth    || this.lastBoxHeight    !== this.boxHeight\r
                                ){\r
-                                       // scroll の停止、GPU の解除\r
-                                       this._check();\r
+                                       X_UI_rootData[ 'listenOnce' ]( X.UI.Event.LAYOUT_COMPLETE, this, X_UI_ScrollBox_onLayoutComplete );\r
                                };\r
-               \r
                },\r
                \r
                scrollBy : function( x, y, opt_time, opt_easing ){\r
-                       this.scrollTo( this.x + x, this.y + y, opt_time, opt_easing );\r
+                       this.scrollTo( this.scrollX + x, this.scrollY + y, opt_time, opt_easing );\r
                },\r
        \r
-               scrollTo : function( x, y, opt_time, opt_easing ){\r
-                       opt_time   = 0 <= opt_time ? opt_time : 0;\r
-                       opt_easing = opt_easing || 'circular';\r
-       \r
-                       this.isInTransition = !!opt_time;\r
-       \r
-                       this.containerNode.animate(\r
-                               {\r
-                                       x : this.x,\r
-                                       y : this.y\r
-                               },\r
-                               {\r
-                                       x : x,\r
-                                       y : y\r
-                               },\r
-                               opt_time, opt_easing, 1000\r
-                       );\r
+               scrollTo : function( x, y, opt_time, opt_easing, opt_release ){\r
+                       //if( this.scrollX === x && this.scrollY === y ) return;\r
+                       \r
+                       opt_time    = 0 <= opt_time ? opt_time : 0;\r
+                       opt_easing  = opt_easing || 'circular';\r
+                       opt_release = 0 <= opt_release ? opt_release : 300;\r
        \r
-                       this.x = x;\r
-                       this.y = y;\r
+                       this.isInTransition = 0 < opt_time;\r
        \r
-                       if( this.indicators ){\r
-                               for( i = this.indicators.length; i--; ){\r
-                                       this.indicators[ i ].updatePosition( opt_time, opt_easing );\r
-                               };\r
-                       };\r
-               },\r
-               \r
-               _check : function(){\r
-                       var needVScroll, needHScroll;\r
-                       if( this.boxWidth < this._containerNode.scrollWidth || this.boxHeight < this._containerNode.scrollHeight ){\r
-                               // scroll\r
-                               if( this.scrolling ){\r
-                                       // fix scroll position from scrollXPercent, scrollYPercent\r
-                                       //\r
-                                       \r
-                               } else {\r
-                                       // create scroller\r
-                                       \r
-                                       \r
-                                       this[ 'listen' ]( X.UI.Event.POINTER_START, X_UI_ScrollBox_onStart );\r
-                                       \r
-                                       \r
-                                       this._move( 0, 0 );\r
-                                       \r
-                                       this.scrolling = true;\r
-                               };\r
-                       } else\r
-                       // no scroll\r
-                       if( this.scrolling ){\r
-                               // remove scroller\r
-                               this[ 'unlisten' ]( X.UI.Event.POINTER_START );\r
-                               \r
-                               ( this._scrollX !== 0 || this._scrollY !== 0 ) && this._move( 0, 0 );\r
-                               \r
-                               delete this.scrolling;\r
-                       };\r
-               },\r
-               \r
-               _move : function( x, y ){\r
-                       \r
+                       X_UI_ScrollBox_translate( this, x, y, opt_time, opt_easing, opt_release );\r
                },\r
                \r
                _remove : function(){\r
@@ -197,16 +167,102 @@ X.UI._ScrollBox = X.UI._ChromeBox.inherits(
        }\r
 );\r
 \r
+function X_UI_ScrollBox_onLayoutBefore( e ){\r
+       //this._containerXNode.stop();\r
+};\r
+\r
+function X_UI_ScrollBox_onLayoutComplete( e ){\r
+       // scroll の停止、GPU の解除\r
+       var font = this.fontSize = this._containerXNode.call( 'fontSize' );\r
+       \r
+       this.maxScrollX = ( this.boxWidth  - this._containerNode.boxWidth ) * font;\r
+       this.maxScrollY = ( this.boxHeight - this._containerNode.boxHeight ) * font;\r
+\r
+       this.hasHScroll = this.scrollXEnabled && this.maxScrollX < 0;\r
+       this.hasVScroll = this.scrollYEnabled && this.maxScrollY < 0;\r
+\r
+       if( !this.hasHScroll ){\r
+               this.maxScrollX  = 0;\r
+               //this.scrollWidth = this.boxWidth;\r
+       };\r
+\r
+       if( !this.hasVScroll ){\r
+               this.maxScrollY   = 0;\r
+               //this.scrollHeight = this.boxHeight;\r
+       };\r
+\r
+       delete this.endTime;\r
+       delete this.directionX;\r
+       delete this.directionY;\r
+\r
+       //this.wrapperOffset = this.xnodeWrapper[ 'offset' ]();\r
+\r
+       //this[ 'dispatch' ]('refresh');\r
+\r
+       X_UI_ScrollBox_resetPosition( this, 0 );\r
+\r
+       if( this.hasHScroll || this.hasVScroll ){\r
+               // scroll が必要。\r
+               if( this.scrolling ){\r
+                       this.scrollTo( this.maxScrollX * this.scrollXPercent, this.maxScrollY * this.scrollYPercent, 100 );\r
+               } else {\r
+                       // scroller 作る\r
+                       this[ 'listen' ]( X.UI.Event._POINTER_DOWN, this, X_UI_ScrollBox_onStart );\r
+                       X_UI_rootData[ 'listen' ]( X.UI.Event.LAYOUT_BEFORE, this, X_UI_ScrollBox_onLayoutBefore );\r
+                       \r
+                       this.scrollTo( this.maxScrollX * this.scrollXPercent, this.maxScrollY * this.scrollYPercent );\r
+                       this.scrolling = true;\r
+               };\r
+       } else\r
+       // scroll 不要\r
+       if( this.scrolling ){\r
+               // scroller 削除\r
+               this[ 'unlisten' ]( X.UI.Event._POINTER_DOWN, this, X_UI_ScrollBox_onStart );\r
+               X_UI_rootData[ 'unlisten' ]( X.UI.Event.LAYOUT_BEFORE,   this, X_UI_ScrollBox_onLayoutBefore );\r
+               \r
+               ( this.scrollX !== 0 || this.scrollY !== 0 ) && this.scrollTo( 0, 0 );\r
+               \r
+               delete this.scrolling;\r
+       };\r
+};\r
+\r
+               function X_UI_ScrollBox_translate( that, x, y, opt_time, opt_easing, opt_release ){\r
+                       \r
+                       opt_time    = 0 <= opt_time ? opt_time : 0;\r
+                       opt_easing  = opt_easing === '' ? '' : opt_easing || 'circular';\r
+                       opt_release = 0 <= opt_release ? opt_release : 300;\r
+                       \r
+                       that._containerXNode.animate(\r
+                               {\r
+                                       x : that.scrollX,\r
+                                       y : that.scrollY\r
+                               },\r
+                               {\r
+                                       x : x | 0,\r
+                                       y : y | 0\r
+                               },\r
+                               opt_time, opt_easing, opt_release\r
+                       );\r
+                       \r
+                       that.scrollX = x | 0;\r
+                       that.scrollY = y | 0;\r
+                       \r
+                       if( that.indicators ){\r
+                               for( i = that.indicators.length; i--; ){\r
+                                       that.indicators[ i ].updatePosition();\r
+                               };\r
+                       };\r
+               };\r
 \r
 function X_UI_ScrollBox_onStart( e ){\r
        var ret = X_Callback_NONE;\r
-                                               \r
+\r
        // React to left mouse button only\r
        if( e.pointerType === 'mouse' && e.button !== 0 ){\r
                return ret;\r
        };\r
-\r
-       if( !this.enabled || ( this.initiated && e.pointerType !== this.initiated ) ){\r
+       \r
+       if( !this.scrollEnabled || ( this.initiated && e.pointerType !== this.initiated ) ){\r
                return ret;\r
        };\r
 \r
@@ -220,22 +276,21 @@ function X_UI_ScrollBox_onStart( e ){
        this.startTime       = X_Timer_now();\r
 \r
        // スクロール中の停止\r
-       if( this.isAnimating ){\r
-               delete this.isAnimating;\r
+       if( this.isInTransition || this.isAnimating ){\r
+               this.isInTransition = this.isAnimating = false;\r
                this[ 'dispatch' ]( X.UI.Event.SCROLL_END );\r
        };                      \r
 \r
-       this.startX    = this.x;\r
-       this.startY    = this.y;\r
-       this.absStartX = this.x;\r
-       this.absStartY = this.y;\r
+       this.startX    = this.scrollX;\r
+       this.startY    = this.scrollY;\r
+       this.absStartX = this.scrollX;\r
+       this.absStartY = this.scrollY;\r
        this.pointX    = e.pageX;\r
        this.pointY    = e.pageY;\r
        \r
-       this[ 'listen' ]( X.UI.Event.POINTER_MOVE, X_UI_ScrollBox_onMove );\r
-       this[ 'listen' ]( X.UI.Event.POINTER_END , X_UI_ScrollBox_onEnd );\r
+       this[ 'listen' ]( X.UI.Event._POINTER_MOVE, this, X_UI_ScrollBox_onMove );\r
+       this[ 'listen' ]( [ X.UI.Event._POINTER_UP, X.UI.Event._POINTER_CANCEL ], this, X_UI_ScrollBox_onEnd );\r
 \r
-       //console.log( 'start : 3' );\r
        return ret | X_Callback_PREVENT_DEFAULT;\r
 };\r
 \r
@@ -246,14 +301,15 @@ function X_UI_ScrollBox_onMove( e ){
                absDistX, absDistY;\r
        // 規定以上の move でスクロール開始\r
        \r
-       if( !this.enabled || e.pointerType !== this.initiated ){\r
+       if( !this.scrollEnabled || e.pointerType !== this.initiated ){\r
                return ret;\r
        };\r
 \r
        // gpu の用意\r
-       if( !this.containerNode[ '_anime' ] ){\r
-               console.log( 'gpuレイヤーの用意' );\r
-               this._translate( this.x, this.y );\r
+       if( !this._containerXNode[ '_anime' ] ){\r
+               //console.log( 'gpuレイヤーの用意 ' + e.pageY );\r
+               //console.log( 'mov1 x:' + this.scrollX + ' y:' + this.scrollY );\r
+               X_UI_ScrollBox_translate( this, this.scrollX, this.scrollY, 0, '', 300 );\r
                return ret;\r
        };\r
 \r
@@ -305,26 +361,29 @@ function X_UI_ScrollBox_onMove( e ){
                this[ 'dispatch' ]( X.UI.Event.SCROLL_MOVE );\r
        };\r
 \r
-       newX = this.x + deltaX;// - this.minusX;\r
-       newY = this.y + deltaY;// - this.minusY;\r
+       newX = this.scrollX + deltaX;// - this.minusX;\r
+       newY = this.scrollY + deltaY;// - this.minusY;\r
 \r
        // Slow down if outside of the boundaries\r
        if( 0 < newX || newX < this.maxScrollX ){\r
-               newX = this.bounce ? this.x + ( deltaX ) / 3 : 0 < newX ? 0 : this.maxScrollX;\r
+               newX = this.bounceEnabled ? this.scrollX + ( deltaX ) / 3 : 0 < newX ? 0 : this.maxScrollX;\r
        };\r
+       \r
        if( 0 < newY || newY < this.maxScrollY ){\r
-               newY = this.bounce ? this.y + ( deltaY ) / 3 : 0 < newY ? 0 : this.maxScrollY;\r
+               //console.log( 'slow... ' + newY + ' ' + this.maxScrollY );\r
+               newY = this.bounceEnabled ? this.scrollY + ( deltaY ) / 3 : 0 < newY ? 0 : this.maxScrollY;\r
        };\r
 \r
        this.directionX = 0 < deltaX ? -1 : deltaX < 0 ? 1 : 0;\r
        this.directionY = 0 < deltaY ? -1 : deltaY < 0 ? 1 : 0;\r
 \r
-       this._translate( newX, newY );\r
+       //console.log( 'mov2 x:' + newX + ' y:' + newY );\r
+       X_UI_ScrollBox_translate( this, newX, newY, 0, '', 300 );\r
 \r
        if( 300 < timestamp - this.startTime ){\r
                this.startTime = timestamp;\r
-               this.startX = this.x;\r
-               this.startY = this.y;\r
+               this.startX = this.scrollX;\r
+               this.startY = this.scrollY;\r
        };\r
        // イベントの拘束\r
        return ret | X_Callback_PREVENT_DEFAULT | X_Callback_MONOPOLY;\r
@@ -336,12 +395,12 @@ function X_UI_ScrollBox_onEnd( e ){
                easing = '',\r
                newX, newY,\r
                momentumX, momentumY,\r
-               duration, distanceX, distanceY;\r
+               duration, distanceX, distanceY, font;\r
                                                \r
-       this[ 'unlisten' ]( X.UI.Event.POINTER_MOVE, X_UI_ScrollBox_onMove );\r
-       this[ 'unlisten' ]( X.UI.Event.POINTER_END,  X_UI_ScrollBox_onEnd );\r
+       this[ 'unlisten' ]( X.UI.Event._POINTER_MOVE, this, X_UI_ScrollBox_onMove );\r
+       this[ 'unlisten' ]( [ X.UI.Event._POINTER_UP, X.UI.Event._POINTER_CANCEL ], this, X_UI_ScrollBox_onEnd );\r
        \r
-       if( !this.enabled || e.pointerType !== this.initiated ){\r
+       if( !this.scrollEnabled || e.pointerType !== this.initiated ){\r
                return ret;\r
        };\r
 \r
@@ -350,13 +409,13 @@ function X_UI_ScrollBox_onEnd( e ){
        this.endTime = X_Timer_now();                   \r
 \r
        duration  = this.endTime - this.startTime;\r
-       newX      = Math.round( this.x );\r
-       newY      = Math.round( this.y );\r
+       newX      = Math.round( this.scrollX );\r
+       newY      = Math.round( this.scrollY );\r
        distanceX = Math.abs(newX - this.startX);\r
        distanceY = Math.abs(newY - this.startY);\r
 \r
        // reset if we are outside of the boundaries\r
-       if( X_UI_ScrollBox_resetPosition( this, this.options.bounceTime ) ){\r
+       if( X_UI_ScrollBox_resetPosition( this, this.bounceTime ) ){\r
                return ret;\r
        };\r
 \r
@@ -365,116 +424,85 @@ function X_UI_ScrollBox_onEnd( e ){
                // this[ 'dispatch' ]( X_EVENT_CANCELED );\r
                return ret;\r
        };\r
-       \r
-       this.scrollTo( newX, newY, 0 ); // ensures that the last position is rounded\r
 \r
        // start momentum animation if needed\r
-       if( this.options.momentum && duration < 300 ){\r
+       if( this.momentumEnabled && duration < 300 ){\r
+               font = this.fontSize;\r
                momentumX = this.hasHScroll ?\r
-                                               X_UI_ScrollBox_momentum( this.x, this.startX, duration, this.maxScrollX, this.options.bounce ? this.wrapperWidth  : 0, this.options.deceleration ) :{ destination: newX, duration: 0 };\r
+                                               X_UI_ScrollBox_momentum( this.scrollX, this.startX, duration, this.maxScrollX, this.bounceEnabled ? this.boxWidth  * font : 0, this.deceleration ) :\r
+                                               { destination: newX, duration: 0 };\r
                momentumY = this.hasVScroll   ?\r
-                                               X_UI_ScrollBox_momentum( this.y, this.startY, duration, this.maxScrollY, this.options.bounce ? this.wrapperHeight : 0, this.options.deceleration ) : { destination: newY, duration: 0 };\r
+                                               X_UI_ScrollBox_momentum( this.scrollY, this.startY, duration, this.maxScrollY, this.bounceEnabled ? this.boxHeight * font : 0, this.deceleration ) :\r
+                                               { destination: newY, duration: 0 };\r
                newX = momentumX.destination;\r
                newY = momentumY.destination;\r
-               time = Math.max( momentumX.duration, momentumY.duration );\r
-               this.isInTransition = 1;\r
+               time = Math.max( momentumX.duration, momentumY.duration ) | 0;\r
+               this.isInTransition = true;\r
+       } else {\r
+               //console.log( '慣性無し' );\r
        };\r
 \r
-       if( newX != this.x || newY != this.y ){\r
+       if( newX != this.scrollX || newY != this.scrollY ){\r
                // change easing function when scroller goes out of the boundaries\r
                if( 0 < newX || newX < this.maxScrollX || 0 < newY || newY < this.maxScrollY ){\r
                        easing = 'quadratic';\r
                };\r
 \r
-               this.scrollTo( newX, newY, time, easing );\r
+               //console.log( 'end2 x:' + newX + ' y:' + newY + ' t:' + time );\r
+               this.scrollTo( newX, newY, time, easing, 1000 );\r
                return ret;\r
        };\r
 \r
+       //console.log( 'end1 x:' + newX + ' y:' + newY );\r
+       this.scrollTo( newX, newY, 0, '', 1000 );       // ensures that the last position is rounded\r
+\r
        this[ 'dispatch' ]( X.UI.Event.SCROLL_END );\r
        \r
        return ret;\r
 };\r
 \r
 function X_UI_ScrollBox_resetPosition( that, time ){\r
-       var x = this.x,\r
-               y = this.y;\r
+       var x = that.scrollX,\r
+               y = that.scrollY;\r
 \r
        time = time || 0;\r
 \r
-       if( !this.hasHScroll || 0 < this.x ){\r
+       if( !that.hasHScroll || 0 < that.scrollX ){\r
                x = 0;\r
        } else\r
-       if( this.x < this.maxScrollX ){\r
-               x = this.maxScrollX;\r
+       if( that.scrollX < that.maxScrollX ){\r
+               x = that.maxScrollX;\r
        };\r
 \r
-       if( !this.hasVScroll || 0 < this.y ){\r
+       if( !that.hasVScroll || 0 < that.scrollY ){\r
                y = 0;\r
        } else\r
-       if( this.y < this.maxScrollY ){\r
-               y = this.maxScrollY;\r
+       if( that.scrollY < that.maxScrollY ){\r
+               y = that.maxScrollY;\r
        };\r
 \r
-       if( x === this.x && y === this.y ){\r
-               console.log( 'no バウンド' );\r
+       if( x === that.scrollX && y === that.scrollY ){\r
+               //console.log( 'no バウンド y:' + y + ' max:' + that.maxScrollY );\r
                return false;\r
        };\r
 \r
-       console.log( 'バウンド!' );\r
-       this.scrollTo( x, y, time, this.options.bounceEasing );\r
+       //console.log( 'バウンド!' );\r
+       //console.log( 'rese x:' + x + ' y:' + y );\r
+       that.scrollTo( x, y, time, that.bounceEasing, 1000 );\r
 \r
        return true;\r
 };\r
 \r
-function X_UI_ScrollBox_translate( x, y ){\r
-       this.containerNode.animate(\r
-               {\r
-                       x : this.x,\r
-                       y : this.y\r
-               },\r
-               {\r
-                       x : x,\r
-                       y : y\r
-               },\r
-               0, '', 300\r
-       );\r
-       \r
-       this.x = x;\r
-       this.y = y;\r
-       \r
-       if( this.indicators ){\r
-               for( i = this.indicators.length; i--; ){\r
-                       this.indicators[ i ].updatePosition();\r
-               };\r
-       };\r
-};\r
-\r
-function X_UI_ScrollBox_refresh( remove ){\r
-       this.maxScrollX = this.boxWidth  - this.containerNode.boxWidth;\r
-       this.maxScrollY = this.boxHeight - this.containerNode.boxHeight;\r
-\r
-       this.hasHScroll = this.User[ 'attr' ]( 'scrollX' ) && this.maxScrollX < 0;\r
-       this.hasVScroll = this.User[ 'attr' ]( 'scrollY' ) && this.maxScrollY < 0;\r
-\r
-       if( !this.hasHScroll ){\r
-               this.maxScrollX    = 0;\r
-               this.scrollerWidth = this.wrapperWidth;\r
+function X_UI_ScrollBox_onAnimeEnd( e ){\r
+       if( e.target !== this._containerXNode || !this.isInTransition ){\r
+               return X_Callback_NONE;\r
        };\r
-\r
-       if( !this.hasVScroll ){\r
-               this.maxScrollY     = 0;\r
-               this.scrollerHeight = this.wrapperHeight;\r
+       //this.xnodeScroller.stop();\r
+       if( !X_UI_ScrollBox_resetPosition( this, this.bounceTime ) ){\r
+               this.isInTransition = false;\r
+               this.dispatch( X.UI.Event.SCROLL_END );\r
        };\r
-\r
-       delete this.endTime;\r
-       delete this.directionX;\r
-       delete this.directionY;\r
-\r
-       this.wrapperOffset = this.xnodeWrapper[ 'offset' ]();\r
-\r
-       //this[ 'dispatch' ]('refresh');\r
-\r
-       X_UI_ScrollBox_resetPosition( this, 0 );\r
+       return X_Callback_NONE;\r
 };\r
 \r
 X.UI.ScrollBox = X.UI.ChromeBox.inherits(\r
@@ -483,7 +511,17 @@ X.UI.ScrollBox = X.UI.ChromeBox.inherits(
        X.UI._ScrollBox,\r
        {\r
                Constructor : function(){\r
-                       var args = [],\r
+                       var args = [\r
+                                               0, // layout                    \r
+                                               {\r
+                                                       name   : 'ScrollBox-Scroller',\r
+                                                       role   : 'container',\r
+                                                       width       : 'auto',\r
+                                                       minWidth    : '100%',\r
+                                                       height      : 'auto',\r
+                                                       minHeight   : '100%'\r
+                                               }\r
+                                       ],\r
                                i    = arguments.length,\r
                                arg, layout;\r
                        \r
@@ -495,24 +533,20 @@ X.UI.ScrollBox = X.UI.ChromeBox.inherits(
                                        args[ args.length ] = arg;\r
                                };\r
                        };\r
-                       /*\r
-                       this.style = DisplayNodeStyle( this,\r
-                               X_Class_newPrivate(\r
-                                       this,\r
-                                       X.UI.Layout.Canvas,\r
-                                       [\r
-                                               Box(\r
-                                                       layout || VerticalLayoutManager,\r
-                                                       {\r
-                                                               name : 'ScrollBox-Scroller',\r
-                                                               role : 'container'\r
-                                                       },\r
-                                                       args\r
-                                               )\r
-                                       ]\r
-                               )\r
+                       \r
+                       args[ 0 ] = X.UI.Layout.Vertical;\r
+                       \r
+                       X_Class_newPrivate(\r
+                               this,\r
+                               X.UI.Layout.Canvas,\r
+                               [\r
+                                       {\r
+                                               width  : '100%',\r
+                                               height : '100%'\r
+                                       },\r
+                                       X.UI.VBox.apply( 0, args )\r
+                               ]\r
                        );\r
-                       this.style.addName( 'ScrollBox' ); */\r
                },\r
                scrollX  : function(){\r
                        \r
index 43fbb74..8890fd4 100644 (file)
@@ -114,7 +114,7 @@ X.UI._PageRoot = X.UI._Box.inherits(
                        } );
                        
                        // hover や rollover rollout のための move イベントの追加
-                       this.xnodeInteractiveLayer[ 'listen' ]( X.UI.Event.IdToName[ X.UI.Event._POINTER_MOVE ], X_UI_eventRellay );
+                       this.xnodeInteractiveLayer[ 'listen' ]( 'pointermove', X_UI_eventRellay );
                        if( counter[ X.UI.Event._POINTER_MOVE ] ){
                                ++counter[ X.UI.Event._POINTER_MOVE ];
                        } else {
@@ -145,12 +145,16 @@ X.UI._PageRoot = X.UI._Box.inherits(
                        };
                },
                calculate : function( e ){
-                       var size = X[ 'ViewPort' ][ 'getSize' ](),
-                               font = X[ 'ViewPort' ][ 'getBaseFontSize' ](),
-                               w    = size[ 0 ],
-                               h    = size[ 1 ];
-                       this.layout.calculate( this, false, 0, 0, w / font, h / font );
+                       var size, font, w, h;
+                       
+                       this[ 'dispatch' ]( X.UI.Event.LAYOUT_BEFORE );
+                       
+                       size = X[ 'ViewPort' ][ 'getSize' ]();
+                       font = X[ 'ViewPort' ][ 'getBaseFontSize' ]();
+                       this.layout.calculate( this, false, 0, 0, size[ 0 ] / font, size[ 1 ] / font );
                        this.calcReserved = false;
+                       
+                       X_ViewPort[ 'listenOnce' ]( X_EVENT_AFTER_UPDATE, this, XUI_PageRoot_onViewUpdate );
                },
                
                updateCoursor : function( cursor ){
@@ -164,6 +168,10 @@ X.UI._PageRoot = X.UI._Box.inherits(
        }
 );
 
+function XUI_PageRoot_onViewUpdate( e ){
+       this[ 'dispatch' ]( X.UI.Event.LAYOUT_COMPLETE );
+};
+
 X.UI.PageRoot = X.UI.Box.presets(
        'PageRoot',
        X.UI._PageRoot,