1 var XUI_rootData = null,
2 XUI_xnodeIneraction = null,
3 XUI_mousemoveFix = X_UA[ 'WinPhone' ] && X_UA[ 'IE9' ],
4 XUI_mousemoveFixOn = 0,
7 XUI_mousemoveFixLast = null,
8 XUI_UINODES_HOVER = [],
9 XUI_EVENT_COUNTER = {},
10 XUI_uinodeTarget = null,
11 XUI_xnodeInteractionOverlay,
12 XUI_interactionBusy = false;
14 function XUI_mousemoveFixResetScroll(){
15 var raw = XUI_xnodeInteractionOverlay[ '_rawObject' ];
17 if( XUI_mousemoveFix ){
18 XUI_mousemoveFixX = raw.scrollLeft = raw.offsetWidth;
19 XUI_mousemoveFixY = raw.scrollTop = raw.offsetHeight;
23 function XUI_mousemoveFixScrollEnd(){
24 var raw = XUI_xnodeInteractionOverlay[ '_rawObject' ];
26 XUI_mousemoveFixOn = 0;
27 XUI_mousemoveFixLast.type = 'pointerup';
28 X_UI_eventRellay( XUI_mousemoveFixLast );
30 raw.scrollLeft = XUI_mousemoveFixX;
31 raw.scrollTop = XUI_mousemoveFixY;
34 function X_UI_eventRellay( e ){
35 var font = X_ViewPort_baseFontSize,
36 x = e.pageX, // clientX は iOS4- で通らない?
38 type = XUI_Event.NameToID[ e.type ],
42 ret = X_CALLBACK_NONE,
43 list = XUI_UINODES_HOVER,
44 raw, parent, _ret, eventIn, eventOut;
46 // mouseup で alert を出すと mouseleave が発生、ということでイベント中のイベント発火を禁止
47 if( XUI_interactionBusy ) return ret;
49 XUI_interactionBusy = true;
51 if( XUI_mousemoveFix ){
52 if( e.type === 'scroll' ){
53 raw = XUI_xnodeInteractionOverlay[ '_rawObject' ];
54 type = XUI_mousemoveFixOn ? XUI_Event._POINTER_MOVE : XUI_Event._POINTER_DOWN;
55 x = XUI_mousemoveFixX - raw.scrollLeft;
56 y = XUI_mousemoveFixY - raw.scrollTop;
60 e[ 'timestamp' ] = e[ 'timeStamp' ];
62 e[ 'pointerType' ] = 'mouse';
64 XUI_mousemoveFixOn && X_Timer_remove( XUI_mousemoveFixOn );
65 XUI_mousemoveFixOn = X_Timer_once( 250, XUI_mousemoveFixScrollEnd );
66 XUI_mousemoveFixLast = X_Object_copy( e );
70 e = X_Object_copy( e );
73 // capture は pointer 毎に!
74 data.capcher( x / font, y / font );
75 data = XUI_uinodeTarget || data;
78 _ret = data[ 'dispatch' ]( e, sysOnly ) || X_CALLBACK_NONE;
80 if( type < XUI_Event._START_BUBLEUP || ret & X_CALLBACK_STOP_PROPAGATION ){
83 data = data.parentData;
86 for( i = list.length; i; ){
87 parent = data = list[ --i ];
88 while( parent.parentData && parent === parent.parentData.hitChildData ){
89 parent = parent.parentData;
91 if( parent !== XUI_rootData ){
92 if( data[ '_listeners' ] && data[ '_listeners' ][ XUI_Event.POINTER_OUT ] ){
94 eventOut = X_Object_copy( e );
95 eventOut.type = XUI_Event.POINTER_OUT;
97 data[ 'dispatch' ]( eventOut, false );
102 if( !data.hovering ){
103 if( data[ '_listeners' ] && data[ '_listeners' ][ XUI_Event.POINTER_IN ] ){
105 eventIn = X_Object_copy( e );
106 eventIn.type = XUI_Event.POINTER_IN;
108 data[ 'dispatch' ]( eventIn, true );
110 data.hovering = true;
113 XUI_interactionBusy = false;
114 return ret | X_CALLBACK_PREVENT_DEFAULT;
117 function X_UI_onMouseOut( e ){
118 var list = XUI_UINODES_HOVER,
120 console.log( 'pointer out!!' + e.type + i + ' ' + e.pointerType );
122 e = X_Object_copy( e );
123 e.type = XUI_Event.POINTER_OUT;
127 data[ '_listeners' ] && data[ '_listeners' ][ XUI_Event.POINTER_OUT ] && data[ 'dispatch' ]( e, false ); // new Event
128 delete data.hovering;
134 * body が存在したら要素を作成、css も指定
135 * 背景画像を読み終える onload で活動開始
138 var XUI_Root = XUI_Box.inherits(
142 layout : XUI_Layout_Canvas,
144 calcReserved : false,
148 Constructor : function( user, layout, args ){
149 this[ 'Super' ]( user, layout, args );
151 if( X_ViewPort_readyState === X_EVENT_XDOM_READY ){
152 X_Timer_once( 0, this, this.start );
154 X_ViewPort[ 'listenOnce' ]( X_EVENT_XDOM_READY, this, this.start );
161 this.initialize( this.User, this, null, null );
162 X_Timer_once( 0, this, this.addToView );
164 addToView : function(){
165 // XUI_xnodeInteractionOverlay の前に追加する!
166 this.addToParent( X_Node_body );
168 XUI_xnodeInteractionOverlay = X_Node_body.create( 'div', {
169 'class' : XUI_mousemoveFix ? 'mouse-operation-catcher-scrollFix' : 'mouse-operation-catcher',
173 X_Node_body[ 'listen' ]( 'pointerleave', this, X_UI_onMouseOut );
175 // hover や rollover rollout のための move イベントの追加
176 // TODO この切り替えを ViewPort へ
177 XUI_xnodeIneraction = ( X_UA[ 'IE' ] < 9 ? X_ViewPort_document : X_UA[ 'Opera' ] < 8 ? X_Node_body : X_ViewPort );
179 if( XUI_mousemoveFix ){
180 XUI_xnodeInteractionOverlay[ 'listen' ]( [ 'scroll', 'mouseup' ], X_UI_eventRellay )[ 'create' ]( 'div' );
182 XUI_xnodeIneraction[ 'listen' ]( 'pointermove', X_UI_eventRellay );
185 if( XUI_EVENT_COUNTER[ XUI_Event._POINTER_MOVE ] ){
186 ++XUI_EVENT_COUNTER[ XUI_Event._POINTER_MOVE ];
188 XUI_EVENT_COUNTER[ XUI_Event._POINTER_MOVE ] = 1;
191 X_Timer_once( 0, this, this.afterAddToView );
193 afterAddToView : function(){
194 this.xnode[ 'className' ]( 'Root' );
196 this.creationComplete();
197 X_Timer_once( 0, this, XUI_Root_do1stCalculate );
200 reserveCalc : function(){
201 if( !this.calcReserved ){
202 this.calcReserved = true;
203 X_Timer_once( 0, this, this.calculate );
206 calculate : function( e ){
207 var cancelable = !e || ( e.type !== X_EVENT_VIEW_RESIZED && e.type !== X_EVENT_BASE_FONT_RESIZED ),
210 if( ( this[ 'dispatch' ]( { type : XUI_Event.LAYOUT_BEFORE, 'cancelable' : cancelable } ) & X_CALLBACK_PREVENT_DEFAULT ) && cancelable ){
211 console.log( 'Layout のキャンセル' );
212 return X_CALLBACK_NONE;
215 console.log( 'レイアウト開始' );
217 XUI_mousemoveFix && XUI_mousemoveFixResetScroll();
219 size = X[ 'ViewPort' ][ 'getSize' ]();
220 font = X[ 'ViewPort' ][ 'getBaseFontSize' ]();
221 this.layout.calculate( this, false, 0, 0, size[ 0 ] / font, size[ 1 ] / font );
224 this.calcReserved = false;
226 // size を測りながらレイアウトする結果、アップデートがない場合がある
227 if( X_Node_updateTimerID ){
228 X_ViewPort[ 'listenOnce' ]( X_EVENT_AFTER_UPDATE, this, XUI_Root_onViewUpdate );
230 this[ 'asyncDispatch' ]( XUI_Event.LAYOUT_COMPLETE );
233 return X_CALLBACK_NONE;
236 updateCoursor : function( cursor ){
242 function XUI_Root_do1stCalculate(){
246 [ 'listen' ]( X_EVENT_VIEW_RESIZED, this, this.calculate )
247 [ 'listen' ]( X_EVENT_BASE_FONT_RESIZED, this, this.calculate );
250 function XUI_Root_onViewUpdate( e ){
251 console.log( 'レイアウト完了' );
252 this[ 'dispatch' ]( XUI_Event.LAYOUT_COMPLETE );
257 X.UI.Root = X.UI.Box.inherits(
261 Constructor : function(){
265 supports = XUI_Attr_createAttrDef( XUI_Box.prototype.usableAttrs, XUI_Layout_Canvas.overrideAttrsForSelf );
267 //XUI_Root.prototype.layout = XUI_Layout_Canvas;
268 XUI_Root.prototype.usableAttrs = supports;
269 XUI_Root.prototype.attrClass = XUI_Attr_preset( XUI_Box.prototype.attrClass, supports, {
274 X_Pair_create( this, XUI_Root( this, XUI_Layout_Canvas, arguments ) );
278 X.UI.Root = X.UI.Box.presets(