OSDN Git Service

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