OSDN Git Service

Version 0.6.107, cleanup X.NodeCSS, fix X.Node.Event for touch, add unescape for...
[pettanr/clientJs.git] / 0.6.x / js / 01_core / 10_XCallback.js
1 \r
2 // ------------------------------------------------------------------------- //\r
3 // ------------ local variables -------------------------------------------- //\r
4 // ------------------------------------------------------------------------- //\r
5 \r
6 var X_Callback_LIVE_LIST        = [],\r
7         X_Callback_POOL_LIST        = [],\r
8         X_Closure_COMMAND_BACK      = X_Callback_LIVE_LIST,\r
9         X_Closure_COMMAND_DROP      = X_Callback_POOL_LIST,\r
10         \r
11         X_Callback_THIS_FUNC        = 1,\r
12         X_Callback_HANDLEEVENT      = 2,\r
13         X_Callback_FUNC_ONLY        = 3,\r
14 \r
15         X_Callback_NONE             =  0,\r
16         X_Callback_UN_LISTEN        =  1,\r
17         X_Callback_STOP_PROPAGATION =  2,  // 上位階層への伝播のキャンセル\r
18         X_Callback_STOP_NOW         =  4 | 2,  // 同一階層のリスナーのキャンセル(上位へもキャンセル)\r
19         X_Callback_PREVENT_DEFAULT  =  8,  // 結果動作のキャンセル,\r
20         X_Callback_MONOPOLY         = 16,  // move event を独占する\r
21         X_Callback_SYS_CANCEL       = 32 | 4 | 2;\r
22 \r
23 /*\r
24  * handleEvent という関数のメンバーを持つオブジェクト\r
25  * @typedef {{ handleEvent : function }}\r
26  */\r
27 var listener;\r
28 \r
29 /*\r
30  * コールバックに thisObject や、追加の引数を設定するための情報を収めたハッシュ\r
31  * @typedef {{ k : number, f : (function|undefined), x : (listener|undefined), s : (Array|undefined) }}\r
32  */\r
33 var callbackHash;\r
34 \r
35 \r
36 X.Callback = {\r
37         NONE             : X_Callback_NONE,\r
38         UN_LISTEN        : X_Callback_UN_LISTEN,\r
39         STOP_PROPAGATION : X_Callback_STOP_PROPAGATION,\r
40         STOP_NOW         : X_Callback_STOP_NOW,\r
41         PREVENT_DEFAULT  : X_Callback_PREVENT_DEFAULT,\r
42         MONOPOLY         : X_Callback_MONOPOLY\r
43 };\r
44 \r
45 // ------------------------------------------------------------------------- //\r
46 // --- implements ---------------------------------------------------------- //\r
47 // ------------------------------------------------------------------------- //\r
48 \r
49 function X_Callback_create( thisObject, opt_callback, opt_args /* [ listener || ( context + function ) || function ][ args... ] */ ){\r
50         var obj = X_Callback_classifyCallbackArgs( thisObject, opt_callback, opt_args ),\r
51                 l, ret, _obj;\r
52         if( !obj.k ) return obj;\r
53         if( l = X_Callback_POOL_LIST.length ){\r
54                 ret    = X_Callback_POOL_LIST[ l - 1 ]; --X_Callback_POOL_LIST.length; // ret = X_Callback_POOL_LIST.pop();\r
55                 _obj   = ret( X_Closure_COMMAND_BACK );\r
56                 _obj.k = obj.k;\r
57                 _obj.f = obj.f;\r
58                 _obj.x = obj.x;\r
59                 _obj.s = obj.s;\r
60                 _obj._ = X_Callback_proxyCallback;\r
61         } else {\r
62                 ret = X_Callback_actualClosure( obj );\r
63                 obj._ = X_Callback_proxyCallback;\r
64         };\r
65         X_Callback_LIVE_LIST[ X_Callback_LIVE_LIST.length ] = ret;\r
66         return ret;\r
67 };\r
68 \r
69 \r
70 function X_Callback_classifyCallbackArgs( arg1, arg2, arg3, alt_context ){\r
71         var obj;\r
72         \r
73         if( arg1 && X.Type.isFunction( arg2 ) ){\r
74                 obj  = { x : arg1, f : arg2, k : X_Callback_THIS_FUNC };\r
75         } else\r
76         if( arg1 && X.Type.isFunction( arg1[ 'handleEvent' ] ) ){\r
77                 obj  = { x : arg1, k : X_Callback_HANDLEEVENT };\r
78                 arg3 = arg2;\r
79         } else\r
80         if( X.Type.isFunction( arg1 ) ){\r
81                 arg3 = arg2;\r
82                 if( alt_context ){\r
83                         obj  = { x : alt_context, f : arg1, k : X_Callback_THIS_FUNC };\r
84                 } else {\r
85                         obj  = { f : arg1, k : X_Callback_FUNC_ONLY };\r
86                 };\r
87         } else\r
88         if( X.Type.isFunction( arg2 ) ){\r
89                 //console.log( 'X_Callback_classifyCallbackArgs : arg1 が ' + arg1 + 'です' ); ie4 で error\r
90                 if( alt_context ){\r
91                         obj  = { x : alt_context, f : arg2, k : X_Callback_THIS_FUNC };\r
92                 } else {\r
93                         obj  = { f : arg2, k : X_Callback_FUNC_ONLY };\r
94                 };\r
95         } else\r
96         if( alt_context ){\r
97                 obj  = { x : alt_context, k : X_Callback_HANDLEEVENT };\r
98                 arg3 = arg1;\r
99         } else {\r
100                 console.log( '不正 ' + arg1 );\r
101                 console.dir( arg1 );\r
102                 return;\r
103         };\r
104         \r
105         if( X.Type.isArray( arg3 )){\r
106                 obj.s = arg3;\r
107         };\r
108         return ( obj.x || obj.s ) ? obj : arg1;\r
109 };\r
110 \r
111 function X_Callback_actualClosure( obj ){\r
112         return function(){\r
113                 if( arguments[ 0 ] === X_Closure_COMMAND_BACK ) return obj;\r
114                 if( arguments[ 0 ] !== X_Closure_COMMAND_DROP ) return obj._( obj, arguments );\r
115         };\r
116 };\r
117 \r
118 function X_Callback_proxyCallback( xfunc, _args ){\r
119         var args    = _args || [],\r
120                 thisObj = xfunc.x,\r
121                 func    = xfunc.f,\r
122                 supp    = xfunc.s,\r
123                 temp, ret;      \r
124         \r
125         if( supp && supp.length ){\r
126                 temp = [];\r
127                 args.length &&\r
128                         (\r
129                                 args.length === 1 ?\r
130                                         ( temp[ 0 ] = args[ 0 ] ) :\r
131                                         temp.push.apply( temp, args )\r
132                         );\r
133                 supp.length === 1 ?\r
134                         ( temp[ temp.length ] = supp[ 0 ] ) :\r
135                         temp.push.apply( temp, supp );\r
136                 args = temp;\r
137         };\r
138         \r
139         switch( xfunc.k ){\r
140 \r
141                 case X_Callback_THIS_FUNC :\r
142                         return args.length === 0 ? func.call( thisObj ) : func.apply( thisObj, args );\r
143                         \r
144                 case X_Callback_HANDLEEVENT :\r
145                         temp = thisObj[ 'handleEvent' ];\r
146                         if( X.Type.isFunction( temp ) ){\r
147                                 return args.length === 0 ? thisObj[ 'handleEvent' ]() :\r
148                                            args.length === 1 ? thisObj[ 'handleEvent' ]( args[ 0 ] ) : temp.apply( thisObj, args );\r
149                         };\r
150                         break;\r
151                         /*\r
152                         if( temp !== func && X.Type.isFunction( temp ) ){\r
153                                 return args.length === 0 ? thisObj[ 'handleEvent' ]() : temp.apply( thisObj, args );\r
154                         } else\r
155                         if( X.Type.isFunction( thisObj ) ){\r
156                                 return args.length === 0 ? thisObj.call( thisObj ) : thisObj.apply( thisObj, args );\r
157                         };\r
158                         return args.length === 0 ? func.call( thisObj ) : func.apply( thisObj, args );*/\r
159                                                 \r
160                 case X_Callback_FUNC_ONLY :\r
161                         return args.length === 0 ?\r
162                                         func() :\r
163                                 args.length === 1 ?\r
164                                         func( args[ 0 ] ) :\r
165                                         func.apply( null, args );\r
166         };\r
167         return X_Callback_NONE;\r
168 };\r
169 \r
170 function X_Callback_correct( f ){\r
171         var i = X_Callback_LIVE_LIST.indexOf( f ),\r
172                 obj;\r
173         if( i !== -1 ){\r
174                 X_Callback_LIVE_LIST.splice( i, 1 );\r
175                 X_Callback_POOL_LIST[ X_Callback_POOL_LIST.length ] = f;\r
176                 obj = f( X_Closure_COMMAND_BACK );\r
177                 delete obj.k;\r
178                 if( obj.f ) delete obj.f;\r
179                 if( obj.x ) delete obj.x;\r
180                 if( obj.s ) delete obj.s;\r
181                 delete obj._;\r
182                 return true;\r
183         };\r
184         return false;\r
185 };\r
186 \r
187 function X_Callback_monitor(){\r
188         return {\r
189                 'Callback:Live' : X_Callback_LIVE_LIST.length,\r
190                 'Callback:Pool' : X_Callback_POOL_LIST.length\r
191         };\r
192 };\r
193 function X_Callback_gc(){\r
194         X_Callback_POOL_LIST.length = 0; // ?\r
195 };\r
196 \r
197 X_TEMP.onSystemReady.push( function( sys ){\r
198         sys.monitor( X_Callback_monitor );\r
199         sys.gc( X_Callback_gc );\r
200 });\r
201 \r
202 \r
203 console.log( 'X.Core.Callback' );\r
204 \r