OSDN Git Service

version 0.5.1 bugfix.
[pettanr/clientJs.git] / 0.5.x / javascripts / system.js
1 /*\r
2  * http://pettanr.sourceforge.jp/test/type.html\r
3  */\r
4         var Type = {\r
5                 isObject : function(v) {\r
6                         return v !== null && typeof v === 'object';\r
7                 },\r
8                 isFunction : function(v) {\r
9                         return typeof v === 'function';\r
10                 },\r
11                 isArray : function(v) {\r
12                         return Object.prototype.toString.call(v) === "[object Array]";\r
13                 },\r
14                 isBoolean : function(v) {\r
15                         return typeof v === 'boolean';\r
16                 },\r
17                 isString : function(v) {\r
18                         return typeof v === 'string';\r
19                 },\r
20                 isNumber : function(v) {\r
21                         return typeof v === 'number';\r
22                 },\r
23                 isFinite : function(v){\r
24                         return Type.isNumber(v) === true && isFinite(v);\r
25                 },\r
26                 isHTMLElement : function(v){\r
27                         if( 'HTMLElement' in window ){\r
28                                 Type.isHTMLElement = function(v){\r
29                                         return v instanceof HTMLElement;\r
30                                 }\r
31                         } else {\r
32                                 Type.isHTMLElement = function(v) {\r
33                                         if( Type.isObject(v) === false ){\r
34                                                 return false;\r
35                                         }\r
36                                         var r;\r
37                                         if(v && v.nodeType === 1){\r
38                                                 try{\r
39                                                         r = v.cloneNode(false);\r
40                                                 } catch(n) {\r
41                                                         return false;\r
42                                                 }\r
43                                                 if(r === v) return false;\r
44                                                 try{\r
45                                                         r.nodeType = 9;\r
46                                                         return r.nodeType === 1;\r
47                                                 } catch(n) {}\r
48                                                 return true;\r
49                                         }\r
50                                         return false;\r
51                                 }\r
52                         }\r
53                         return Type.isHTMLElement(v);\r
54                 },\r
55                 /*\r
56                 isElementCollection : function(v) {\r
57                         return (Object.prototype.toString.call(v) === "[object HTMLCollection]");\r
58                 },\r
59                 */\r
60                 isNull : function(v) {\r
61                         return v === null;\r
62                 },\r
63                 isUndefined : function(v) {\r
64                         return typeof v === 'undefined';\r
65                 }\r
66         };\r
67 \r
68 /* ----------------------------------------------------\r
69  * Util\r
70  * \r
71  *   extend( baseInstance, extend)\r
72  *   cleanCommnetNode()\r
73  *   cleanElement()\r
74  *   getElementSize( _elm)\r
75  *   getImageSize()\r
76  *   getAbsolutePath()\r
77  *   getGrobalObjectName()\r
78  * \r
79  */\r
80         var Util = ( function(){\r
81                 var ELM_SIZE_GETTER = ( function(){\r
82                                 var ret = document.createElement( 'DIV' ),\r
83                                         style = ret.style;\r
84                                 ret.id = 'elmSizeGetter';\r
85                                 style.position = 'absolute';\r
86                                 style.left = '0px';\r
87                                 style.top = '-9999px';\r
88                                 style.visibility = 'hidden';\r
89                                 document.body.appendChild( ret);\r
90                                 return ret;\r
91                         })(),\r
92                         IMG_SIZE_GETTER = ( function(){\r
93                                 var ret = ELM_SIZE_GETTER.cloneNode( true );\r
94                                 ret.id = 'imgSizeGetter';\r
95                                 document.body.appendChild( ret);\r
96                                 return ret;\r
97                         })(),\r
98                         CLEAN_TARGET_ELEMENT = 'script,style,object,applet,embed,iframe,frame,base,bgsound,frameset,listing'.split( ',' );\r
99                 \r
100                 /* clean comment node */\r
101                 cleanCommnetNode();\r
102                 \r
103                 /* clean noscript */\r
104                 ( function(){\r
105                         var nodeNoscript = document.getElementsByTagName( 'noscript' ),\r
106                                 noscript;\r
107                         for( var i=0; i<nodeNoscript.length; ++i ){\r
108                                 noscript = nodeNoscript[i];\r
109                                 noscript.parentNode && noscript.parentNode.removeChild( noscript );\r
110                         };\r
111                 })();\r
112         \r
113                 function cleanCommnetNode( _targetElm ){\r
114                         search( _targetElm || document.body );\r
115                         \r
116                         function search( _elm ){\r
117                                 if( !_elm ) return;\r
118                                 if( _elm.nodeType === 8 ){\r
119                                         _elm.parentNode.removeChild( _elm );\r
120                                         return;\r
121                                 };\r
122                                 var i, l, _children = _elm.childNodes, _array = [];\r
123                                 if( _children && typeof _children.length === 'number' ){\r
124                                         // liveNode > array\r
125                                         for( i=0, l=_children.length; i<l; ++i ){\r
126                                                 _array.push( _children[ i ] );\r
127                                         };\r
128                                         while( _array.length !== 0 ){\r
129                                                 search( _array.shift() );\r
130                                         };\r
131                                 };\r
132                         };\r
133                 };\r
134                 \r
135                 return {\r
136                         extend: function( baseInstance, extend ){\r
137                                 for( var key in extend ){\r
138                                         if( Type.isUndefined( baseInstance[ key ] ) === true ){\r
139                                                 baseInstance[ key ] = extend[ key ];\r
140                                         } else\r
141                                         if( typeof baseInstance[ key ] === typeof extend[ key ] ){\r
142                                                 baseInstance[ key ] = extend[ key ];\r
143                                         } else {\r
144                                                 alert( 'extend error' );\r
145                                         }\r
146                                 }\r
147                                 return baseInstance;\r
148                         },      \r
149                         cleanCommnetNode: cleanCommnetNode,\r
150                         cleanElement: function( _targetElm ){\r
151                                 var _nodes, _elm, _array, j, m;\r
152                                 for( var i=0, l=CLEAN_TARGET_ELEMENT.length; i<l; ++i){\r
153                                         _nodes = _targetElm.getElementsByTagName( CLEAN_TARGET_ELEMENT[ i]);\r
154                                         _array = [];\r
155                                         for( j=0, m = _nodes.length; j<m; ++j){\r
156                                                 _array.push( _nodes[ j]);\r
157                                         }\r
158                                         for( j=0, m = _array.length; j<m; ++j){\r
159                                                 _elm = _nodes[ j];\r
160                                                 _elm.parentNode && _elm.parentNode.removeChild( _elm);\r
161                                         }\r
162                                 }\r
163                                 cleanCommnetNode( _targetElm );\r
164                                 if( UA.isIE === false ) return;\r
165                                 _nodes = _targetElm.all || _targetElm.getElementsByName( '*' );\r
166                                 for( i=0, l = _nodes.length; i<l; ++i){\r
167                                         _elm = _nodes[ i ];\r
168                                         _elm.style.filter = '';\r
169                                         _elm.style.behavior = '';\r
170                                 }\r
171                         },\r
172                         getElementSize: function( _elm ){\r
173                                 if( Type.isHTMLElement( _elm ) === false ){\r
174                                         return {\r
175                                                 width:  0,\r
176                                                 height: 0\r
177                                         };\r
178                                 };\r
179                                 var     parentElm   = _elm.parentNode,\r
180                                         prevElm     = _elm.previousSibling,\r
181                                         nextElm     = _elm.nextSibling,\r
182                                         displayNone = _elm.style.display === 'none';\r
183                                 if( displayNone === true ) _elm.style.display = 'block';\r
184                                 ELM_SIZE_GETTER.appendChild( _elm );\r
185                                 var ret = {\r
186                                         width:          _elm.offsetWidth,\r
187                                         height:         _elm.offsetHeight\r
188                                 }\r
189                                 if( displayNone === true ) _elm.style.display = 'none';\r
190                                 if( nextElm ){\r
191                                         parentElm.insertBefore( _elm, nextElm );\r
192                                 } else          \r
193                                 if( prevElm && prevElm.nextSibling ){\r
194                                         parentElm.insertBefore( _elm, prevElm.nextSibling );\r
195                                 } else {\r
196                                         parentElm && parentElm.appendChild( _elm );\r
197                                 }                       \r
198                                 return ret;\r
199                         },\r
200                         getImageSize: function( img ){\r
201                                 var     parentElm = img.parentNode,\r
202                                         prevElm = img.previousSibling,\r
203                                         nextElm = img.nextSibling,\r
204                                         displayNone = img.style.display === 'none';\r
205                                 if( displayNone === true ) img.style.display = '';\r
206                                 IMG_SIZE_GETTER.appendChild( img );\r
207                                 \r
208                                 var size = getActualDimension( img );\r
209                                 \r
210                                 IMG_SIZE_GETTER.removeChild( img );\r
211                                 if( displayNone === true ) img.style.display = 'none';\r
212                                 if( nextElm ){\r
213                                         parentElm.insertBefore( img, nextElm );\r
214                                 } else          \r
215                                 if( prevElm && prevElm.nextSibling ){\r
216                                         parentElm.insertBefore( img, prevElm.nextSibling );\r
217                                 } else {\r
218                                         parentElm && parentElm.appendChild( img );\r
219                                 }\r
220                                 \r
221                         /* LICENSE: MIT\r
222                          * AUTHOR: uupaa.js@gmail.com\r
223                          */\r
224                                 function getActualDimension(image) {\r
225                                         var run, mem, w, h, key = "actual";\r
226                                 \r
227                                 // for Firefox, Safari, Google Chrome\r
228                                         if ("naturalWidth" in image) {\r
229                                                 return {\r
230                                                         width:  image.naturalWidth,\r
231                                                         height: image.naturalHeight\r
232                                                 };\r
233                                         }\r
234                                 \r
235                                         if ("src" in image) { // HTMLImageElement\r
236                                                 if (image[key] && image[key].src === image.src) {\r
237                                                         return image[key];\r
238                                                 }\r
239                                                 if (document.uniqueID) { // for IE\r
240                                                         run = image.runtimeStyle;\r
241                                                         mem = { w: run.width, h: run.height }; // keep runtimeStyle\r
242                                                         run.width  = "auto"; // override\r
243                                                         run.height = "auto";\r
244                                                         w = image.width;\r
245                                                         h = image.height;\r
246                                                         run.width  = mem.w; // restore\r
247                                                         run.height = mem.h;\r
248                                                 } else { // for Opera and Other\r
249                                                         mem = { w: image.width, h: image.height }; // keep current style\r
250                                                         image.removeAttribute("width");\r
251                                                         image.removeAttribute("height");\r
252                                                         w = image.width;\r
253                                                         h = image.height;\r
254                                                         image.width  = mem.w; // restore\r
255                                                         image.height = mem.h;\r
256                                                 }\r
257                                                 return image[key] = { width: w, height: h, src: image.src }; // bond\r
258                                         }\r
259                                         // HTMLCanvasElement\r
260                                         return { width: image.width, height: image.height };\r
261                                 }\r
262                                 \r
263                                 return size;\r
264                         },\r
265                         getAbsolutePath: function( path) {\r
266                                 var e = document.createElement("div");\r
267                                 e.innerHTML = '<a href=\"' + path + '\" />';\r
268                                 return e.firstChild.href;\r
269                         },\r
270                         getAbsolutePosition: function( _elm){\r
271                                 // Find the destination's position\r
272                                 var     destx = _elm.offsetLeft,\r
273                                         desty = _elm.offsetTop,\r
274                                         thisNode = _elm,\r
275                                         body = document.body;\r
276                                 while (thisNode.offsetParent && thisNode.offsetParent !== body){\r
277                                         thisNode = thisNode.offsetParent;\r
278                                         destx += thisNode.offsetLeft;\r
279                                         desty += thisNode.offsetTop;\r
280                                 }\r
281                                 return {\r
282                                         x:      destx,\r
283                                         y:      desty\r
284                                 }\r
285                         },\r
286                         pullHtmlAsTemplete: function( html ){\r
287                                 var elm = document.createElement( 'div' );\r
288                                 elm.innerHTML = html;\r
289                                 return elm.firstChild;\r
290                         },\r
291                         getElementsByClassName: function( _elm, _className, opt_tagName){\r
292                                 var _all = !opt_tagName || opt_tagName === '*',\r
293                                         _nodes = _all === true ? ( _elm.all || _elm.getElementsByTagName( '*')) : _elm.getElementsByTagName( opt_tagName),\r
294                                         _node, _classes, ret = [];\r
295                                 for( var i=0, l = _nodes.length; i<l; ++i){\r
296                                         _node = _nodes[ i];\r
297                                         _node.nodeType === 1 && this.hasClassName( _node, _className) === true && ret.push( _node);\r
298                                 }\r
299                                 return ret;\r
300                         },\r
301                         getChildIndex: function( _parent, _child ){\r
302                                 var _children = _parent.getElementsByTagName( _child.tagName ),\r
303                                         l = _children.length;\r
304                                 for(var i=0; i<l; ++i){\r
305                                         if( _children[ i] === _child) return i;\r
306                                 }\r
307                                 return -1;\r
308                         },\r
309                         hasClassName: function( _elm, _className){\r
310                                 var _classes = ( _elm.className || '').split( ' ');\r
311                                 for( var i=0, l=_classes.length; i<l; ++i){\r
312                                         if( _classes[ i] === _className) return true;\r
313                                 }\r
314                                 return false;\r
315                         },\r
316                         removeAllChildren: function ( _elm){\r
317                                 while( _elm.firstChild){\r
318                                         remove( _elm.firstChild);\r
319                                 }\r
320                                 function remove( _node){\r
321                                         while( _node.firstChild){\r
322                                                 remove( _node.firstChild);\r
323                                         }\r
324                                         _node.parentNode && _node.parentNode.removeChild( _node);\r
325                                 }\r
326                         },\r
327                         getIndex: function( _array, _element){\r
328                                 if( Array.prototype.indexof ){\r
329                                         Util.getIndex = function( _array, _element){\r
330                                                 return _array.indexof( _element);\r
331                                         }\r
332                                 } else {\r
333                                         Util.getIndex = function( _array, _element){\r
334                                                 for( var i=0, l = _array.length; i<l; ++i){\r
335                                                         if( _array[ i] === _element) return i;\r
336                                                 }\r
337                                                 return -1;                                      \r
338                                         }\r
339                                 }\r
340                                 return Util.getIndex( _array, _element);\r
341                         },\r
342                         copyArray: function( _array ){\r
343                                 var ret = new Array( l );\r
344                                 for( var i=0, l = _array.length; i<l; ++i ){\r
345                                         ret[ i ] = _array[ i ];\r
346                                 }\r
347                                 return ret;\r
348                         },\r
349                         /*\r
350                          * \r
351                          */\r
352                         createGlobalFunction: function( _func ){\r
353                                 var randomKey = null;\r
354                                 while( true) {\r
355                                         randomKey = '_glovalFunction_' + ( '' + Math.random()).replace( /\./,'');\r
356                                         if( eval( 'typeof '+randomKey) === 'undefined') {\r
357                                                 break;\r
358                                         }\r
359                                 }\r
360                                 window[ randomKey ] = _func;\r
361                                 return randomKey;\r
362                         },\r
363                         createGlobalFunc: function( func){\r
364                                 var randomKey = null;\r
365                                 while(true) {\r
366                                         randomKey = 'hogeGlovalFunc_'+(''+Math.random()).replace(/\./,'');\r
367                                         if(eval('typeof '+randomKey) == 'undefined') {\r
368                                                 break;\r
369                                         }\r
370                                 }\r
371                                 eval(randomKey+'='+((typeof func=='string') ? func : func.toString()));\r
372                                 return randomKey;\r
373                         },\r
374                         createGlobalVar: function( obj){\r
375                                 var randomKey = null;\r
376                                 while(true) {\r
377                                         randomKey = 'hogeGlovalVar_'+(''+Math.random()).replace(/\./,'');\r
378                                         if(eval('typeof '+randomKey+'') == 'undefined') {\r
379                                                 break;\r
380                                         }\r
381                                 }\r
382                                 var globalObj = eval(randomKey+'={}');\r
383                                 globalObj.value = obj;\r
384                                 return randomKey;\r
385                         },\r
386                         createGlobalUniqueName: function(){\r
387                                 var randomKey = null;\r
388                                 while(true) {\r
389                                         randomKey = '_uniqueName'+(''+Math.random()).replace(/\./,'');\r
390                                         if( typeof window[randomKey] === 'undefined'){\r
391                                                 break;\r
392                                         }\r
393                                 }\r
394                                 return randomKey;\r
395                         },\r
396                         createIframe: function( id, callback){\r
397                                 var ua = UA;\r
398                     var el = document.createElement( ua.isIE ? '<iframe name="' + id + '" frameborder="0" scrolling="no">' : 'iframe');\r
399         \r
400                     if( ua.isIE){\r
401                                         el.onreadystatechange = detect;\r
402                     } else {\r
403                         // iron(chrome) の場合、append の前に onload を指定しないと onload が呼ばれない\r
404                         el.onload = onLoad;\r
405                         //setTimeout( asynkCallback, 0 );\r
406                                 }\r
407         \r
408                                 document.body.appendChild( el);\r
409                     el.id = el.name = id;\r
410                     el.setAttribute( 'name', id);\r
411                     el.style.cssText = 'width:1px;height:1px;visibility:hidden;position:absolute;top:1px;left:1px;';\r
412                                 // http://d.hatena.ne.jp/onozaty/20070830/p1\r
413                                 // [JavaScript]IE6ではJavaScriptで動的に作成したiframeに対してsubmitできない(IE7は未確認) ->解決\r
414                                 el.contentWindow.name = id;                                     \r
415                     \r
416                     window[id] = el;\r
417         \r
418                     function detect(){\r
419                         if ( this.readyState === "complete" ){\r
420                             this.onreadystatechange = new Function();\r
421                             this.onreadystatechange = null;\r
422                             setTimeout( asynkCallback, 0 );\r
423                         };\r
424                     };\r
425                                 function onLoad(){\r
426                                         el.onload = null;\r
427                                         setTimeout( asynkCallback, 0 );\r
428                                 };\r
429                                 function asynkCallback(){\r
430                                         callback( el );\r
431                                 };\r
432                         }\r
433                 }\r
434         })();\r
435 \r
436 \r
437 /*\r
438  * UA\r
439  * \r
440  *   detect userAgent\r
441  *   detect plug in\r
442  */\r
443         var UA = ( function(){\r
444                 var ua = (function(){\r
445                                 var acme = {};\r
446                                 \r
447                                 var n    = navigator;\r
448                                 var dua  = n.userAgent;\r
449                                 var dav  = n.appVersion;\r
450                                 var tv   = parseFloat(dav);\r
451                                 acme.isOpera  = (dua.indexOf("Opera") >= 0) ? tv: undefined;\r
452                                 acme.isKhtml  = (dav.indexOf("Konqueror") >= 0) ? tv : undefined;\r
453                                 acme.isWebKit = parseFloat(dua.split("WebKit\/")[1]) || undefined;\r
454                                 acme.isChrome = parseFloat(dua.split("Chrome\/")[1]) || undefined;\r
455                                 acme.isGecko  = (dua.indexOf("Gecko\/") >= 0) ? parseFloat(dua.split("rv:")[1].replace( /^(\d*\.\d*)\.(\d*)/, '$1$2' )) : undefined;\r
456                                 var index = Math.max(dav.indexOf("WebKit"), dav.indexOf("Safari"), 0);\r
457                                 if(index && !acme.isChrome){\r
458                                         acme.isSafari = parseFloat(dav.split("Version/")[1]);\r
459                                         if(!acme.isSafari || parseFloat(dav.substr(index + 7)) <= 419.3){\r
460                                                 acme.isSafari = 2;\r
461                                         }\r
462                                 }\r
463                                 if(document.all && !acme.isOpera){\r
464                                         acme.isIE = parseFloat(dav.split("MSIE ")[1]) || undefined;\r
465                                 }\r
466                                 \r
467                                 return acme;\r
468                         })(),\r
469                         isIE = navigator.userAgent.toLowerCase().indexOf( 'msie') !== -1,\r
470                         ieVersion = isIE === true ? parseInt( navigator.appVersion.toLowerCase().replace( /.*msie[ ]/, '').match( /^[0-9]+/)) : 0,\r
471                         ieRenderingVersion = ieVersion === 8 ? document.documentMode : ieVersion,\r
472                         isStanderdMode = document.compatMode === 'CSS1Compat',\r
473                         ActiveX = ( function(){\r
474                                 if( isIE === false || ieVersion > 8 ) return false;\r
475                                 var     b = document.body,\r
476                                         c = b.className || '',\r
477                                         x,\r
478                                         ret = undefined, //pettanr.URL_PARAMS.ActiveX,\r
479                                         ns = 'pettanr-ActiveX-',\r
480                                         enabled = 'enabled',\r
481                                         disabled = 'disabled';\r
482                                 if( ret !== true && ret !== false){\r
483                                         if( Util.hasClassName( b, ns + enabled) === true )  return true;\r
484                                         if( Util.hasClassName( b, ns + disabled) === true ) return false;\r
485                                         x = document.createElement( 'div' );\r
486                                         b.appendChild(x);\r
487                                         x.style.cssText = 'width:1px;height:1px;line-height:1px;filter:progid:DXImageTransform.Microsoft.Shadow()';\r
488                                         ret = x.offsetHeight > 1;\r
489                                         b.removeChild(x);\r
490                                 }\r
491                                 b.className += [ c !== '' ? ' ' : c, ns, ret === true ? enabled : disabled ].join( '');\r
492                                 return ret;\r
493                         })(),\r
494                         VML = ( function(){\r
495                                 if( ActiveX === false || isIE === false || ieVersion > 8) return false;\r
496                                 var globalObjectName = Util.createGlobalUniqueName(),\r
497                                         script,\r
498                                         id = 'detectVML';\r
499                                 document.write( [ '<!--[if gte vml 1]><script id="', id, '">window', '.', globalObjectName, '=1;<\/script><![endif]-->'].join( ''));\r
500                                 if( window[globalObjectName] === 1){\r
501                                         script = document.getElementById( id);\r
502                                         script.parentNode.removeChild( script);\r
503                                         window[globalObjectName] = null;\r
504                                         return true;\r
505                                 }\r
506                                 return false;\r
507                         })(),\r
508                         isStandAloneMode = ( function(){\r
509                                 if( isIE === false) return false;\r
510                                 if( VML === true) return false;\r
511                                 var globalObjectName = Util.createGlobalUniqueName(),\r
512                                         script,\r
513                                         id = 'detectStandAlone';\r
514                                 document.write( [ '<!--[if IE ', Math.floor( ieVersion ), ']><script id="', id, '">window', '.', globalObjectName, '=1;<\/script><![endif]-->'].join( ''));\r
515                                 if( window[globalObjectName] === 1){\r
516                                         script = document.getElementById( id);\r
517                                         script.parentNode.removeChild( script);\r
518                                         window[globalObjectName] = null;\r
519                                         return false;\r
520                                 }\r
521                                 return true;\r
522                         })();\r
523                 return {\r
524                         IE:                                     ua.isIE,\r
525                         GECKO:                          ua.isGecko,\r
526                         OPERA:                          ua.isOpera,\r
527                         KHTML:                          ua.isKhtml,\r
528                         WEBKIT:                         ua.isWebKit,\r
529                         CHROME:                         ua.isChrome,\r
530                         isIE:                           isIE,\r
531                         ieVersion:                      ieVersion,\r
532                         ieRenderingVersion:     ieRenderingVersion,\r
533                         isStanderdMode:         isStanderdMode,\r
534                         ACTIVEX:            ActiveX,\r
535                         VML:                VML,\r
536                         STANDALONE:         isStandAloneMode,\r
537                         VENDER_PREFIX: ( function() {\r
538                                 var ua = navigator.userAgent.toLowerCase();\r
539                                 if ( ua.indexOf('opera') !== -1 ){\r
540                                         return 'O';\r
541                                 } else if ( ua.indexOf('msie') !== -1 ){\r
542                                         return 'ms';\r
543                                 } else if ( ua.indexOf('webkit') !== -1 ){\r
544                                         return 'webkit';\r
545                                 } else if ( navigator.product === 'Gecko' ){\r
546                                         return 'Moz';\r
547                                 }\r
548                                 return '';\r
549                         })(),\r
550                         startVML: function(){\r
551                                 delete UA.startVML;\r
552                                 if( UA.VML !== true) return false;\r
553                                 if (!document.namespaces["v"]) {\r
554                                 document.namespaces.add("v", "urn:schemas-microsoft-com:vml", "#default#VML");\r
555                             }\r
556                             document.createStyleSheet().cssText = "v\:shape,v\:image{behavior:url(#default#VML);display:block;};";\r
557                         }\r
558                 }\r
559         })();\r
560 \r
561 \r
562 \r
563 /* ----------------------------------------------------\r
564  * gadgetOS\r
565  * \r
566  */     \r
567 \r
568 ( function( window, undefined ){\r
569         \r
570         var doc            = window.document;\r
571         var body           = doc.getElementsByTagName( 'body' )[ 0 ]; //( doc.compatMode || '' ) !== 'CSS1Compat' ? doc.body : doc.documentElement;// \r
572         \r
573         var SERVICE_LIST   = [];\r
574         var SUPER_USER_KEY = { getUID: function(){ return 0; }};\r
575         var API_USER_LIST  = [ SUPER_USER_KEY ];\r
576         var numApiUser     = 1;\r
577         \r
578         function isApiUser( _user ){\r
579                 if( _user === SUPER_USER_KEY ) return true;\r
580                 if( File.isDriver( _user ) === true ) return true;\r
581                 if( Application.isApplicationInstance( _user ) === true ) return true;\r
582                 return false;\r
583         }\r
584         \r
585         var Const = {\r
586                 FILE: {\r
587                         TYPE: {\r
588                                 UNKNOWN:        0,\r
589                                 FOLDER:         1,\r
590                                 IMAGE:          2,\r
591                                 TEXT:           3,\r
592                                 HTML:           4,\r
593                                 CSV:            5,\r
594                                 JSON:           6,\r
595                                 XML:            7\r
596                         },\r
597                         STATE: {\r
598                                 UNKNOWN:        0,\r
599                                 OK:                     1,\r
600                                 LOADING:        2,\r
601                                 ERROR:          3,\r
602                                 BROKEN:         4\r
603                         },\r
604                         UPDATE_POLICY: {\r
605                                 _____:          parseInt( '00000', 2 ),\r
606                                 ____C:          parseInt( '00001', 2 ), // hasCreateMenu\r
607                                 ___W_:          parseInt( '00010', 2 ), // isWritable\r
608                                 ___WC:          parseInt( '00011', 2 ), // isWritable\r
609                                 __R__:          parseInt( '00100', 2 ), // isRenamable\r
610                                 __R_C:          parseInt( '00101', 2 ), // hasCreateMenu\r
611                                 __RW_:          parseInt( '00110', 2 ), // isWritable\r
612                                 __RWC:          parseInt( '00111', 2 ), // isWritable\r
613                                 _S___:          parseInt( '01000', 2 ), // childrenIsSortable\r
614                                 _S__C:          parseInt( '01001', 2 ),\r
615                                 _S_W_:          parseInt( '01010', 2 ),\r
616                                 _S_WC:          parseInt( '01011', 2 ),\r
617                                 _SR__:          parseInt( '01100', 2 ),\r
618                                 _SR_C:          parseInt( '01101', 2 ),\r
619                                 _SRW_:          parseInt( '01110', 2 ),\r
620                                 _SRWC:          parseInt( '01111', 2 ),\r
621                                 D____:          parseInt( '10000', 2 ),\r
622                                 D___C:          parseInt( '10001', 2 ), // hasCreateMenu\r
623                                 D__W_:          parseInt( '10010', 2 ), // isWritable\r
624                                 D__WC:          parseInt( '10011', 2 ), // isWritable\r
625                                 D_R__:          parseInt( '10100', 2 ), // isRenamable\r
626                                 D_R_C:          parseInt( '10101', 2 ), // hasCreateMenu\r
627                                 D_RW_:          parseInt( '10110', 2 ), // isWritable\r
628                                 D_RWC:          parseInt( '10111', 2 ), // isWritable\r
629                                 DS___:          parseInt( '11000', 2 ), // childrenIsSortable\r
630                                 DS__C:          parseInt( '11001', 2 ),\r
631                                 DS_W_:          parseInt( '11010', 2 ),\r
632                                 DS_WC:          parseInt( '11011', 2 ),\r
633                                 DSR__:          parseInt( '11100', 2 ),\r
634                                 DSR_C:          parseInt( '11101', 2 ),\r
635                                 DSRW_:          parseInt( '11110', 2 ),\r
636                                 DSRWC:          parseInt( '11111', 2 ),\r
637                                 CREATE:         1,\r
638                                 WRAITE:         2,\r
639                                 RENAME:         4,\r
640                                 SORT:           8,\r
641                                 DELETE:         16\r
642                         },\r
643                         EVENT: {\r
644                                 UPDATE_ATTRIVUTE:       'onFileUpdate',\r
645                                 GET_SEQENTIAL_FILES:'gotSeqentilFiles'\r
646                         },\r
647                         DATA_PROPERTY_RESERVED: [\r
648                                 'children', 'driver', 'state', 'type'\r
649                         ]                       \r
650                 },\r
651                 TREE: {\r
652                         EVENT: {\r
653                                 UPDATE:                         'onTreeUpdate'\r
654                         }\r
655                 },\r
656                 KEY: {\r
657                         EVENT: {\r
658                                 KEY_DOWN:                       'keydown',\r
659                                 KEY_UP:                         'keyup',\r
660                                 KEY_CHANGE:                     'keychange',\r
661                                 CURSOL:                         'cursol'\r
662                         }\r
663                 }\r
664         };\r
665 \r
666 var EX = ( function(){\r
667         var F = new Function();\r
668         \r
669         function clone( src ) {\r
670                 var ret;\r
671                 if( Type.isArray(src) === true ){\r
672                         ret = [];\r
673                 } else\r
674                 if( Type.isObject(src) === true ){\r
675                         ret = {};\r
676                 } else\r
677                 if( Type.isNumber(src) === true || Type.isString(src) === true || Type.isBoolean( src ) === true ){\r
678                         return src;\r
679                 } else {\r
680                         return null;\r
681                 }\r
682                 for( var key in src ){\r
683                         ret[ key ] = clone( src[ key ]);\r
684                 }\r
685                 return ret;\r
686         };\r
687         \r
688         return {\r
689                 extend: function( base, extend ){\r
690                         F.prototype = base;\r
691                         var ret = new F;\r
692                         for( var p in extend ){\r
693                                 ret[ p ] = extend[ p ];\r
694                         };\r
695                         return ret;\r
696                 },\r
697                 clone: function( obj ){\r
698                         return clone( obj );\r
699                 },\r
700                 kill: function(){\r
701                         var self = this, v;\r
702                         for( var p in s ){\r
703                                 if( self.hasOwnProperty && !self.hasOwnProperty( p ) ) continue;\r
704                                 v = self[ p ];\r
705                                 v && v instanceof TicketBase && self.kill();\r
706                                 delete self[ p ];\r
707                         }\r
708                 }\r
709         }\r
710 })();\r
711 \r
712 var TicketBase = function(){\r
713         this.kill = function(){\r
714                 var t = this, v;\r
715                 for( var p in t ){\r
716                         if( t.hasOwnProperty && !t.hasOwnProperty( p ) ) continue;\r
717                         v = t[ p ];\r
718                         v && v instanceof TicketBase && v.kill();\r
719                         delete t[ p ];\r
720                 }\r
721         };\r
722 };\r
723 \r
724 \r
725 \r
726 /* --------------------------------------------------------------\r
727  * System Timer\r
728  * \r
729  */\r
730 \r
731 var SystemTimer = ( function(){\r
732         var setTimeout    = window.setTimeout;\r
733         var clearTimeout  = window.clearTimeout;\r
734         var INTERVAL_TIME = 16;\r
735         var TICKET_LIST   = [];\r
736         var timerId       = undefined;\r
737         var next          = 0;\r
738         \r
739         function loop(){\r
740             for( var i = 0; i < TICKET_LIST.length; ) {\r
741                 if( TICKET_LIST[ i ].call( next ) !== false ) ++i;\r
742             };\r
743             timerId = undefined;\r
744             update();\r
745         };\r
746         function update(){\r
747                 var l = TICKET_LIST.length,\r
748                         n = 99999999,\r
749                         c;\r
750                 if( l === 0 ){\r
751                         timerId !== undefined && clearTimeout( timerId );\r
752                         timerId = undefined;\r
753                         return;\r
754                 };\r
755             for( var i = 0; i<l; i++ ){\r
756                 c = TICKET_LIST[ i ].count;\r
757                 if( n > c ) n = c;\r
758             };\r
759             if( next > n || timerId === undefined ){\r
760                 timerId !== undefined && clearTimeout( timerId );\r
761                 timerId = setTimeout( loop, INTERVAL_TIME * n );\r
762                 next = n;\r
763             };\r
764         };\r
765         \r
766         var TimerTicketClass = function( _apiuser, _callback, _time, _once ){\r
767                 this.apiuser  = _apiuser;\r
768                 this.callback = _callback;\r
769                 this.time     = _time;\r
770                 this.count    = _time;\r
771                 this.once     = _once;\r
772                 _apiuser = _callback = null;\r
773         };\r
774         TimerTicketClass.prototype = new TicketBase();\r
775         TimerTicketClass.prototype.call = function( c ){\r
776                 this.count -= c;\r
777                 if( this.count <= 0 ){\r
778                         this.callback();\r
779                         if( this.once === true ){\r
780                                 this.destroy();\r
781                                 TICKET_LIST.splice( Util.getIndex( TICKET_LIST, this ), 1 );\r
782                                 return false;\r
783                         } else {\r
784                                 this.count = this.time;\r
785                         };\r
786                 };\r
787         };\r
788         TimerTicketClass.prototype.destroy = function( _apiuser, _callback ){\r
789                 if( _apiuser  && _apiuser  !== this.apiuser )  return false;\r
790                 if( _callback && _callback !== this.callback ) return false;\r
791                 \r
792                 this.kill();\r
793                 return true;\r
794         };\r
795         \r
796         return {\r
797                 add: function( _apiuser, _handler, _time, _once ){\r
798                         if( Type.isNumber( _time ) === false || _time < INTERVAL_TIME ) _time = INTERVAL_TIME;\r
799                         \r
800                     var _ticket = new TimerTicketClass( _apiuser, _handler, Math.ceil( _time / INTERVAL_TIME ), _once );\r
801                     TICKET_LIST.push( _ticket );\r
802                     \r
803                     update();\r
804                 },\r
805                 remove: function( _apiuser, _handler ) {\r
806                         var _ticket,\r
807                                 i = 0;\r
808                         while( _ticket = TICKET_LIST[ i ] ){\r
809                                 if( _ticket.destroy( _apiuser, _handler ) === true ){\r
810                                         TICKET_LIST.splice( i, 1 );\r
811                                 } else {\r
812                                         ++i;\r
813                                 };\r
814                         };\r
815                     update();\r
816                 }\r
817         }\r
818 })();\r
819 \r
820 /* --------------------------------------------------------------\r
821  * Async Callback\r
822  * \r
823  */\r
824 var AsyncCall = ( function(){\r
825         var CALLBACK_LIST = [];\r
826 \r
827         var CallbackTicketClass = function( _apiuser, _callback, _argments ){\r
828                 this.apiuser  = _apiuser;\r
829                 this.callback = _callback;\r
830                 this.argments = _argments;\r
831                 _apiuser = _callback = _argments = null;\r
832         }\r
833         CallbackTicketClass.prototype = new TicketBase();\r
834         CallbackTicketClass.prototype.call = function(){\r
835                 var f = this.callback,\r
836                         a = this.argments;\r
837                 if( Type.isArray( a ) === true ){\r
838                         f.apply( this.apiuser, a );\r
839                 } else {\r
840                         f( a );\r
841                 }\r
842         };\r
843         CallbackTicketClass.prototype.destroy = function( _apiuser, _callback ){\r
844                 if( _apiuser  && _apiuser  !== this.apiuser ) return false;\r
845                 if( _callback && _callback !== this.callback ) return false;\r
846                 \r
847                 this.kill();\r
848                 return true;\r
849         };\r
850 \r
851         function dispatch(){\r
852                 var _ticket = CALLBACK_LIST.shift();\r
853                 if( _ticket ){\r
854                         _ticket.call();\r
855                         _ticket.destroy();\r
856                         CALLBACK_LIST.length !== 0 && SystemTimer.add( SUPER_USER_KEY, dispatch, 1, true );\r
857                 }\r
858         }\r
859 \r
860         return {\r
861                 add: function( _apiuser, _callback, _argments ){\r
862                         CALLBACK_LIST.length === 0 && SystemTimer.add( SUPER_USER_KEY, dispatch, 1, true );\r
863                         CALLBACK_LIST.push( new CallbackTicketClass( _apiuser, _callback, _argments ) );\r
864                 },\r
865                 remove: function( _apiuser, _callback ){\r
866                         var _ticket,\r
867                                 i = 0;\r
868                         while( _ticket = CALLBACK_LIST[ i ] ){\r
869                                 if( _ticket.destroy( _apiuser, _callback ) === true ){\r
870                                         CALLBACK_LIST.splice( i, 1 );\r
871                                 } else {\r
872                                         ++i;\r
873                                 }\r
874                         }\r
875                 }\r
876         }\r
877 })();\r
878 \r
879 /* -----------------------------------------------------------\r
880  * 画像一覧は\r
881  *      お気に入り画像一覧 > tag:ペン次郎 > ペン次郎:笑う\r
882  *  最近アップロードされた画像 > images\r
883  *  最近使われた画像 > images\r
884  *  キャラクター画像庫 > アニマル系 > tag:ペン次郎 > ペン次郎:笑う\r
885  *  風景画像庫 >\r
886  *  効果画像庫 >\r
887  *  アイテム画像庫 >\r
888  *  \r
889  * 画像一覧を読み込むタイミング\r
890  */\r
891 var File = ( function(){\r
892         var DRIVER_LIST             = [];\r
893         \r
894         var FILE_TYPE_IS_FOLDER     = Const.FILE.TYPE.FOLDER,\r
895                 numFileType             = Const.FILE.TYPE.XML,\r
896                 FILEDATA_RESITER        = [],                   // store all of fileData( json object )\r
897                 FILEDATA_ACCESS         = [],                   // file operations for Kernel only ! hide from Out of File\r
898                 FILE_OBJECT_POOL        = [],\r
899                 EVENT_LISTENER_REGISTER = [],\r
900                 TREE_ARRAY              = [],\r
901                 TREE_ACCESS_ARRAY       = [];\r
902         \r
903         var REQUEST_CONTROLER = ( function(){\r
904                 var REQUEST_TICKET_RESISTER = [],\r
905                         currentTicket           = null,\r
906                         currentData             = null,\r
907                         DATA_TYPE_ARRAY         = 'json,xml,html,text'.split( ','),\r
908                         DATA_IS_JSON            = 0,\r
909                         DATA_IS_XML             = 1,\r
910                         DATA_IS_HTML            = 2,\r
911                         DATA_IS_TEXT            = 3,\r
912                         numError                = 0;\r
913                 \r
914                 var RequestTicketClass = function( _apiuser, _type, _data, _url, _onLoad, _onError ){\r
915                         this.apiuser = _apiuser;\r
916                         this.type    = _type;\r
917                         this.data    = _data;\r
918                         this.url     = _url;\r
919                         this.onLoad  = _onLoad;\r
920                         this.onError = _onError;\r
921                         this.state   = 0;\r
922                         _apiuser = _type = _data = _onLoad = _onError = null;\r
923                 };\r
924                 RequestTicketClass.prototype = new TicketBase();\r
925                 RequestTicketClass.prototype.load = function( _data ){\r
926                         AsyncCall.add( this.apiuser, this.onLoad, [ this.data, _data ] );\r
927                 };\r
928                 RequestTicketClass.prototype.error = function(){\r
929                         AsyncCall.add( this.apiuser, this.onError, this.data );\r
930                 };\r
931                 \r
932                 function request(){\r
933                         if( currentTicket !== null || REQUEST_TICKET_RESISTER.length === 0 ) return;\r
934                         currentTicket = REQUEST_TICKET_RESISTER.shift();\r
935                         $.ajax({\r
936                                 url:            currentTicket.url,\r
937                                 dataType:       DATA_TYPE_ARRAY[ currentTicket.type ],\r
938                                 success:        onSuccess,\r
939                                 error:          onError\r
940                         });\r
941                 }\r
942                 function onSuccess( _data ){\r
943                         currentTicket.load( _data );\r
944                         currentTicket.kill();\r
945                         currentTicket = null;\r
946                         request();\r
947                 }\r
948                 function onError(){\r
949                         ++numError;\r
950                         currentTicket.error();\r
951                         currentTicket.kill(); // retry\r
952                         currentTicket = null;\r
953                         request();\r
954                 }\r
955 \r
956                 return {\r
957                         getNumTask: function(){\r
958                                 return REQUEST_TICKET_RESISTER.length;\r
959                         },\r
960                         getNumError: function(){\r
961                                 return numError;\r
962                         },\r
963                         getJson: function( _apiuser, _data, _url, _onLoad, _onError ){\r
964                                 REQUEST_TICKET_RESISTER.push( new RequestTicketClass( _apiuser, DATA_IS_JSON, _data, _url, _onLoad, _onError ));\r
965                                 currentTicket === null && request();\r
966                         }\r
967                 }\r
968         })();\r
969 \r
970         var FILE_CONTROLER = {\r
971                 createTree: function( _apiuser, _rootFileData ){\r
972                         var _tree = new TreeClass( _apiuser, _rootFileData );\r
973                         TREE_ARRAY.push( _tree );\r
974                         return _tree;\r
975                 },\r
976                 getFileUID: function( FILEDATAorFILE ){\r
977                         if( FILEDATAorFILE instanceof FileClass ){\r
978                                 return FILEDATAorFILE.getUID();\r
979                         }\r
980                         \r
981                         var uid = Util.getIndex( FILEDATA_RESITER, FILEDATAorFILE );\r
982                         if( uid === -1 ){\r
983                                 uid = FILEDATA_RESITER.length;\r
984                                 FILEDATA_RESITER.push( FILEDATAorFILE );\r
985                         }\r
986                         return uid;\r
987                 },\r
988                 getFileDataAccess: function( UIDorFILEorFILEDATA ){\r
989                         var _uid, _data = FILE_CONTROLER.getFileData( UIDorFILEorFILEDATA ), _access;\r
990 \r
991                         if( _data === null || typeof _data !== 'object' ) return null;\r
992                         for( var i=0, l = FILEDATA_ACCESS.length; i<l; ++i ){\r
993                                 _access = FILEDATA_ACCESS[ i ];\r
994                                 if( _access.DATA === _data ) return _access;\r
995                         };\r
996                         return null;\r
997                 },      \r
998                 getFileData: function( UIDorFILEorFILEDATA ){\r
999                         if( typeof UIDorFILEorFILEDATA === 'number' ){\r
1000                                 return FILEDATA_RESITER[ UIDorFILEorFILEDATA ] || null;\r
1001                         } else\r
1002                         if( UIDorFILEorFILEDATA instanceof FileClass ){\r
1003                                 return FILEDATA_RESITER[ UIDorFILEorFILEDATA.getUID() ] || null;\r
1004                         } else\r
1005                         if( Util.getIndex( FILEDATA_RESITER, UIDorFILEorFILEDATA ) !== -1 ){\r
1006                                 return UIDorFILEorFILEDATA;\r
1007                         }\r
1008                         return null;\r
1009                 },\r
1010                 getChildren: function( UIDorFILEorFILEDATA ){\r
1011                         var _data = FILE_CONTROLER.getFileData( UIDorFILEorFILEDATA );\r
1012                         return _data !== null ? _data.children || null : null;\r
1013                 },\r
1014                 getDriver: function( _file ){\r
1015                         var _data = FILE_CONTROLER.getFileData( _file );\r
1016                         return _data !== null && _data.driver ? _data.driver : BASE_DRIVER;\r
1017                 },\r
1018                 getUpdateFlag: function( _file, _bit ){\r
1019                         var _driver = FILE_CONTROLER.getDriver( _file ),\r
1020                                 _policy;\r
1021                         if( typeof _driver.getUpdatePolicy === 'function' ){\r
1022                                 _policy = _driver.getUpdatePolicy( _file );\r
1023                                 \r
1024                         }\r
1025                         if( typeof _policy !== 'number' ) {\r
1026                                 _policy = BASE_DRIVER.getUpdatePolicy( _file )\r
1027                         }\r
1028                         return _policy % ( _bit * 2 ) >= _bit;\r
1029                 },\r
1030                 move: function( _prentUID, _targetfile, _newFolder, _newIndex, _opt_callback ){\r
1031                         var _parentData = FILE_CONTROLER.getFileDataAccess( _prentUID ),\r
1032                                 _parentType = _parentData.TYPE,\r
1033                                 _targetData = FILE_CONTROLER.getFileDataAccess( _targetfile ),\r
1034                                 _targetType = _targetData.TYPE;\r
1035                 },\r
1036                 replace: function( _uid, _file, _newIndex ){\r
1037                         \r
1038                 },\r
1039                 addEventListener: function( FILEorNULL, _eventType, _callback ){\r
1040                         var _uid = FILEorNULL instanceof FileClass ? FILEorNULL.getUID() : FILEorNULL;\r
1041                         EVENT_LISTENER_REGISTER.push( new FileEventTicketClass( _uid, _eventType, _callback ));\r
1042                 },\r
1043                 removeEventListener: function( FILEorNULL, _eventType, _callback ){\r
1044                         var _uid = FILEorNULL instanceof FileClass ? FILEorNULL.getUID() : FILEorNULL,\r
1045                                 _ticket;\r
1046                         for(var i=0, l = EVENT_LISTENER_REGISTER.length; i<l; ++i ){\r
1047                                 _ticket = EVENT_LISTENER_REGISTER[ i ];\r
1048                                 if( _ticket.fileUID === _uid && _ticket.eventType === _eventType && _ticket.callBack === _callback ){\r
1049                                         EVENT_LISTENER_REGISTER.splice( i, 1 );\r
1050                                         _ticket.kill();\r
1051                                 }\r
1052                         }\r
1053                 },\r
1054                 getTreeAccess: function(){\r
1055                         \r
1056                 },\r
1057                 fileEventRellay: function( _uid, _event ){\r
1058                         var _fileAccess = FILE_CONTROLER.getFileDataAccess( _uid );\r
1059                         if( _fileAccess === null ) return;\r
1060                         var _treeUID    =  _fileAccess.TREE.getUID(),\r
1061                                 _treeAccess = TREE_ACCESS_ARRAY[ _treeUID ],\r
1062                                 _data       = _fileAccess.DATA,\r
1063                                 _tree;\r
1064                         if( !_treeAccess ) return;\r
1065                         _treeAccess.dispatchFileEvent( _event );\r
1066                         for( var i=0, l = TREE_ARRAY.length; i<l; ++i ){\r
1067                                 if( i !== _treeUID ){\r
1068                                         _tree = TREE_ARRAY[ i ];\r
1069                                         if( FILE_CONTROLER.getFileData( _tree.getCurrentFile() ) === _data ){\r
1070                                                 _treeAccess = TREE_ACCESS_ARRAY[ _tree.getUID() ];\r
1071                                                 _treeAccess && _treeAccess.dispatchFileEvent( _event );\r
1072                                         }\r
1073                                 }\r
1074                         }\r
1075                 }\r
1076         }\r
1077         \r
1078         var TreeClass = function( apiuser, rootFileData ){\r
1079                 var PARENT_FILE_RESITER = [],\r
1080                         ACCESS = {\r
1081                                 apiuser          : apiuser,\r
1082                                 dispatchFileEvent: dispatchFileEvent\r
1083                         },\r
1084                         EVENT_LISTENER_ARRAY = [],\r
1085                         instance             = this,\r
1086                         rootFile             = new FileClass( instance, null, rootFileData ),\r
1087                         currentFile          = rootFile;\r
1088                 \r
1089                 currentFile.getSeqentialFiles();\r
1090                 TREE_ACCESS_ARRAY.push( ACCESS );\r
1091                 \r
1092                 function dispatchFileEvent( e ){\r
1093                         var _eventType  = e.eventType,\r
1094                                 _targetFile = e.targetFile,\r
1095                                 _uid        = _targetFile.getUID(),\r
1096                                 _ticket, _type, _callback;\r
1097                         for( var i=0, l = EVENT_LISTENER_REGISTER.length; i<l; ++i ){\r
1098                                 _ticket   = EVENT_LISTENER_REGISTER[ i ];\r
1099                                 _type     = _ticket.eventType;\r
1100                                 _callback = _ticket.callBack;\r
1101                                 if( _eventType === _type && _uid === _ticket.fileUID ){\r
1102                                         AsyncCall.add( apiuser, _callback, [ _eventType, _targetFile, e.key, e.value ] );\r
1103                                 } else\r
1104                                 if( _type === Const.TREE.EVENT.UPDATE && _eventType === Const.FILE.EVENT.GET_SEQENTIAL_FILES ){\r
1105                                         //_callback( _eventType, _targetFile );\r
1106                                         AsyncCall.add( apiuser, _callback, [ _eventType, _targetFile ] );\r
1107                                 }\r
1108                         }\r
1109                 }\r
1110                 \r
1111                 this.getUID = function(){\r
1112                         return Util.getIndex( TREE_ACCESS_ARRAY, ACCESS );\r
1113                 };\r
1114                 this.getRootFile = function(){\r
1115                         return rootFile;\r
1116                 };\r
1117                 this.getCurrentFile = function(){\r
1118                         return currentFile;\r
1119                 };\r
1120                 this.hierarchy = function(){\r
1121                         return PARENT_FILE_RESITER.length;\r
1122                 };\r
1123                 this.getParentFileAt = function( _index ){\r
1124                         var l = PARENT_FILE_RESITER.length;\r
1125                         if( typeof _index !== 'number' || _index < 0 || _index >= l ) return null;\r
1126                         return PARENT_FILE_RESITER[ l -1 -_index ];\r
1127                 };\r
1128                 this.down = function( _index ){\r
1129                         if( typeof _index !== 'number' || _index < 0 || _index >= currentFile.getChildFileLength()) return;\r
1130                         PARENT_FILE_RESITER.unshift( currentFile );\r
1131                         currentFile = currentFile.getChildFileByIndex( _index );\r
1132                         currentFile.getSeqentialFiles();\r
1133                         return currentFile;\r
1134                 };\r
1135                 this.up = function( _index ){\r
1136                         var l = PARENT_FILE_RESITER.length;\r
1137                         if( l === 0) return null;\r
1138                         \r
1139                         if( currentFile ){\r
1140                                 var _currentFile = currentFile;\r
1141                                 currentFile = null;\r
1142                                 _currentFile.destroy();\r
1143                         };\r
1144                         if( typeof _index === 'number'){\r
1145                                 if( _index >= l) return null;\r
1146                                 currentFile = this.getParentFileAt( _index );\r
1147                                 PARENT_FILE_RESITER.splice( 0, l -_index);\r
1148                         } else {\r
1149                                 currentFile = PARENT_FILE_RESITER.shift();\r
1150                         };\r
1151                         currentFile.getSeqentialFiles();\r
1152                         return currentFile;     \r
1153                 };\r
1154                 this.addTreeEventListener = function( _eventType, _callback ){\r
1155                         FILE_CONTROLER.addEventListener( null, _eventType, _callback );\r
1156                 };\r
1157                 this.removeTreeEventListener = function( _eventType, _callback ){\r
1158                         FILE_CONTROLER.removeEventListener( null, _eventType, _callback );\r
1159                 };\r
1160                 this.destroy = function( _apiuser ){\r
1161                         if( _apiuser && apiuser !== _apiuser ) return false;\r
1162                         // removeEvent\r
1163                         var _currentFile = currentFile;\r
1164                         currentFile = rootFile = rootFileData = null;\r
1165                         // currentFile, rootFile を null にしないと .File.destroy() ができない.\r
1166                         _currentFile.destroy();\r
1167                         while( PARENT_FILE_RESITER.length > 0 ){\r
1168                                 _currentFile = PARENT_FILE_RESITER.shift();\r
1169                                 _currentFile.destroy();\r
1170                         }\r
1171                         \r
1172                         AsyncCall.remove( apiuser );\r
1173                         instance = apiuser = null;\r
1174                         return true;\r
1175                 }\r
1176         };\r
1177 \r
1178         var FileEventTicketClass = function( _uid, _eventType, _callback ){\r
1179                 this.fileUID   = _uid;\r
1180                 this.eventType = _eventType;\r
1181                 this.callBack  = _callback;\r
1182                 _uid = _eventType = _callback = undefined;\r
1183         };\r
1184         FileEventTicketClass.prototype = new TicketBase();\r
1185         \r
1186         var FileEventClass = function( eventType, file, key, value ){\r
1187                 this.eventType = eventType;\r
1188                 this.targetFile = file;\r
1189                 this.updatedAttribute = key;\r
1190                 this.updatedValue = value;\r
1191         };\r
1192 \r
1193 /*\r
1194  * file の data は object で保持している。\r
1195  * File の外からファイルをみるときは、FileClassを通して操作する。\r
1196  * fileの変更、それに付随して追加されたイベントは、TreeClassで管理される。\r
1197  * treeがdestryされると、fileのイベントリスナーも全て削除される。\r
1198  * 他の tree も data の共通する currentFile に対してのみは、file の変更イベントを受け取って流す.\r
1199  * \r
1200  */\r
1201         \r
1202         var FileClass = function( tree, parentData, data ){\r
1203                 var uid = FILE_CONTROLER.getFileUID( data );\r
1204                 \r
1205                 FILEDATA_ACCESS.push( {\r
1206                         TREE:                           tree,\r
1207                         parentData:                     parentData,\r
1208                         DATA:                           data\r
1209                 } );\r
1210                 \r
1211                 tree = parentData = data = null;\r
1212 \r
1213                 this.getUID = function(){\r
1214                         return uid;\r
1215                 }\r
1216         };\r
1217         \r
1218         FileClass.prototype = {\r
1219                 isChildFile: function( _FILEorFILEDATA ){\r
1220                         return this.getChildFileIndex( _FILEorFILEDATA) !== -1;\r
1221                 },\r
1222                 getSeqentialFiles: function(){\r
1223                         var _driver = FILE_CONTROLER.getDriver( this );\r
1224                         if( _driver !== null && typeof _driver.getSeqentialFiles === 'function' ){\r
1225                                 _driver.getSeqentialFiles( this );\r
1226                         }\r
1227                 },\r
1228                 addEventListener: function( _eventType, _callback ){\r
1229                         FILE_CONTROLER.addEventListener( this, _eventType, _callback );\r
1230                 },\r
1231                 removeEventListener: function( _eventType, _callback ){\r
1232                         FILE_CONTROLER.removeEventListener( this, _eventType, _callback );\r
1233                 },\r
1234                 dispatchEvent: function( e ){\r
1235                         e instanceof FileEventClass && FILE_CONTROLER.fileEventRellay( this.getUID(), e );\r
1236                 },\r
1237                 getChildFileLength: function(){\r
1238                         var children = FILE_CONTROLER.getChildren( this );\r
1239                         return Type.isArray( children ) === true ? children.length : -1;\r
1240                 },\r
1241                 getChildFileIndex: function( _FILEorFILEDATA ){\r
1242                         var children = FILE_CONTROLER.getChildren( this );\r
1243                         if( Type.isArray( children ) === false ) return -1;\r
1244                         var l = children.length,\r
1245                                 _fileData = FILE_CONTROLER.getFileData( _FILEorFILEDATA );\r
1246                         if( _fileData === null ) return -1;\r
1247                         for( var i=0; i<l; ++i ){\r
1248                                 if( children[ i ] === _fileData ) return i;\r
1249                         }\r
1250                         return -1;\r
1251                 },\r
1252                 getChildFileByIndex: function( _index ){\r
1253                         var _access = FILE_CONTROLER.getFileDataAccess( this ),\r
1254                                 _children = FILE_CONTROLER.getChildren( this );\r
1255                         if( typeof _index !== 'number' || _index < 0 || Type.isArray( _children ) === false || _index >= _children.length) return null;\r
1256                         var _file = new FileClass( _access.TREE, _access.DATA, _children[ _index ]);\r
1257                         // _file.init();\r
1258                         return _file;\r
1259                 },\r
1260                 getName: function(){\r
1261                         var driver = FILE_CONTROLER.getDriver( this );\r
1262                         if( typeof driver.getName === 'function'){\r
1263                                 return driver.getName( this );\r
1264                         }\r
1265                         return BASE_DRIVER.getName( this);\r
1266                 },\r
1267                 getThumbnail: function(){\r
1268                         var driver = FILE_CONTROLER.getDriver( this );\r
1269                         if( typeof driver.getThumbnail === 'function'){\r
1270                                 return driver.getThumbnail( this );\r
1271                         }\r
1272                         return BASE_DRIVER.getThumbnail( this );\r
1273                 },\r
1274                 getType: function(){\r
1275                         var _data = FILE_CONTROLER.getFileData( this );\r
1276                         return typeof _data.type === 'number' ? _data.type : Const.FILE.TYPE.UNKNOWN;\r
1277                 },\r
1278                 getState: function(){\r
1279                         var _data = FILE_CONTROLER.getFileData( this );\r
1280                         return typeof _data.state === 'number' ? _data.state : Const.FILE.STATE.OK;\r
1281                 },\r
1282                 getSummary: function(){\r
1283                         var driver = FILE_CONTROLER.getDriver( this );\r
1284                         if( typeof driver.getSummary === 'function'){\r
1285                                 return driver.getSummary( this );\r
1286                         }\r
1287                         return BASE_DRIVER.getSummary( this );\r
1288                 },\r
1289                 isWritable: function(){\r
1290                         return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.WRITE );\r
1291                 },\r
1292                 isSortable: function(){\r
1293                         return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.SORT );\r
1294                 },              \r
1295                 isCreatable: function(){\r
1296                         return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.CREATE );\r
1297                 },\r
1298                 isRenamable: function(){\r
1299                         return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.RENAME );\r
1300                 },\r
1301                 isDeletable: function(){\r
1302                         return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.DELETE );\r
1303                 },\r
1304                 read: function(){\r
1305                         // simpleDeepCopy\r
1306                         var driver = FILE_CONTROLER.getDriver( this ),\r
1307                                 data;\r
1308                         if( typeof driver.read === 'function'){\r
1309                                  data = driver.read( this );\r
1310                         }\r
1311                         return BASE_DRIVER.read( data || this );\r
1312                 },\r
1313                 write: function( _newData, _onUpdateFunction ){\r
1314                         var driver = FILE_CONTROLER.getDriver( this );\r
1315                         if( typeof driver.write === 'function'){\r
1316                                 return driver.write( this, _newData, _onUpdateFunction );\r
1317                         }\r
1318                         return BASE_DRIVER.write( this, _newData, _onUpdateFunction );\r
1319                 },\r
1320                 viewerApplicationList: function(){\r
1321                         var driver = FILE_CONTROLER.getDriver( this );\r
1322                         if( typeof driver.viewerApplicationList === 'function'){\r
1323                                 return driver.viewerApplicationList( this );\r
1324                         }\r
1325                         return BASE_DRIVER.viewerApplicationList( this );\r
1326                 },\r
1327                 editorApplicationList: function(){\r
1328                         var driver = FILE_CONTROLER.getDriver( this );\r
1329                         if( typeof driver.editorApplicationList === 'function'){\r
1330                                 return driver.editorApplicationList( this );\r
1331                         }\r
1332                         return BASE_DRIVER.viwerApps( this );\r
1333                 },\r
1334                 create: function(){\r
1335                         \r
1336                 },\r
1337                 sort: function(){\r
1338                         \r
1339                 },\r
1340                 onCopy: function(){\r
1341                         \r
1342                 },\r
1343                 onDelete: function(){\r
1344                         \r
1345                 },\r
1346                 move: function( _newFolder, _newIndex, opt_callback ){\r
1347                         var _access = FILE_CONTROLER.getFileDataAccess( this );\r
1348                         _access.TREE.move( _access.parentData, this.getUID(), _newFolder, _newIndex, opt_callback );\r
1349                 },\r
1350                 replace: function( _newIndex, opt_callback ){\r
1351                         var _access = FILE_CONTROLER.getFileDataAccess( this );\r
1352                         _access.TREE.replace( _access.parentData, this.getUID(), _newIndex, opt_callback);\r
1353                 },\r
1354                 /**\r
1355                  * サーチ\r
1356                  * 探しているファイルの属性と値を指定.一致する child の index を配列で返す.\r
1357                  */\r
1358                 search: function( obj, rule ){\r
1359                         var _children = FILE_CONTROLER.getChildren( this ),\r
1360                                 _child,\r
1361                                 ret = [], k, c;\r
1362                         for( var i=0, l=_children.length; i<l; ++i ){\r
1363                                 _child = _children[ i ];\r
1364                                 c = true;\r
1365                                 for( k in obj ){\r
1366                                         if( obj[ k ] !== _child[ k ] ){\r
1367                                                 c = false;\r
1368                                                 break;\r
1369                                         }\r
1370                                 }\r
1371                                 c === true && ret.push( i );\r
1372                         }\r
1373                         return ret;\r
1374                 },\r
1375                 destroy: function(){\r
1376                         var _access = FILE_CONTROLER.getFileDataAccess( this );\r
1377                         var _tree = _access.TREE;\r
1378                         if( _tree.getCurrentFile() === this ) return;\r
1379                         if( _tree.getRootFile() === this ) return;\r
1380                         for( var i=0, l = _tree.hierarchy(); i<l; ++i ){\r
1381                                 if( _tree.getParentFileAt( i ) === this ){\r
1382                                         return;\r
1383                                 }\r
1384                         }\r
1385                         var _index = Util.getIndex( FILEDATA_ACCESS, _access );\r
1386                         if( _index === -1 ) return;\r
1387                         // event の 削除\r
1388                         FILEDATA_ACCESS.splice( _index, 1 );\r
1389                         delete _access.DATA;\r
1390                         delete _access.TREE;\r
1391                         delete _access.parentData;\r
1392                 }\r
1393         }\r
1394 \r
1395         /*\r
1396          * FileDriverBase\r
1397          */\r
1398         var FileDriverBase = function( driverClass ){\r
1399                 this.getUID = function(){\r
1400                         return Util.getIndex( API_USER_LIST, driverClass );\r
1401                 };\r
1402                 this.getSeqentialFiles = function( _file ){\r
1403                 };\r
1404                 this.getName = function( _file ){\r
1405                         var _data = FILE_CONTROLER.getFileData( _file );\r
1406                         return _data.name || 'No Name';\r
1407                 };\r
1408                 this.getThumbnail = function( _file ){\r
1409                         var _data = FILE_CONTROLER.getFileData( _file ),\r
1410                                 _type = _data.type,\r
1411                                 _className = '';\r
1412                         if( _type === Const.FILE.TYPE.FOLDER){\r
1413                                 _className = 'folder';\r
1414                         } else\r
1415                         if( _type === Const.FILE.TYPE.IMAGE){\r
1416                                 \r
1417                         } else\r
1418                         if( _type === Const.FILE.TYPE.TEXT){\r
1419                                 \r
1420                         } else\r
1421                         if( _type === Const.FILE.TYPE.HTML){\r
1422                                 \r
1423                         } else\r
1424                         if( _type === Const.FILE.TYPE.CSV){\r
1425                                 \r
1426                         } else\r
1427                         if( _type === Const.FILE.TYPE.JSON){\r
1428                                 \r
1429                         } else\r
1430                         if( _type === Const.FILE.TYPE.XML){\r
1431                                 \r
1432                         }\r
1433                         return {\r
1434                                 image:          null,\r
1435                                 className:      ' file-type-' + _className\r
1436                         }\r
1437                 };\r
1438                 this.getSummary = function( _file ){\r
1439                         var _data = FILE_CONTROLER.getFileData( _file ),\r
1440                                 _type = _data.type;\r
1441                         if( _type === Const.FILE.TYPE.FOLDER ){\r
1442                                 return 'folder';\r
1443                         } else\r
1444                         if( _type === Const.FILE.TYPE.IMAGE ){\r
1445                                 return 'image file';\r
1446                         } else\r
1447                         if( _type === Const.FILE.TYPE.TEXT ){\r
1448                                 return 'text file';\r
1449                         } else\r
1450                         if( _type === Const.FILE.TYPE.HTML ){\r
1451                                 return 'html document file';\r
1452                         } else\r
1453                         if( _type === Const.FILE.TYPE.CSV ){\r
1454                                 return 'csv daat file';\r
1455                         } else\r
1456                         if( _type === Const.FILE.TYPE.JSON ){\r
1457                                 return 'json data file';\r
1458                         } else\r
1459                         if( _type === Const.FILE.TYPE.XML ){\r
1460                                 return 'xml data file';\r
1461                         }\r
1462                         return '';\r
1463                 };\r
1464                 this.getUpdatePolicy = function( _file ){\r
1465                         // debug用 全てのメニューを許可\r
1466                         return Const.FILE.UPDATE_POLICY.DSRWC;\r
1467                 };\r
1468                 this.read = function( _FILEorDATA ){\r
1469                         var data,\r
1470                                 protects = Const.FILE.DATA_PROPERTY_RESERVED;                   \r
1471                         if( _FILEorDATA instanceof FileClass ){\r
1472                                 data = FILE_CONTROLER.getFileData( _FILEorDATA )\r
1473                         } else {\r
1474                                 data = _FILEorDATA;\r
1475                         }\r
1476 \r
1477                         function clone( src ) {\r
1478                                 var ret;\r
1479                                 if( Type.isArray(src) === true ){\r
1480                                         ret = [];\r
1481                                 } else\r
1482                                 if( Type.isObject(src) === true ){\r
1483                                         ret = {};\r
1484                                 } else\r
1485                                 if( Type.isNumber(src) === true || Type.isString(src) === true || Type.isBoolean( src ) === true ){\r
1486                                         return src;\r
1487                                 } else {\r
1488                                         return null;\r
1489                                 }\r
1490                                 for( var key in src ){\r
1491                                         if( Util.getIndex( protects, key ) === -1 ){\r
1492                                                 //alert( key )\r
1493                                                 ret[ key ] = clone( src[ key ]);\r
1494                                         }\r
1495                                 }\r
1496                                 return ret;\r
1497                         };\r
1498                                 \r
1499                         return clone( data );\r
1500                 };\r
1501                 this.write = function( _file, _newData, _onUpdateFunction ){\r
1502                         var _data = FILE_CONTROLER.getFileData( _file ),\r
1503                                 _type = _data.type;\r
1504                         return false;\r
1505                 };\r
1506                 this.viewerApplicationList = function(){\r
1507                         return [];\r
1508                 };\r
1509                 this.editorApplicationList = function(){\r
1510                         return [];\r
1511                 };\r
1512                 this.onCreate = function(){\r
1513                         \r
1514                 };\r
1515                 this.onSort = function(){\r
1516                         \r
1517                 };\r
1518                 this.onCopy = function(){\r
1519                         \r
1520                 };\r
1521                 this.onDelete = function(){\r
1522                         \r
1523                 };\r
1524         }\r
1525         \r
1526         var BASE_DRIVER   = new FileDriverBase();\r
1527         \r
1528         var ROOT_FILEDATA = {\r
1529                         name:           'system root',\r
1530                         type:           FILE_TYPE_IS_FOLDER,\r
1531                         children:       []\r
1532                 },\r
1533                 SYSTEM_TREE = FILE_CONTROLER.createTree( SUPER_USER_KEY, ROOT_FILEDATA ),\r
1534                 ROOT_FILE   = SYSTEM_TREE.getRootFile();\r
1535 \r
1536         function createFileTypeID(){\r
1537                 return ++numFileType;\r
1538         }\r
1539         \r
1540         var FileAPIClass = function( driver ){\r
1541                 var constObject;\r
1542                 this.createFolderUnderRoot = function( _fileData ){\r
1543                         if( _fileData !== null && Type.isObject( _fileData ) === true ){\r
1544                                 ROOT_FILEDATA.children.push( _fileData );\r
1545                                 ROOT_FILE.dispatchEvent( new FileEventClass( Const.FILE.EVENT.GET_SEQENTIAL_FILES, ROOT_FILE, 'children', null ));\r
1546                         }\r
1547                 };\r
1548                 this.createFileEvent   = function( _eventType, _file, _key, _value ){\r
1549                         return new FileEventClass( _eventType, _file, _key, _value );\r
1550                 };\r
1551                 this.createFileTypeID  = createFileTypeID;\r
1552                 this.getFileDataAccess = FILE_CONTROLER.getFileDataAccess;\r
1553                 this.getFileData       = FILE_CONTROLER.getFileData;\r
1554                 this.getJson           = function( _data, _url, _onLoad, _onError ){\r
1555                         REQUEST_CONTROLER.getJson( driver, _data, _url, _onLoad, _onError );\r
1556                 };\r
1557                 this.createTree        = function( _rootFile ){\r
1558                         return FILE_CONTROLER.createTree( driver, _rootFile );\r
1559                 };\r
1560                 this.isTreeInstance    = function( _tree ){\r
1561                         return _tree instanceof TreeClass;\r
1562                 };\r
1563                 this.isFileInstance    = function( _file ){\r
1564                         return _file instanceof FileClass;\r
1565                 };\r
1566                 this.isFileEvent       = function( _event ){\r
1567                         return _event instanceof FileEventClass;\r
1568                 };\r
1569                 this.getConst          = function(){\r
1570                         return Const; // constObject = constObject || clone( Const )\r
1571                 };\r
1572         }\r
1573         \r
1574         return {\r
1575                 registerDriver: function( _class ){\r
1576                         _class.prototype = new FileDriverBase( _class );\r
1577                         var _driver = new _class();\r
1578                         \r
1579                         DRIVER_LIST.push( _driver );\r
1580                         API_USER_LIST.push( _class );\r
1581 \r
1582                         return new FileAPIClass( _driver );\r
1583                 },\r
1584                 isDriver: function( _driver ){\r
1585                         return _driver instanceof FileDriverBase;\r
1586                 },\r
1587                 isTreeInstance: function( _tree ){\r
1588                         return _tree instanceof TreeClass;\r
1589                 },\r
1590                 isFileInstance: function( _file ){\r
1591                         return _file instanceof FileClass;\r
1592                 }\r
1593         }\r
1594 })();\r
1595 \r
1596 \r
1597 /* ----------------------------------------------------\r
1598  * ApplicationManager\r
1599  * window resize event, overlayApplication currentAplication に流す\r
1600  */     \r
1601 \r
1602 var APPLICATION_LIST         = [];\r
1603 \r
1604 var AbstractBasicPane = function(){\r
1605         var instance    = null;\r
1606         this.MIN_WIDTH  = 240;\r
1607         this.MIN_HEIGHT = 240;\r
1608         this.init = function(){\r
1609                 instance = this;\r
1610                 instance.onInit();\r
1611         };\r
1612         this.onInit = function(){};\r
1613         this.resize = function( _w, _h ){\r
1614                 if( instance.MIN_WIDTH > _w || instance.MIN_HEIGHT > _h ){\r
1615                         if( Type.isHTMLElement( instance.rootElement ) === true ){\r
1616                                 // 小さすぎる!、と表示\r
1617                         };\r
1618                         return;\r
1619                 };\r
1620                 instance.onPaneResize( _w, _h );\r
1621         };\r
1622         this.onPaneResize = function( _w, _h ){};\r
1623         this.close = function(){\r
1624                 instance.onClose();\r
1625                 instance = this;\r
1626         };\r
1627 }\r
1628 \r
1629 var AbstractApplication = function( displayName, appClass, isOverlay ){\r
1630         var self         = null, // init で設定\r
1631                 uiList       = [],\r
1632                 finderList   = [];\r
1633         this.rootElement = document.createElement( 'div' );\r
1634         this.bgColor     = '#C1CACF';\r
1635         this.getUID = function(){\r
1636                 return Util.getIndex( API_USER_LIST, appClass );\r
1637         }\r
1638         this.init = function(){\r
1639                 self = this;\r
1640                 self.onInit();\r
1641         };\r
1642         this.open = function( _w, _h /*, _option */ ){\r
1643                 if( self.MIN_WIDTH > _w || self.MIN_HEIGHT > _h ){\r
1644                         if( Type.isHTMLElement( self.rootElement ) === true ){\r
1645                                 // 小さすぎる!、と表示\r
1646                         }\r
1647                 }\r
1648                 if( arguments.length > 2 ){\r
1649                         self.onOpen.apply( self, arguments );\r
1650                 } else {\r
1651                         self.onOpen( _w, _h );\r
1652                 }\r
1653         };\r
1654         this.resize = function( _w, _h ){\r
1655                 if( self.MIN_WIDTH > _w || self.MIN_HEIGHT > _h ){\r
1656                         if( Type.isHTMLElement( self.rootElement ) === true ){\r
1657                                 // 小さすぎる!、と表示\r
1658                         };\r
1659                         return;\r
1660                 };\r
1661                 self.onPaneResize( _w, _h );\r
1662         };\r
1663         this.close = function(){\r
1664                 if( self.onClose() === false ){\r
1665                         return false;\r
1666                 };\r
1667                 MouseEvent.remove( self );\r
1668                 KeyEvent.remove( self );\r
1669                 SystemTimer.remove( self );\r
1670                 AsyncCall.remove( self );\r
1671                 \r
1672                 while( uiList.length > 0 ){\r
1673                         uiList.shift().destroy();\r
1674                 };\r
1675                 while( finderList.length > 0 ){\r
1676                         finderList.shift().destroy();\r
1677                 };\r
1678                 var elm = self.rootElement;\r
1679                 Util.removeAllChildren( elm );\r
1680                 elm.parentNode.removeChild( elm );\r
1681                 self.rootElement = null;\r
1682                 \r
1683                 Application.shutdown( self, isOverlay );\r
1684                 self = appClass = uiList = null;\r
1685         };\r
1686         this.createUIGroup = function(){\r
1687                 var _ui = UI.createUIGroup( self );\r
1688                 uiList.push( _ui );\r
1689                 return _ui;\r
1690         };\r
1691         this.createFinder = function( _elmTarget, _tree, _header, _footer, _onSelect, _viewerOption, _editorOption ){\r
1692                 var _finder = Finder.create( self, _elmTarget, _tree, _header, _footer, _onSelect, _viewerOption, _editorOption );\r
1693                 finderList.push( _finder );\r
1694                 return _finder;\r
1695         };\r
1696         this.createBasicPane = function( _class, _options ){\r
1697                 if( Type.isFunction( _class ) === false ) return null;\r
1698                 _class.prototype = new AbstractBasicPane();\r
1699                 return new _class( _options );\r
1700         };\r
1701 }\r
1702 \r
1703 AbstractApplication.prototype = new AbstractBasicPane();\r
1704 AbstractApplication.prototype.onInit = function(){\r
1705         // overrride\r
1706 };      \r
1707 AbstractApplication.prototype.onOpen = function( _w, _h /*, _option */ ){\r
1708         // overrride\r
1709 };\r
1710 AbstractApplication.prototype.onClose = function(){\r
1711         // overrride\r
1712         return true;\r
1713 }; // false の場合、close の拒否 \r
1714 AbstractApplication.prototype.addMouseEventListener = function( _element, _eventType, _handler ){\r
1715         MouseEvent.add( this, _element, _eventType, _handler );\r
1716 };\r
1717 AbstractApplication.prototype.removeMouseEventListener = function( _element, _eventType, _handler ){\r
1718         MouseEvent.remove( this, _element, _eventType, _handler );\r
1719 };\r
1720 AbstractApplication.prototype.addKeyEventListener = function( _eventType, _handler, _keyCode, _shift, _ctrl ){\r
1721         KeyEvent.add( this, _eventType, _handler, _keyCode, _shift, _ctrl );\r
1722 };\r
1723 AbstractApplication.prototype.removeKeyEventListener = function( _eventType, _handler, _keyCode, _shift, _ctrl ){\r
1724         KeyEvent.remove( this, _eventType, _handler, _keyCode, _shift, _ctrl );\r
1725 };\r
1726 AbstractApplication.prototype.shiftEnabled = function(){\r
1727         return KeyEvent.shiftEnabled;\r
1728 };\r
1729 AbstractApplication.prototype.ctrlEnabled = function(){\r
1730         return KeyEvent.ctrlEnabled;\r
1731 };\r
1732 AbstractApplication.prototype.addTimer = function( handler, time, once ){\r
1733         SystemTimer.add( this, handler, time, !!once );\r
1734 };\r
1735 AbstractApplication.prototype.removeTimer = function( handler ){\r
1736         SystemTimer.remove( this, handler );\r
1737 };\r
1738 AbstractApplication.prototype.addAsyncCall = function( _callback, _argments ){\r
1739         AsyncCall.add( this, _callback, _argments );\r
1740 };\r
1741 AbstractApplication.prototype.removeAsyncCall = function( _callback ){\r
1742         AsyncCall.remove( this, _callback );\r
1743 };\r
1744 AbstractApplication.prototype.fetchHTMLElement = function( id ){\r
1745         var elm = doc.getElementById( id );\r
1746         if( elm ){\r
1747                 elm.removeAttribute( 'id' );\r
1748                 elm.parentNode.removeChild( elm );\r
1749                 return elm;\r
1750         };\r
1751 };\r
1752 \r
1753 var Application = ( function(){\r
1754         \r
1755         var LIVE_APPLICATION_LIST = [];\r
1756         \r
1757         var currentApplication    = null,\r
1758                 coveredApplication    = null,\r
1759                 winW                  = 0,\r
1760                 winH                  = 0;\r
1761         \r
1762         var ApplicationReference = function( appClass, isOverlay, displayName, id, thumbnailUrl, tailColor ){\r
1763                 var self          = this;\r
1764                 var application   = null;\r
1765                 this.id           = id;\r
1766                 this.displayName  = displayName;\r
1767                 this.thumbnailUrl = thumbnailUrl;\r
1768                 this.tailColor    = tailColor;\r
1769                 this.getUID = function(){\r
1770                         return Util.getIndex( API_USER_LIST, appClass );\r
1771                 };\r
1772                 this.boot = function( /* _option */ ){\r
1773                         application = Application.boot( displayName, self.getUID(), appClass, isOverlay, Util.copyArray( arguments ) );\r
1774                 };\r
1775                 this.shutdown = function(){\r
1776                         if( !application ) return false;\r
1777                         \r
1778                         if( ( isOverlay === true ? Overlay.hide() : application.close() ) === false ) return false;\r
1779                         application = null;\r
1780                 };\r
1781         };\r
1782         \r
1783         function asyncBootHome(){\r
1784                 currentApplication === null && Home.boot();\r
1785         };\r
1786         function asyncOpen( /* arguments */ ){\r
1787                 var _arg = Util.copyArray( arguments );\r
1788                 _arg.unshift( winW, winH );\r
1789                 currentApplication.open.apply( currentApplication, _arg );\r
1790         };\r
1791         return {\r
1792                 register: function( _class, _overlay, _tail, _displayName, _id, _thumbnailUrl, _tailColor ){\r
1793                         APPLICATION_LIST.push( _class );\r
1794                         API_USER_LIST.push( _class );\r
1795                         var _ref = new ApplicationReference( _class, _overlay, _displayName, _id, _thumbnailUrl, _tailColor );\r
1796                         _tail === true && Home.add( _ref );\r
1797                         return _ref;\r
1798                 },\r
1799                 isBasicPaneInstance: function( _basicPane ){\r
1800                         return  _basicPane instanceof AbstractBasicPane;\r
1801                 },\r
1802                 isApplicationInstance: function( _application ){\r
1803                         return _application instanceof AbstractApplication;\r
1804                 },\r
1805                 isApplicationReference: function( _reference ){\r
1806                         return _reference instanceof ApplicationReference;\r
1807                 },\r
1808                 isCurrentAppplication: function( _application ){\r
1809                         return true\r
1810                 },\r
1811                 boot: function( displayName, uid, appClass, isOverlay, arg ){\r
1812                         if( currentApplication ){\r
1813                                 if( currentApplication.getUID() === uid ) return null;\r
1814                                 if( isOverlay === false && currentApplication.close() === false ) return null;\r
1815                         }\r
1816 \r
1817                         appClass.prototype = new AbstractApplication( displayName, appClass, isOverlay );\r
1818                         var application = new appClass(); // new は boot で\r
1819                         \r
1820                         coveredApplication = isOverlay === true ? currentApplication : null;\r
1821                         \r
1822                         Application.onCurrentApplicationChange( application );\r
1823                         \r
1824                         if( isOverlay === false ){\r
1825                                 body.style.backgroundColor = application.bgColor;\r
1826                                 \r
1827                                 body.appendChild( application.rootElement );\r
1828                                 application.init();\r
1829 \r
1830                                 application.addAsyncCall( asyncOpen, arg );\r
1831                         } else {\r
1832                                 Overlay.show( application, arg );\r
1833                         }\r
1834                         \r
1835                         return application;\r
1836                 },\r
1837                 shutdown: function( _application, isOverlay ){\r
1838                         if( isOverlay === false ){\r
1839                                 currentApplication = null;\r
1840                                 AsyncCall.add( SUPER_USER_KEY, asyncBootHome );\r
1841                         } else {\r
1842                                 Application.onCurrentApplicationChange( coveredApplication );\r
1843                                 coveredApplication = null;\r
1844                         }\r
1845                 },\r
1846                 onCurrentApplicationChange: function( _application ){\r
1847                         if( Application.isApplicationInstance( _application ) === false ) return;\r
1848                         if( currentApplication === _application ) return;\r
1849                         currentApplication = _application;\r
1850                         MouseEvent.onCurrentApplicationChange( _application );\r
1851                         KeyEvent.updateCurrentListener( _application );\r
1852                 },\r
1853                 onApplicationShutdown: function( _application ){\r
1854                         LIVE_APPLICATION_LIST.splice( Util.getIndex(  LIVE_APPLICATION_LIST, _application ) );\r
1855                 },\r
1856                 onWindowResize: function( w, h ){\r
1857                         winW = w;\r
1858                         winH = h;\r
1859                         currentApplication && currentApplication.resize( w, h );\r
1860                         Overlay.onWindowResize( w, h );\r
1861                         UI.onWindowResize( w, h );\r
1862                 },\r
1863                 onSystemShutdown: function(){\r
1864                         \r
1865                 }\r
1866         }\r
1867 })();\r
1868 \r
1869 /* --------------------------------------------------------------\r
1870  * Home\r
1871  * \r
1872  */\r
1873         var Home = ( function(){\r
1874                 var APP_REF_LIST    = [];\r
1875                 var ELM_TAIL_ORIGIN = ( function(){\r
1876                         var ret = document.createElement( 'div' ),\r
1877                                 h2  = document.createElement( 'h2' );\r
1878                         ret.className = 'tail-wrapper';\r
1879                         ret.appendChild( h2 );\r
1880                         h2.appendChild( document.createTextNode( 'appName' ) );\r
1881                         return ret;\r
1882                 })();\r
1883                 \r
1884                 var TailClass = function( appRef ){\r
1885                         this.elm = ELM_TAIL_ORIGIN.cloneNode( true );\r
1886                         this.destroy = function(){\r
1887                                 appRef = self = elmName = null;\r
1888                         };                      \r
1889                         \r
1890                         var self    = this,\r
1891                                 elmName = this.elm.getElementsByTagName( 'h2' )[ 0 ].firstChild;\r
1892                         \r
1893                         this.elm.style.backgroundColor = appRef.tailColor;\r
1894                         elmName.data = appRef.displayName;\r
1895                 };\r
1896                 \r
1897                 var ref = Application.register( function(){\r
1898                         var self     = this,\r
1899                                 winW     = 0,\r
1900                                 winH     = 0,\r
1901                                 tailList = [],\r
1902                                 elmContainer;\r
1903                         \r
1904                         function draw(){\r
1905                                 var tail, elm;\r
1906                                 for( var i=0, l=APP_REF_LIST.length; i<l; ++i ){\r
1907                                         tail = new TailClass( APP_REF_LIST[ i ] );\r
1908                                         tailList.push( tail );\r
1909                                         elm  = tail.elm;\r
1910                                         elmContainer.appendChild( elm );\r
1911                                         self.addMouseEventListener( elm, 'click', onTailClick );\r
1912                                 };\r
1913                         };\r
1914                         \r
1915                         function onTailClick( e ){\r
1916                                 var _children = elmContainer.getElementsByTagName( 'div' );\r
1917                                 for( var i=0, l=_children.length; i<l; ++i ){\r
1918                                         if( this === _children[ i ] ){\r
1919                                                 APP_REF_LIST[ i ].boot();\r
1920                                                 break;\r
1921                                         };\r
1922                                 };\r
1923                         };\r
1924                         \r
1925                         this.bgColor     = '#0F6D39';\r
1926                         this.MIN_WIDTH   = 320;\r
1927                         this.MIN_HEIGHT  = 320;\r
1928                         this.onInit = function(){\r
1929                                 self.rootElement.id = 'home-root';\r
1930                                 elmContainer        = document.createElement( 'div' );\r
1931                                 self.rootElement.appendChild( elmContainer );\r
1932                                 elmContainer.id     = 'home-tail-container';\r
1933                         };\r
1934                         this.onOpen = function( _w, _h ){\r
1935                                 winW = _w;\r
1936                                 winH = _h;\r
1937                                 draw();\r
1938                         };\r
1939                         this.onPaneResize = function( _w, _h ){\r
1940                                 \r
1941                         };\r
1942                         this.onClose = function(){\r
1943                                 self.removeMouseEventListener();\r
1944                                 while( tailList.length > 0 ){\r
1945                                         tailList.shift().destroy();\r
1946                                 }\r
1947                                 self = tailList = elmContainer = null;\r
1948                         };\r
1949                 }, false, false, 'home', 'home', null );\r
1950                 \r
1951                 return {\r
1952                         add: function( _appRef ){\r
1953                                 if( Application.isApplicationReference( _appRef ) === false ) return;\r
1954                                 Util.getIndex( APP_REF_LIST, _appRef ) === -1 && APP_REF_LIST.push( _appRef );\r
1955                         },\r
1956                         boot: function(){\r
1957                                 ref.boot();\r
1958                         }\r
1959                 }\r
1960         })();\r
1961 \r
1962 /* --------------------------------------------------------------\r
1963  * Event\r
1964  * \r
1965  *  screenX\r
1966  *  スクリーン座標は、コンピュータのディスプレイの左上を原点とする座標系である。screenX, screenY属性で取得できる。Javascritpでは、同名のプロパティとして実装されている。\r
1967  *  しかし、これは、現実的には、何の役に立たない。ブラウザ自体がディスプレイのどの位置にいるのかがわからないので、画面上の位置を知ったところで、何にもならないからだ。 \r
1968  * \r
1969  *  clientX\r
1970  *  ウインドウ座標とは、現在のブラウザのウインドウの、ドキュメントを表示している部分の左上原点とした座標である。\r
1971  *  問題は、ウインドウは、必ずしもドキュメント全体を表示するとは限らない。スクロールと呼ばれるUIによって、ドキュメントの一部だけを表示しているかもしれない。
1972  */\r
1973         var XBrowserEvent = ( function(){\r
1974                 var wrappedHandlerClass,\r
1975                         wrappedEventClass,\r
1976                         tmp;\r
1977                 \r
1978                 if( window.addEventListener ){\r
1979                         wrappedHandlerClass = function( element, handler ){\r
1980                                 this.handler = function( e ){\r
1981                                         if( handler.call( element, e ) !== false ) return;\r
1982                                         e.preventDefault();\r
1983                                         e.stopPropagation();\r
1984                                         return false;\r
1985                                 };\r
1986                                 this.destroy = function(){\r
1987                                         element = handler = null;\r
1988                                         delete this.handler;\r
1989                                         delete this.destroy;\r
1990                                 };\r
1991                         }\r
1992                 } else {\r
1993                         wrappedEventClass = function( e, element ){\r
1994                                 this._event        = e;\r
1995                                 this.type          = e.type;\r
1996                                 this.target        = e.srcElement;\r
1997                                 this.currentTarget = element;\r
1998                                 this.relatedTarget = e.formElement ? e.formElement : e.toElement;\r
1999                                 this.eventPhase    = e.srcElement === element ? 2: 3;\r
2000                                 \r
2001                                 this.clientX       = e.clientX;\r
2002                                 this.clientY       = e.clientY;\r
2003                                 this.screenX       = e.screenX;\r
2004                                 this.screenY       = e.screenY;\r
2005                                 \r
2006                                 this.altKey        = e.altKey;\r
2007                                 this.ctrlKey       = e.ctrlKey;\r
2008                                 this.shiftKey      = e.shiftKey;\r
2009                                 this.charCode      = e.keyCode;\r
2010                                 \r
2011                                 this.wheelDelta    = e.wheelDelta;\r
2012                                 \r
2013                                 e = element = null;\r
2014                         }\r
2015                         wrappedEventClass.prototype.stopPropagation = function(){\r
2016                                 this._event.cancelBubble = true;\r
2017                         }\r
2018                         wrappedEventClass.prototype.preventDefault  = function(){\r
2019                                 this._event.returnValue = false;\r
2020                         }\r
2021 \r
2022                         if( doc.attachEvent ){\r
2023                                 wrappedHandlerClass = function( element, handler ){\r
2024                                         this.handler = function(){\r
2025                                                 var e = new wrappedEventClass( window.event, element );\r
2026                                                 if( handler.call( element, e ) !== false ) return;\r
2027                                                 e.preventDefault();\r
2028                                                 e.stopPropagation();\r
2029                                         e._event.keyCode = 0;\r
2030                                                 return false;\r
2031                                         };\r
2032                                         this.destroy = function(){\r
2033                                                 element = handler = null;\r
2034                                                 delete this.handler;\r
2035                                                 delete this.destroy;\r
2036                                         };\r
2037                                 };\r
2038                         } else {\r
2039                                 tmp = {\r
2040                                         list: [],\r
2041                                         find: function( _ticket ){\r
2042                                                 for( var i=0, l= tmp.list.length, _item; i<l; ++i ){\r
2043                                                         _item = tmp.list[ i ];\r
2044                                                         if( _item.match( _ticket.element, _ticket.eventType ) === true ){\r
2045                                                                 return _item;\r
2046                                                         };\r
2047                                                 };\r
2048                                                 return null;\r
2049                                         }\r
2050                                 };\r
2051                                 tmp.ticketClass = function( _ticket ){\r
2052                                         var self = this;\r
2053                                         this.element   = _ticket.element;\r
2054                                         this.eventType = _ticket.eventType;\r
2055                                         this.handlers  = [ _ticket.handler ];\r
2056                                         this.element[ 'on' + this.eventType ] = function( e ){\r
2057                                                 return self.fire( self, e );\r
2058                                         };\r
2059                                         _ticket = null;\r
2060                                 };\r
2061                                 tmp.ticketClass.prototype = {\r
2062                                         add: function( _ticket ){\r
2063                                                 this.match( _ticket.element, _ticket.eventType ) === true && \r
2064                                                         this.match( null, null, _ticket.handler ) === false &&\r
2065                                                                 this.handlers.push( _ticket.handler );\r
2066                                         },\r
2067                                         remove: function( _ticket ){\r
2068                                                 if( this.match( _ticket.element, _ticket.eventType, _ticket.handler ) === true ){\r
2069                                                         var i = Util.getIndex( this.handlers, handler );\r
2070                                                         i !== 0 && this.handlers.splice( i, 1 );\r
2071                                                         this.handlers.length === 0 && this.destroy();\r
2072                                                 }\r
2073                                         },\r
2074                                         fire: function( self, e ){\r
2075                                                 e = e || new wrappedEventClass( window.event, self.element );\r
2076                                                 for( var i=self.handlers.length, cancel; i; ){\r
2077                                                         self.element._currentHandler = self.handlers[ --i ];\r
2078                                                         if( self.element._currentHandler( e ) === false ) cancel = false;\r
2079                                                         delete self.element._currentHandler;\r
2080                                                 };\r
2081                                                 return cancel;\r
2082                                         },\r
2083                                         match: function( element, eventType, handler ){\r
2084                                                 if( handler && Util.getIndex( this.handlers, handler ) === -1 ) return false;\r
2085                                                 if( eventType && this.eventType !== eventType ) return false;\r
2086                                                 if( element && this.element !== element ) return false;\r
2087                                                 return true;\r
2088                                         },\r
2089                                         destroy: function(){\r
2090                                                 this.element[ 'on' + this.eventType ] = '';\r
2091                                                 tmp.list.splice( Util.getIndex( tmp.list, this ), 1 );\r
2092                                                 delete this.element;\r
2093                                                 delete this.eventType;\r
2094                                                 delete this.handlers;\r
2095                                         }\r
2096                                 };\r
2097                         };\r
2098                 };\r
2099 \r
2100                 return {\r
2101                         add: function( _ticket ){\r
2102                                 if( doc.addEventListener ){\r
2103                                         XBrowserEvent.add = function( _ticket ){\r
2104                                                 _ticket.wrappedHandler = new wrappedHandlerClass( _ticket.element, _ticket.handler );\r
2105                                                 _ticket.element.addEventListener( _ticket.eventType, _ticket.wrappedHandler.handler, false );\r
2106                                         }\r
2107                                 } else\r
2108                                 if( doc.attachEvent ){\r
2109                                         XBrowserEvent.add = function( _ticket ){\r
2110                                                 _ticket.wrappedHandler = new wrappedHandlerClass( _ticket.element, _ticket.handler );\r
2111                                                 _ticket.element.attachEvent( 'on' + _ticket.eventType, _ticket.wrappedHandler.handler );\r
2112                                         };\r
2113                                 } else {\r
2114                                         XBrowserEvent.add = function( _ticket ){\r
2115                                                 var t = tmp.find( _ticket );\r
2116                                                 if( t !== null ){\r
2117                                                         t.add( _ticket );\r
2118                                                 } else {\r
2119                                                         tmp.list.push( new tmp.ticketClass( _ticket ) );\r
2120                                                 };\r
2121                                         };\r
2122                                 }\r
2123                                 \r
2124                                 XBrowserEvent.add( _ticket );\r
2125                         },\r
2126                         remove: function( _ticket ){\r
2127                                 if( doc.removeEventListener ){\r
2128                                         XBrowserEvent.remove = function( _ticket ){\r
2129                                                 _ticket.element.removeEventListener( _ticket.eventType, _ticket.wrappedHandler.handler, false );\r
2130                                                 _ticket.wrappedHandler.destroy();\r
2131                                         };\r
2132                                 } else\r
2133                                 if( doc.detachEvent ){\r
2134                                         XBrowserEvent.remove = function( _ticket ){\r
2135                                                 _ticket.element.detachEvent( 'on' + _ticket.eventType, _ticket.wrappedHandler.handler );\r
2136                                                 _ticket.wrappedHandler.destroy();\r
2137                                         };\r
2138                                 } else {\r
2139                                         XBrowserEvent.remove = function( _ticket ){\r
2140                                                 var t = tmp.find( _ticket );\r
2141                                                 if( t !== null ){\r
2142                                                         t.remove( _ticket );\r
2143                                                 };\r
2144                                         };\r
2145                                 };\r
2146                                 \r
2147                                 XBrowserEvent.remove( _ticket );\r
2148                         }\r
2149                 }\r
2150         })();\r
2151 \r
2152 /*\r
2153  * EventTicketClass\r
2154  */\r
2155         var EventTicketClass = function( _element, _eventType, _handler ){\r
2156                 this.element        = _element;\r
2157                 this.eventType      = _eventType;\r
2158                 this.handler        = _handler;\r
2159                 this.wrappedHandler = null; // for ie\r
2160                 \r
2161                 XBrowserEvent.add( this );\r
2162                 \r
2163                 _element = _eventType = _handler = null;\r
2164         };\r
2165         EventTicketClass.prototype = {\r
2166                 match: function( _element, _eventType, _handler ){\r
2167                         if( _handler   && _handler   !== this.handler )   return false;\r
2168                         if( _eventType && _eventType !== this.eventType ) return false;\r
2169                         if( _element   && _element   !== this.element )   return false;\r
2170                         \r
2171                         return true;\r
2172                 },\r
2173                 destroy: function( _element, _eventType, _handler ){\r
2174                         if( this.match( _element, _eventType, _handler ) === false ) return false;\r
2175                         \r
2176                         XBrowserEvent.remove( this );\r
2177                         \r
2178                         delete this.element;\r
2179                         delete this.eventType;\r
2180                         delete this.handler;\r
2181                         delete this.wrappedHandler;\r
2182                         \r
2183                         return true;\r
2184                 }\r
2185         };\r
2186 \r
2187 var ReadyEvent = ( function(){\r
2188         var timer  = null,\r
2189                 script = null,\r
2190                 ticketReady,\r
2191                 ticketLoad;\r
2192 \r
2193         function detect(){\r
2194                 var state = document.readyState;\r
2195                 if( state === 'loaded' || state === 'complete' ){\r
2196                         timer && window.clearInterval( timer );\r
2197                         timer = null;\r
2198                         onReady();\r
2199                 }\r
2200         }\r
2201         function ieDetect(){\r
2202                 if( this.readyState === 'loaded' || this.readyState === 'complete' ){\r
2203                         this.onreadystatechange = new Function();\r
2204                         this.onreadystatechange = null;\r
2205                         this.parentNode.removeChild( this );\r
2206                         script = null;\r
2207                         onReady();\r
2208                 }\r
2209         }\r
2210         \r
2211         function onReady(){\r
2212                 Home.boot();\r
2213                 ticketReady && ticketReady.destroy();\r
2214                 ticketLoad  && ticketLoad.destroy();\r
2215                 ticketReady = ticketLoad = null;\r
2216         }\r
2217         \r
2218         // Apple WebKit (Safari, OmniWeb, ...)\r
2219         if( doc.readyState && !!UA.WEBKIT ){\r
2220                 timer = window.setInterval( detect, 50 );\r
2221         } else\r
2222         if( document.readyState && UA.isIE ){\r
2223                 document.write('<script type="text/javascript" defer="defer" id="ieDOMContentLoaded" src="' +\r
2224                         ( ( window.location.protocol === 'https:' ) ? '://0' : 'javascript:void(0)' ) +\r
2225                         '"><\/script>');\r
2226                 script = document.getElementById( 'ieDOMContentLoaded' );\r
2227                 script.onreadystatechange = ieDetect;\r
2228         } else {\r
2229                 ticketReady = new EventTicketClass( doc, 'DOMContentLoaded', onReady );\r
2230                 ticketLoad  = new EventTicketClass( doc, 'load', onReady );\r
2231         }\r
2232 })();\r
2233 \r
2234 \r
2235 \r
2236 \r
2237 /* =====================================================\r
2238  *  ResizeEvent\r
2239  * \r
2240  */\r
2241 \r
2242 var ResizeEvent = ( function(){\r
2243         var _globalLock = 0;\r
2244         var _resize;\r
2245         var root = window;\r
2246         var w = 0, h = 0;\r
2247         \r
2248         function getInnerSize(){\r
2249                 return {\r
2250                         w : root.innerWidth || root.clientWidth,\r
2251                         h : root.innerHeight || root.clientHeight\r
2252                 };\r
2253         }\r
2254         function unlock(){\r
2255                 _globalLock = 0;\r
2256         }\r
2257         \r
2258         if( document.uniqueID ){\r
2259                 _resize = function(){\r
2260                         root = (doc.compatMode || "") !== "CSS1Compat" ? doc.body : doc.documentElement;\r
2261 \r
2262                         // resize agent\r
2263                         function loop(){\r
2264                                 if( !_globalLock++ ){\r
2265                                         var size = getInnerSize();\r
2266                                         if( w !== size.w || h !== size.h ){// resized\r
2267                                                 w = size.w;\r
2268                                                 h = size.h;\r
2269                                                 // update\r
2270                                                 Application.onWindowResize( w, h );\r
2271                                         }\r
2272                                         window.setTimeout( unlock, 0 );\r
2273                                         // delay unlock\r
2274                                 }\r
2275                                 window.setTimeout( loop, 100 );\r
2276                         }\r
2277                         loop();\r
2278                 };\r
2279         } else {\r
2280                 _resize = function(){\r
2281                         new EventTicketClass( window, 'resize', onResize );\r
2282                         \r
2283                         function onResize(){\r
2284                                 if( !_globalLock++ ) {\r
2285                                         var size = getInnerSize();\r
2286                                         if( w !== size.w || h !== size.h ){// resized\r
2287                                                 w = size.w;\r
2288                                                 h = size.h;\r
2289                                                 // update\r
2290                                                 Application.onWindowResize( w, h );\r
2291                                         }\r
2292                                         window.setTimeout( unlock, 0 );\r
2293                                 }\r
2294                         }\r
2295                         onResize();\r
2296                 };\r
2297         }\r
2298         AsyncCall.add( SUPER_USER_KEY, _resize );\r
2299         \r
2300         return {\r
2301                 getSize: getInnerSize,\r
2302                 onSystemShutdown: function(){\r
2303                         \r
2304                 }\r
2305         }\r
2306 })();\r
2307 \r
2308 \r
2309 /* =====================================================\r
2310  *  MouseEvent\r
2311  * 
2312  */\r
2313         var MouseEvent = ( function(){\r
2314                 var CLICK_OFFSET   = 2 * 2;             \r
2315                 \r
2316                 var EVENT_LIST_MAP = [],\r
2317                         TMP = {},\r
2318                         currentEventList;\r
2319 \r
2320                 /* ClickHelper\r
2321                  * mousedown, mouseup, の移動距離を調べて clickハンドラ を呼ぶ\r
2322                  */\r
2323                 var ClickEventTicketClass = function( element, clickhandler ){\r
2324                         var startX, startY,\r
2325                                 mousedownTicket = new EventTicketClass( element, 'mousedown', mousedownHandler ),\r
2326                                 mouseupTicket, mouseoutTicket;\r
2327                         \r
2328                         function mousedownHandler( e ){\r
2329                                 startX = e.clientX;\r
2330                                 startY = e.clientY;\r
2331                                 \r
2332                                 mouseupTicket  = new EventTicketClass( element, 'mouseup', mouseupHandler );\r
2333                                 mouseoutTicket = new EventTicketClass( element, 'mouseout', mouseoutHandler );                          \r
2334                         }\r
2335                         \r
2336                         function mouseupHandler( e ){\r
2337                                 var offsetX = e.clientX - startX,\r
2338                                         offsetY = e.clientY - startY;\r
2339                                 mouseoutHandler();\r
2340                                 if( offsetX * offsetX + offsetY * offsetY < CLICK_OFFSET ){\r
2341                                         if( Function.prototype.call ){\r
2342                                                 return clickhandler.call( element, e );\r
2343                                         }\r
2344                                         element._currentHandler = clickhandler;\r
2345                                         var ret = element._currentHandler( e );\r
2346                                         delete element._currentHandler;\r
2347                                         return ret;\r
2348                                 };\r
2349                         };\r
2350                         function mouseoutHandler( e ){\r
2351                                 mouseupTicket && mouseupTicket.destroy();\r
2352                                 mouseoutTicket && mouseoutTicket.destroy();\r
2353                                 mouseupTicket = mouseoutTicket = null;\r
2354                         };\r
2355                         \r
2356                         this.element = element;\r
2357                         this.handler = clickhandler;            \r
2358                         this.destroy = function( _element, _eventType, _handler ){\r
2359                                 if( this.match( _element, _eventType, _handler ) === false ) return false;\r
2360                                 \r
2361                                 mouseoutHandler();\r
2362                                 mousedownTicket.destroy();\r
2363                                 element = clickhandler = mousedownTicket = null;\r
2364                                 \r
2365                                 delete this.element;\r
2366                                 delete this.eventType;\r
2367                                 delete this.handler;\r
2368                                 \r
2369                                 return true;\r
2370                         };\r
2371                 };\r
2372                 ClickEventTicketClass.prototype = {\r
2373                         eventType: 'click',\r
2374                         match    : EventTicketClass.prototype.match\r
2375                 };\r
2376                 \r
2377                 /* WheelHelper\r
2378                  */\r
2379                 var WheelEventTicketClass = ( function(){\r
2380                         if( UA.GECKO ){\r
2381                                 return function( element, wheelhandler ){\r
2382                                         this.wheelTicket = new EventTicketClass( element, 'DOMMouseScroll', onWheel );\r
2383                                         this.element     = element;\r
2384                                         this.handler     = wheelhandler;\r
2385                                         this.destroy     = function( _element, _eventType, _handler ){\r
2386                                                 if( this.match( _element, _eventType, _handler ) === false ) return false;\r
2387                                                 element = wheelhandler = null;\r
2388                                                 \r
2389                                                 this.wheelTicket && this.wheelTicket.destroy();\r
2390                                                 \r
2391                                                 delete this.wheelTicket;\r
2392                                                 delete this.element;\r
2393                                                 delete this.handler;\r
2394                                                 \r
2395                                                 return true;\r
2396                                         };\r
2397                                         \r
2398                                         function onWheel( e ){\r
2399                                                 e.wheelDelta = e.detail * -40;\r
2400                                                 return wheelhandler.call( element, e );\r
2401                                         }\r
2402                                 };\r
2403                         } else\r
2404                         if( true || UA.isIE ){\r
2405                                 return function( element, wheelhandler ){\r
2406                                         this.wheelTicket    = new EventTicketClass( element, 'mousewheel', wheelhandler );\r
2407                                         this.element        = element;\r
2408                                         this.handler        = wheelhandler;\r
2409                                         element = wheelhandler = null;\r
2410                                 };\r
2411                         } else {\r
2412                                 TMP.wheelList   = [];\r
2413                                 //TMP.wheelLegacy = undefined;\r
2414                                 TMP.onWheel   = function( e ){\r
2415                                         e = e || window.event;\r
2416                                         var cancel = true,\r
2417                                                 f = TMP.wheelLegacy;\r
2418                                         if( f ) cancel = f.call( this, e );\r
2419                                         \r
2420                                         for( i = TMP.wheelList.length; i; ){\r
2421                                                 if( TMP.wheelList[ --i ].call( this, e ) === false ) cancel = false;\r
2422                                         }\r
2423                                         return cancel;\r
2424                                 };\r
2425                                 return function( element, wheelhandler ){\r
2426                                         this.wheelTicket    = null;\r
2427                                         this.element        = element;\r
2428                                         this.handler        = wheelhandler;\r
2429                                         this.destroy        = function( _element, _eventType, _handler ){\r
2430                                                 if( this.match( _element, _eventType, _handler ) === false ) return false;\r
2431                                                 \r
2432                                                 TMP.wheelList.splice( Util.getIndex( TMP.wheelList, this.handler ) );\r
2433                                                 if( TMP.wheelList.length === 0 ) this.element.onmousewheel = '';\r
2434                                                 \r
2435                                                 delete this.element;\r
2436                                                 delete this.handler;\r
2437                                                 \r
2438                                                 return true;\r
2439                                         };\r
2440                                         \r
2441                                         if( TMP.wheelList.length === 0 ){\r
2442                                                 //TMP.wheelLegacy     = Type.isFunction( window.onmousewheel ) === true ? window.onmousewheel : undefined;\r
2443                                                 element.onmousewheel = TMP.onWheel;\r
2444                                         };\r
2445                                         TMP.wheelList.push( wheelhandler );\r
2446                                         element = wheelhandler = null;\r
2447                                 };\r
2448                         }\r
2449                 })();\r
2450                 WheelEventTicketClass.prototype = {\r
2451                         eventType : 'mousewheel',\r
2452                         match     : EventTicketClass.prototype.match,\r
2453                         destroy   : function( _element, _eventType, _handler ){\r
2454                                 if( this.match( _element, _eventType, _handler ) === false ) return false;\r
2455                                 \r
2456                                 this.wheelTicket && this.wheelTicket.destroy();\r
2457                                 \r
2458                                 delete this.wheelTicket;\r
2459                                 delete this.element;\r
2460                                 delete this.handler;\r
2461                                 \r
2462                                 return true;\r
2463                         }\r
2464                 };\r
2465                 \r
2466                 \r
2467                 return {\r
2468                         add: function( _apiuser, _element, _eventType, _handler ){\r
2469                                 if( isApiUser( _apiuser ) === true &&\r
2470                                         ( Type.isHTMLElement( _element ) === true || _element === window || _element === doc ) &&\r
2471                                         Type.isString( _eventType ) === true &&\r
2472                                         Type.isFunction( _handler ) === true\r
2473                                 ){\r
2474                                         var _uid    = _apiuser.getUID(),\r
2475                                                 _events = EVENT_LIST_MAP[ _uid ];\r
2476                                         if( Type.isArray( _events ) === false ){\r
2477                                                 _events = EVENT_LIST_MAP[ _uid ] = [];\r
2478                                         } else {\r
2479                                                 // 2重登録の禁止\r
2480                                                 for( var i=0, l=_events.length; i<l; ++i ){\r
2481                                                         if( _events[ i ].match( _element, _eventType, _handler ) === true ) return;\r
2482                                                 }\r
2483                                         };\r
2484                                         if( _eventType === 'click' ){\r
2485                                                 _events.push( new ClickEventTicketClass( _element, _handler ) );\r
2486                                         } else\r
2487                                         if( _eventType === 'mousewheel' ){\r
2488                                                 _events.push( new WheelEventTicketClass( _element, _handler ) );\r
2489                                         } else {\r
2490                                                 _events.push( new EventTicketClass( _element, _eventType, _handler ) );\r
2491                                         };\r
2492                                 };\r
2493                         },\r
2494                         remove: function( _apiuser, _element, _eventType, _handler ){\r
2495                                 if( isApiUser( _apiuser ) === true ){\r
2496                                         var _uid    = _apiuser.getUID(),\r
2497                                                 _events = EVENT_LIST_MAP[ _uid ],\r
2498                                                 _removed,\r
2499                                                 i = 0;\r
2500                                         if( Type.isArray( _events ) === false ) return;\r
2501                                         for( ;i < _events.length; ){\r
2502                                                 if( _events[ i ].destroy( _element, _eventType, _handler ) === true ){\r
2503                                                         _events.splice( i, 1 );\r
2504                                                 } else {\r
2505                                                         ++i;\r
2506                                                 }\r
2507                                         }\r
2508                                         if( _events.length === 0 ){\r
2509                                                 _events = EVENT_LIST_MAP[ _uid ] = null;\r
2510                                         }\r
2511                                 }\r
2512                         },\r
2513                         onCurrentApplicationChange: function(){\r
2514                                 \r
2515                         },\r
2516                         onApplicationShutdown: function(){\r
2517                                 \r
2518                         },\r
2519                         onSystemShutdown: function(){\r
2520                                 \r
2521                         }\r
2522                 }\r
2523         })();\r
2524 \r
2525 /* ----------------------------------------\r
2526  * KEY\r
2527  * \r
2528  *  - EDITABLE_TEXT_CONTROL\r
2529  * \r
2530  *    .SHIFT_DOWN_EVENT:        'shiftDown',\r
2531  *    .SHIFT_UP_EVENT:          'shiftUp',\r
2532  *    .CTRL_DOWN_EVENT:         'ctrlDown',\r
2533  *    .CTRL_UP_EVENT:           'ctrlUp',\r
2534  *    .SPACE_DOWN_EVENT:        'spaceDown',\r
2535  *    .SPACE_UP_EVENT:          'spaceUp',\r
2536  *    .init:                            function,\r
2537  *    .addKeyDownEvent:         function,\r
2538  *    .keyEventDispatcher:      function,\r
2539  * \r
2540  * ショートカットキーの監視とテキスト入力(input, textarea)、チェックボックスを管理する。\r
2541  * キー入力はdocumentで受けて、テキスト編集中(input, textarea)はそちらにキーイベント流す。\r
2542  * \r
2543  */\r
2544 var KeyEvent = ( function(){\r
2545         var EVENT_LIST_MAP = [],\r
2546                 application    = null,\r
2547                 currentList    = null;\r
2548 \r
2549         window.focus();\r
2550         \r
2551         var focusTicket    = null,\r
2552                 keydownTicket  = null,\r
2553                 keyupTicket    = null,\r
2554                 keyPress       = null,\r
2555                 keypressTicket = null;\r
2556 \r
2557         function onKeyChange( e ){\r
2558                 var cancel         = false,\r
2559                         type           = e.type,\r
2560                         key            = e.keyCode || e.charCode || e.which,\r
2561                         shift          = Type.isBoolean( e.shiftKey ) === true ? e.shiftKey : ( e.modifiers & Event.SHIFT_MASK ),\r
2562                         ctrl           = Type.isBoolean( e.ctrlKey  ) === true ? e.ctrlKey  : ( e.modifiers & Event.CONTROL_MASK ),\r
2563                         t;\r
2564 \r
2565                 if( key === 16 || shift === true ){\r
2566                         KeyEvent.shiftEnabled = type !== 'keyup';\r
2567                 }\r
2568                 if( key === 17 || ctrl === true ){\r
2569                         KeyEvent.ctrlEnabled  = type !== 'keyup';\r
2570                 }\r
2571 \r
2572                 for( var i=currentList.length; t = currentList[ --i ]; ){\r
2573                         if( Type.isFunction( t[ type ] ) === true && t.keyCode === key && ( t.shift === undefined || t.shift === shift ) && ( t.ctrl === undefined || t.ctrl === ctrl )){\r
2574                                 AsyncCall.add( t.apiuser, t[ type ], e );\r
2575                                 cancel = true;\r
2576                         }\r
2577                 }\r
2578                 if( cancel === true || key === 18 || key === 9 || key === 27 || e.altKey === true ){ // 13.enter 18.esc 9.tab 27.esc   || ( key === 13 && overlayEnabled === false)\r
2579                         return false;\r
2580                 }\r
2581         }\r
2582         \r
2583         if( UA.isIE === true && UA.ieRenderingVersion < 9 ){\r
2584                 keyPress = function( e ){\r
2585                         var key = e.charCode;\r
2586                         if( key === 13 || key === 27 ){\r
2587                                 e.type = 'keydown';\r
2588                                 return onKeyChange( e );\r
2589                         };\r
2590                 };\r
2591         };\r
2592         \r
2593         var KeyEventTicketClass = function( _apiuser, _type, _onKeydown, _onKeyup, _keyCode, _shift, _ctrl ){\r
2594                 this.apiuser = _apiuser;\r
2595                 this.type    = _type;\r
2596                 this.keydown = _onKeydown;\r
2597                 this.keyup   = _onKeyup;                \r
2598                 this.keyCode = _keyCode;\r
2599                 this.shift   = _shift;\r
2600                 this.ctrl    = _ctrl;\r
2601                 _apiuser = _onKeydown = _onKeyup = null;\r
2602         }\r
2603         KeyEventTicketClass.prototype = {\r
2604                 match: function( _apiuser, _type, _handler, _keyCode, _shift, _ctrl ){\r
2605                         if( _apiuser  && _apiuser  !== this.apiuser ) return false;\r
2606                         if( _type     && _type     !== this.type )    return false;\r
2607                         if( _handler ){\r
2608                                 if( this.type === 'keydown' ){\r
2609                                         if( _handler !== this.keydown ) return false;\r
2610                                 } else {\r
2611                                         if( _handler !== this.keyup )   return false;\r
2612                                 }\r
2613                         }\r
2614                         if( _keyCode  && _keyCode  !== this.keyCode ) return false;\r
2615                         if( _shift    && _shift    !== this.shift )   return false;\r
2616                         if( _ctrl     && _ctrl     !== this.ctrl )    return false;\r
2617                         return true;\r
2618                 },\r
2619                 destroy: function( _apiuser, _type, _handler, _keyCode, _shift, _ctrl ){\r
2620                         if( this.match( _apiuser, _type, _handler, _keyCode, _shift, _ctrl ) === false ) return false;\r
2621                         \r
2622                         delete this.apiuser;\r
2623                         delete this.keydown;\r
2624                         delete this.keyup;\r
2625                         \r
2626                         return true;\r
2627                 }\r
2628         }\r
2629         \r
2630         function registerEvent( _apiuser, _type, _onKeydown, _onKeyup, _keyCode, _shift, _ctrl ){\r
2631                 var _uid  = _apiuser.getUID(),\r
2632                         _list = EVENT_LIST_MAP[ _uid ];\r
2633                 if( Type.isArray( _list ) === false ){\r
2634                         _list = EVENT_LIST_MAP[ _uid ] = [];\r
2635                 }\r
2636                 for( var i=0, l=_list.length; i<l; ++i ){\r
2637                         if( _list[ i ].match( _apiuser, _type, _onKeydown || _onKeyup, _keyCode, _shift, _ctrl ) === true ) return;\r
2638                 }\r
2639                 _list.push( new KeyEventTicketClass( _apiuser, _type, _onKeydown, _onKeyup, _keyCode, _shift, _ctrl ));\r
2640                 \r
2641                 if( _apiuser === application ) KeyEvent.updateCurrentListener( _apiuser );\r
2642         };\r
2643         \r
2644         return {\r
2645                 add: function( _apiuser, _type, _handler, _keyCode, _shift, _ctrl ){\r
2646                         if( _type === 'keydown' ){\r
2647                                 registerEvent( _apiuser, _type, _handler, null, _keyCode, _shift, _ctrl );\r
2648                         } else\r
2649                         if( _type === 'keyup' ){\r
2650                                 registerEvent( _apiuser, _type, null, _handler, _keyCode, _shift, _ctrl );\r
2651                         } else\r
2652                         if( _type === 'keychange' ){\r
2653                                 registerEvent( _apiuser, _type, _handler, _handler, _keyCode, _shift, _ctrl );\r
2654                         } else\r
2655                         if( _type === 'cursol' ){\r
2656                                 \r
2657                         }\r
2658                 },\r
2659                 remove: function( _apiuser, _type, _handler, _keyCode, _shift, _ctrl ){\r
2660                         var _list = EVENT_LIST_MAP[ _apiuser.getUID() ],\r
2661                                 i = 0;\r
2662                         if( Type.isArray( _list ) === true ){\r
2663                                 while( i < _list.length ){\r
2664                                         if( _list[ i ].destroy( _apiuser, _type, _handler, _keyCode, _shift, _ctrl ) === true ){\r
2665                                                 _list.splice( i, 1 );\r
2666                                         } else {\r
2667                                                 ++i;\r
2668                                         }\r
2669                                 }\r
2670                         }\r
2671                         if( _apiuser === application ) KeyEvent.updateCurrentListener( _apiuser );\r
2672                 },\r
2673                 shiftEnabled: false,\r
2674                 ctrlEnabled:  false,\r
2675                 /*\r
2676                  * currentListener\r
2677                  *  currrentApplication ( overlay Application ) or\r
2678                  *  superuser ( UI )
2679                  */\r
2680                 updateCurrentListener: function( _apiuser ){\r
2681                         application = _apiuser;\r
2682                         currentList = EVENT_LIST_MAP[ _apiuser.getUID() ] || [];\r
2683                         \r
2684                         var _ticket,\r
2685                                 _down = false,\r
2686                                 _up   = false;\r
2687                         for( var i=currentList.length; _ticket = currentList[ --i ]; ){\r
2688                                 if( _down === false ) _down = !!_ticket.keydown;\r
2689                                 if( _up   === false ) _up   = !!_ticket.keyup;\r
2690                                 if( _down && _up ) break;\r
2691                         }\r
2692                         if( _down === true ){\r
2693                                 keydownTicket = new EventTicketClass( doc, 'keydown', onKeyChange );\r
2694                                 keypressTicket = keyPress !== null ? new EventTicketClass( doc, 'keypress', keyPress ) : null;\r
2695                         } else {\r
2696                                 keydownTicket && keydownTicket.destroy();\r
2697                                 keypressTicket && keypressTicket.destroy();\r
2698                                 keydownTicket = keypressTicket = null;\r
2699                         }\r
2700                         if( _up === true ){\r
2701                                 keyupTicket   = new EventTicketClass( doc, 'keyup', onKeyChange );\r
2702                         } else {\r
2703                                 keyupTicket && keyupTicket.destroy();\r
2704                                 keyupTicket = null;\r
2705                         }\r
2706                         \r
2707                         if( _down === true || _up === true ){\r
2708                                 focusTicket   = new EventTicketClass( doc, 'mouseenter', window.focus );\r
2709                         } else {\r
2710                                 focusTicket && focusTicket.destroy();\r
2711                                 focusTicket = null;\r
2712                         }\r
2713                 },\r
2714                 onApplicationShutdown: function( _apiuser ){\r
2715                         KeyEvent.remove( _apiuser );\r
2716                 },\r
2717                 onSystemShutdown: function(){\r
2718                         \r
2719                 }\r
2720         }\r
2721 })();\r
2722 \r
2723 /* ----------------------------------------\r
2724  * 
2725  */\r
2726 \r
2727 var Overlay = ( function(){\r
2728         var elmContainer, elmShadow, elmCloseButton,\r
2729                 application    = null,\r
2730                 visible        = false,\r
2731                 bodyOverflow   = '',\r
2732                 windowW, windowH;\r
2733 \r
2734         function onCloseClick( e ){\r
2735                 Overlay.hide();\r
2736                 return false;\r
2737         };\r
2738         function asyncInit( /* arguments */ ){  \r
2739                 \r
2740                 //body.appendChild( application.rootElement );\r
2741                 elmContainer.insertBefore( application.rootElement, elmCloseButton );\r
2742                 application.init();\r
2743                 \r
2744                 \r
2745         };\r
2746         function asyncOpen( /* arguments */ ){\r
2747                 \r
2748                 var _arg = Util.copyArray( arguments );\r
2749                 _arg.unshift( windowW, windowH );\r
2750                 application.open.apply( application, _arg );\r
2751                 \r
2752                 elmContainer.style.cssText = "top:" + body.scrollTop + 'px;display:none;';\r
2753                 $( elmContainer ).stop().fadeIn( onFadeInComplete );            \r
2754         };\r
2755         function onFadeInComplete(){\r
2756                 KeyEvent.add( application, Const.KEY.EVENT.KEY_DOWN, Overlay.hide, 27 ); // 27.esc\r
2757                 MouseEvent.add( application, elmCloseButton, 'click', onCloseClick );\r
2758         };\r
2759         function onFadeOutComplete(){   \r
2760                 Util.removeAllChildren( elmContainer );\r
2761                 body.removeChild( elmContainer );\r
2762                 elmContainer = elmShadow = elmCloseButton = null;\r
2763         };\r
2764         return {\r
2765                 show: function( _application, _bootParams ){\r
2766                         if( visible === true && application === _application ) return;\r
2767                         if( Application.isApplicationInstance( _application ) === false ) return;\r
2768                         \r
2769                         elmContainer = document.createElement( 'div' );\r
2770                         body.appendChild( elmContainer );\r
2771                         \r
2772                         elmContainer.id = 'overlay-container';\r
2773                         \r
2774                         bodyOverflow        = body.style.overflow;\r
2775                         body.style.overflow = 'hidden';\r
2776                         \r
2777                         elmShadow = document.createElement( 'div' );\r
2778                         elmContainer.appendChild( elmShadow );\r
2779                         elmShadow.id = 'overlay-shadow';\r
2780                         \r
2781                         elmCloseButton  = document.createElement( 'div' );\r
2782                         elmContainer.appendChild( elmCloseButton );\r
2783                         elmCloseButton.id = 'overlay-close-button';\r
2784                         elmCloseButton.appendChild( document.createTextNode( 'x' ) );\r
2785                         \r
2786                         elmContainer.style.display = 'none'; // hide for fadeIn\r
2787                         \r
2788                         _application.addAsyncCall( asyncInit );\r
2789                         _application.addAsyncCall( asyncOpen, _bootParams );\r
2790                         \r
2791                         visible     = true;\r
2792                         application = _application;\r
2793                 },\r
2794                 hide: function(){\r
2795                         if( visible === false ) return;\r
2796                         if( application.close() === false ) return false;\r
2797                         \r
2798                         body.style.overflow = bodyOverflow;\r
2799                         \r
2800                         $( elmContainer ).stop().css( {\r
2801                                 filter:         '',\r
2802                                 opacity:        ''\r
2803                         }).fadeOut( onFadeOutComplete );\r
2804                         visible = false;\r
2805                         \r
2806                         KeyEvent.remove( application, Const.KEY.EVENT.KEY_DOWN, Overlay.hide ); // 27.esc\r
2807                         MouseEvent.remove( application, elmCloseButton );\r
2808                         \r
2809                         application = null;\r
2810                 },\r
2811                 onWindowResize: function( _windowW, _windowH ){\r
2812                         windowW = _windowW;\r
2813                         windowH = _windowH;                     \r
2814                         \r
2815                         if( application === null ) return;\r
2816                         \r
2817                         elmContainer.style.height = _windowH + 'px';\r
2818                         elmContainer.style.top    = body.scrollTop + 'px';\r
2819 \r
2820                         elmShadow.style.height = _windowH + 'px';\r
2821 \r
2822                         AsyncCall.add( application, application.resize, [ _windowW, _windowH ] );\r
2823                 }\r
2824         }\r
2825 })();\r
2826 \r
2827 /* ----------------------------------------\r
2828  * UI\r
2829  * \r
2830  * keyEventRellay\r
2831  *  form -> overlay -> view\r
2832  * \r
2833  */\r
2834 \r
2835 var UI = ( function(){\r
2836         var UI_LIST     = [],\r
2837                 currentUser = null,\r
2838                 currentList = null,\r
2839                 currentUi   = null,\r
2840                 currentItem = null,\r
2841                 windowW     = 0,\r
2842                 windowH     = 0;\r
2843 \r
2844         var CLASSNAME_COMBOBOX_OPTION = 'combobox-option',\r
2845                 ELM_A_ORIGIN = ( function(){\r
2846                         var ret = document.createElement( 'a' );\r
2847                         ret.href = '#';\r
2848                         return ret;\r
2849                 })(),\r
2850                 ELM_INPUT_TEXT = ( function(){\r
2851                         var ret = document.createElement( 'input' );\r
2852                         ret.type = 'text';\r
2853                         return ret;\r
2854                 })(),\r
2855                 ELM_COMBOBOX = ( function(){\r
2856                         var ret       = document.createElement( 'a' ),\r
2857                                 elmToggle = document.createElement( 'span' ),\r
2858                                 elmValue  = document.createElement( 'span' );\r
2859                         ret.href = '#';\r
2860                         ret.appendChild( elmToggle );\r
2861                         ret.appendChild( elmValue );\r
2862                         elmToggle.className = 'combobox-toggle';\r
2863                         elmValue.className  = 'combobox-value';\r
2864                         \r
2865                         elmToggle.appendChild( document.createTextNode( '▼' ));\r
2866                         elmValue.appendChild( document.createTextNode( 'null' ));\r
2867                         return ret;\r
2868                 })();\r
2869                 \r
2870         var InputTextClass = function( apiuser, uiGroup, elmWrapper, elmValue, onUpdate, validater ){\r
2871                 var elmA     = ELM_A_ORIGIN.cloneNode( true ),\r
2872                         instance = this,\r
2873                         focus    = false,\r
2874                         visible  = true,\r
2875                         enabled  = true,\r
2876                         value    = elmValue.innerHTML;\r
2877                 elmValue.innerHTML = '';\r
2878                 elmValue.className += ' editable-text';\r
2879                 elmValue.appendChild( elmA );\r
2880                 \r
2881                 this.value = function( _value ){\r
2882                         if( Type.isString( _value ) === true ){\r
2883                                 elmA.innerHTML = value = _value;\r
2884                                 if( focus === true ){\r
2885                                         ELM_INPUT_TEXT.value = value;\r
2886                                 }\r
2887                         }\r
2888                         focus === true && instance.blur();\r
2889                         return value;\r
2890                 };\r
2891                 this.focus = function( e ){\r
2892                         focus = true;\r
2893                         start( apiuser, uiGroup, instance );\r
2894                         elmA.style.display = 'none';\r
2895                         elmValue.appendChild( ELM_INPUT_TEXT );\r
2896                         ELM_INPUT_TEXT.value = value;\r
2897                         try {\r
2898                                 ELM_INPUT_TEXT.focus();\r
2899                                 ELM_INPUT_TEXT.select();                                \r
2900                         } catch(e) {\r
2901                                 \r
2902                         }\r
2903 \r
2904                         return false;\r
2905                 };\r
2906                 this.blur = function( keep ){\r
2907                         var _newValue = ELM_INPUT_TEXT.value,\r
2908                                 _validated = Type.isFunction( validater ) === true ? '' + validater( _newValue ) : _newValue;\r
2909                         _newValue = keep !== 27 ? _validated : value; // 27:ESC\r
2910 \r
2911                         elmValue.removeChild( ELM_INPUT_TEXT );\r
2912                         \r
2913                         elmA.innerHTML     = _newValue;\r
2914                         elmA.style.display = 'block';\r
2915                         \r
2916                         onUpdate && _newValue !== value && onUpdate( _newValue, value );\r
2917                         \r
2918                         value = _newValue;\r
2919                         focus = false;\r
2920                         finish( apiuser, uiGroup, instance );\r
2921                 };\r
2922                 this.enabled = function(){\r
2923                         return enabled;\r
2924                 };\r
2925                 this.visible = function( _visible ){\r
2926                         if( Type.isBoolean( _visible ) === true ){\r
2927                                 elmWrapper.style.display = _visible ? '' : 'none';\r
2928                                 visible = _visible;\r
2929                         }\r
2930                         return visible;\r
2931                 };\r
2932                 this.destroy = function(){\r
2933                         if( focus === true ){\r
2934                                 elmValue.removeChild( ELM_INPUT_TEXT );\r
2935                         }\r
2936                         MouseEvent.remove( apiuser, elmWrapper );\r
2937                         apiuser = uiGroup = elmWrapper = elmValue = elmA = onUpdate = validater = instance = null;\r
2938                 };\r
2939                 instance.value( value );\r
2940                 MouseEvent.add( apiuser, elmWrapper, 'click', instance.focus );\r
2941         }\r
2942         \r
2943         var ButtonClass = function( apiuser, uiGroup, elmWrapper, onUpdate ){\r
2944                 var className = elmWrapper.className || '',\r
2945                         instance = this,\r
2946                         focus = false,\r
2947                         visible = true,\r
2948                         enabled = true;\r
2949                 MouseEvent.add( apiuser, elmWrapper, 'click', onClick );\r
2950                 \r
2951                 function onClick(){\r
2952                         focus = true;\r
2953                         onUpdate();\r
2954                         return false;\r
2955                 };\r
2956                 this.focus = function(){\r
2957                         focus = true;\r
2958                         elmWrapper.className = className + ' button-has-focus';\r
2959                         start( apiuser, uiGroup, instance );\r
2960                 };\r
2961                 this.blur = function( keyCode ){\r
2962                         keyCode === 13 && onClick();\r
2963                         elmWrapper.className = className;\r
2964                         focus = false;\r
2965                         finish( apiuser, uiGroup, instance );\r
2966                 };\r
2967                 this.enabled = function(){\r
2968                         return enabled;\r
2969                 };\r
2970                 this.visible = function( _visible ){\r
2971                         if( Type.isBoolean( _visible ) === true ){\r
2972                                 elmWrapper.style.display = _visible ? '' : 'none';\r
2973                                 visible = _visible;\r
2974                         };\r
2975                         return visible;\r
2976                 };\r
2977                 this.destroy = function(){\r
2978                         MouseEvent.remove( apiuser, elmWrapper );\r
2979                         apiuser = uiGroup = elmWrapper = onUpdate = instance = null;\r
2980                 };\r
2981         }\r
2982 \r
2983         var FileInputClass = function( apiuser, uiGroup, elmWrapper, onUpdate, validater, elmFileInput ){\r
2984                 var elmFilePath = Util.getElementsByClassName( elmWrapper, 'file-path' )[ 0 ],\r
2985                         focus       = false,\r
2986                         visible     = true,\r
2987                         enabled     = true,\r
2988                         index       = GROUP_ID ? itemList[ GROUP_ID ].length : -1,\r
2989                         value,\r
2990                         instance;\r
2991                 elmFileInput = elmWrapper.getElementsByTagName('input')[0] || elmFileInput || document.createElement( 'input');\r
2992                 elmFileInput.type = 'file';\r
2993                 elmFileInput.style.visivility = 'hidden';\r
2994 \r
2995                 elmWrapper.onclick = onClick;\r
2996                 elmFileInput.onchange = onChange;\r
2997                 \r
2998                 function onChange(){\r
2999                         elmFilePath.innerHTML = elmFileInput.value;\r
3000                 }\r
3001                 return {\r
3002                         init: function(){\r
3003                                 instance = this;\r
3004                                 delete this.init;\r
3005                         },\r
3006                         focus: function( e ){\r
3007                                 focus = true;\r
3008                                 start( apiuser, uiGroup, instance );\r
3009                                 elmFileInput.click();\r
3010                                 return false;\r
3011                         },\r
3012                         blur: function( keep ){\r
3013                                 focus = false;\r
3014                         },\r
3015                         enabled: function(){\r
3016                                 return enabled;\r
3017                         },\r
3018                         visible: function( _visible ){\r
3019                                 if( Type.isBoolean( _visible ) === true ){\r
3020                                         elmWrapper.style.display = _visible ? '' : 'none';\r
3021                                         visible = _visible;\r
3022                                 };\r
3023                                 return visible;\r
3024                         },\r
3025                         index : index\r
3026                 }\r
3027         }\r
3028 \r
3029         var ComboBoxClass = function( apiuser, uiGroup, elmWrapper, onUpdate ){\r
3030                 var elmBox     = Util.getElementsByClassName( elmWrapper, 'combobox' )[ 0 ],\r
3031                         elmA       = ELM_COMBOBOX.cloneNode( true ),\r
3032                         elmToggle  = Util.getElementsByClassName( elmA, 'combobox-toggle' )[ 0 ],\r
3033                         elmValue   = Util.getElementsByClassName( elmA, 'combobox-value' )[ 0 ].firstChild,\r
3034                         index      = 0,\r
3035                         optionList = [],\r
3036                         instance   = this,\r
3037                         focus      = false,\r
3038                         visible    = true,\r
3039                         enabled    = true,\r
3040                         value;\r
3041                 elmBox.appendChild( elmA );\r
3042 \r
3043                 this.elm = elmBox;\r
3044                 this.focus = function( e ){\r
3045                         MouseEvent.remove( apiuser, elmWrapper, 'click', instance.focus );\r
3046                         focus = true;\r
3047                         elmA.className = 'combobox-has-focus';\r
3048                         start( apiuser, uiGroup, instance );\r
3049                         OptionControl.show( apiuser, instance, optionList );\r
3050                         return false;\r
3051                 };\r
3052                 this.blur = function( keyCode ){\r
3053                         OptionControl.hide( instance );\r
3054                         focus = false;\r
3055                         elmA.className = '';\r
3056                         finish( apiuser, uiGroup, instance );\r
3057                         MouseEvent.add( apiuser, elmWrapper, 'click', instance.focus );\r
3058                 };\r
3059                 this.enabled = function(){\r
3060                         return enabled;\r
3061                 };\r
3062                 this.visible = function( _visible ){\r
3063                         if( Type.isBoolean( _visible ) === true ){\r
3064                                 elmWrapper.style.display = _visible ? '' : 'none';\r
3065                                 visible = _visible;\r
3066                         };\r
3067                         return visible;\r
3068                 };\r
3069                 this.value = function( _value ){\r
3070                         if( Type.isString( _value ) === true && value !== _value ){\r
3071                                 for( var i=0, l = optionList.length, _option; i<l; ++i ){\r
3072                                         _option = optionList[ i ];\r
3073                                         if( _value === _option.value ){\r
3074                                                 value = _value;\r
3075                                                 index = i;\r
3076                                                 elmValue.data = _option.displayValue;\r
3077                                                 if( focus === true ){\r
3078                                                         OptionControl.update( instance, _value );\r
3079                                                 }\r
3080                                                 break;\r
3081                                         }\r
3082                                 }\r
3083                         }\r
3084                         return value;\r
3085                 };\r
3086                 this.selectIndex = function(){\r
3087                         return index;\r
3088                 };\r
3089                 this.createOption = function( _displayValue, _value, _isSelected ){\r
3090                         var option = null,\r
3091                                 _option,\r
3092                                 _index;\r
3093                         _value = _value || _displayValue;\r
3094                         for( var i = 0, l = optionList.length; i < l; ++i ){\r
3095                                 _option = optionList[ i ];\r
3096                                 if( _value === _option.value ){\r
3097                                         option = _option;\r
3098                                         _index = i;\r
3099                                 } else {\r
3100                                         _option.current = _option.value === _value;\r
3101                                 }\r
3102                         }\r
3103                         if( option === null ){\r
3104                                 option = new OptionClass( instance, _displayValue, _value, _isSelected );\r
3105                                 _index = optionList.length;\r
3106                                 optionList.push( option );\r
3107                         }\r
3108                         if( _isSelected === true ){\r
3109                                 elmValue.data = _displayValue;\r
3110                         }\r
3111                 };\r
3112                 this.destroy = function(){\r
3113                         instance.blur();\r
3114                         MouseEvent.remove( apiuser, elmWrapper );\r
3115                         optionList.length = 0;\r
3116                         apiuser = uiGroup = elmWrapper = onUpdate = elmBox = elmA = elmToggle = elmValue = optionList = instance = null;\r
3117                 };\r
3118                 MouseEvent.add( apiuser, elmWrapper, 'click', instance.focus );\r
3119         };\r
3120         var OptionClass = function( combobox, displayValue, value, isCurrent ){\r
3121                 this.displayValue = displayValue;\r
3122                 this.value        = value = value || displayValue;\r
3123                 this.current      = isCurrent;\r
3124                 displayValue = value = null;\r
3125         };\r
3126 \r
3127         var OptionControl = ( function(){\r
3128                 var ELM_OPTION_WRAPPER = ( function(){\r
3129                                 var ret = document.createElement( 'div' );\r
3130                                 ret.className = 'option-container';\r
3131                                 return ret;\r
3132                         })(),\r
3133                         ELM_OPTION_ORIGIN = ( function(){\r
3134                                 var ret = document.createElement( 'a' );\r
3135                                 ret.appendChild( document.createTextNode( 'option' ) );\r
3136                                 ret.href = '#';\r
3137                                 return ret;\r
3138                         })();\r
3139 \r
3140                 var OptionClass = function( apiuser, option ){\r
3141                         this.elm  = ELM_OPTION_ORIGIN.cloneNode( true );\r
3142                         this.data = option;\r
3143                         this.current = function( _current ){\r
3144                                 this.elm.className = CLASSNAME_COMBOBOX_OPTION;\r
3145                                 option.current = _current;\r
3146                                 currentOption  = this;\r
3147                         };\r
3148                         this.destroy = function(){\r
3149                                 MouseEvent.remove( apiuser, this.elm );\r
3150                                 apiuser = option = null;\r
3151                                 ELM_OPTION_WRAPPER.removeChild( this.elm );\r
3152                                 delete this.elm;\r
3153                                 delete this.data;\r
3154                         };\r
3155                         \r
3156                         ELM_OPTION_WRAPPER.appendChild( this.elm );\r
3157                         this.elm.firstChild.data = option.displayValue;\r
3158                         this.current( option.current );\r
3159                         MouseEvent.add( SUPER_USER_KEY, this.elm, 'mousedown', onOptionSelect );// onclick では 選択ボックス 隠すように body に設定した onmouseup が先に動いてしまう!\r
3160                 }\r
3161                 \r
3162                 function onOptionSelect( e ){\r
3163                         for( var i = 0, l = OPTION_LIST.length, _option; i < l; ++i){\r
3164                                 _option = OPTION_LIST[ i ];\r
3165                                 \r
3166                                 if( this === _option.elm ){\r
3167                                         //currentOption = _option;\r
3168                                                 // alert( i +'   ' + OPTION_LIST.length )                       \r
3169                                         //OptionControl.update( currentCombobox, _option.data.value );\r
3170                                         updateCurrrentOption(  _option.data.value, true );\r
3171                                         // OptionControl.hide( currentCombobox );\r
3172                                         currentCombobox.blur();\r
3173                                         break;\r
3174                                 };\r
3175                         };\r
3176                         return false;                   \r
3177                 };\r
3178                 \r
3179                 var OPTION_LIST     = [],\r
3180                         currentCombobox = null,\r
3181                         apiuser,\r
3182                         elm,\r
3183                         currentOption,\r
3184                         currentIndex;\r
3185                 \r
3186                 function updateCurrrentOption( _value, _updateCombobox ){\r
3187                         var _option;\r
3188                         for( var i = OPTION_LIST.length; i; ){\r
3189                                 _option = OPTION_LIST[ --i ];\r
3190                                 if( _value === _option.data.value ){\r
3191                                         currentOption && currentOption.current( false );\r
3192                                         _option.current( true );\r
3193                                         currentOption = _option;\r
3194                                         currentIndex  = i;\r
3195                                         _updateCombobox === true && currentCombobox.value( _value );\r
3196                                         \r
3197                                         break;\r
3198                                 };\r
3199                         };\r
3200                 };\r
3201                 function bodyMouseupHandler(){\r
3202                         currentCombobox.blur();\r
3203                         OptionControl.hide( currentCombobox );\r
3204                 };\r
3205                 function updateWrapperPosition(){\r
3206                         var position = Util.getAbsolutePosition( elm );\r
3207                         \r
3208                         ELM_OPTION_WRAPPER.style.cssText = [\r
3209                                         'width:', elm.offsetWidth - 2, 'px;',\r
3210                                         'left:', position.x, 'px;',\r
3211                                         'top:', position.y + elm.offsetHeight, 'px;'\r
3212                                 ].join('');                     \r
3213                 };\r
3214                 function change( e ){\r
3215                         var l   = OPTION_LIST.length,\r
3216                                 i   = currentIndex + e.keyCode === 40 ? 1 : -1;\r
3217                         if( currentCombobox === null || l < 2 ) return;\r
3218                         i = i < 0 ?\r
3219                                         l - 1 :\r
3220                                         i < l ? i : 0;\r
3221                         updateCurrrentOption( OPTION_LIST[ i ].data.value, true );\r
3222                         return false;\r
3223                 };\r
3224                 return {\r
3225                         show: function( _apiuser, _combobox, _optionList ){\r
3226                                 if( currentItem !== _combobox || currentCombobox === _combobox ) return;\r
3227                                 currentCombobox && currentCombobox.blur();\r
3228                                 \r
3229                                 apiuser         = _apiuser;\r
3230                                 currentCombobox = _combobox;\r
3231                                 elm             = _combobox.elm;\r
3232                                 \r
3233                                 for( var i = _optionList.length; i; ){\r
3234                                         OPTION_LIST.unshift( new OptionClass( _apiuser, _optionList[ --i ] ) );\r
3235                                 }\r
3236                                 MouseEvent.add( SUPER_USER_KEY, doc, 'mouseup', bodyMouseupHandler );\r
3237                                 KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, change, 38 );\r
3238                                 KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, change, 40 );\r
3239                                 //KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onEnter, 13 );\r
3240                                 //KeyEvent.updateCurrentListener( SUPER_USER_KEY );\r
3241                                 \r
3242                                 body.appendChild( ELM_OPTION_WRAPPER );\r
3243                                 \r
3244                                 updateCurrrentOption( _combobox.value(), false );\r
3245                                 updateWrapperPosition();\r
3246                         },\r
3247                         hide: function( _combobox ){\r
3248                                 if( currentCombobox !== _combobox || currentCombobox === null ) return;\r
3249 \r
3250                                 var _option;\r
3251                                 while( _option = OPTION_LIST.shift() ){\r
3252                                         _option.destroy();\r
3253                                 };\r
3254                                 \r
3255                                 body.removeChild( ELM_OPTION_WRAPPER );\r
3256                                 \r
3257                                 MouseEvent.remove( SUPER_USER_KEY, doc, 'mouseup', bodyMouseupHandler );\r
3258                                 KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, change );\r
3259                                 KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, change );\r
3260                                 //KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onEnter );\r
3261                                 //KeyEvent.updateCurrentListener( apiuser );\r
3262                                 \r
3263                                 apiuser         = null;\r
3264                                 currentCombobox = null;\r
3265                                 currentOption   = null;\r
3266                                 currentIndex    = 0;                            \r
3267                         },\r
3268                         onEnter: function(){\r
3269                                 currentCombobox.value( currentOption.data.value );\r
3270                                 //currentCombobox.blur();\r
3271                                 //OptionControl.hide( currentCombobox );\r
3272                         },\r
3273                         update: function( _combobox, _value ){\r
3274                                 if( currentCombobox !== _combobox || currentItem !== _combobox ) return;\r
3275                                 if( currentOption.data.value === _value ) return;\r
3276                                 updateCurrrentOption( _value, true );\r
3277                         },\r
3278                         onWindowResize: function( _w, _h ){\r
3279                                 currentCombobox && AsyncCall.add( apiuser, updateWrapperPosition );\r
3280                         }\r
3281                 }\r
3282         })();\r
3283 \r
3284         var UIGroupClass = function( apiuser ){\r
3285                 var self        = this,\r
3286                         itemList    = [],\r
3287                         currentItem = null,\r
3288                         windowW, windowH;\r
3289 \r
3290                 this.focus = function( _value ){\r
3291                         if( _value === true ){\r
3292                                 if( currentItem ){\r
3293                                         start( apiuser, self, currentItem );\r
3294                                 } else\r
3295                                 if( itemList.length > 0 ){\r
3296                                         start( apiuser, self, itemList[ 0 ] );\r
3297                                 };\r
3298                         } else\r
3299                         if( _value === false ){\r
3300                                 finish( apiuser, self, currentItem );\r
3301                         } else\r
3302                         if( _value && Util.getIndex( itemList, _value ) !== -1 ){\r
3303                                 currentItem = _value;\r
3304                                 currentList = itemList;\r
3305                         };\r
3306                         return currentUi === self; \r
3307                 };\r
3308                 this.blur = function(){\r
3309                         if( currentList === itemList ){\r
3310                                 currentList = null;\r
3311                         };\r
3312                 };\r
3313                 this.createInputText = function( _elmWrapper, _onUpdate, _validater ){\r
3314                         var _elmValue = Util.getElementsByClassName( _elmWrapper, 'editable-value' )[ 0 ];\r
3315                         if( _elmValue ){\r
3316                                 var ret = new InputTextClass( apiuser, self, _elmWrapper, _elmValue, _onUpdate, _validater );\r
3317                                 itemList.push( ret );\r
3318                                 return ret;\r
3319                         }\r
3320                         alert( 'error createInputText' );\r
3321                 };\r
3322                 this.createButton = function( _elm, _onClick ){\r
3323                         var ret = new ButtonClass( apiuser, self, _elm, _onClick );\r
3324                         itemList.push( ret );\r
3325                         return ret;\r
3326                 };\r
3327                 this.createFileInput = function( _elm, _onUpdate, _validater, _elmFileInput ){\r
3328                         var ret = FileInputClass( apiuser, self, _elm, _onUpdate, _validater, _elmFileInput );\r
3329                         itemList.push( ret );\r
3330                         return ret;\r
3331                 };\r
3332                 this.createCombobox = function( _elm, _onUpdate, _optionList ){\r
3333                         var ret = new ComboBoxClass( apiuser, self, _elm, _onUpdate, _optionList );\r
3334                         itemList.push( ret );\r
3335                         return ret;\r
3336                 };\r
3337                 this.createCheckBox = function(){\r
3338                         \r
3339                 };\r
3340                 this.createRadio = function(){\r
3341                         \r
3342                 };\r
3343                 this.createSlider = function(){\r
3344                         \r
3345                 };\r
3346                 this.destroy = function(){\r
3347                         var _item;\r
3348                         while( _item = itemList.shift() ){\r
3349                                 _item.destroy();\r
3350                         }\r
3351                 };\r
3352         };\r
3353         \r
3354         function start( _apiuser, _uigroup, _item ){\r
3355                 if( currentItem !== _item ){\r
3356                         currentItem !== null && currentItem.blur();\r
3357                         \r
3358                         if( currentUser !== _apiuser ) {\r
3359                                 KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 13 );\r
3360                                 KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 27 );\r
3361                                 KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown,  9 );\r
3362                                 KeyEvent.updateCurrentListener( SUPER_USER_KEY );\r
3363                         };\r
3364                         if( currentUi !== _uigroup ){\r
3365                                 currentUi && currentUi.blur();\r
3366                         };\r
3367                         currentUser = _apiuser;\r
3368                         currentUi   = _uigroup;\r
3369                         currentItem = _item;\r
3370                         \r
3371                         _uigroup.focus( _item );\r
3372                 };\r
3373         }\r
3374         function finish( _apiuser, _uigroup, _item ){\r
3375                 if( currentItem === _item ){\r
3376                         _uigroup.blur();\r
3377                         \r
3378                         currentUser = null;\r
3379                         currentUi   = null;\r
3380                         currentItem = null;\r
3381                         \r
3382                         KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 13 );\r
3383                         KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 27 );\r
3384                         KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown,  9 );\r
3385                         KeyEvent.updateCurrentListener( _apiuser );\r
3386                 }\r
3387         }\r
3388 \r
3389         function onKeyDown( e ){\r
3390                 if( currentItem === null ) return true;\r
3391                 var keyCode = e.keyCode,\r
3392                         _index  = Util.getIndex( currentList, currentItem );\r
3393                 if( keyCode === 13 || keyCode === 27 || keyCode === 9 || keyCode === 18 || e.altKey === true ){ // 13.return 27.esc 9.tab 18.alt\r
3394                         keyCode === 9  && tabShift( _index, e.shiftKey === true ? -1 : 1 );\r
3395                         keyCode === 13 && currentItem instanceof ComboBoxClass && OptionControl.onEnter();\r
3396                         keyCode === 13 && tabShift( _index, 1 );                        \r
3397                         currentItem && currentItem.blur( keyCode );\r
3398                 };\r
3399                 return false;\r
3400         }\r
3401 \r
3402         function tabShift( _index, _way ){\r
3403                 var l = currentList.length,\r
3404                         i = _index + _way,\r
3405                         _item;\r
3406                 if( l < 2 ) return;\r
3407                 while( i !== _index ){\r
3408                         i = i < 0 ?\r
3409                                 l - 1 :\r
3410                                 i < l ? i : 0; // 0 < i < l\r
3411                         _item = currentList[ i ];\r
3412                         if( _item.enabled() === true && _item.visible() === true ){\r
3413                                 AsyncCall.add( currentUser, _item.focus );\r
3414                                 return;\r
3415                         };\r
3416                         i += _way;\r
3417                 };\r
3418         };\r
3419         \r
3420         return {\r
3421                 createUIGroup: function( _apiuser ){\r
3422                         var _uid  = _apiuser.getUID(),\r
3423                                 _list = UI_LIST[ _uid ],\r
3424                                 _ui   = new UIGroupClass( _apiuser );\r
3425                         if( Type.isArray( _list ) === false ){\r
3426                                 _list = UI_LIST[ _uid ] = [];\r
3427                         }\r
3428                         _list.push( _ui );\r
3429                         return _ui;\r
3430                 },\r
3431                 onWindowResize: function( w, h ){\r
3432                         windowW = w;\r
3433                         windowH = h;\r
3434                         currentItem instanceof ComboBoxClass && OptionControl.onWindowResize( w, h );\r
3435                 },\r
3436                 onCurrentApplicationChange: function( _apiuser ){\r
3437                         currentList = UI_LIST[ _apiuser.getUID() ];\r
3438                 },\r
3439                 onApplicationShutdown: function( _apiuser ){\r
3440                         KeyEvent.remove( _apiuser );\r
3441                 },\r
3442                 onSystemShutdown: function(){\r
3443                         \r
3444                 }\r
3445         }\r
3446 })();\r
3447 \r
3448 \r
3449 var Finder = ( function(){\r
3450         var HTML_FINDER_ICON = ( function(){\r
3451                 return ( UA.isIE === true && UA.ieVersion < 8 ?\r
3452                 [\r
3453                         '<div class="finder-icon fnder-icon-ie7">',\r
3454                                 '<a href="#" class="finder-icon-main">',\r
3455                                         '<span class="finder-icon-handle"></span>',\r
3456                                         '<span class="finder-icon-thumbnail"></span>',\r
3457                                         '<span class="finder-icon-cell finder-icon-ie-filename">',\r
3458                                                 '<span class="finder-icon-vertical-middle-outer">',\r
3459                                                         '<span class="finder-icon-vertical-middle-inner">',\r
3460                                                                 '<span class="finder-icon-filename break-word">file name</span>',\r
3461                                                         '</span>',\r
3462                                                 '</span>',\r
3463                                         '</span>',\r
3464                                         '<span class="finder-icon-cell finder-icon-ie-summary">',\r
3465                                                 '<span class="finder-icon-vertical-middle-outer">',\r
3466                                                         '<span class="finder-icon-vertical-middle-inner">',\r
3467                                                                 '<span class="finder-icon-summary break-word">file descriptiion</span>',\r
3468                                                         '</span>',\r
3469                                                 '</span>',\r
3470                                         '</span>',\r
3471                                 '</a>',\r
3472                                 '<div class="finder-icon-console">',\r
3473                                         '<a href="#" class="finder-icon-console-action"></a>',\r
3474                                         '<a href="#" class="finder-icon-console-editor-apps"></a>',\r
3475                                         '<a href="#" class="finder-icon-console-viewer-apps"></a>',\r
3476                                 '</div>',\r
3477                         '</div>'\r
3478                 ] :\r
3479                 [\r
3480                         '<div class="finder-icon fnder-icon-modern">',\r
3481                                 '<span class="finder-icon-handle"></span>',\r
3482                                 '<span class="finder-icon-thumbnail"></span>',\r
3483                                 '<span class="finder-icon-filename break-word">file name</span>',\r
3484                                 '<span class="finder-icon-summary break-word">file descriptiion</span>',\r
3485                                 '<div class="finder-icon-console">',\r
3486                                         '<a href="#" class="finder-icon-console-action"></a>',\r
3487                                         '<a href="#" class="finder-icon-console-editor-apps"></a>',\r
3488                                         '<a href="#" class="finder-icon-console-viewer-apps"></a>',\r
3489                                 '</div>',\r
3490                         '</div>',\r
3491                 ] ).join( '' );\r
3492         })();\r
3493 \r
3494         \r
3495         var FINDER_ARRAY                    = [],\r
3496                 ELM_ORIGIN_FINDER_LOCATION_ITEM = Util.pullHtmlAsTemplete( '<li id="templete-finder-location-item" class="finder-location-item"><a href="#"></a></li>'),\r
3497                 ELM_ORIGIN_FINDER_ICON          = Util.pullHtmlAsTemplete( HTML_FINDER_ICON ),\r
3498                 ELM_ORIGIN_CONTAINER            = Util.pullHtmlAsTemplete( [\r
3499                         '<div id="templete-finder-container" class="finder-container">',\r
3500                                 '<div class="finder-header">',\r
3501                                         '<ul class="finder-location"></ul>',\r
3502                                         '<div class="finder-sidebar-switch button">side</div>',\r
3503                                         '<div class="finder-style-switch button">style</div>',\r
3504                                         '<div class="finder-action-switch button">action</div>',\r
3505                                 '</div>',\r
3506                                 '<div class="finder-body"></div>',\r
3507                         '</div>',\r
3508                 ].join( '' ) ),\r
3509                 ICON_HEIGHT                     = Util.getElementSize( ELM_ORIGIN_FINDER_ICON ).height,\r
3510                 ICON_CLASSNAME                  = 'finder-icon-thumbnail',\r
3511                 FINDER_ICON_POOL                = [],\r
3512                 BREAD_OBJECT_POOL               = [];\r
3513         \r
3514         var FinderIconClass = function(){\r
3515                 var elmContainer,\r
3516                         ELM_WRAPPER       = ELM_ORIGIN_FINDER_ICON.cloneNode( true),\r
3517                         ELM_THUMBNAIL     = Util.getElementsByClassName( ELM_WRAPPER, ICON_CLASSNAME )[ 0 ],\r
3518                         ELM_FILENAME      = Util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-filename' )[ 0 ],\r
3519                         ELM_DESCRIPTION   = Util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-summary' )[ 0 ],\r
3520                         ELM_EDITOR_BUTTON = Util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-console-editor-apps' )[ 0 ],\r
3521                         ELM_VIEWER_BUTTON = Util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-console-viewer-apps' )[ 0 ],\r
3522                         ELM_ACTION_BUTTON = Util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-console-action' )[ 0 ],\r
3523                         instansce         = this,\r
3524                         file, w, index, style,\r
3525                         onDownCallback, onEditorCallback, onViewerCallback, onActionCallback,\r
3526                         viewerList, editorList;\r
3527                 \r
3528                 MouseEvent.add( SUPER_USER_KEY, ELM_WRAPPER,       'click', onDownClick );\r
3529                 MouseEvent.add( SUPER_USER_KEY, ELM_EDITOR_BUTTON, 'click', onEditorClick );\r
3530                 MouseEvent.add( SUPER_USER_KEY, ELM_VIEWER_BUTTON, 'click', onViwerClick );\r
3531                 MouseEvent.add( SUPER_USER_KEY, ELM_ACTION_BUTTON, 'click', onActionClick );\r
3532                 function onDownClick(){\r
3533                         onDownCallback( index );\r
3534                         return false;\r
3535                 }\r
3536                 function onEditorClick(){\r
3537                         onEditorCallback( file, editorList[ 0 ] );\r
3538                         return false;\r
3539                 }\r
3540                 function onViwerClick(){\r
3541                         onViewerCallback( file, viewerList[ 0 ] );\r
3542                         return false;\r
3543                 }\r
3544                 function onActionClick(){\r
3545                         onActionCallback( file );\r
3546                         return false;\r
3547                 }\r
3548                 function draw(){\r
3549                         var _thumb = file.getThumbnail();\r
3550                         if( _thumb.image ){\r
3551                                 ELM_THUMBNAIL.className = ICON_CLASSNAME + ' has-thumbnail';\r
3552                                 ELM_THUMBNAIL.style.backgroundImage = [ 'url(', _thumb.image, ')'].join( '');\r
3553                         } else {\r
3554                                 ELM_THUMBNAIL.className = ICON_CLASSNAME + ' ' + _thumb.className;\r
3555                                 ELM_THUMBNAIL.style.backgroundImage = '';\r
3556                         }\r
3557                         ELM_FILENAME.firstChild.data = file.getName();\r
3558                         ELM_DESCRIPTION.firstChild.data = file.getSummary();\r
3559                         \r
3560                         if( Type.isArray( viewerList ) === true && viewerList.length > 0 ){\r
3561                                 ELM_VIEWER_BUTTON.style.display = '';\r
3562                         } else {\r
3563                                 ELM_VIEWER_BUTTON.style.display = 'none';\r
3564                         };\r
3565                         if( Type.isArray( editorList ) === true && editorList.length > 0 ){\r
3566                                 ELM_EDITOR_BUTTON.style.display = '';\r
3567                         } else {\r
3568                                 ELM_EDITOR_BUTTON.style.display = 'none';\r
3569                         };\r
3570                 }\r
3571                 function resize(){\r
3572                         // ELM_WRAPPER.style.top = (index * ICON_HEIGHT) +'px';\r
3573                 }\r
3574                 function onCollect(){\r
3575                         elmContainer.removeChild( ELM_WRAPPER );\r
3576                         elmContainer = null;\r
3577                         FINDER_ICON_POOL.push( instansce );\r
3578                 }\r
3579                 \r
3580                 this.init = function( _file, _elmContainer, _w, _index, _style, _onDownCallback, _onEditorCallback, _onViewerCallback, _onActionCallback ){\r
3581                         if( elmContainer !== _elmContainer){\r
3582                                 _elmContainer.appendChild( ELM_WRAPPER );\r
3583                                 elmContainer = _elmContainer;\r
3584                         }\r
3585                         if( file !== _file ){\r
3586                                 file && file.destroy();\r
3587                                 file       = _file;\r
3588                                 viewerList = file.viewerApplicationList();\r
3589                                 editorList = file.editorApplicationList();\r
3590                                 draw();\r
3591                         }\r
3592                         if( index !== _index){\r
3593                                 index = _index;\r
3594                                 resize();\r
3595                         }\r
3596                         onDownCallback   = _onDownCallback;\r
3597                         onEditorCallback = _onEditorCallback;\r
3598                         onViewerCallback = _onViewerCallback;\r
3599                         onActionCallback = _onActionCallback;\r
3600                 };\r
3601                 this.elm = ELM_WRAPPER,\r
3602                 this.index = function( _index){ \r
3603                         return index;\r
3604                 };\r
3605                 this.style = function( _style ){\r
3606                         return style;\r
3607                 };\r
3608                 this.onResize = function( w ){\r
3609                         \r
3610                 };\r
3611                 this.destroy = function(){\r
3612                         //MouseEvent.remove( SUPER_USER_KEY, ELM_WRAPPER,       'click', onDownClick );\r
3613                         //MouseEvent.remove( SUPER_USER_KEY, ELM_EDITOR_BUTTON, 'click', onEditorClick );\r
3614                         //MouseEvent.remove( SUPER_USER_KEY, ELM_VIEWER_BUTTON, 'click', onViwerClick );\r
3615                         //MouseEvent.remove( SUPER_USER_KEY, ELM_ACTION_BUTTON, 'click', onActionClick );\r
3616                         elmContainer.removeChild( ELM_WRAPPER );\r
3617                         file && file.destroy();\r
3618                         file = elmContainer = onDownCallback = onEditorCallback = onViewerCallback = onActionCallback = viewerList = editorList = null;\r
3619                         FINDER_ICON_POOL.push( instansce);\r
3620                 };\r
3621         }\r
3622         function updateIconPosition( _style, _w, _index, _elm ){\r
3623                 \r
3624         }\r
3625         var BreadcrumbClass = function(){\r
3626                 var elmContainer,\r
3627                         ELM_WRAPPER  = ELM_ORIGIN_FINDER_LOCATION_ITEM.cloneNode( true ),\r
3628                         ELM_FILENAME = ELM_WRAPPER.getElementsByTagName( 'a' )[ 0 ],\r
3629                         instansce    = this,\r
3630                         file, w, index,\r
3631                         callback;\r
3632                 MouseEvent.add( SUPER_USER_KEY, ELM_WRAPPER, 'click', onClick );\r
3633                 function draw(){\r
3634                         ELM_FILENAME.className = 'file-icon-' + file.getType();\r
3635                         ELM_FILENAME.innerHTML = file.getName();\r
3636                 }\r
3637                 function resize( index ){\r
3638                         ELM_WRAPPER.style.left = ( index * 90 ) + 'px';\r
3639                 }\r
3640                 function onClick(){\r
3641                         callback( index );\r
3642                         return false;\r
3643                 }\r
3644                 this.init = function( _file, _elmContainer, _index, _callback ){\r
3645                         instansce;\r
3646                         if( elmContainer !== _elmContainer ){\r
3647                                 _elmContainer.appendChild( ELM_WRAPPER );\r
3648                                 elmContainer = _elmContainer;\r
3649                         }\r
3650                         if( file !== _file){\r
3651                                 file = _file;\r
3652                                 draw();\r
3653                         }\r
3654                         if( index !== _index){\r
3655                                 index = _index;\r
3656                                 resize( index );\r
3657                         }\r
3658                         callback = _callback;\r
3659                 };\r
3660                 this.elm = ELM_WRAPPER;\r
3661                 this.index = function( _index ){\r
3662                         return index;\r
3663                 };\r
3664                 this.onResize = function( w ){\r
3665                         \r
3666                 };\r
3667                 this.destroy = function(){\r
3668                         elmContainer.removeChild( ELM_WRAPPER );\r
3669                         file = elmContainer = null;\r
3670                         BREAD_OBJECT_POOL.push( this );\r
3671                 };\r
3672         }\r
3673         \r
3674         var FinderClass = function( application, elmRoot, tree, header, footer, onSelect, viewerOption, editorOption ){\r
3675                 var ICON_ARRAY       = [],\r
3676                         BREAD_ARRAY      = [],\r
3677                         elmContainer     = ELM_ORIGIN_CONTAINER.cloneNode( true ),\r
3678                         elmLocation      = elmContainer.getElementsByTagName( 'ul' )[ 0 ],\r
3679                         nodesDiv         = elmContainer.getElementsByTagName( 'div' ),\r
3680                         elmSidebarButton = nodesDiv[ 1 ],\r
3681                         elmStyleButton   = nodesDiv[ 2 ],\r
3682                         elmActionButton  = nodesDiv[ 3 ],\r
3683                         elmBody          = nodesDiv[ nodesDiv.length -1 ],\r
3684                         headX,\r
3685                         headY,\r
3686                         headH            = Util.getElementSize( nodesDiv[ 0 ] ).height,\r
3687                         bodyY,\r
3688                         currentFile      = null,\r
3689                         breadW           = 90,\r
3690                         size             = Util.getElementSize( ELM_ORIGIN_FINDER_ICON ),\r
3691                         iconW            = size.width,\r
3692                         iconH            = size.height,\r
3693                         style            = 0,\r
3694                         w, h, bodyH,\r
3695                         instance = this;\r
3696                         \r
3697                 tree.addTreeEventListener( Const.TREE.EVENT.UPDATE, draw );\r
3698                 elmRoot.appendChild( elmContainer );\r
3699                 \r
3700                 function draw( _w, _h ){\r
3701                         w = Type.isFinite( _w ) === true ? _w : w;\r
3702                         h = Type.isFinite( _h ) === true ? _h : h;\r
3703                         bodyH = h - headH;\r
3704                         var     l = tree.hierarchy() + 1,\r
3705                                 m = BREAD_ARRAY.length,\r
3706                                 _file, _bread;\r
3707                         for( var i=0; i<l; ++i ){\r
3708                                 _file = i !== l-1 ? tree.getParentFileAt( i ) : tree.getCurrentFile();\r
3709                                 if( i < m ){\r
3710                                         BREAD_ARRAY[ i ].init( _file, elmLocation, i, onHeadClick );\r
3711                                 } else {\r
3712                                         BREAD_ARRAY.push( getBreadcrumb( _file, elmLocation, i, onHeadClick ));\r
3713                                 }\r
3714                         };\r
3715                         while( l < BREAD_ARRAY.length ){\r
3716                                 BREAD_ARRAY.pop().destroy();\r
3717                         };\r
3718                         \r
3719                         l = _file.getChildFileLength();\r
3720                         m = ICON_ARRAY.length;\r
3721 \r
3722                         for( i=0; i<l; ++i ){\r
3723                                 if( i < m ){\r
3724                                         ICON_ARRAY[ i ].init( _file.getChildFileByIndex( i ), elmBody, w, i, style, onDown, onEditor, onViwer, onAction );\r
3725                                 } else {\r
3726                                         ICON_ARRAY.push( getFinderIcon( _file.getChildFileByIndex( i ), elmBody, _w, i, style, onDown, onEditor, onViwer, onAction ));\r
3727                                 }\r
3728                         };\r
3729                         if( _file.getState() === Const.FILE.STATE.LOADING ){\r
3730                                 elmBody.className = 'finder-body loading';\r
3731                         } else {\r
3732                                 elmBody.className = 'finder-body';\r
3733                         };\r
3734                         \r
3735                         elmBody.style.height = bodyH + 'px';\r
3736                         \r
3737                         while( l < ICON_ARRAY.length && ICON_ARRAY.length > 0 ){\r
3738                                 ICON_ARRAY.pop().destroy();\r
3739                         };\r
3740                 };\r
3741                 \r
3742                 function onHeadClick( i){\r
3743                         var l = BREAD_ARRAY.length -1;\r
3744                         if( i < l){\r
3745                                 var _file = tree.getParentFileAt( i);\r
3746                                 if( _file !== null){\r
3747                                         tree.up( i);\r
3748                                         draw( w, h );\r
3749                                 };\r
3750                         };\r
3751                 };\r
3752                 function onDown( i ){\r
3753                         if( i < ICON_ARRAY.length ){\r
3754                                 var _file = tree.getCurrentFile().getChildFileByIndex( i );\r
3755                                 if( _file !== null && ( _file.getChildFileLength() !== -1 || _file.getType() === Const.FILE.TYPE.FOLDER )){\r
3756                                         tree.down( i );\r
3757                                         draw( w, h );\r
3758                                 } else {\r
3759                                         Type.isFunction( onSelect ) === true && onSelect( _file  );\r
3760                                 };\r
3761                                 _file.destroy();\r
3762                         };\r
3763                 };\r
3764                 function onEditor( _file, _app, editorOption ){\r
3765                         _app.boot( _file, editorOption );\r
3766                 };\r
3767                 function onViwer( _file, _app ){\r
3768                         _app.boot( _file, viewerOption );\r
3769                 };\r
3770                 function onAction( _file ){\r
3771 \r
3772                 };\r
3773                 this.MIN_WIDTH     = 240;\r
3774                 this.MIN_HEIGHT    = 240;\r
3775                 this.onInit = function(){\r
3776                         var position = Util.getAbsolutePosition( elmLocation );\r
3777                         headX = position.x;\r
3778                         headY = position.y;\r
3779                         bodyY = Util.getAbsolutePosition( elmBody ).y;\r
3780                 };\r
3781                 this.onPaneResize = function( _w, _h ){\r
3782                         draw( _w, _h );                 \r
3783                         \r
3784                         w = _w;\r
3785                         h = _h;\r
3786                         elmBody.style.height = ( _h - headH ) + 'px';\r
3787                         \r
3788                         for( var i=0, l=ICON_ARRAY.length; i<l; ++i ){\r
3789                                 ICON_ARRAY[ i].onResize( _w );\r
3790                         }\r
3791                 };\r
3792                 this.destroy = function(){\r
3793                         tree.removeTreeEventListener( Const.TREE.EVENT.UPDATE, draw );\r
3794                         \r
3795                         while( BREAD_ARRAY.length > 0 ){\r
3796                                 BREAD_ARRAY.shift().destroy();\r
3797                         }\r
3798                         while( ICON_ARRAY.length > 0 ){\r
3799                                 ICON_ARRAY.shift().destroy();\r
3800                         }\r
3801                 };\r
3802         };\r
3803         FinderClass.prototype = new AbstractBasicPane();\r
3804         \r
3805         function getFinderIcon( _file, _elmContainer, w, index, style, onDown, onEditor, onViwer, onAction){\r
3806                 var _icon;\r
3807                 if( FINDER_ICON_POOL.length > 0){\r
3808                         _icon = FINDER_ICON_POOL.shift();\r
3809                 } else {\r
3810                         _icon = new FinderIconClass();\r
3811                 }\r
3812                 _icon.init( _file, _elmContainer, w, index, style, onDown, onEditor, onViwer, onAction );\r
3813                 return _icon;\r
3814         }\r
3815         \r
3816         function getBreadcrumb( _file, _elmContainer, index, callback ){\r
3817                 var _bread;\r
3818                 if( BREAD_OBJECT_POOL.length > 0 ){\r
3819                         _bread = BREAD_OBJECT_POOL.shift();\r
3820                 } else {\r
3821                         _bread = new BreadcrumbClass();\r
3822                 }\r
3823                 _bread.init( _file, _elmContainer, index, callback );\r
3824                 return _bread;\r
3825         }\r
3826 \r
3827         return {\r
3828                 init: function(){\r
3829                         \r
3830                 },\r
3831                 create: function( _application, _elmTarget, _tree, _header, _footer, _onSelect, _viewerOption, _editorOption ){\r
3832                         //if( Application.isApplicationInstance( _application ) === false ) return;\r
3833                         \r
3834                         var _finder = new FinderClass( _application, _elmTarget, _tree, _header, _footer, _onSelect, _viewerOption, _editorOption );\r
3835                         _finder.init();\r
3836                         FINDER_ARRAY.push( _finder );\r
3837                         return _finder;\r
3838                 },\r
3839                 registerFinderHead: function(){\r
3840                         \r
3841                 },\r
3842                 registerFinderPane: function( _finderPane ){\r
3843                         \r
3844                 },\r
3845                 isFinderInstance: function( _finder ){\r
3846                         return _finder instanceof FinderClass;\r
3847                 },\r
3848                 isFinderPaneInstance: function(){\r
3849                         \r
3850                 },\r
3851                 isFinderHeadInstance: function(){\r
3852                 }\r
3853         }\r
3854 })();\r
3855 \r
3856 \r
3857 /* --------------------------------------------\r
3858  * 
3859  */\r
3860 \r
3861         Application.onCurrentApplicationChange( SUPER_USER_KEY );\r
3862         \r
3863         SERVICE_LIST.push( MouseEvent );\r
3864         \r
3865         new EventTicketClass( window, 'unload', function(){\r
3866                 var _service;\r
3867                 while( SERVICE_LIST.length > 0 ){\r
3868                         _service = SERVICE_LIST.shift();\r
3869                         Type.isFunction( _service.onSystemShutdown ) === true && _service.onSystemShutdown();\r
3870                 }\r
3871         });\r
3872         // beforeunload\r
3873 \r
3874 \r
3875 /* ---------------------------------------------\r
3876  * broadcast to global
3877  */\r
3878         window.gOS = {};\r
3879         \r
3880         gOS.registerApplication = Application.register;\r
3881         gOS.registerDriver      = File.registerDriver;\r
3882         \r
3883 })( window );\r