OSDN Git Service

bug fixes superCall, merge X.UI.Gesture to X.UI.AbstructUINode.
[pettanr/clientJs.git] / 0.6.x / js / 20_ui / 20_Root.js
1 var XUI_rootData        = null,
2         XUI_xnodeIneraction = null,
3         XUI_UINODES_HOVER   = [],
4         XUI_EVENT_COUNTER   = {},
5         XUI_uinodeTarget    = null,
6         XUI_xnodeInteractionOverlay,
7         XUI_interactionBusy = false;
8
9 function X_UI_eventRellay( e ){
10         var font    = X_ViewPort_baseFontSize,
11                 x       = e.pageX / font, // clientX は iOS4- で通らない?
12                 y       = e.pageY / font,
13                 type    = XUI_Event.NameToID[ e.type ],
14                 i       = 0,
15                 data    = XUI_rootData,
16                 sysOnly = false,
17                 ret     = X_CALLBACK_NONE,
18                 list, parent, _ret, eventIn, eventOut;
19
20         // mouseup で alert を出すと mouseleave が発生、ということでイベント中のイベント発火を禁止
21         if( !data || XUI_interactionBusy ) return ret;
22         
23         XUI_interactionBusy = true;
24
25         e = X_Object_copy( e );
26         e.type = type;
27
28         // TODO capture は pointer 毎に!
29         list = XUI_UINODES_HOVER;
30         ( XUI_uinodeTarget = XUI_rootData ).capcher( x, y );
31         data = XUI_uinodeTarget;
32
33         while( data ){
34                 _ret = data[ 'dispatch' ]( e, sysOnly );
35                 ret |= _ret;
36                 if( type < XUI_Event._START_BUBLEUP || ret & X_CALLBACK_STOP_PROPAGATION ){
37                         break;
38                 };
39                 data = data.parentData;
40         };
41
42         for( i = list.length; i; ){
43                 parent = data = list[ --i ];
44                 while( parent.parentData && parent === parent.parentData.hitChildData ){
45                         parent = parent.parentData;
46                 };
47                 if( parent !== XUI_rootData ){
48                         if( data[ '_listeners' ] && data[ '_listeners' ][ XUI_Event.POINTER_OUT ] ){
49                                 if( !eventOut ){
50                                         eventOut = X_Object_copy( e );
51                                         eventOut.type = XUI_Event.POINTER_OUT;                                  
52                                 };
53                                 data[ 'dispatch' ]( eventOut, false );
54                         };
55                         delete data.hovering;
56                         list.splice( i, 1 );
57                 } else
58                 if( !data.hovering ){
59                         if( data[ '_listeners' ] && data[ '_listeners' ][ XUI_Event.POINTER_IN ] ){
60                                 if( !eventIn ){
61                                         eventIn = X_Object_copy( e );
62                                         eventIn.type = XUI_Event.POINTER_IN;                            
63                                 };
64                                 data[ 'dispatch' ]( eventIn, true );
65                         };
66                         data.hovering = true;
67                 };
68         };
69         XUI_interactionBusy = false;
70         return ret | X_CALLBACK_PREVENT_DEFAULT;
71 };
72
73 function X_UI_onMouseOut( e ){
74         var list = XUI_UINODES_HOVER,
75                 i = list.length;
76         console.log( 'pointer out!!' + e.type + i + ' ' + e.pointerType );
77
78         e = X_Object_copy( e );
79         e.type = XUI_Event.POINTER_OUT;
80         
81         for( ; i; ){
82                 data = list[ --i ];
83                 data[ '_listeners' ] && data[ '_listeners' ][ XUI_Event.POINTER_OUT ] && data[ 'dispatch' ]( e, false ); // new Event
84                 delete data.hovering;
85         };
86         list.length = 0;
87 };
88
89 /*
90  * body が存在したら要素を作成、css も指定
91  * 背景画像を読み終える onload で活動開始
92  */
93
94 var XUI_Root = XUI_Box.inherits(
95         '_Root',
96         X_Class.FINAL,
97         {
98                 layout                : XUI_Layout_Canvas,
99                 
100                 calcReserved          : false,
101                 
102                 cursorStyle           : null,
103                 
104                 Constructor : function( user, layout, args ){
105                         this[ 'Super' ]( user, layout, args );
106                         
107                         if( X_ViewPort_readyState === X_EVENT_XDOM_READY ){
108                                 X_Timer_once( 0, this, this.start );
109                         } else {
110                                 X_ViewPort[ 'listenOnce' ]( X_EVENT_XDOM_READY, this, this.start );
111                         };
112                         
113                         XUI_rootData = this;
114                 },
115                 
116                 start : function(){
117
118                         
119                         this.initialize( this.User, this, null, null );
120                         X_Timer_once( 0, this, this.addToView );
121                 },
122                 addToView : function(){
123                         // XUI_xnodeInteractionOverlay の前に追加する!
124                         this.addToParent( X_Node_body );
125                         
126                         XUI_xnodeInteractionOverlay = X_Node_body.create( 'div', {
127                                 'class'      : 'mouse-operation-catcher',
128                                 unselectable : 'on'
129                         } );
130                         
131                         X_Node_body[ 'listen' ]( 'pointerleave', this, X_UI_onMouseOut );
132                         
133                         // hover や rollover rollout のための move イベントの追加
134                         // TODO この切り替えを ViewPort へ
135                         XUI_xnodeIneraction = ( X_UA[ 'IE' ] < 9 ? X_ViewPort_document : X_UA[ 'Opera' ] < 8 ? X_Node_body : X_ViewPort );
136                         XUI_xnodeIneraction[ 'listen' ]( 'pointermove', X_UI_eventRellay );
137                         
138                         if( XUI_EVENT_COUNTER[ XUI_Event._POINTER_MOVE ] ){
139                                 ++XUI_EVENT_COUNTER[ XUI_Event._POINTER_MOVE ];
140                         } else {
141                                 XUI_EVENT_COUNTER[ XUI_Event._POINTER_MOVE ] = 1;
142                         };
143
144                         X_Timer_once( 0, this, this.afterAddToView );
145                 },
146                 afterAddToView : function(){
147                         this.xnode[ 'className' ]( 'Root' );
148                         
149                         this.creationComplete();
150                         X_Timer_once( 0, this, XUI_Root_do1stCalculate );
151                 },
152                 
153                 reserveCalc : function(){
154                         if( this.calcReserved === false ){
155                                 this.calcReserved = true;
156                                 X_Timer_once( 0, this, this.calculate );
157                         };
158                 },
159                 calculate : function( e ){
160                         var cancelable = !e || ( e.type !== X_EVENT_VIEW_RESIZED && e.type !== X_EVENT_BASE_FONT_RESIZED ),
161                                 size, font, w, h;
162                         
163                         if( ( this[ 'dispatch' ]( { type : XUI_Event.LAYOUT_BEFORE, 'cancelable' : cancelable } ) & X_CALLBACK_PREVENT_DEFAULT ) && cancelable ){
164                                 return X_CALLBACK_NONE;
165                         };
166                         
167                         size = X[ 'ViewPort' ][ 'getSize' ]();
168                         font = X[ 'ViewPort' ][ 'getBaseFontSize' ]();
169                         this.layout.calculate( this, false, 0, 0, size[ 0 ] / font, size[ 1 ] / font );
170                         this.updateLayout();
171                         
172                         this.calcReserved = false;
173                         
174                         X_ViewPort[ 'listenOnce' ]( X_EVENT_AFTER_UPDATE, this, XUI_Root_onViewUpdate );
175                         
176                         return X_CALLBACK_NONE;
177                 },
178                 
179                 updateCoursor : function( cursor ){
180                         
181                 },
182                 
183                 _remove : function(){
184                         X_EventDispatcher_unlistenAll( XUI_xnodeInteractionOverlay );
185                         _Box.prototype._remove.call( this );
186                 }
187         }
188 );
189
190 function XUI_Root_do1stCalculate(){
191         this.calculate();
192         this.phase = 4;
193         X_ViewPort
194                 [ 'listen' ]( X_EVENT_VIEW_RESIZED, this, this.calculate )
195                 [ 'listen' ]( X_EVENT_BASE_FONT_RESIZED, this, this.calculate );
196 };
197
198 function XUI_Root_onViewUpdate( e ){
199         this[ 'dispatch' ]( XUI_Event.LAYOUT_COMPLETE );
200 };
201
202 //var XUI_Root;
203 // TODO singleton
204 X.UI.Root = X.UI.Box.inherits(
205         'Root',
206         X_Class.NONE,
207         {
208                 Constructor : function(){
209                         var supports;
210                         
211                         //if( !XUI_Root ){
212                                 supports = XUI_Attr_createAttrDef( XUI_Box.prototype.usableAttrs, XUI_Layout_Canvas.overrideAttrsForSelf );
213                                 
214                                 //XUI_Root.prototype.layout       = XUI_Layout_Canvas;
215                                 XUI_Root.prototype.usableAttrs = supports;
216                                 XUI_Root.prototype.attrClass    = XUI_Attr_preset( XUI_Box.prototype.attrClass, supports, {
217                                                                         width  : '100%',
218                                                                         height : '100%'
219                                                                 } );
220                         //};
221                         X_Pair_create( this, XUI_Root( this, XUI_Layout_Canvas, arguments ) );
222                 }
223         });
224 /*
225 X.UI.Root = X.UI.Box.presets(
226         'Root',
227         XUI_Root,
228         {
229                 width  : '100%',
230                 height : '100%'
231         }
232 );*/
233