OSDN Git Service

add enter home button.
[pettanr/pettanr.git] / app / assets / javascripts / system.js
1 /*\r
2  * pettanR system.js\r
3  *   version 0.5.18\r
4  * \r
5  * \r
6  * Type\r
7  * \r
8  * UA\r
9  * \r
10  * Util\r
11  * \r
12  * CSS\r
13  * \r
14  * gadgetOS\r
15  *   author:\r
16  *     itozyun\r
17  *   licence:\r
18  *     3-clause BSD\r
19  */\r
20 \r
21 \r
22 /*\r
23  * http://pettanr.sourceforge.jp/test/type.html\r
24  */\r
25         var Type = {\r
26                 isObject : function(v) {\r
27                         return v !== null && typeof v === 'object';\r
28                 },\r
29                 isFunction : function(v) {\r
30                         return typeof v === 'function';\r
31                 },\r
32                 isArray : function(v) {\r
33                         return Object.prototype.toString.call(v) === "[object Array]";\r
34                 },\r
35                 isBoolean : function(v) {\r
36                         return typeof v === 'boolean';\r
37                 },\r
38                 isString : function(v) {\r
39                         return typeof v === 'string';\r
40                 },\r
41                 isNumber : function(v) {\r
42                         return typeof v === 'number';\r
43                 },\r
44                 isFinite : function(v){\r
45                         return Type.isNumber(v) === true && isFinite(v);\r
46                 },\r
47                 isHTMLElement : function(v){\r
48                         if( 'HTMLElement' in window ){\r
49                                 Type.isHTMLElement = function(v){\r
50                                         return v instanceof HTMLElement;\r
51                                 }\r
52                         } else {\r
53                                 Type.isHTMLElement = function(v) {\r
54                                         if( Type.isObject(v) === false ){\r
55                                                 return false;\r
56                                         }\r
57                                         var r;\r
58                                         if(v && v.nodeType === 1 ){\r
59                                                 try{\r
60                                                         r = v.cloneNode(false);\r
61                                                 } catch(n) {\r
62                                                         return false;\r
63                                                 }\r
64                                                 if(r === v) return false;\r
65                                                 try{\r
66                                                         r.nodeType = 9;\r
67                                                         return r.nodeType === 1;\r
68                                                 } catch(n) {}\r
69                                                 return true;\r
70                                         }\r
71                                         return false;\r
72                                 }\r
73                         }\r
74                         return Type.isHTMLElement(v);\r
75                 },\r
76                 /*\r
77                 isElementCollection : function(v) {\r
78                         return (Object.prototype.toString.call(v) === "[object HTMLCollection]");\r
79                 },\r
80                 */\r
81                 isNull : function(v) {\r
82                         return v === null;\r
83                 },\r
84                 isUndefined : function(v) {\r
85                         return typeof v === 'undefined';\r
86                 }\r
87         };\r
88 \r
89 /*\r
90  * UA\r
91  * \r
92  *   detect userAgent\r
93  *   detect plug in\r
94  */\r
95         var UA = ( function(){\r
96                 var ua = (function(){\r
97                                 var acme = {};\r
98                                 \r
99                                 var n    = navigator;\r
100                                 var dua  = n.userAgent;\r
101                                 var dav  = n.appVersion;\r
102                                 var tv   = parseFloat(dav);\r
103                                 acme.isOpera  = (dua.indexOf("Opera") >= 0) ? tv: undefined;\r
104                                 acme.isKhtml  = (dav.indexOf("Konqueror") >= 0) ? tv : undefined;\r
105                                 acme.isWebKit = parseFloat(dua.split("WebKit\/")[1]) || undefined;\r
106                                 acme.isChrome = parseFloat(dua.split("Chrome\/")[1]) || undefined;\r
107                                 acme.isGecko  = (dua.indexOf("Gecko\/") >= 0) ? parseFloat(dua.split("rv:")[1].replace( /^(\d*\.\d*)\.(\d*)/, '$1$2' )) : undefined;\r
108                                 var index = Math.max(dav.indexOf("WebKit"), dav.indexOf("Safari"), 0);\r
109                                 if(index && !acme.isChrome){\r
110                                         acme.isSafari = parseFloat(dav.split("Version/")[1]);\r
111                                         if(!acme.isSafari || parseFloat(dav.substr(index + 7)) <= 419.3){\r
112                                                 acme.isSafari = 2;\r
113                                         }\r
114                                 }\r
115                                 if(document.all && !acme.isOpera){\r
116                                         acme.isIE = parseFloat(dav.split("MSIE ")[1]) || undefined;\r
117                                 }\r
118                                 \r
119                                 return acme;\r
120                         })(),\r
121                         isIE = navigator.userAgent.toLowerCase().indexOf( 'msie') !== -1,\r
122                         ieVersion = isIE === true ? parseInt( navigator.appVersion.toLowerCase().replace( /.*msie[ ]/, '').match( /^[0-9]+/)) : 0,\r
123                         ieRenderingVersion = ieVersion === 8 ? document.documentMode : ieVersion,\r
124                         isStanderdMode = document.compatMode === 'CSS1Compat',\r
125                         ActiveX = ( function(){\r
126                                 if( isIE === false || ieVersion > 8 ) return false;\r
127                                 var     b = document.body,\r
128                                         c = b.className || '',\r
129                                         x,\r
130                                         ret = undefined, //pettanr.URL_PARAMS.ActiveX,\r
131                                         ns = 'pettanr-ActiveX-',\r
132                                         enabled = 'enabled',\r
133                                         disabled = 'disabled';\r
134                                 if( ret !== true && ret !== false){\r
135                                         if( b.className.indexOf( ns + enabled ) !== -1 )  return true;\r
136                                         if( b.className.indexOf( ns + disabled ) !== -1 ) return false;\r
137                                         x = document.createElement( 'div' );\r
138                                         b.appendChild(x);\r
139                                         x.style.cssText = 'width:1px;height:1px;line-height:1px;filter:progid:DXImageTransform.Microsoft.Shadow()';\r
140                                         ret = x.offsetHeight > 1;\r
141                                         b.removeChild(x);\r
142                                 }\r
143                                 b.className += [ c !== '' ? ' ' : c, ns, ret === true ? enabled : disabled ].join( '');\r
144                                 return ret;\r
145                         })(),\r
146                         VML = ( function(){\r
147                                 if( ActiveX === false || isIE === false || ieVersion > 8) return false;\r
148                                 var globalObjectName = 'detect_activex',//Util.createGlobalUniqueName(),\r
149                                         script,\r
150                                         id = 'detectVML';\r
151                                 document.write( [ '<!--[if gte vml 1]><script id="', id, '">window', '.', globalObjectName, '=1;<\/script><![endif]-->'].join( ''));\r
152                                 if( window[ globalObjectName ] === 1 ){\r
153                                         script = document.getElementById( id );\r
154                                         script.parentNode.removeChild( script );\r
155                                         window[ globalObjectName ] = null;\r
156                                         return true;\r
157                                 }\r
158                                 return false;\r
159                         })(),\r
160                         isStandAloneMode = ( function(){\r
161                                 if( isIE === false) return false;\r
162                                 if( VML === true) return false;\r
163                                 var globalObjectName = 'detect_standalone', //Util.createGlobalUniqueName(),\r
164                                         script,\r
165                                         id = 'detectStandAlone';\r
166                                 document.write( [ '<!--[if IE ', Math.floor( ieVersion ), ']><script id="', id, '">window', '.', globalObjectName, '=1;<\/script><![endif]-->'].join( ''));\r
167                                 if( window[globalObjectName] === 1){\r
168                                         script = document.getElementById( id);\r
169                                         script.parentNode.removeChild( script);\r
170                                         window[globalObjectName] = null;\r
171                                         return false;\r
172                                 }\r
173                                 return true;\r
174                         })();\r
175                 return {\r
176                         IE:                                     ua.isIE,\r
177                         GECKO:                          ua.isGecko,\r
178                         OPERA:                          ua.isOpera,\r
179                         KHTML:                          ua.isKhtml,\r
180                         WEBKIT:                         ua.isWebKit,\r
181                         CHROME:                         ua.isChrome,\r
182                         isIE:                           isIE,\r
183                         ieVersion:                      ieVersion,\r
184                         ieRenderingVersion:     ieRenderingVersion,\r
185                         isStanderdMode:         isStanderdMode,\r
186                         ACTIVEX:            ActiveX,\r
187                         VML:                VML,\r
188                         STANDALONE:         isStandAloneMode,\r
189                         VENDER_PREFIX: ( function() {\r
190                                 var ua = navigator.userAgent.toLowerCase();\r
191                                 if ( ua.indexOf('opera') !== -1 ){\r
192                                         return 'O';\r
193                                 } else if ( ua.indexOf('msie') !== -1 ){\r
194                                         return 'ms';\r
195                                 } else if ( ua.indexOf('webkit') !== -1 ){\r
196                                         return 'webkit';\r
197                                 } else if ( navigator.product === 'Gecko' ){\r
198                                         return 'Moz';\r
199                                 }\r
200                                 return '';\r
201                         })(),\r
202                         startVML: function(){\r
203                                 delete UA.startVML;\r
204                                 if( UA.VML !== true) return false;\r
205                                 if (!document.namespaces["v"]) {\r
206                                 document.namespaces.add("v", "urn:schemas-microsoft-com:vml", "#default#VML");\r
207                             }\r
208                             document.createStyleSheet().cssText = "v\:shape,v\:image{behavior:url(#default#VML);display:block;};";\r
209                         }\r
210                 };\r
211         })();\r
212 \r
213 \r
214 /* ----------------------------------------------------\r
215  * Util\r
216  * \r
217  *   extend( baseInstance, extend)\r
218  *   cleanCommnetNode()\r
219  *   cleanElement()\r
220  *   getElementSize( _elm)\r
221  *   getImageSize()\r
222  *   getAbsolutePath()\r
223  *   getGrobalObjectName()\r
224  * \r
225  */\r
226         var Util = ( function( window, document, undefined ){\r
227                 var body = document.getElementsByTagName( 'body' )[ 0 ];\r
228                         \r
229                 var ELM_SIZE_GETTER = ( function(){\r
230                                 var ret = document.createElement( 'div' );\r
231                                 body.appendChild( ret );\r
232                                 \r
233                                 ret.id            = 'elmSizeGetter';\r
234                                 ret.style.cssText = 'position:absolute;left:0;top:-9999px;visibility:hidden';\r
235                                 \r
236                                 body.removeChild( ret );\r
237                                 return ret;\r
238                         })(),\r
239                         CLEAN_TARGET_ELEMENT = 'script,style,object,applet,embed,iframe,frame,base,bgsound,frameset,listing'.split( ',' );\r
240                 \r
241                 var UNIT_RATIO = ( function( elm ){\r
242                                 var ret = {},\r
243                                         unit,\r
244                                         units = 'cm,mm,in,pt,pc'.split( ',' );\r
245                                 \r
246                                 body.appendChild( elm );\r
247                                 \r
248                                 for( var i=units.length; i; ){\r
249                                         unit = units[ --i ];\r
250                                         elm.style.width = 1000 + unit;\r
251                                         ret[ unit ] = elm.offsetWidth / 1000;\r
252                                 };\r
253                                 elm.style.cssText = '';\r
254                                 \r
255                                 body.removeChild( elm );\r
256                                 return ret;\r
257                         })( ELM_SIZE_GETTER );\r
258                         \r
259                 var FONT_SIZE_RATIO = ( function( elm ){\r
260                                 var ret = {},\r
261                                         size,\r
262                                         list = 'xx-large,x-large,large,larger,medium,small,smaller,x-small,xx-small'.split( ',' );\r
263                                 \r
264                                 body.appendChild( elm );\r
265                                 elm.style.cssText = 'font-size:100px;line-height:1em;';\r
266                                 elm.appendChild( document.createTextNode( 'X' ) );\r
267                                 \r
268                                 base = elm.offsetHeight;\r
269                                 \r
270                                 for( var i = list.length; i; ){\r
271                                         size = list[ --i ];\r
272                                         elm.style.fontSize = size;\r
273                                         ret[ size ] = elm.offsetHeight;// / base;\r
274                                 };\r
275                                 \r
276                                 elm.style.cssText = '';\r
277                                 elm.removeChild( elm.firstChild );\r
278                                 body.removeChild( elm );\r
279                                 return ret;\r
280                         })( ELM_SIZE_GETTER );\r
281                 \r
282                 var REG_LARGE = /[A-Z]/g;\r
283                 \r
284                 /* clean comment node */\r
285                 window.setTimeout( function(){\r
286                         Util.cleanCommnetNode();\r
287                         \r
288                         /* clean noscript */\r
289 \r
290                         var noscripts = Util.copyArray( document.getElementsByTagName( 'noscript' ) ),\r
291                                 ns;\r
292                         for( var i = noscripts.length; i; ){\r
293                                 ns = noscripts[ --i ];\r
294                                 ns.parentNode && ns.parentNode.removeChild( ns );\r
295                         };\r
296                 }, 0 );\r
297                 \r
298                 function clone( src ) {\r
299                         var ret;\r
300                         if( Type.isArray(src) === true ){\r
301                                 ret = [];\r
302                         } else\r
303                         if( Type.isObject(src) === true ){\r
304                                 ret = {};\r
305                         } else\r
306                         if( Type.isNumber(src) === true || Type.isString(src) === true || Type.isBoolean( src ) === true ){\r
307                                 return src;\r
308                         } else {\r
309                                 return null;\r
310                         };\r
311                         for( var key in src ){\r
312                                 ret[ key ] = clone( src[ key ]);\r
313                         };\r
314                         return ret;\r
315                 };\r
316                 \r
317                 return {\r
318                         parse: function( v ){\r
319                                 if( Type.isString( v ) === true ){\r
320                                         if( v === 'true' )      return true;\r
321                                         if( v === 'false' )     return false;\r
322                                         if( v === 'null' )      return null;\r
323                                         if( v === 'undefined' ) return undefined;\r
324                                         if( v === 'NaN' )       return NaN;\r
325                                         if( v === '' )          return v;\r
326                                         var _v = v.split( ' ' ).join( '' ),\r
327                                                 n = _v - 0;\r
328                                         if( '' + n === _v || '' + n === '0' + _v  ) return n - 0;\r
329                                 };\r
330                                 return v;\r
331                         },\r
332                         extend: function( baseInstance, extend ){\r
333                                 for( var key in extend ){\r
334                                         if( Type.isUndefined( baseInstance[ key ] ) === true ){\r
335                                                 baseInstance[ key ] = extend[ key ];\r
336                                         } else\r
337                                         if( typeof baseInstance[ key ] === typeof extend[ key ] ){\r
338                                                 baseInstance[ key ] = extend[ key ];\r
339                                         } else {\r
340                                                 alert( 'extend error' );\r
341                                         };\r
342                                 };\r
343                                 return baseInstance;\r
344                         },\r
345                         copy: function( objOrArray ){\r
346                                 return clone( objOrArray );\r
347                         },\r
348                         cleanCommnetNode: function ( _targetElm ){\r
349                                 search( _targetElm || body );\r
350                                 \r
351                                 function search( _elm ){\r
352                                         if( !_elm ) return;\r
353                                         if( _elm.nodeType === 8 ){\r
354                                                 _elm.parentNode.removeChild( _elm );\r
355                                                 return;\r
356                                         };\r
357                                         if( _elm.nodeType === 1 ){\r
358                                                 var _array = Util.copyArray( _elm.childNodes ); // liveNode > array\r
359                                                 while( _array.length > 0 ) search( _array.shift() );\r
360                                         };\r
361                                 };\r
362                         },\r
363                         cleanElement: function( _targetElm ){\r
364                                 var _array, _elm, j, _css;\r
365                                 for( var i = CLEAN_TARGET_ELEMENT.length; i; ){\r
366                                         _array = Util.copyArray( _targetElm.getElementsByTagName( CLEAN_TARGET_ELEMENT[ --i ] ) );\r
367                                         for( j = _array.length; j; ){\r
368                                                 _elm = _nodes[ --j ];\r
369                                                 _elm.parentNode && _elm.parentNode.removeChild( _elm );\r
370                                         };\r
371                                 };\r
372                                 Util.cleanCommnetNode( _targetElm );\r
373                                 \r
374                                 if( UA.isIE === false ) return;\r
375                                 _nodes = _targetElm.all || _targetElm.getElementsByTagName( '*' );\r
376                                 for( i = _nodes.length; i; ){\r
377                                         _elm = _nodes[ --i ];\r
378                                         _css = Util.getInlineStyle( _elm );\r
379                                         _css.filter   = null;\r
380                                         _css.behavior = null;\r
381                                         _elm.style.cssText = Util.toCssText( _css );\r
382                                 };\r
383                         },\r
384                         camelize: function( cssProp ){\r
385                             var parts = cssProp.split( ' ' ).join( '' ).split( '-' ),\r
386                                 l     = parts.length;\r
387                             if( l === 1 ) return parts[ 0 ];\r
388                         \r
389                             var camelized = cssProp.charAt(0) === '-'\r
390                               ? parts[ 0 ].charAt( 0 ).toUpperCase() + parts[ 0 ].substring( 1 )\r
391                               : parts[ 0 ];\r
392                         \r
393                             for( var i = 1; i < l; ++i ){\r
394                                 camelized += parts[ i ].charAt( 0 ).toUpperCase() + parts[ i ].substring( 1 );\r
395                             };\r
396                             return camelized;\r
397                         },\r
398                         uncamelize: function( str ){\r
399                                 return str.split( ' ' ).join( '' ).replace( REG_LARGE, '-$&' ).toLowerCase();\r
400                         },\r
401                         pxTo: function( _px, _unit ){\r
402                                 return _px / ( UNIT_RATIO[ _unit ] || 1 );\r
403                         },\r
404                         toPx: function( x, _unit ){\r
405                                 return x * ( UNIT_RATIO[ _unit ] || 1 );\r
406                         },\r
407                         absoluteFontSizeToPx: function( fontsize ){\r
408                                 return FONT_SIZE_RATIO[ fontsize ] || 0;\r
409                         },\r
410                         getElementSize: function( _elm ){\r
411                                 if( Type.isHTMLElement( _elm ) === false ){\r
412                                         return {\r
413                                                 width:  0,\r
414                                                 height: 0\r
415                                         };\r
416                                 };\r
417                                 var     parentElm   = _elm.parentNode,\r
418                                         prevElm     = _elm.previousSibling,\r
419                                         nextElm     = _elm.nextSibling,\r
420                                         displayNone = _elm.style.display === 'none';\r
421                                 if( displayNone === true ) _elm.style.display = 'block';\r
422                                 \r
423                                 body.appendChild( ELM_SIZE_GETTER );\r
424                                 ELM_SIZE_GETTER.appendChild( _elm );\r
425                                 \r
426                                 var ret = {\r
427                                         width:          _elm.offsetWidth,\r
428                                         height:         _elm.offsetHeight\r
429                                 };\r
430                                 if( displayNone === true ) _elm.style.display = 'none';\r
431                                 if( nextElm ){\r
432                                         parentElm.insertBefore( _elm, nextElm );\r
433                                 } else          \r
434                                 if( prevElm && prevElm.nextSibling ){\r
435                                         parentElm.insertBefore( _elm, prevElm.nextSibling );\r
436                                 } else {\r
437                                         parentElm && parentElm.appendChild( _elm );\r
438                                 };\r
439                                 body.removeChild( ELM_SIZE_GETTER );\r
440                                 \r
441                                 return ret;\r
442                         },\r
443                         getImageSize: function( img ){\r
444                                 var     parentElm   = img.parentNode,\r
445                                         prevElm     = img.previousSibling,\r
446                                         nextElm     = img.nextSibling,\r
447                                         displayNone = img.style.display === 'none';\r
448                                 if( displayNone === true ) img.style.display = '';\r
449                                 \r
450                                 body.appendChild( ELM_SIZE_GETTER );\r
451                                 ELM_SIZE_GETTER.appendChild( img );\r
452                                 \r
453                                 var size = getActualDimension( img );\r
454                                 \r
455                                 if( displayNone === true ) img.style.display = 'none';\r
456                                 if( nextElm ){\r
457                                         parentElm.insertBefore( img, nextElm );\r
458                                 } else          \r
459                                 if( prevElm && prevElm.nextSibling ){\r
460                                         parentElm.insertBefore( img, prevElm.nextSibling );\r
461                                 } else {\r
462                                         parentElm && parentElm.appendChild( img );\r
463                                 }\r
464                                 body.removeChild( ELM_SIZE_GETTER );\r
465                                 \r
466                         /* LICENSE: MIT\r
467                          * AUTHOR: uupaa.js@gmail.com\r
468                          */\r
469                                 function getActualDimension(image) {\r
470                                         var run, mem, w, h, key = "actual";\r
471                                 \r
472                                 // for Firefox, Safari, Google Chrome\r
473                                         if( "naturalWidth" in image ){\r
474                                                 return {\r
475                                                         width:  image.naturalWidth,\r
476                                                         height: image.naturalHeight\r
477                                                 };\r
478                                         };\r
479                                 \r
480                                         if( "src" in image ){ // HTMLImageElement\r
481                                                 if (image[key] && image[key].src === image.src) {\r
482                                                         return image[key];\r
483                                                 };\r
484                                                 if( document.uniqueID ){ // for IE\r
485                                                         run = image.runtimeStyle;\r
486                                                         mem = { w: run.width, h: run.height }; // keep runtimeStyle\r
487                                                         run.width  = "auto"; // override\r
488                                                         run.height = "auto";\r
489                                                         w = image.width;\r
490                                                         h = image.height;\r
491                                                         run.width  = mem.w; // restore\r
492                                                         run.height = mem.h;\r
493                                                 } else { // for Opera and Other\r
494                                                         mem = { w: image.width, h: image.height }; // keep current style\r
495                                                         image.removeAttribute("width");\r
496                                                         image.removeAttribute("height");\r
497                                                         w = image.width;\r
498                                                         h = image.height;\r
499                                                         image.width  = mem.w; // restore\r
500                                                         image.height = mem.h;\r
501                                                 };\r
502                                                 return image[key] = { width: w, height: h, src: image.src }; // bond\r
503                                         };\r
504                                         // HTMLCanvasElement\r
505                                         return { width: image.width, height: image.height };\r
506                                 };\r
507                                 \r
508                                 return size;\r
509                         },\r
510                         getAbsolutePath: function( path ){\r
511                                 var elm = document.createElement('div');\r
512                                 body.appendChild( elm );\r
513                                 elm.innerHTML = '<a href=\"' + path + '\" />';\r
514                                 body.removeChild( elm );\r
515                                 return elm.firstChild.href;\r
516                         },\r
517                         getAbsolutePosition: function( _elm ){\r
518                                 // Find the destination's position\r
519                                 // need html, body { fontfamily: "MS PGothic", "MS Gothic" } for ie6.\r
520                                 var     destx    = _elm.offsetLeft,\r
521                                         desty    = _elm.offsetTop,\r
522                                         thisNode = _elm,\r
523                                         body     = document.body;\r
524                                 while( thisNode.offsetParent && thisNode !== body ){\r
525                                         thisNode = thisNode.offsetParent;\r
526                                         destx += thisNode.offsetLeft;\r
527                                         desty += thisNode.offsetTop;\r
528                                 };\r
529                                 return {\r
530                                         x:      destx,\r
531                                         y:      desty\r
532                                 };\r
533                         },\r
534                         pullHtmlAsTemplete: function( html ){\r
535                                 var elm = document.createElement( 'div' );\r
536                                 body.appendChild( elm );\r
537                                 elm.innerHTML = html;\r
538                                 body.removeChild( elm );\r
539                                 return elm.firstChild;\r
540                         },\r
541                         getElementsByClassName: function( _elm, _className, opt_tagName ){\r
542                                 var _all       = !opt_tagName || opt_tagName === '*',\r
543                                         _livenodes = _all === true ? ( _elm.all || _elm.getElementsByTagName( '*' )) : _elm.getElementsByTagName( opt_tagName ),\r
544                                         _nodes     = Util.copyArray( _livenodes );\r
545                                 for( var j = 0; j < _nodes.length; ){\r
546                                         _node = _nodes[ j ];\r
547                                         if( _node.nodeType !== 1 || Util.hasClassName( _node, _className ) === false ){\r
548                                                 _nodes.splice( j, 1 );\r
549                                         } else {\r
550                                                 ++j;\r
551                                         };\r
552                                 };\r
553                                 return _nodes;\r
554                         },\r
555                         getChildIndex: function( _parent, _child ){\r
556                                 var _children = _parent.getElementsByTagName( _child.tagName );\r
557                                 for( var i = _children.length; i; ){\r
558                                         if( _children[ --i ] === _child ) return i;\r
559                                 };\r
560                                 return -1;\r
561                         },\r
562                         hasClassName: function( _elm, _className ){\r
563                                 var cnames  = ( _elm.className || '' ).split( ' ' ),\r
564                                         _cnames = _className.split( ' ' ),\r
565                                         cname;\r
566                                 for( var i = _cnames.length; i; ){\r
567                                         cname = _cnames[ --i ];\r
568                                         if( cname === '' ) continue;\r
569                                         if( Util.getIndex( cnames, cname ) === -1 ) return false;\r
570                                 };\r
571                                 return true;\r
572                         },\r
573                         addClass: function( _elm, _className ){\r
574                                 if( Util.hasClassName( _elm, _className ) === false ){\r
575                                         var sp = ' ';\r
576                                         var _array = ( _elm.className || '' ).replace( /\s+/g, sp ).split( sp );\r
577                                         _array.push( _className );\r
578                                         _elm.className = _array.join( sp );\r
579                                 };\r
580                         },\r
581                         removeClass: function( _elm, _className ){\r
582                                 var sp     = ' ',\r
583                                         _array = _elm.className.replace( /\s+/g, sp ).split( sp ),\r
584                                         i      = Util.getIndex( _array, _className );\r
585                                 if( i !== -1 ){\r
586                                         _array.splice( i, 1 );\r
587                                         _elm.className = _array.join( sp );\r
588                                 };\r
589                         },\r
590                         toggleClass: function( _elm, _className ){\r
591                                 Util.hasClassName( _elm, _className ) === false ? Util.addClass( _elm, _className ) : Util.removeClass( _elm, _className );\r
592                         },\r
593                         removeAllChildren: function ( _elm){\r
594                                 while( _elm.firstChild){\r
595                                         remove( _elm.firstChild);\r
596                                 }\r
597                                 function remove( _node){\r
598                                         while( _node.firstChild){\r
599                                                 remove( _node.firstChild);\r
600                                         }\r
601                                         _node.parentNode && _node.parentNode.removeChild( _node);\r
602                                 }\r
603                         },\r
604                         getIndex: function( _array, _element ){\r
605                                 if( Array.prototype.indexof ){\r
606                                         Util.getIndex = function( _array, _element ){\r
607                                                 return _array.indexof( _element );\r
608                                         };\r
609                                 } else {\r
610                                         Util.getIndex = function( _array, _element ){\r
611                                                 for( var i = _array.length; i; ){\r
612                                                         if( _array[ --i ] === _element ) return i;\r
613                                                 };\r
614                                                 return -1;\r
615                                         };\r
616                                 };\r
617                                 return Util.getIndex( _array, _element );\r
618                         },\r
619                         copyArray: function( _array ){\r
620                                 var l = _array.length,\r
621                                         ret = new Array( l );\r
622                                 for( var i=0; i<l; ++i ){\r
623                                         ret[ i ] = _array[ i ];\r
624                                 }\r
625                                 return ret;\r
626                         },\r
627                         /*\r
628                          * \r
629                          */\r
630                         createGlobalUniqueName: function(){\r
631                                 var randomKey = null;\r
632                                 while( true ){\r
633                                         randomKey = '_uniqueName'+(''+Math.random()).replace(/\./,'');\r
634                                         if( typeof window[randomKey] === 'undefined'){\r
635                                                 break;\r
636                                         }\r
637                                 }\r
638                                 return randomKey;\r
639                         },\r
640                         createIframe: function( id, callback){\r
641                                 var ua = UA;\r
642                     var el = document.createElement( ua.isIE ? '<iframe name="' + id + '" frameborder="0" scrolling="no">' : 'iframe');\r
643         \r
644                     if( ua.isIE){\r
645                                         el.onreadystatechange = detect;\r
646                     } else {\r
647                         // iron(chrome) の場合、append の前に onload を指定しないと onload が呼ばれない\r
648                         el.onload = onLoad;\r
649                         //setTimeout( asynkCallback, 0 );\r
650                                 }\r
651         \r
652                                 document.body.appendChild( el);\r
653                     el.id = el.name = id;\r
654                     el.setAttribute( 'name', id);\r
655                     el.style.cssText = 'width:1px;height:1px;visibility:hidden;position:absolute;top:1px;left:1px;';\r
656                                 // http://d.hatena.ne.jp/onozaty/20070830/p1\r
657                                 // [JavaScript]IE6ではJavaScriptで動的に作成したiframeに対してsubmitできない(IE7は未確認) ->解決\r
658                                 el.contentWindow.name = id;                                     \r
659                     \r
660                     window[id] = el;\r
661         \r
662                     function detect(){\r
663                         if ( this.readyState === "complete" ){\r
664                             this.onreadystatechange = new Function();\r
665                             this.onreadystatechange = null;\r
666                             setTimeout( asynkCallback, 0 );\r
667                         };\r
668                     };\r
669                                 function onLoad(){\r
670                                         el.onload = null;\r
671                                         setTimeout( asynkCallback, 0 );\r
672                                 };\r
673                                 function asynkCallback(){\r
674                                         callback( el );\r
675                                 };\r
676                         }\r
677                 };\r
678         })( window, document );\r
679 \r
680 \r
681 var CSS = ( function( window, documwnt, undefined ){\r
682         var     CORON                  = ':',\r
683                 EMPTY                  = '',\r
684                 SEMICORON              = ';';\r
685                 UNITS                  = 'px,cm,mm,in,pt,pc,em,%'.split( ',' ),\r
686                 CLIP_SEPARATOR         = UA.isIE === true && UA.ieVersion < 8 ? ' ' : ',';\r
687 \r
688         var SPECIAL = ( function(){\r
689                 var _special = {};\r
690                 if( UA.isIE === true && UA.ieVersion < 9 ){\r
691                         if( UA.ACTIVEX === true ){\r
692                                 // _special.opacity    = 'ActiveXOpacity';\r
693                                 _special.setFilters = function( style ){\r
694                                         var filters = ( style.filter || '' ).split( ') ' ),\r
695                                                 data    = {},\r
696                                                 i       = filters.length,\r
697                                                 filter, names, props, prop, j, l, key, v;\r
698                                         for( ; i; ){\r
699                                                 filter   = filters[ --i ].split( ' ' ).join( '' ).split( '(' );\r
700                                                 if( filter.length !== 2 ) continue;\r
701                                                 names    = filter[ 0 ].split( '.' ); // progid:DXImageTransform.Microsoft.Shadow(color=#666666,direction=120,strength=9)\r
702                                                 props    = filter[ 1 ].split( ',' ); // \r
703                                                 filter   = {};\r
704                                                 for( j = 0, l = props.length; j < l; ++j ){\r
705                                                         prop = props[ j ].split( '=' );\r
706                                                         key  = prop[ 0 ].toLowerCase();\r
707                                                         v    = prop[ 1 ];\r
708                                                         filter[ key ] = v; //v.charAt( 0 ) === '#' ? v : parseInt( v );\r
709                                                 };\r
710                                                 data[ names[ names.length - 1 ] ] = filter;\r
711                                         };\r
712                                         \r
713                                         style.filter  = data;\r
714                                         style.opacity = data.alpha && data.alpha.opacity ? data.alpha.opacity / 100 : 1;\r
715                                 };\r
716                                 _special.hasLayout = function( elm ){\r
717                                         return elm.currentStyle.hasLayout;\r
718                                 };\r
719                         } else {\r
720                                 _special.opacity = null;\r
721                         };\r
722                 } else {\r
723                         var style = document.documentElement.style;\r
724                         _special.opacity = style.opacity          !== undefined ? 'opacity' : \r
725                                                         style.MozOpacity          !== undefined ? 'MozOpacity' :\r
726                                                         style.KhtmlOpacity        !== undefined ? 'KhtmlOpacity' :\r
727                                                         style[ '-khtml-opacity' ] !== undefined ? 'KhtmlOpacity' : null;\r
728 \r
729                         // if( style.backgroundPositionX === undefined ){\r
730                                 _special.setBackgroundPositionXY = function( style ){\r
731                                         var bgp = ( style.backgroundPosition || '' ).split( ' ' );\r
732                                         style.backgroundPositionX = bgp[ 0 ] || 0;\r
733                                         style.backgroundPositionY = bgp[ 1 ] || 0;\r
734                                 };\r
735                         // };\r
736                         if( style.clipTop === undefined && style[ 'clip-top' ] === undefined ){\r
737                                 _special.setClipTopRightBottomLeft = function( style ){\r
738                                         var clip = style.clip || '';\r
739                                         if( clip.indexOf( 'rect(' ) === -1 ){\r
740                                                 style.clipTop    = 0;\r
741                                                 style.clipRight  = 0;\r
742                                                 style.clipBottom = 0;\r
743                                                 style.clipLeft   = 0;\r
744                                                 return;\r
745                                         };\r
746                                         clip = clip.split( '(' )[ 1 ].split( ')' )[ 0 ].split( clip.indexOf( ',' ) !== -1 ? ',' : ' ' );\r
747                                         ret.clipTop    = clip[ 0 ];\r
748                                         ret.clipRight  = clip[ 1 ];\r
749                                         ret.clipBottom = clip[ 2 ];\r
750                                         ret.clipLeft   = clip[ 3 ];\r
751                                 };\r
752                         };\r
753                 };\r
754                                 \r
755                 return _special;\r
756         })();\r
757         \r
758         function cssToObject( css ){\r
759                 var ret = {}, i, nv, n, v, parse = Util.parse, isNumber = Type.isNumber;\r
760                 if( Type.isString( css ) === true ){\r
761                         css = css.split( ';' );\r
762                         for( i = css.length; i; ){\r
763                                 nv    = css[ --i ].split( ':' ); // filter の場合, progid: がくる\r
764                                 n     = nv.shift();\r
765                                 if( isNumber( parse( n ) ) === true ) continue;\r
766                                 v     = nv.join( '' );\r
767                                 while( v.charAt( 0 ) === ' ' ) v = v.substr( 1 );\r
768                                 ret[ Util.camelize( n ) ] = parse( v );\r
769                         };\r
770                 } else {\r
771                         for( n in css ){\r
772                                 if( Type.isNumber( parse( n ) ) === false ) ret[ n ] = parse( css[ n ] );\r
773                         };\r
774                 };\r
775 \r
776                 if( SPECIAL.setFilters ){\r
777                         SPECIAL.setFilters( ret );\r
778                 } else {\r
779                         ret.opacity = SPECIAL.opacity !== null ? ret[ SPECIAL.opacity ] : 1;\r
780                 };\r
781                 \r
782                 SPECIAL.setBackgroundPositionXY && SPECIAL.setBackgroundPositionXY( ret );\r
783                 SPECIAL.setClipTopRightBottomLeft && SPECIAL.setClipTopRightBottomLeft( ret );\r
784                 \r
785                 return ret;\r
786         };\r
787 \r
788         var COLOR = ( function(){\r
789                 var ret = {}, v, name,\r
790                         list = [\r
791                                 0, 'BLACK',\r
792                                 parseInt( 'FF0000', 16 ), 'RED',\r
793                                 parseInt( '00FF00', 16 ), 'LIME',\r
794                                 parseInt( '0000FF', 16 ), 'BLUE',\r
795                                 parseInt( 'FFFF00', 16 ), 'YELLOW',\r
796                                 parseInt( '00FFFF', 16 ), 'AQUA or CYAN',\r
797                                 parseInt( 'FF00FF', 16 ), 'FUCHSIA or MAGENTA',\r
798                                 parseInt( 'FFFFFF', 16 ), 'WHITE',\r
799                                 parseInt( '008000', 16 ), 'GREEN',\r
800                                 parseInt( '800080', 16 ), 'PURPLE',\r
801                                 parseInt( '800000', 16 ), 'MAROON',\r
802                                 parseInt( '000080', 16 ), 'NAVY',\r
803                                 parseInt( '808000', 16 ), 'OLIVE',\r
804                                 parseInt( '008080', 16 ), 'TEAL',\r
805                                 parseInt( '808080', 16 ), 'GRAY',\r
806                                 parseInt( 'C0C0C0', 16 ), 'SILVER',\r
807                                 parseInt( '696969', 16 ), 'DIMGRAY',\r
808                                 parseInt( '708090', 16 ), 'SLATEGRAY',\r
809                                 parseInt( 'A9A9A9', 16 ), 'DARKGRAY',\r
810                                 parseInt( 'DCDCDC', 16 ), 'GAINSBORO',\r
811                                 parseInt( '191970', 16 ), 'MIDNIGHTBLUE',\r
812                                 parseInt( '6A5ACD', 16 ), 'SLATEBLUE',\r
813                                 parseInt( '0000CD', 16 ), 'MEDIUMBLUE',\r
814                                 parseInt( '4169E1', 16 ), 'ROYALBLUE',\r
815                                 parseInt( '1E90FF', 16 ), 'DODGERBLUE',\r
816                                 parseInt( '87CEEB', 16 ), 'SKYBLUE',\r
817                                 parseInt( '4682B4', 16 ), 'STEELBLUE',\r
818                                 parseInt( 'ADD8E6', 16 ), 'LIGHTBLUE',\r
819                                 parseInt( 'AFEEEE', 16 ), 'PALETURQUOISE',\r
820                                 parseInt( '40E0D0', 16 ), 'TURQUOISE',\r
821                                 parseInt( 'E0FFFF', 16 ), 'LIGHTCYAN',\r
822                                 parseInt( '7FFFD4', 16 ), 'AQUAMARINE',\r
823                                 parseInt( '006400', 16 ), 'DARKGREEN',\r
824                                 parseInt( '2E8B57', 16 ), 'SEAGREEN',\r
825                                 parseInt( '90EE90', 16 ), 'LIGHTGREEN',\r
826                                 parseInt( '7FFF00', 16 ), 'CHARTREUSE',\r
827                                 parseInt( 'ADFF2F', 16 ), 'GREENYELLOW',\r
828                                 parseInt( '32CD32', 16 ), 'LIMEGREEN',\r
829                                 parseInt( '9ACD32', 16 ), 'YELLOWGREEN',\r
830                                 parseInt( '6B8E23', 16 ), 'OLIVEDRAB',\r
831                                 parseInt( 'BCB76B', 16 ), 'DARKKHAKI',\r
832                                 parseInt( 'EEE8AA', 16 ), 'PALEGOLDENROD',\r
833                                 parseInt( 'FFFFE0', 16 ), 'LIGHTYELLOW',\r
834                                 parseInt( 'FFD700', 16 ), 'GOLD',\r
835                                 parseInt( 'DAA520', 16 ), 'GOLDENROD',\r
836                                 parseInt( 'B8860B', 16 ), 'DARKGOLDENROD',\r
837                                 parseInt( 'BC8F8F', 16 ), 'ROSYBROWN',\r
838                                 parseInt( 'CD5C5C', 16 ), 'INDIANRED',\r
839                                 parseInt( '8B4513', 16 ), 'SADDLEBROWN',\r
840                                 parseInt( 'A0522D', 16 ), 'SIENNA',\r
841                                 parseInt( 'CD853F', 16 ), 'PERU',\r
842                                 parseInt( 'DEB887', 16 ), 'BURLYWOOD',\r
843                                 parseInt( 'F5F5DC', 16 ), 'BEIGE',\r
844                                 parseInt( 'F5DEB3', 16 ), 'WHEAT',\r
845                                 parseInt( 'F4A460', 16 ), 'SANDYBROWN',\r
846                                 parseInt( 'D2B48C', 16 ), 'TAN',\r
847                                 parseInt( 'D2691E', 16 ), 'CHOCOLATE',\r
848                                 parseInt( 'B22222', 16 ), 'FIREBRICK',\r
849                                 parseInt( 'A52A2A', 16 ), 'BROWN',\r
850                                 parseInt( 'FA8072', 16 ), 'SALMON',\r
851                                 parseInt( 'FFA500', 16 ), 'ORANGE',\r
852                                 parseInt( 'FF7F50', 16 ), 'CORAL',\r
853                                 parseInt( 'FF6347', 16 ), 'TOMATO',\r
854                                 parseInt( 'FF69B4', 16 ), 'HOTPINK',\r
855                                 parseInt( 'FFC0CB', 16 ), 'PINK',\r
856                                 parseInt( 'FF1493', 16 ), 'DEEPPINK',\r
857                                 parseInt( 'DB7093', 16 ), 'PALEVIOLETRED',\r
858                                 parseInt( 'EE82EE', 16 ), 'VIOLET',\r
859                                 parseInt( 'DDA0DD', 16 ), 'PLUM',\r
860                                 parseInt( 'DA70D6', 16 ), 'ORCHILD',\r
861                                 parseInt( '9400D3', 16 ), 'DARKVIOLET',\r
862                                 parseInt( '8A2BE2', 16 ), 'BLUEVIOLET',\r
863                                 parseInt( '9370DB', 16 ), 'MEDIUMPURPLE',\r
864                                 parseInt( 'D8BFD8', 16 ), 'THISTLE',\r
865                                 parseInt( 'E6E6FA', 16 ), 'LAVENDER',\r
866                                 parseInt( 'FFE4E1', 16 ), 'MISTYROSE',\r
867                                 parseInt( 'FFFFF0', 16 ), 'IVORY',\r
868                                 parseInt( 'FFFACD', 16 ), 'LEMONCHIFFON'\r
869                         ];\r
870                 for( i=list.length; i; ){\r
871                         v    = list[ --i ];\r
872                         name = list[ --i ];\r
873                         ret[ name ] = v;\r
874                 };\r
875                 return ret;\r
876         })();\r
877         \r
878         var PARAMS = ( function(){\r
879                 ret = {};\r
880                 register( ret.percent = {},\r
881                         'marginBottom,marginLeft,marginRight,marginTop,paddingBottom,paddingLeft,paddingRight,paddingTop,fontSize,textIndent'\r
882                 );\r
883                 register( ret.offset = {},\r
884                         'height,width,bottom,left,right,top'\r
885                 );              \r
886                 register( ret.size = {},\r
887                         'borderBottomWidth,borderLeftWidth,borderRightWidth,borderTopWidth,letterSpacing'\r
888                 );\r
889                 register( ret.color = {},\r
890                         'backgroundColor,borderBottomColor,borderLeftColor,borderRightColor,borderTopColor,color'\r
891                 );\r
892                 register( ret.region = {},\r
893                         'margin,padding,borderWidth,borderColor'\r
894                 );              \r
895                 register( ret.special = {},\r
896                         'clip,backgroundPosition,opacity,lineHeight,zIndex'\r
897                 );\r
898                 register( ret.unit = {}, 'px,cm,mm,in,pt,pc,em,%' );\r
899                 \r
900                 register( ret.margin = {}, 'marginBottom,marginLeft,marginRight,marginTop,paddingBottom' );\r
901                 register( ret.padding = {}, 'paddingBottom,paddingLeft,paddingRight,paddingTop' );\r
902                 register( ret.borderWidth = {}, 'borderBottomWidth,borderLeftWidth,borderRightWidth,borderTopWidth' );\r
903                 register( ret.borderColor = {}, 'borderBottomColor,borderLeftColor,borderRightColor,borderTopColor' );\r
904                 \r
905                 function register( obj, params ){\r
906                         params = params.split( ',' );\r
907                         for( var i=params.length; i; ) obj[ params[ --i ] ] = true;\r
908                 };\r
909                 return ret;\r
910         })();\r
911         \r
912         /*\r
913          * \r
914          */\r
915         var PropertyClass = function( name, value, unit, pxPerEm ){\r
916                 this.name    = name;\r
917                 this.value   = value;\r
918                 this.unit    = unit;\r
919                 this.pxPerEm = pxPerEm; // XXpx = 1em;\r
920         };\r
921         PropertyClass.prototype = {\r
922                 name:    '',\r
923                 value:   0,\r
924                 pxPerEm: 12, // 1em === ??px\r
925                 unit:    '',\r
926                 equal: function( prop ){\r
927                         if( this.unit === prop.unit ){\r
928                                 return this.value === prop.value;\r
929                         };\r
930                         return Math.abs( this._toPx() - prop._toPx() ) < 1;\r
931                 },\r
932                 convert: function( prop ){\r
933                         var u = prop.unit, v;\r
934                         if( this.unit === u ) return;\r
935                         this.value = v = this._toPx();\r
936                         this.unit  = u;\r
937                         if( u !== px ){\r
938                                 this.value = u === 'em' ? v / this.pxPerEm : Util.pxTo( v, u );\r
939                         };\r
940                 },\r
941                 setValue: function( v ){\r
942                         this.value = v;\r
943                 },\r
944                 getValue: function(){\r
945                         return this.value;\r
946                 },\r
947                 getOffset: function( prop ){\r
948                         return prop.value - this.value;\r
949                 },\r
950                 getUnit: function(){\r
951                         return this.unit;\r
952                 },\r
953                 getValueText: function(){\r
954                         return this.value === 0 ? '0' : this.value + this.unit;\r
955                 },\r
956                 clear: function(){\r
957                         var t = this, p;\r
958                         for( p in t ){\r
959                                 if( t.hasOwnProperty && !t.hasOwnProperty( p ) ) continue;\r
960                                 delete t[ p ];\r
961                         };\r
962                 },\r
963                 _toPx: function(){\r
964                         var v = this.value, u = this.unit;\r
965                         if( u === px )   return v;\r
966                         if( u === 'em' ) return v * this.pxPerEm;\r
967                         if( u === '' && this.name === 'lineHeight' ) return v * this.pxPerEm;\r
968                         return Util.toPx( v, u );\r
969                 },\r
970                 isValid: function( t ){\r
971                         t = t || this;\r
972                         var n = t.name,\r
973                                 v = t.value,\r
974                                 u = t.unit,\r
975                                 z = u !== '' ? true : v === 0;\r
976                         if( PARAMS.percent[ n ] === true ) return z;\r
977                         if( PARAMS.offset[ n ] === true  ) return z;\r
978                         if( PARAMS.size[ n ] === true  )   return z && u !== '%';\r
979                         if( PARAMS.special[ n ] === true  ){\r
980                                 if( n === 'lineHeight' ) return true;\r
981                                 if( n === 'opacity' )    return 0 <= v && v <= 1 && u === '';\r
982                                 if( n === 'zIndex'  )    return u === '';\r
983                         };\r
984                         return false;\r
985                 }\r
986         };\r
987         \r
988         /**\r
989          * backgroundPosition, clip\r
990          */\r
991         var PropertyGroupClass = function( name ){\r
992                 this.name  = name;\r
993                 this.props = [];\r
994                 for( var i = 1, l = arguments.length; i<l; ++i ){\r
995                         this.props.push( arguments[ i ] );\r
996                 };\r
997         };\r
998         \r
999         /**\r
1000          * margin, padding, borderWidth, borderColor\r
1001          */\r
1002         var FrexiblePropertyClass = function( name ){\r
1003                 this.name  = name;\r
1004                 this.props = [];\r
1005                 for( var i = 1, l = arguments.length; i<l; ++i ){\r
1006                         this.props.push( arguments[ i ] );\r
1007                 };\r
1008                 // top, bottom, left, right, topbottom, leftright, all\r
1009         };\r
1010         FrexiblePropertyClass.prototype = PropertyGroupClass.prototype = {\r
1011                 name:    '',\r
1012                 equal: function( prop ){\r
1013                         var ps = this.props, i = ps.length;\r
1014                         for( ; i; ){\r
1015                                 --i;\r
1016                                 if( ps[ i ].equal( prop[ i ] ) === false ) return false;\r
1017                         };\r
1018                         return true;\r
1019                 },\r
1020                 convert: function( prop ){\r
1021                         var ps = this.props, i = ps.length;\r
1022                         for( ; i; ){\r
1023                                 --i;\r
1024                                 ps[ i ].convert( prop[ i ] );\r
1025                         };\r
1026                 },\r
1027                 setValue: function( ary ){\r
1028                         var ps = this.props, i = 0, l = ps.length;\r
1029                         for( ; i<l; ++i ){\r
1030                                 ps[ i ].setValue( ary[ i ] );\r
1031                         };\r
1032                 },\r
1033                 getValue: function(){\r
1034                         var ret = [], ps = this.props, i = 0, l = ps.length;\r
1035                         for( ; i<l; ++i ){\r
1036                                 ret.push( ps[ i ].getValue() );\r
1037                         };\r
1038                         return ret;\r
1039                 },\r
1040                 getOffset: function( prop ){\r
1041                         var ret = [],\r
1042                                 ps  = this.props,\r
1043                                 _ps = prop.props,\r
1044                                 i   = 0,\r
1045                                 l = ps.length;\r
1046                         for( ; i<l; ++i ){\r
1047                                 ret.push( ps[ i ].getOffset( _ps[ i ] ) );\r
1048                         };\r
1049                         return ret;\r
1050                 },\r
1051                 getUnit: function(){\r
1052                         var ret = [], ps = this.props, i = 0, l = ps.length;\r
1053                         for( ; i<l; ++i ){\r
1054                                 ret.push( ps[ i ].getUnit() );\r
1055                         };\r
1056                         return ret;\r
1057                 },\r
1058                 getValueText: function(){\r
1059                         var ret = [], ps = this.props, i = 0, l = ps.length;\r
1060                         for( ; i<l; ++i ){\r
1061                                 ret.push( ps[ i ].getValueText() );\r
1062                         };                      \r
1063                         if( this.name === 'clip' ){\r
1064                                 return 'rect(' + ret.join( CLIP_SEPARATOR ) + ')';\r
1065                         };\r
1066                         return ret.join( ' ' );\r
1067                 },\r
1068                 clear: function(){\r
1069                         var ps = this.props, i = ps.length;\r
1070                         for( ; i; ){\r
1071                                 ps[ --i ].clear();\r
1072                         };\r
1073                         delete this.name;\r
1074                         delete this.props;\r
1075                 },\r
1076                 isValid: function( t ){\r
1077                         t = t || this;\r
1078                         var ps = t.props, i = ps.length;\r
1079                         for( ; i; ){\r
1080                                 --i;\r
1081                                 if( ps[ i ].isValid() === false ) return false;\r
1082                         };\r
1083                         return true;\r
1084                 }\r
1085         };\r
1086 \r
1087         var ColorPropertyClass = function( name, r, g, b, pct ){\r
1088                 this.name = name;\r
1089                 this.r    = r;\r
1090                 this.g    = g;\r
1091                 this.b    = b;\r
1092                 this.pct  = pct;\r
1093         };\r
1094         ColorPropertyClass.prototype = {\r
1095                 name:    '',\r
1096                 equal: function( prop ){\r
1097                         if( this.pct === prop.pct ){\r
1098                                 return this.r === prop.r && this.g === prop.g && this.b === prop.b;\r
1099                         };\r
1100                         var rgb  = this._toPct(),\r
1101                                 _rgb = prop._toPct();\r
1102                         for( var i = rgb.length; i; ){\r
1103                                 --i;\r
1104                                 if( Math.abs( rgb[ i ] - _rgb[ i ] ) > 1 ) return false;\r
1105                         };\r
1106                         return true;\r
1107                 },\r
1108                 convert: function( prop ){\r
1109                         var u = prop.pct;\r
1110                         if( this.pct === u ) return;\r
1111                         var x    = u === true ? 100 / 255 : 2.55;\r
1112                         this.r  *= x;\r
1113                         this.g  *= x;\r
1114                         this.b  *= x;\r
1115                         this.pct = u;\r
1116                 },\r
1117                 setValue: function( rgb ){\r
1118                         this.r = rgb[ 0 ];\r
1119                         this.g = rgb[ 1 ];\r
1120                         this.b = rgb[ 2 ];\r
1121                 },\r
1122                 getValue: function(){\r
1123                         return [ this.r, this.g, this.b ];\r
1124                 },\r
1125                 getOffset: function( prop ){\r
1126                         return [ prop.r - this.r, prop.g - this.g, prop.b - this.b ];\r
1127                 },\r
1128                 getUnit: function(){\r
1129                         return this.pct === true ? '%' : '';\r
1130                 },\r
1131                 getValueText: function(){\r
1132                         if( this.pct === true ){\r
1133                                 return [ 'rgb(', this.r, '%,', this.g, '%,', this.b, '%)' ].join( '' );\r
1134                         };\r
1135                         var round = Math.round;\r
1136                         //return [ 'rgb(', round( this.r ), ',', round( this.g ), ',', round( this.b ), ')' ].join( '' );\r
1137                         \r
1138                         var rgb   = '00000' + ( ( round( this.r ) << 16 ) + ( round( this.g ) << 8 ) + round( this.b ) ).toString( 16 );\r
1139                         return '#' + rgb.substr( rgb.length - 6 );\r
1140                 },\r
1141                 clear: function(){\r
1142                         var t = this, p;\r
1143                         for( p in t ){\r
1144                                 if( t.hasOwnProperty && !t.hasOwnProperty( p ) ) continue;\r
1145                                 delete t[ p ];\r
1146                         };\r
1147                 },\r
1148                 _toPct: function(){\r
1149                         if( this.pct === true ) return [ this.r, this.g, this.b ];\r
1150                         return [ this.r / 2.55, this.g / 2.55, this.b / 2.55 ];\r
1151                 },\r
1152                 isValid: function( t ){\r
1153                         var isFinite = window.isFinite;\r
1154                         if( !isFinite( this.r ) || !isFinite( this.g ) || !isFinite( this.b ) ) return false;\r
1155                         if( 0 > this.r || 0 > this.g || 0 > this.b ) return false;\r
1156                         if( this.pct === true ){\r
1157                                 return this.r <= 100 && this.g <= 100 && this.b <= 100;\r
1158                         };\r
1159                         return this.r <= 255 && this.g <= 255 && this.b <= 255;\r
1160                 }\r
1161         };\r
1162         \r
1163         var isString       = Type.isString,\r
1164                 isNumber       = Type.isNumber;\r
1165         var REG_UINIT      = /.*\d(\w{1,2})?/,\r
1166                 $1             = '$1',\r
1167                 px             = 'px',\r
1168                 REG_XXXXXX     = /^#[\da-fA-F]{6}?/,\r
1169                 REG_XXX        = /^#[\da-fA-F]{3}?/;\r
1170         \r
1171         var WrappedStyleClass = function( elm, style, pxPerEm ){\r
1172                 this.elm     = elm;\r
1173                 this.style   = style;\r
1174                 this.pxPerEm = this.get( 'fontSize' )._toPx();\r
1175         };\r
1176 \r
1177         WrappedStyleClass.prototype = {\r
1178                 get: function( p ){\r
1179                         if( PARAMS.special[ p ] === true || PARAMS.region[ p ] === true ){\r
1180                                 if( p === 'clip' )        return this.getClip();\r
1181                                 if( p === 'margin' )      return this.getMarginPaddingBorder( p );\r
1182                                 if( p === 'padding' )     return this.getMarginPaddingBorder( p );\r
1183                                 if( p === 'borderWidth' ) return this.getMarginPaddingBorder( 'border', 'Width' );\r
1184                                 if( p === 'borderColor' ) return this.getBorderColor( 'borderColor' );\r
1185                                 if( p === 'backgroundPosition' ) return this.getBackgroundPosition( p );\r
1186                                 // opacity, zindex, lineHeight\r
1187                                 return new PropertyClass( p, this.getValue( x, p ), this.getUnit( x ), this.pxPerEm );\r
1188                         };\r
1189                         var x = this.style[ p ], e, v, u;\r
1190                         if( PARAMS.offset[ p ] === true ){\r
1191                                 return new PropertyClass( p, this.getValue( x, p ), this.getUnit( x, p ), this.pxPerEm );\r
1192                                 /*\r
1193                                 e = this.elm;\r
1194                                 if( p === 'width'  ) v = e.offsetWidth;\r
1195                                 if( p === 'height' ) v = e.offsetHeight;\r
1196                                 if( p === 'top'    ) v = e.offsetTop;\r
1197                                 if( p === 'bottom' ) v = e.offsetBottom;\r
1198                                 if( p === 'left'   ) v = e.offsetLeft;\r
1199                                 if( p === 'right'  ) v = e.offsetRight;\r
1200                                 u = this.getUnit( x, p );\r
1201                                 // alert( p + this.pxTo( v, u ) + u )\r
1202                                 return new PropertyClass( p, this.pxTo( v, u ), u, this.pxPerEm ); */\r
1203                         };\r
1204                         if( p === 'fontSize' ){ // xx-small 等\r
1205                                 v = Util.absoluteFontSizeToPx( x );\r
1206                                 if( v !== 0 ){\r
1207                                         return new PropertyClass( p, v, px, this.pxPerEm );\r
1208                                 };\r
1209                         };                      \r
1210                         if( PARAMS.percent[ p ] === true ){\r
1211                                 // alert( p + ' , ' + x + ' , ' + this.getUnit( x, p ) )\r
1212                                 return new PropertyClass( p, this.getValue( x, p ), this.getUnit( x, p ), this.pxPerEm );\r
1213                         };\r
1214                         if( PARAMS.size[ p ] === true ){\r
1215                                 return new PropertyClass( p, this.getValue( x, p ), this.getUnit( x, p ), this.pxPerEm );\r
1216                         };\r
1217                         if( PARAMS.color[ p ] === true ){\r
1218                                 return this.getColor( x, p );\r
1219                         };\r
1220                 },\r
1221                 pxTo: function( px, unit ){\r
1222                         if( unit === 'em' ) return px / this.pxPerEm;\r
1223                         return Util.pxTo( px, unit );\r
1224                 },\r
1225                 getValue: function( x, p ){\r
1226                         if( isString( x ) === true ){\r
1227                                 return parseInt( x );\r
1228                         } else\r
1229                         if( isNumber( x ) === true ){\r
1230                                 return x;\r
1231                         };\r
1232                         return 0;\r
1233                 },\r
1234                 getUnit: function( x, p ){\r
1235                         var u;\r
1236                         if( isString( x ) === true ){\r
1237                                 u = x.replace( REG_UINIT, $1 );\r
1238                                 if( p === 'lineHeight' ) return u;\r
1239                                 if( PARAMS.unit[ u ] !== true ) return px;\r
1240                                 return u;\r
1241                         };\r
1242                         return px;\r
1243                 },\r
1244                 getColor: function( x, p ){\r
1245                         var rgb = COLOR[ x.toUpperCase() ],\r
1246                                 pct = false,\r
1247                                 r   = 0,\r
1248                                 g   = 0,\r
1249                                 b   = 0;\r
1250                         if( isNumber( rgb ) === true ){\r
1251                                 r = ( rgb & 0xff0000 ) >> 16;\r
1252                                 g = ( rgb & 0xff00 ) >> 8;\r
1253                                 b = ( rgb & 0xff );\r
1254                         } else\r
1255                         if( x.match( REG_XXXXXX ) ){\r
1256                                 r = parseInt( x.charAt( 1 ) + x.charAt( 2 ), 16 );\r
1257                                 g = parseInt( x.charAt( 3 ) + x.charAt( 4 ), 16 );\r
1258                                 b = parseInt( x.charAt( 5 ) + x.charAt( 6 ), 16 );\r
1259                                 //alert( x + ' g: ' + g )\r
1260                         } else                  \r
1261                         if( x.match( REG_XXX ) ){\r
1262                                 r = parseInt( x.charAt( 1 ) + x.charAt( 1 ), 16 );\r
1263                                 g = parseInt( x.charAt( 2 ) + x.charAt( 2 ), 16 );\r
1264                                 b = parseInt( x.charAt( 3 ) + x.charAt( 3 ), 16 );\r
1265                         } else\r
1266                         if( x.indexOf( 'rgb(' ) === 0 ){\r
1267                                 rgb = x.substr( 4 ).split( ',' );\r
1268                                 r = parseFloat( rgb[ 0 ] );\r
1269                                 g = parseFloat( rgb[ 1 ] );\r
1270                                 b = parseFloat( rgb[ 2 ] );\r
1271                                 if( x.indexOf( '%' ) !== -1 ){\r
1272                                         pct = true;\r
1273                                 };\r
1274                         } else {\r
1275                                 r = 255;\r
1276                                 g = 255;\r
1277                                 b = 255;\r
1278                         };\r
1279                         return new ColorPropertyClass( p, r, g, b, pct );\r
1280                 },\r
1281                 getClip: function( name ){\r
1282                         // rect(...)    クリップします。<top>, <bottom> は上端からの、 <right>, <left> は左端からのオフセットで指定します。Internet Explorer 4~7 では、カンマの代わりにスペースで区切る必要があります。\r
1283                         // position:absolute または position:fixed を適用した要素に対してのみ有効です。\r
1284                         var top    = this.get( name + 'Top' ),\r
1285                                 right  = this.get( name + 'Right' ),\r
1286                                 bottom = this.get( name + 'Bottom' ),\r
1287                                 left   = this.get( name + 'Left' ),\r
1288                                 ret    = new PropertyGroupClass( name, top, right, bottom, left );\r
1289                         if( ret.isValid() === true ) return ret;\r
1290                         ret.clear();\r
1291                         all    = this.style[ name ].split( '(' )[ 1 ].split( ')' )[ 0 ].split( CLIP_SEPARATOR );\r
1292                         return new PropertyGroupClass( name,\r
1293                                 new PropertyClass( name + 'Top',    all[ 0 ], px, this.pxPerEm ),\r
1294                                 new PropertyClass( name + 'Right',  all[ 1 ], px, this.pxPerEm ),\r
1295                                 new PropertyClass( name + 'Bottom', all[ 2 ], px, this.pxPerEm ),\r
1296                                 new PropertyClass( name + 'Left',   all[ 3 ], px, this.pxPerEm )\r
1297                         );\r
1298                 },\r
1299                 getBackgroundPosition: function( name ){\r
1300                         var x   = this.get( name + 'X' ),\r
1301                                 y   = this.get( name + 'Y' ),\r
1302                                 ret = new PropertyGroupClass( name, x, y ),\r
1303                                 xy;\r
1304                         if( ret.isValid() === true ) return ret;\r
1305                         ret.clear();\r
1306                         xy  = this.style[ name ].split( ' ' );\r
1307                         return new PropertyGroupClass( name,\r
1308                                 new PropertyClass( name + 'X', this.getValue( xy[ 0 ] ), this.getUnit( xy[ 0 ] ), this.pxPerEm ),\r
1309                                 new PropertyClass( name + 'Y', this.getValue( xy[ 1 ] ), this.getUnit( xy[ 1 ] ), this.pxPerEm )\r
1310                         );\r
1311                 },\r
1312                 getMarginPaddingBorder: function( name, widthOrColor ){\r
1313                         widthOrColor = widthOrColor || '';\r
1314                         var _class = PropertyClass;\r
1315                                 top    = this.get( name + 'Top' + widthOrColor ),\r
1316                                 right  = this.get( name + 'Right' + widthOrColor ),\r
1317                                 bottom = this.get( name + 'Bottom' + widthOrColor ),\r
1318                                 left   = this.get( name + 'Left' + widthOrColor ),\r
1319                                 ret    = new FrexiblePropertyClass( name, top, right, bottom, left ),\r
1320                                 all, x, v, u;\r
1321                         \r
1322                         if( ret.isValid() === true ) return ret;\r
1323                         ret.clear();\r
1324                         all = this.style[ name + widthOrColor ].split( ' ' );\r
1325                         \r
1326                         for( var i=0, l=all.length; i<l; ++i ){\r
1327                                 x = all[ i ];\r
1328                                 v = this.getValue( x );\r
1329                                 u = this.getUnit( x );\r
1330                                 if( l === 4 ){\r
1331                                         if( i === 0 ) top    = new _class( name + 'Top' +    widthOrColor, v, u, this.pxPerEm );\r
1332                                         if( i === 1 ) right  = new _class( name + 'Right' +  widthOrColor, v, u, this.pxPerEm );\r
1333                                         if( i === 2 ) bottom = new _class( name + 'Bottom' + widthOrColor, v, u, this.pxPerEm );\r
1334                                         if( i === 3 ) left   = new _class( name + 'Left' +   widthOrColor, v, u, this.pxPerEm );\r
1335                                 } else\r
1336                                 if( l === 3 ){\r
1337                                         if( i === 0 ) top    = new _class( name + 'Top' + widthOrColor, v, u, this.pxPerEm );\r
1338                                         if( i === 1 ){\r
1339                                                 right  = new _class( name + 'Right' + widthOrColor, v, u, this.pxPerEm );\r
1340                                                 left   = new _class( name + 'Left'  + widthOrColor, v, u, this.pxPerEm );\r
1341                                         } else\r
1342                                         if( i === 2 ) bottom = new _class( name + 'Bottom' + widthOrColor , v, u, this.pxPerEm );\r
1343                                 } else\r
1344                                 if( l === 2 ){\r
1345                                         if( i === 0 ){\r
1346                                                 top    = new _class( name + 'Top'    + widthOrColor, v, u, this.pxPerEm );\r
1347                                                 bottom = new _class( name + 'Bottom' + widthOrColor, v, u, this.pxPerEm );\r
1348                                         } else\r
1349                                         if( i === 1 ){\r
1350                                                 right  = new _class( name + 'Right' + widthOrColor, v, u, this.pxPerEm );\r
1351                                                 left   = new _class( name + 'Left'  + widthOrColor, v, u, this.pxPerEm );\r
1352                                         };\r
1353                                 } else\r
1354                                 if( l === 1 ){\r
1355                                         top    = new _class( name + 'Top'    + widthOrColor, v, u, this.pxPerEm );\r
1356                                         bottom = new _class( name + 'Bottom' + widthOrColor, v, u, this.pxPerEm );\r
1357                                         right  = new _class( name + 'Right'  + widthOrColor, v, u, this.pxPerEm );\r
1358                                         left   = new _class( name + 'Left'   + widthOrColor, v, u, this.pxPerEm );\r
1359                                 };\r
1360                         };\r
1361                         return new FrexiblePropertyClass( name, top, right, bottom, left );\r
1362                 },\r
1363                 getBorderColor: function( name ){\r
1364                         var getColor = this.getColor;\r
1365                                 top      = this.get( name + 'TopColor' ),\r
1366                                 right    = this.get( name + 'RightColor' ),\r
1367                                 bottom   = this.get( name + 'BottomColor' ),\r
1368                                 left     = this.get( name + 'LeftColor' ),\r
1369                                 ret      = new FrexiblePropertyClass( name, top, right, bottom, left ),\r
1370                                 all, x;\r
1371                         \r
1372                         if( ret.isValid() === true ) return ret;\r
1373                         ret.clear();\r
1374                         all = this.style[ name ].split( ' ' );\r
1375                         \r
1376                         for( var i=0, l=all.length; i<l; ++i ){\r
1377                                 x = all[ i ];\r
1378                                 if( l === 4 ){\r
1379                                         if( i === 0 ) top    = getColor( x, name + 'Top' );\r
1380                                         if( i === 1 ) right  = getColor( x, name + 'Right' );\r
1381                                         if( i === 2 ) bottom = getColor( x, name + 'Bottom' );\r
1382                                         if( i === 3 ) left   = getColor( x, name + 'Left' );\r
1383                                 } else\r
1384                                 if( l === 3 ){\r
1385                                         if( i === 0 ) top    = getColor( x, name + 'Top' );\r
1386                                         if( i === 1 ){\r
1387                                                 right  = getColor( x, name + 'Right' );\r
1388                                                 left   = getColor( x, name + 'Left' );\r
1389                                         } else\r
1390                                         if( i === 2 ) bottom = getColor( x, name + 'Bottom' );\r
1391                                 } else\r
1392                                 if( l === 2 ){\r
1393                                         if( i === 0 ){\r
1394                                                 top    = getColor( x, name + 'Top' );\r
1395                                                 bottom = getColor( x, name + 'Bottom' );\r
1396                                         } else\r
1397                                         if( i === 1 ){\r
1398                                                 right  = getColor( x, name + 'Right' );\r
1399                                                 left   = getColor( x, name + 'Left' );\r
1400                                         };\r
1401                                 } else\r
1402                                 if( l === 1 ){\r
1403                                         top    = getColor( x, name + 'Top' );\r
1404                                         bottom = getColor( x, name + 'Bottom' );\r
1405                                         right  = getColor( x, name + 'Right' );\r
1406                                         left   = getColor( x, name + 'Left' );\r
1407                                 };\r
1408                         };\r
1409                         return new FrexiblePropertyClass( name, top, right, bottom, left );\r
1410                 },\r
1411                 clear: function(){\r
1412                         var t = this, p;\r
1413                         for( p in t ){\r
1414                                 if( t.hasOwnProperty && !t.hasOwnProperty( p ) ) continue;\r
1415                                 delete t[ p ];\r
1416                         };\r
1417                 }\r
1418         };\r
1419         function camelizeHash( obj ){\r
1420                 var p, _p;\r
1421                 for( p in obj ){\r
1422                         _p = Util.camelize( p );\r
1423                         if( _p === p ) continue;\r
1424                         obj[ _p ] = obj[ _p ] || obj[ p ];\r
1425                         delete obj[ p ];\r
1426                 };\r
1427         };\r
1428         \r
1429         return {\r
1430                 getWrappedStyle: function( elm, opt_css ){\r
1431                         opt_css && camelizeHash( opt_css );\r
1432                         return new WrappedStyleClass( elm, opt_css || CSS.getComputedStyle( elm ) );\r
1433                 },\r
1434                 getInlineStyle: function( _elm ){\r
1435                         return cssToObject( _elm.style.cssText );\r
1436                 },\r
1437                 getComputedStyle: function( elm ){\r
1438                         /* if( window.getComputedStyle ){\r
1439                         CSS.getComputedStyle = function( elm ){\r
1440                                 return cssToObject( window.getComputedStyle( elm, '' ) );\r
1441                         };\r
1442                         } else */\r
1443                     if( document.defaultView && document.defaultView.getComputedStyle ){\r
1444                         CSS.getComputedStyle = function( elm ){\r
1445                                 var obj = document.defaultView.getComputedStyle( elm, '' );\r
1446                                 return cssToObject( obj.cssText || obj );\r
1447                         };\r
1448                     } else {\r
1449                         CSS.getComputedStyle = function( elm ){\r
1450                                 return cssToObject( elm.currentStyle );\r
1451                         };\r
1452                     };\r
1453                     return CSS.getComputedStyle( elm );\r
1454                 },\r
1455                 toCssText: function( _css ){\r
1456                         var ret = [], v;\r
1457                         for( var p in _css ){\r
1458                                 if( PARAMS.margin[ p ] === true && _css.margin ) continue;\r
1459                                 if( PARAMS.padding[ p ] === true && _css.padding ) continue;\r
1460                                 if( PARAMS.borderWidth[ p ] === true && _css.borderWidth ) continue;\r
1461                                 if( PARAMS.borderColor[ p ] === true && _css.borderColor ) continue;\r
1462                                 v = _css[ p ];\r
1463                                 v && ret.push( [ Util.uncamelize( p ), v ].join( ':' ) );\r
1464                         };\r
1465                         return ret.join( ';' );\r
1466                 }\r
1467         };\r
1468         \r
1469 })( window, document );\r
1470 \r
1471 \r
1472 /* ----------------------------------------------------\r
1473  * gadgetOS\r
1474  * \r
1475  */     \r
1476 \r
1477 ( function( window, document, undefined ){\r
1478         \r
1479         var doc            = window.document;\r
1480         var body           = doc.getElementsByTagName( 'body' )[ 0 ]; //( doc.compatMode || '' ) !== 'CSS1Compat' ? doc.body : doc.documentElement;// \r
1481         \r
1482         var SERVICE_LIST   = [];\r
1483         var SUPER_USER_KEY = { getUID: function(){ return 0; }};\r
1484         var API_USER_LIST  = [ SUPER_USER_KEY ];\r
1485         var numApiUser     = 1;\r
1486         \r
1487         function isApiUser( _user ){\r
1488                 if( _user === SUPER_USER_KEY ) return true;\r
1489                 if( File.isDriver( _user ) === true ) return true;\r
1490                 if( Application.isApplicationInstance( _user ) === true ) return true;\r
1491                 return false;\r
1492         }\r
1493         \r
1494         var Const = {\r
1495                 FILE: {\r
1496                         TYPE: {\r
1497                                 UNKNOWN:        0,\r
1498                                 FOLDER:         1,\r
1499                                 IMAGE:          2,\r
1500                                 TEXT:           3,\r
1501                                 HTML:           4,\r
1502                                 CSV:            5,\r
1503                                 JSON:           6,\r
1504                                 XML:            7\r
1505                         },\r
1506                         STATE: {\r
1507                                 UNKNOWN:        0,\r
1508                                 OK:                     1,\r
1509                                 LOADING:        2,\r
1510                                 ERROR:          3,\r
1511                                 BROKEN:         4\r
1512                         },\r
1513                         UPDATE_POLICY: {\r
1514                                 _____:          parseInt( '00000', 2 ),\r
1515                                 ____C:          parseInt( '00001', 2 ), // hasCreateMenu\r
1516                                 ___W_:          parseInt( '00010', 2 ), // isWritable\r
1517                                 ___WC:          parseInt( '00011', 2 ), // isWritable\r
1518                                 __R__:          parseInt( '00100', 2 ), // isRenamable\r
1519                                 __R_C:          parseInt( '00101', 2 ), // hasCreateMenu\r
1520                                 __RW_:          parseInt( '00110', 2 ), // isWritable\r
1521                                 __RWC:          parseInt( '00111', 2 ), // isWritable\r
1522                                 _S___:          parseInt( '01000', 2 ), // childrenIsSortable\r
1523                                 _S__C:          parseInt( '01001', 2 ),\r
1524                                 _S_W_:          parseInt( '01010', 2 ),\r
1525                                 _S_WC:          parseInt( '01011', 2 ),\r
1526                                 _SR__:          parseInt( '01100', 2 ),\r
1527                                 _SR_C:          parseInt( '01101', 2 ),\r
1528                                 _SRW_:          parseInt( '01110', 2 ),\r
1529                                 _SRWC:          parseInt( '01111', 2 ),\r
1530                                 D____:          parseInt( '10000', 2 ),\r
1531                                 D___C:          parseInt( '10001', 2 ), // hasCreateMenu\r
1532                                 D__W_:          parseInt( '10010', 2 ), // isWritable\r
1533                                 D__WC:          parseInt( '10011', 2 ), // isWritable\r
1534                                 D_R__:          parseInt( '10100', 2 ), // isRenamable\r
1535                                 D_R_C:          parseInt( '10101', 2 ), // hasCreateMenu\r
1536                                 D_RW_:          parseInt( '10110', 2 ), // isWritable\r
1537                                 D_RWC:          parseInt( '10111', 2 ), // isWritable\r
1538                                 DS___:          parseInt( '11000', 2 ), // childrenIsSortable\r
1539                                 DS__C:          parseInt( '11001', 2 ),\r
1540                                 DS_W_:          parseInt( '11010', 2 ),\r
1541                                 DS_WC:          parseInt( '11011', 2 ),\r
1542                                 DSR__:          parseInt( '11100', 2 ),\r
1543                                 DSR_C:          parseInt( '11101', 2 ),\r
1544                                 DSRW_:          parseInt( '11110', 2 ),\r
1545                                 DSRWC:          parseInt( '11111', 2 ),\r
1546                                 CREATE:         1,\r
1547                                 WRAITE:         2,\r
1548                                 RENAME:         4,\r
1549                                 SORT:           8,\r
1550                                 DELETE:         16\r
1551                         },\r
1552                         EVENT: {\r
1553                                 UPDATE_ATTRIVUTE:       'onFileUpdate',\r
1554                                 GET_SEQENTIAL_FILES:'gotSeqentilFiles'\r
1555                         },\r
1556                         DATA_PROPERTY_RESERVED: [\r
1557                                 'children', 'driver', 'state', 'type'\r
1558                         ]                       \r
1559                 },\r
1560                 TREE: {\r
1561                         EVENT: {\r
1562                                 UPDATE:                         'onTreeUpdate'\r
1563                         }\r
1564                 },\r
1565                 KEY: {\r
1566                         EVENT: {\r
1567                                 KEY_DOWN:                       'keydown',\r
1568                                 KEY_UP:                         'keyup',\r
1569                                 KEY_CHANGE:                     'keychange',\r
1570                                 CURSOL:                         'cursol'\r
1571                         }\r
1572                 },\r
1573                 APP: {\r
1574                         TYPE: {\r
1575                                 GENERAL: 0,\r
1576                                 OVERLAY: 1,\r
1577                                 PAGE:    2\r
1578                         }\r
1579                 }\r
1580         };\r
1581 \r
1582 var EX = ( function(){\r
1583         var F = new Function();\r
1584         \r
1585         function clone( src ) {\r
1586                 var ret;\r
1587                 if( Type.isArray(src) === true ){\r
1588                         ret = [];\r
1589                 } else\r
1590                 if( Type.isObject(src) === true ){\r
1591                         ret = {};\r
1592                 } else\r
1593                 if( Type.isNumber(src) === true || Type.isString(src) === true || Type.isBoolean( src ) === true ){\r
1594                         return src;\r
1595                 } else {\r
1596                         return null;\r
1597                 }\r
1598                 for( var key in src ){\r
1599                         ret[ key ] = clone( src[ key ]);\r
1600                 }\r
1601                 return ret;\r
1602         };\r
1603         \r
1604         return {\r
1605                 extend: function( base, extend ){\r
1606                         F.prototype = base;\r
1607                         var ret = new F;\r
1608                         for( var p in extend ){\r
1609                                 ret[ p ] = extend[ p ];\r
1610                         };\r
1611                         return ret;\r
1612                 },\r
1613                 clone: function( obj ){\r
1614                         return clone( obj );\r
1615                 },\r
1616                 kill: function(){\r
1617                         var self = this, v;\r
1618                         for( var p in s ){\r
1619                                 if( self.hasOwnProperty && !self.hasOwnProperty( p ) ) continue;\r
1620                                 v = self[ p ];\r
1621                                 v && v instanceof TicketBase && self.kill();\r
1622                                 delete self[ p ];\r
1623                         }\r
1624                 }\r
1625         }\r
1626 })();\r
1627 \r
1628 var TicketBase = function(){\r
1629         this.kill = function(){\r
1630                 var t = this, v;\r
1631                 for( var p in t ){\r
1632                         if( t.hasOwnProperty && !t.hasOwnProperty( p ) ) continue;\r
1633                         v = t[ p ];\r
1634                         v && v instanceof TicketBase && v.kill();\r
1635                         delete t[ p ];\r
1636                 }\r
1637         };\r
1638 };\r
1639 \r
1640 \r
1641 \r
1642 /* --------------------------------------------------------------\r
1643  * System Timer\r
1644  * \r
1645  */\r
1646 \r
1647 var SystemTimer = ( function(){\r
1648         var setTimeout    = window.setTimeout;\r
1649         var clearTimeout  = window.clearTimeout;\r
1650         var INTERVAL_TIME = 16;\r
1651         var TICKET_LIST   = [];\r
1652         var timerId       = undefined;\r
1653         var next          = 0;\r
1654         \r
1655         function loop(){\r
1656             for( var i = 0; i < TICKET_LIST.length; ) {\r
1657                 if( TICKET_LIST[ i ].call( next ) !== false ) ++i;\r
1658             };\r
1659             timerId = undefined;\r
1660             update();\r
1661         };\r
1662         function update(){\r
1663                 var l = TICKET_LIST.length,\r
1664                         n = 99999999,\r
1665                         c;\r
1666                 if( l === 0 ){\r
1667                         timerId !== undefined && clearTimeout( timerId );\r
1668                         timerId = undefined;\r
1669                         return;\r
1670                 };\r
1671             for( var i = 0; i<l; i++ ){\r
1672                 c = TICKET_LIST[ i ].count;\r
1673                 if( n > c ) n = c;\r
1674             };\r
1675             if( next > n || timerId === undefined ){\r
1676                 timerId !== undefined && clearTimeout( timerId );\r
1677                 timerId = setTimeout( loop, INTERVAL_TIME * n );\r
1678                 next = n;\r
1679             };\r
1680         };\r
1681         \r
1682         var TimerTicketClass = function( _apiuser, _callback, _time, _once ){\r
1683                 this.apiuser  = _apiuser;\r
1684                 this.callback = _callback;\r
1685                 this.time     = _time;\r
1686                 this.count    = _time;\r
1687                 this.once     = _once;\r
1688                 _apiuser = _callback = null;\r
1689         };\r
1690         TimerTicketClass.prototype = new TicketBase();\r
1691         TimerTicketClass.prototype.call = function( c ){\r
1692                 this.count -= c;\r
1693                 if( this.count <= 0 ){\r
1694                         this.callback();\r
1695                         if( this.once === true ){\r
1696                                 this.destroy();\r
1697                                 TICKET_LIST.splice( Util.getIndex( TICKET_LIST, this ), 1 );\r
1698                                 return false;\r
1699                         } else {\r
1700                                 this.count = this.time;\r
1701                         };\r
1702                 };\r
1703         };\r
1704         TimerTicketClass.prototype.destroy = function( _apiuser, _callback ){\r
1705                 if( _apiuser  && _apiuser  !== this.apiuser )  return false;\r
1706                 if( _callback && _callback !== this.callback ) return false;\r
1707                 \r
1708                 this.kill();\r
1709                 return true;\r
1710         };\r
1711         \r
1712         return {\r
1713                 add: function( _apiuser, _handler, _time, _once ){\r
1714                         if( Type.isNumber( _time ) === false || _time < INTERVAL_TIME ) _time = INTERVAL_TIME;\r
1715                         \r
1716                     var _ticket = new TimerTicketClass( _apiuser, _handler, Math.ceil( _time / INTERVAL_TIME ), _once );\r
1717                     TICKET_LIST.push( _ticket );\r
1718                     \r
1719                     update();\r
1720                 },\r
1721                 remove: function( _apiuser, _handler ) {\r
1722                         var _ticket,\r
1723                                 i = 0;\r
1724                         while( _ticket = TICKET_LIST[ i ] ){\r
1725                                 if( _ticket.destroy( _apiuser, _handler ) === true ){\r
1726                                         TICKET_LIST.splice( i, 1 );\r
1727                                 } else {\r
1728                                         ++i;\r
1729                                 };\r
1730                         };\r
1731                     update();\r
1732                 }\r
1733         }\r
1734 })();\r
1735 \r
1736 /* --------------------------------------------------------------\r
1737  * Async Callback\r
1738  * \r
1739  */\r
1740 var AsyncCall = ( function(){\r
1741         var CALLBACK_LIST = [];\r
1742 \r
1743         var CallbackTicketClass = function( _apiuser, _callback, _argments, _thisObject ){\r
1744                 this.apiuser    = _apiuser;\r
1745                 this.callback   = _callback;\r
1746                 this.argments   = _argments;\r
1747                 this.thisObject = _thisObject;\r
1748         };\r
1749         CallbackTicketClass.prototype = new TicketBase();\r
1750         CallbackTicketClass.prototype.call = function(){\r
1751                 var f = this.callback,\r
1752                         a = this.argments,\r
1753                         t = this.thisObject;\r
1754                 this.destroy();\r
1755                 if( Type.isArray( a ) === true ){\r
1756                         f.apply( t, a );\r
1757                 } else {\r
1758                         f.call( t, a );\r
1759                 };\r
1760         };\r
1761         CallbackTicketClass.prototype.destroy = function( _apiuser, _callback ){\r
1762                 if( _apiuser  && _apiuser  !== this.apiuser ) return false;\r
1763                 if( _callback && _callback !== this.callback ) return false;\r
1764                 \r
1765                 this.kill();\r
1766                 return true;\r
1767         };\r
1768 \r
1769         function dispatch(){\r
1770                 var _ticket = CALLBACK_LIST.shift();\r
1771                 if( _ticket ){\r
1772                         _ticket.call();\r
1773                         CALLBACK_LIST.length !== 0 && SystemTimer.add( SUPER_USER_KEY, dispatch, 1, true );\r
1774                 };\r
1775         };\r
1776 \r
1777         return {\r
1778                 add: function( _apiuser, _callback, _argments, _thisObject ){\r
1779                         CALLBACK_LIST.length === 0 && SystemTimer.add( SUPER_USER_KEY, dispatch, 1, true );\r
1780                         CALLBACK_LIST.push( new CallbackTicketClass( _apiuser, _callback, _argments, _thisObject || _apiuser ) );\r
1781                 },\r
1782                 remove: function( _apiuser, _callback ){\r
1783                         var _ticket,\r
1784                                 i = 0;\r
1785                         while( _ticket = CALLBACK_LIST[ i ] ){\r
1786                                 if( _ticket.destroy( _apiuser, _callback ) === true ){\r
1787                                         CALLBACK_LIST.splice( i, 1 );\r
1788                                 } else {\r
1789                                         ++i;\r
1790                                 };\r
1791                         };\r
1792                 }\r
1793         };\r
1794 })();\r
1795 \r
1796 /* -----------------------------------------------------------\r
1797  * 画像一覧は\r
1798  *      お気に入り画像一覧 > tag:ペン次郎 > ペン次郎:笑う\r
1799  *  最近アップロードされた画像 > images\r
1800  *  最近使われた画像 > images\r
1801  *  キャラクター画像庫 > アニマル系 > tag:ペン次郎 > ペン次郎:笑う\r
1802  *  風景画像庫 >\r
1803  *  効果画像庫 >\r
1804  *  アイテム画像庫 >\r
1805  *  \r
1806  * 画像一覧を読み込むタイミング\r
1807  */\r
1808 var File = ( function(){\r
1809         var DRIVER_LIST             = [];\r
1810         \r
1811         var FILE_TYPE_IS_FOLDER     = Const.FILE.TYPE.FOLDER,\r
1812                 numFileType             = Const.FILE.TYPE.XML,\r
1813                 FILEDATA_RESITER        = [],                   // store all of fileData( json object )\r
1814                 FILEDATA_ACCESS         = [],                   // file operations for Kernel only ! hide from Out of File\r
1815                 FILE_OBJECT_POOL        = [],\r
1816                 EVENT_LISTENER_REGISTER = [],\r
1817                 TREE_ARRAY              = [],\r
1818                 TREE_ACCESS_ARRAY       = [];\r
1819         \r
1820         var REQUEST_CONTROLER = ( function(){\r
1821                 var REQUEST_TICKET_RESISTER = [],\r
1822                         currentTicket           = null,\r
1823                         currentData             = null,\r
1824                         DATA_TYPE_ARRAY         = 'json,xml,html,text'.split( ','),\r
1825                         DATA_IS_JSON            = 0,\r
1826                         DATA_IS_XML             = 1,\r
1827                         DATA_IS_HTML            = 2,\r
1828                         DATA_IS_TEXT            = 3,\r
1829                         numError                = 0;\r
1830                 \r
1831                 var RequestTicketClass = function( _apiuser, _type, _data, _url, _onLoad, _onError ){\r
1832                         this.apiuser = _apiuser;\r
1833                         this.type    = _type;\r
1834                         this.data    = _data;\r
1835                         this.url     = _url;\r
1836                         this.onLoad  = _onLoad;\r
1837                         this.onError = _onError;\r
1838                         this.state   = 0;\r
1839                         _apiuser = _type = _data = _onLoad = _onError = null;\r
1840                 };\r
1841                 RequestTicketClass.prototype = new TicketBase();\r
1842                 RequestTicketClass.prototype.load = function( _data ){\r
1843                         AsyncCall.add( this.apiuser, this.onLoad, [ this.data, _data ] );\r
1844                 };\r
1845                 RequestTicketClass.prototype.error = function(){\r
1846                         AsyncCall.add( this.apiuser, this.onError, this.data );\r
1847                 };\r
1848                 \r
1849                 function request(){\r
1850                         if( currentTicket !== null || REQUEST_TICKET_RESISTER.length === 0 ) return;\r
1851                         currentTicket = REQUEST_TICKET_RESISTER.shift();\r
1852                         $.ajax({\r
1853                                 url:            currentTicket.url,\r
1854                                 dataType:       DATA_TYPE_ARRAY[ currentTicket.type ],\r
1855                                 success:        onSuccess,\r
1856                                 error:          onError\r
1857                         });\r
1858                 };\r
1859                 function onSuccess( _data ){\r
1860                         currentTicket.load( _data );\r
1861                         currentTicket.kill();\r
1862                         currentTicket = null;\r
1863                         request();\r
1864                 };\r
1865                 function onError(){\r
1866                         ++numError;\r
1867                         currentTicket.error();\r
1868                         currentTicket.kill(); // retry\r
1869                         currentTicket = null;\r
1870                         request();\r
1871                 };\r
1872 \r
1873                 return {\r
1874                         getNumTask: function(){\r
1875                                 return REQUEST_TICKET_RESISTER.length;\r
1876                         },\r
1877                         getNumError: function(){\r
1878                                 return numError;\r
1879                         },\r
1880                         getJson: function( _apiuser, _data, _url, _onLoad, _onError ){\r
1881                                 REQUEST_TICKET_RESISTER.push( new RequestTicketClass( _apiuser, DATA_IS_JSON, _data, _url, _onLoad, _onError ));\r
1882                                 currentTicket === null && request();\r
1883                         }\r
1884                 };\r
1885         })();\r
1886 \r
1887         var FILE_CONTROLER = {\r
1888                 createTree: function( _apiuser, _rootFileData ){\r
1889                         var _tree = new TreeClass( _apiuser, _rootFileData );\r
1890                         TREE_ARRAY.push( _tree );\r
1891                         return _tree;\r
1892                 },\r
1893                 getFileUID: function( FILEDATAorFILE ){\r
1894                         if( FILEDATAorFILE instanceof FileClass ){\r
1895                                 return FILEDATAorFILE.getUID();\r
1896                         };\r
1897                         \r
1898                         var uid = Util.getIndex( FILEDATA_RESITER, FILEDATAorFILE );\r
1899                         if( uid === -1 ){\r
1900                                 uid = FILEDATA_RESITER.length;\r
1901                                 FILEDATA_RESITER.push( FILEDATAorFILE );\r
1902                         };\r
1903                         return uid;\r
1904                 },\r
1905                 getFileDataAccess: function( UIDorFILEorFILEDATA ){\r
1906                         var _uid, _data = FILE_CONTROLER.getFileData( UIDorFILEorFILEDATA ), _access;\r
1907 \r
1908                         if( _data === null || typeof _data !== 'object' ) return null;\r
1909                         for( var i=0, l = FILEDATA_ACCESS.length; i<l; ++i ){\r
1910                                 _access = FILEDATA_ACCESS[ i ];\r
1911                                 if( _access.DATA === _data ) return _access;\r
1912                         };\r
1913                         return null;\r
1914                 },      \r
1915                 getFileData: function( UIDorFILEorFILEDATA ){\r
1916                         if( typeof UIDorFILEorFILEDATA === 'number' ){\r
1917                                 return FILEDATA_RESITER[ UIDorFILEorFILEDATA ] || null;\r
1918                         } else\r
1919                         if( UIDorFILEorFILEDATA instanceof FileClass ){\r
1920                                 return FILEDATA_RESITER[ UIDorFILEorFILEDATA.getUID() ] || null;\r
1921                         } else\r
1922                         if( Util.getIndex( FILEDATA_RESITER, UIDorFILEorFILEDATA ) !== -1 ){\r
1923                                 return UIDorFILEorFILEDATA;\r
1924                         };\r
1925                         return null;\r
1926                 },\r
1927                 getChildren: function( UIDorFILEorFILEDATA ){\r
1928                         var _data = FILE_CONTROLER.getFileData( UIDorFILEorFILEDATA );\r
1929                         return _data !== null ? _data.children || null : null;\r
1930                 },\r
1931                 getDriver: function( _file ){\r
1932                         var _data = FILE_CONTROLER.getFileData( _file );\r
1933                         return _data !== null && _data.driver ? _data.driver : BASE_DRIVER;\r
1934                 },\r
1935                 getUpdateFlag: function( _file, _bit ){\r
1936                         var _driver = FILE_CONTROLER.getDriver( _file ),\r
1937                                 _policy;\r
1938                         if( typeof _driver.getUpdatePolicy === 'function' ){\r
1939                                 _policy = _driver.getUpdatePolicy( _file );\r
1940                                 \r
1941                         }\r
1942                         if( typeof _policy !== 'number' ) {\r
1943                                 _policy = BASE_DRIVER.getUpdatePolicy( _file )\r
1944                         }\r
1945                         return _policy % ( _bit * 2 ) >= _bit;\r
1946                 },\r
1947                 move: function( _prentUID, _targetfile, _newFolder, _newIndex, _opt_callback ){\r
1948                         var _parentData = FILE_CONTROLER.getFileDataAccess( _prentUID ),\r
1949                                 _parentType = _parentData.TYPE,\r
1950                                 _targetData = FILE_CONTROLER.getFileDataAccess( _targetfile ),\r
1951                                 _targetType = _targetData.TYPE;\r
1952                 },\r
1953                 replace: function( _uid, _file, _newIndex ){\r
1954                         \r
1955                 },\r
1956                 addEventListener: function( FILEorNULL, _eventType, _callback ){\r
1957                         var _uid = FILEorNULL instanceof FileClass ? FILEorNULL.getUID() : FILEorNULL;\r
1958                         EVENT_LISTENER_REGISTER.push( new FileEventTicketClass( _uid, _eventType, _callback ));\r
1959                 },\r
1960                 removeEventListener: function( FILEorNULL, _eventType, _callback ){\r
1961                         var _uid = FILEorNULL instanceof FileClass ? FILEorNULL.getUID() : FILEorNULL,\r
1962                                 _ticket;\r
1963                         for(var i=0, l = EVENT_LISTENER_REGISTER.length; i<l; ++i ){\r
1964                                 _ticket = EVENT_LISTENER_REGISTER[ i ];\r
1965                                 if( _ticket.fileUID === _uid && _ticket.eventType === _eventType && _ticket.callBack === _callback ){\r
1966                                         EVENT_LISTENER_REGISTER.splice( i, 1 );\r
1967                                         _ticket.kill();\r
1968                                 };\r
1969                         };\r
1970                 },\r
1971                 getTreeAccess: function(){\r
1972                         \r
1973                 },\r
1974                 fileEventRellay: function( _uid, _event ){\r
1975                         var _fileAccess = FILE_CONTROLER.getFileDataAccess( _uid );\r
1976                         if( _fileAccess === null ) return;\r
1977                         var _treeUID    =  _fileAccess.TREE.getUID(),\r
1978                                 _treeAccess = TREE_ACCESS_ARRAY[ _treeUID ],\r
1979                                 _data       = _fileAccess.DATA,\r
1980                                 _tree;\r
1981                         if( !_treeAccess ) return;\r
1982                         _treeAccess.dispatchFileEvent( _event );\r
1983                         for( var i=0, l = TREE_ARRAY.length; i<l; ++i ){\r
1984                                 if( i !== _treeUID ){\r
1985                                         _tree = TREE_ARRAY[ i ];\r
1986                                         if( FILE_CONTROLER.getFileData( _tree.getCurrentFile() ) === _data ){\r
1987                                                 _treeAccess = TREE_ACCESS_ARRAY[ _tree.getUID() ];\r
1988                                                 _treeAccess && _treeAccess.dispatchFileEvent( _event );\r
1989                                         };\r
1990                                 };\r
1991                         };\r
1992                 }\r
1993         };\r
1994         \r
1995         var TreeClass = function( apiuser, rootFileData ){\r
1996                 var PARENT_FILE_RESITER = [],\r
1997                         ACCESS = {\r
1998                                 apiuser          : apiuser,\r
1999                                 dispatchFileEvent: dispatchFileEvent\r
2000                         },\r
2001                         EVENT_LISTENER_ARRAY = [],\r
2002                         instance             = this,\r
2003                         rootFile             = new FileClass( instance, null, rootFileData ),\r
2004                         currentFile          = rootFile;\r
2005                 \r
2006                 currentFile.getSeqentialFiles();\r
2007                 TREE_ACCESS_ARRAY.push( ACCESS );\r
2008                 \r
2009                 function dispatchFileEvent( e ){\r
2010                         var _eventType  = e.eventType,\r
2011                                 _targetFile = e.targetFile,\r
2012                                 _uid        = _targetFile.getUID(),\r
2013                                 _ticket, _type, _callback;\r
2014                         for( var i=0, l = EVENT_LISTENER_REGISTER.length; i<l; ++i ){\r
2015                                 _ticket   = EVENT_LISTENER_REGISTER[ i ];\r
2016                                 _type     = _ticket.eventType;\r
2017                                 _callback = _ticket.callBack;\r
2018                                 if( _eventType === _type && _uid === _ticket.fileUID ){\r
2019                                         AsyncCall.add( apiuser, _callback, [ _eventType, _targetFile, e.key, e.value ], _targetFile );\r
2020                                 } else\r
2021                                 if( _type === Const.TREE.EVENT.UPDATE && _eventType === Const.FILE.EVENT.GET_SEQENTIAL_FILES ){\r
2022                                         //_callback( _eventType, _targetFile );\r
2023                                         AsyncCall.add( apiuser, _callback, [ _eventType, _targetFile ], instance );\r
2024                                 };\r
2025                         };\r
2026                 };\r
2027                 \r
2028                 this.getUID = function(){\r
2029                         return Util.getIndex( TREE_ACCESS_ARRAY, ACCESS );\r
2030                 };\r
2031                 this.getRootFile = function(){\r
2032                         return rootFile;\r
2033                 };\r
2034                 this.getCurrentFile = function(){\r
2035                         return currentFile;\r
2036                 };\r
2037                 this.hierarchy = function(){\r
2038                         return PARENT_FILE_RESITER.length;\r
2039                 };\r
2040                 this.getParentFileAt = function( _index ){\r
2041                         var l = PARENT_FILE_RESITER.length;\r
2042                         if( typeof _index !== 'number' || _index < 0 || _index >= l ) return null;\r
2043                         return PARENT_FILE_RESITER[ l -1 -_index ];\r
2044                 };\r
2045                 this.down = function( _index ){\r
2046                         if( typeof _index !== 'number' || _index < 0 || _index >= currentFile.getChildFileLength()) return;\r
2047                         PARENT_FILE_RESITER.unshift( currentFile );\r
2048                         currentFile = currentFile.getChildFileByIndex( _index );\r
2049                         currentFile.getSeqentialFiles();\r
2050                         return currentFile;\r
2051                 };\r
2052                 this.up = function( _index ){\r
2053                         var l = PARENT_FILE_RESITER.length;\r
2054                         if( l === 0) return null;\r
2055                         \r
2056                         if( currentFile ){\r
2057                                 var _currentFile = currentFile;\r
2058                                 currentFile = null;\r
2059                                 _currentFile.destroy();\r
2060                         };\r
2061                         if( typeof _index === 'number'){\r
2062                                 if( _index >= l) return null;\r
2063                                 currentFile = this.getParentFileAt( _index );\r
2064                                 PARENT_FILE_RESITER.splice( 0, l -_index);\r
2065                         } else {\r
2066                                 currentFile = PARENT_FILE_RESITER.shift();\r
2067                         };\r
2068                         currentFile.getSeqentialFiles();\r
2069                         return currentFile;     \r
2070                 };\r
2071                 this.addTreeEventListener = function( _eventType, _callback ){\r
2072                         FILE_CONTROLER.addEventListener( null, _eventType, _callback );\r
2073                 };\r
2074                 this.removeTreeEventListener = function( _eventType, _callback ){\r
2075                         FILE_CONTROLER.removeEventListener( null, _eventType, _callback );\r
2076                 };\r
2077                 this.destroy = function( _apiuser ){\r
2078                         if( _apiuser && apiuser !== _apiuser ) return false;\r
2079                         // removeEvent\r
2080                         var _currentFile = currentFile;\r
2081                         currentFile = rootFile = rootFileData = null;\r
2082                         // currentFile, rootFile を null にしないと .File.destroy() ができない.\r
2083                         _currentFile.destroy();\r
2084                         while( PARENT_FILE_RESITER.length > 0 ){\r
2085                                 _currentFile = PARENT_FILE_RESITER.shift();\r
2086                                 _currentFile.destroy();\r
2087                         };\r
2088                         \r
2089                         AsyncCall.remove( apiuser );\r
2090                         instance = apiuser = null;\r
2091                         return true;\r
2092                 };\r
2093         };\r
2094 \r
2095         var FileEventTicketClass = function( _uid, _eventType, _callback ){\r
2096                 this.fileUID   = _uid;\r
2097                 this.eventType = _eventType;\r
2098                 this.callBack  = _callback;\r
2099                 _uid = _eventType = _callback = undefined;\r
2100         };\r
2101         FileEventTicketClass.prototype = new TicketBase();\r
2102         \r
2103         var FileEventClass = function( eventType, file, key, value ){\r
2104                 this.eventType = eventType;\r
2105                 this.targetFile = file;\r
2106                 this.updatedAttribute = key;\r
2107                 this.updatedValue = value;\r
2108         };\r
2109 \r
2110 /*\r
2111  * file の data は object で保持している。\r
2112  * File の外からファイルをみるときは、FileClassを通して操作する。\r
2113  * fileの変更、それに付随して追加されたイベントは、TreeClassで管理される。\r
2114  * treeがdestryされると、fileのイベントリスナーも全て削除される。\r
2115  * 他の tree も data の共通する currentFile に対してのみは、file の変更イベントを受け取って流す.\r
2116  * \r
2117  */\r
2118         \r
2119         var FileClass = function( tree, parentData, data ){\r
2120                 var uid = FILE_CONTROLER.getFileUID( data );\r
2121                 \r
2122                 FILEDATA_ACCESS.push( {\r
2123                         TREE:                           tree,\r
2124                         parentData:                     parentData,\r
2125                         DATA:                           data\r
2126                 } );\r
2127                 \r
2128                 tree = parentData = data = null;\r
2129 \r
2130                 this.getUID = function(){\r
2131                         return uid;\r
2132                 }\r
2133         };\r
2134         \r
2135         FileClass.prototype = {\r
2136                 isChildFile: function( _FILEorFILEDATA ){\r
2137                         return this.getChildFileIndex( _FILEorFILEDATA) !== -1;\r
2138                 },\r
2139                 getSeqentialFiles: function(){\r
2140                         var _driver = FILE_CONTROLER.getDriver( this );\r
2141                         if( _driver !== null && typeof _driver.getSeqentialFiles === 'function' ){\r
2142                                 _driver.getSeqentialFiles( this );\r
2143                         }\r
2144                 },\r
2145                 addEventListener: function( _eventType, _callback ){\r
2146                         FILE_CONTROLER.addEventListener( this, _eventType, _callback );\r
2147                 },\r
2148                 removeEventListener: function( _eventType, _callback ){\r
2149                         FILE_CONTROLER.removeEventListener( this, _eventType, _callback );\r
2150                 },\r
2151                 dispatchEvent: function( e ){\r
2152                         e instanceof FileEventClass && FILE_CONTROLER.fileEventRellay( this.getUID(), e );\r
2153                 },\r
2154                 getChildFileLength: function(){\r
2155                         var children = FILE_CONTROLER.getChildren( this );\r
2156                         return Type.isArray( children ) === true ? children.length : -1;\r
2157                 },\r
2158                 getChildFileIndex: function( _FILEorFILEDATA ){\r
2159                         var children = FILE_CONTROLER.getChildren( this );\r
2160                         if( Type.isArray( children ) === false ) return -1;\r
2161                         var l = children.length,\r
2162                                 _fileData = FILE_CONTROLER.getFileData( _FILEorFILEDATA );\r
2163                         if( _fileData === null ) return -1;\r
2164                         for( var i=0; i<l; ++i ){\r
2165                                 if( children[ i ] === _fileData ) return i;\r
2166                         }\r
2167                         return -1;\r
2168                 },\r
2169                 getChildFileByIndex: function( _index ){\r
2170                         var _access = FILE_CONTROLER.getFileDataAccess( this ),\r
2171                                 _children = FILE_CONTROLER.getChildren( this );\r
2172                         if( typeof _index !== 'number' || _index < 0 || Type.isArray( _children ) === false || _index >= _children.length) return null;\r
2173                         var _file = new FileClass( _access.TREE, _access.DATA, _children[ _index ]);\r
2174                         // _file.init();\r
2175                         return _file;\r
2176                 },\r
2177                 getName: function(){\r
2178                         var driver = FILE_CONTROLER.getDriver( this );\r
2179                         if( typeof driver.getName === 'function'){\r
2180                                 return driver.getName( this );\r
2181                         }\r
2182                         return BASE_DRIVER.getName( this);\r
2183                 },\r
2184                 getThumbnail: function(){\r
2185                         var driver = FILE_CONTROLER.getDriver( this );\r
2186                         if( typeof driver.getThumbnail === 'function'){\r
2187                                 return driver.getThumbnail( this );\r
2188                         }\r
2189                         return BASE_DRIVER.getThumbnail( this );\r
2190                 },\r
2191                 getType: function(){\r
2192                         var _data = FILE_CONTROLER.getFileData( this );\r
2193                         return typeof _data.type === 'number' ? _data.type : Const.FILE.TYPE.UNKNOWN;\r
2194                 },\r
2195                 getState: function(){\r
2196                         var _data = FILE_CONTROLER.getFileData( this );\r
2197                         return typeof _data.state === 'number' ? _data.state : Const.FILE.STATE.OK;\r
2198                 },\r
2199                 getSummary: function(){\r
2200                         var driver = FILE_CONTROLER.getDriver( this );\r
2201                         if( typeof driver.getSummary === 'function'){\r
2202                                 return driver.getSummary( this );\r
2203                         }\r
2204                         return BASE_DRIVER.getSummary( this );\r
2205                 },\r
2206                 isWritable: function(){\r
2207                         return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.WRITE );\r
2208                 },\r
2209                 isSortable: function(){\r
2210                         return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.SORT );\r
2211                 },              \r
2212                 isCreatable: function(){\r
2213                         return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.CREATE );\r
2214                 },\r
2215                 isRenamable: function(){\r
2216                         return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.RENAME );\r
2217                 },\r
2218                 isDeletable: function(){\r
2219                         return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.DELETE );\r
2220                 },\r
2221                 read: function(){\r
2222                         // simpleDeepCopy\r
2223                         var driver = FILE_CONTROLER.getDriver( this ),\r
2224                                 data;\r
2225                         if( typeof driver.read === 'function'){\r
2226                                  data = driver.read( this );\r
2227                         }\r
2228                         return BASE_DRIVER.read( data || this );\r
2229                 },\r
2230                 write: function( _newData, _onUpdateFunction ){\r
2231                         var driver = FILE_CONTROLER.getDriver( this );\r
2232                         if( typeof driver.write === 'function'){\r
2233                                 return driver.write( this, _newData, _onUpdateFunction );\r
2234                         }\r
2235                         return BASE_DRIVER.write( this, _newData, _onUpdateFunction );\r
2236                 },\r
2237                 viewerApplicationList: function(){\r
2238                         var driver = FILE_CONTROLER.getDriver( this );\r
2239                         if( typeof driver.viewerApplicationList === 'function'){\r
2240                                 return driver.viewerApplicationList( this );\r
2241                         }\r
2242                         return BASE_DRIVER.viewerApplicationList( this );\r
2243                 },\r
2244                 editorApplicationList: function(){\r
2245                         var driver = FILE_CONTROLER.getDriver( this );\r
2246                         if( typeof driver.editorApplicationList === 'function'){\r
2247                                 return driver.editorApplicationList( this );\r
2248                         }\r
2249                         return BASE_DRIVER.viwerApps( this );\r
2250                 },\r
2251                 create: function(){\r
2252                         \r
2253                 },\r
2254                 sort: function(){\r
2255                         \r
2256                 },\r
2257                 onCopy: function(){\r
2258                         \r
2259                 },\r
2260                 onDelete: function(){\r
2261                         \r
2262                 },\r
2263                 move: function( _newFolder, _newIndex, opt_callback ){\r
2264                         var _access = FILE_CONTROLER.getFileDataAccess( this );\r
2265                         _access.TREE.move( _access.parentData, this.getUID(), _newFolder, _newIndex, opt_callback );\r
2266                 },\r
2267                 replace: function( _newIndex, opt_callback ){\r
2268                         var _access = FILE_CONTROLER.getFileDataAccess( this );\r
2269                         _access.TREE.replace( _access.parentData, this.getUID(), _newIndex, opt_callback);\r
2270                 },\r
2271                 /**\r
2272                  * サーチ\r
2273                  * 探しているファイルの属性と値を指定.一致する child の index を配列で返す.\r
2274                  */\r
2275                 search: function( obj, rule ){\r
2276                         var _children = FILE_CONTROLER.getChildren( this ),\r
2277                                 _child,\r
2278                                 ret = [], k, c;\r
2279                         for( var i=0, l=_children.length; i<l; ++i ){\r
2280                                 _child = _children[ i ];\r
2281                                 c = true;\r
2282                                 for( k in obj ){\r
2283                                         if( obj[ k ] !== _child[ k ] ){\r
2284                                                 c = false;\r
2285                                                 break;\r
2286                                         }\r
2287                                 }\r
2288                                 c === true && ret.push( i );\r
2289                         }\r
2290                         return ret;\r
2291                 },\r
2292                 destroy: function(){\r
2293                         var _access = FILE_CONTROLER.getFileDataAccess( this );\r
2294                         var _tree = _access.TREE;\r
2295                         if( _tree.getCurrentFile() === this ) return;\r
2296                         if( _tree.getRootFile() === this ) return;\r
2297                         for( var i=0, l = _tree.hierarchy(); i<l; ++i ){\r
2298                                 if( _tree.getParentFileAt( i ) === this ){\r
2299                                         return;\r
2300                                 }\r
2301                         }\r
2302                         var _index = Util.getIndex( FILEDATA_ACCESS, _access );\r
2303                         if( _index === -1 ) return;\r
2304                         // event の 削除\r
2305                         FILEDATA_ACCESS.splice( _index, 1 );\r
2306                         delete _access.DATA;\r
2307                         delete _access.TREE;\r
2308                         delete _access.parentData;\r
2309                 }\r
2310         }\r
2311 \r
2312         /*\r
2313          * FileDriverBase\r
2314          */\r
2315         var FileDriverBase = function( driverClass ){\r
2316                 this.getUID = function(){\r
2317                         return Util.getIndex( API_USER_LIST, driverClass );\r
2318                 };\r
2319                 this.getSeqentialFiles = function( _file ){\r
2320                 };\r
2321                 this.getName = function( _file ){\r
2322                         var _data = FILE_CONTROLER.getFileData( _file );\r
2323                         return _data.name || 'No Name';\r
2324                 };\r
2325                 this.getThumbnail = function( _file ){\r
2326                         var _data = FILE_CONTROLER.getFileData( _file ),\r
2327                                 _type = _data.type,\r
2328                                 _className = '';\r
2329                         if( _type === Const.FILE.TYPE.FOLDER ){\r
2330                                 _className = 'folder';\r
2331                         } else\r
2332                         if( _type === Const.FILE.TYPE.IMAGE ){\r
2333                                 \r
2334                         } else\r
2335                         if( _type === Const.FILE.TYPE.TEXT ){\r
2336                                 \r
2337                         } else\r
2338                         if( _type === Const.FILE.TYPE.HTML ){\r
2339                                 \r
2340                         } else\r
2341                         if( _type === Const.FILE.TYPE.CSV ){\r
2342                                 \r
2343                         } else\r
2344                         if( _type === Const.FILE.TYPE.JSON ){\r
2345                                 \r
2346                         } else\r
2347                         if( _type === Const.FILE.TYPE.XML ){\r
2348                                 \r
2349                         };\r
2350                         return {\r
2351                                 image:          null,\r
2352                                 className:      ' file-type-' + _className\r
2353                         };\r
2354                 };\r
2355                 this.getSummary = function( _file ){\r
2356                         var _data = FILE_CONTROLER.getFileData( _file ),\r
2357                                 _type = _data.type;\r
2358                         if( _type === Const.FILE.TYPE.FOLDER ){\r
2359                                 return 'folder';\r
2360                         } else\r
2361                         if( _type === Const.FILE.TYPE.IMAGE ){\r
2362                                 return 'image file';\r
2363                         } else\r
2364                         if( _type === Const.FILE.TYPE.TEXT ){\r
2365                                 return 'text file';\r
2366                         } else\r
2367                         if( _type === Const.FILE.TYPE.HTML ){\r
2368                                 return 'html document file';\r
2369                         } else\r
2370                         if( _type === Const.FILE.TYPE.CSV ){\r
2371                                 return 'csv daat file';\r
2372                         } else\r
2373                         if( _type === Const.FILE.TYPE.JSON ){\r
2374                                 return 'json data file';\r
2375                         } else\r
2376                         if( _type === Const.FILE.TYPE.XML ){\r
2377                                 return 'xml data file';\r
2378                         }\r
2379                         return '';\r
2380                 };\r
2381                 this.getUpdatePolicy = function( _file ){\r
2382                         // debug用 全てのメニューを許可\r
2383                         return Const.FILE.UPDATE_POLICY.DSRWC;\r
2384                 };\r
2385                 this.read = function( _FILEorDATA ){\r
2386                         var data,\r
2387                                 protects = Const.FILE.DATA_PROPERTY_RESERVED;                   \r
2388                         if( _FILEorDATA instanceof FileClass ){\r
2389                                 data = FILE_CONTROLER.getFileData( _FILEorDATA )\r
2390                         } else {\r
2391                                 data = _FILEorDATA;\r
2392                         }\r
2393 \r
2394                         function clone( src ) {\r
2395                                 var ret;\r
2396                                 if( Type.isArray(src) === true ){\r
2397                                         ret = [];\r
2398                                 } else\r
2399                                 if( Type.isObject(src) === true ){\r
2400                                         ret = {};\r
2401                                 } else\r
2402                                 if( Type.isNumber(src) === true || Type.isString(src) === true || Type.isBoolean( src ) === true ){\r
2403                                         return src;\r
2404                                 } else {\r
2405                                         return null;\r
2406                                 }\r
2407                                 for( var key in src ){\r
2408                                         if( Util.getIndex( protects, key ) === -1 ){\r
2409                                                 ret[ key ] = clone( src[ key ]);\r
2410                                         }\r
2411                                 }\r
2412                                 return ret;\r
2413                         };\r
2414                                 \r
2415                         return clone( data );\r
2416                 };\r
2417                 this.write = function( _file, _newData, _onUpdateFunction ){\r
2418                         var _data = FILE_CONTROLER.getFileData( _file ),\r
2419                                 _type = _data.type;\r
2420                         return false;\r
2421                 };\r
2422                 this.viewerApplicationList = function(){\r
2423                         return [];\r
2424                 };\r
2425                 this.editorApplicationList = function(){\r
2426                         return [];\r
2427                 };\r
2428                 this.onCreate = function(){\r
2429                         \r
2430                 };\r
2431                 this.onSort = function(){\r
2432                         \r
2433                 };\r
2434                 this.onCopy = function(){\r
2435                         \r
2436                 };\r
2437                 this.onDelete = function(){\r
2438                         \r
2439                 };\r
2440         }\r
2441         \r
2442         var BASE_DRIVER   = new FileDriverBase();\r
2443         \r
2444         var ROOT_FILEDATA = {\r
2445                         name:           'system root',\r
2446                         type:           FILE_TYPE_IS_FOLDER,\r
2447                         children:       []\r
2448                 },\r
2449                 SYSTEM_TREE = FILE_CONTROLER.createTree( SUPER_USER_KEY, ROOT_FILEDATA ),\r
2450                 ROOT_FILE   = SYSTEM_TREE.getRootFile();\r
2451 \r
2452         function createFileTypeID(){\r
2453                 return ++numFileType;\r
2454         }\r
2455         \r
2456         var FileAPIClass = function( driver ){\r
2457                 var constObject;\r
2458                 this.createFolderUnderRoot = function( _fileData ){\r
2459                         if( _fileData !== null && Type.isObject( _fileData ) === true ){\r
2460                                 ROOT_FILEDATA.children.push( _fileData );\r
2461                                 ROOT_FILE.dispatchEvent( new FileEventClass( Const.FILE.EVENT.GET_SEQENTIAL_FILES, ROOT_FILE, 'children', null ));\r
2462                         }\r
2463                 };\r
2464                 this.createFileEvent   = function( _eventType, _file, _key, _value ){\r
2465                         return new FileEventClass( _eventType, _file, _key, _value );\r
2466                 };\r
2467                 this.createFileTypeID  = createFileTypeID;\r
2468                 this.getFileDataAccess = FILE_CONTROLER.getFileDataAccess;\r
2469                 this.getFileData       = FILE_CONTROLER.getFileData;\r
2470                 this.getJson           = function( _data, _url, _onLoad, _onError ){\r
2471                         REQUEST_CONTROLER.getJson( driver, _data, _url, _onLoad, _onError );\r
2472                 };\r
2473                 this.createTree        = function( _rootFile ){\r
2474                         return FILE_CONTROLER.createTree( driver, _rootFile );\r
2475                 };\r
2476                 this.isTreeInstance    = function( _tree ){\r
2477                         return _tree instanceof TreeClass;\r
2478                 };\r
2479                 this.isFileInstance    = function( _file ){\r
2480                         return _file instanceof FileClass;\r
2481                 };\r
2482                 this.isFileEvent       = function( _event ){\r
2483                         return _event instanceof FileEventClass;\r
2484                 };\r
2485                 this.getConst          = function(){\r
2486                         return Const; // constObject = constObject || clone( Const )\r
2487                 };\r
2488         }\r
2489         \r
2490         return {\r
2491                 registerDriver: function( _class ){\r
2492                         _class.prototype = new FileDriverBase( _class );\r
2493                         var _driver = new _class();\r
2494                         \r
2495                         DRIVER_LIST.push( _driver );\r
2496                         API_USER_LIST.push( _class );\r
2497 \r
2498                         return new FileAPIClass( _driver );\r
2499                 },\r
2500                 isDriver: function( _driver ){\r
2501                         return _driver instanceof FileDriverBase;\r
2502                 },\r
2503                 isTreeInstance: function( _tree ){\r
2504                         return _tree instanceof TreeClass;\r
2505                 },\r
2506                 isFileInstance: function( _file ){\r
2507                         return _file instanceof FileClass;\r
2508                 }\r
2509         }\r
2510 })();\r
2511 \r
2512 \r
2513 /* ----------------------------------------------------\r
2514  * ApplicationManager\r
2515  * window resize event, overlayApplication currentAplication に流す\r
2516  */     \r
2517 \r
2518 var APPLICATION_LIST         = [];\r
2519 \r
2520 var AbstractBasicPane = function(){\r
2521         var instance    = null;\r
2522         this.MIN_WIDTH  = 240;\r
2523         this.MIN_HEIGHT = 240;\r
2524         this.init = function(){\r
2525                 instance = this;\r
2526                 instance.onInit();\r
2527         };\r
2528         this.onInit = function(){};\r
2529         this.resize = function( _w, _h ){\r
2530                 if( instance.MIN_WIDTH > _w || instance.MIN_HEIGHT > _h ){\r
2531                         if( Type.isHTMLElement( instance.rootElement ) === true ){\r
2532                                 // 小さすぎる!、と表示\r
2533                         };\r
2534                         return;\r
2535                 };\r
2536                 instance.onPaneResize( _w, _h );\r
2537         };\r
2538         this.onPaneResize = function( _w, _h ){};\r
2539         this.close = function(){\r
2540                 instance.onClose();\r
2541                 instance = this;\r
2542         };\r
2543 }\r
2544 \r
2545 var AbstractApplication = function( displayName, appClass, isOverlay ){\r
2546         var self          = null, // init で設定\r
2547                 uiList        = [],\r
2548                 finderList    = [],\r
2549                 fetchResource = 0,\r
2550                 bootParams    = null,\r
2551                 phase         = 0;\r
2552         this.rootElement = document.createElement( 'div' );\r
2553         this.bgColor     = '#C1CACF';\r
2554         this.getUID = function(){\r
2555                 return Util.getIndex( API_USER_LIST, appClass );\r
2556         }\r
2557         this.init = function(){\r
2558                 phase = 1;\r
2559                 self  = this;\r
2560                 appClass === Page.appClass && Page.show();\r
2561                 self.onInit();\r
2562                 phase = 2;\r
2563         };\r
2564         this.open = function( _w, _h /*, _option */ ){\r
2565                 phase = 3;\r
2566                 bootParams = Util.copyArray( arguments );\r
2567                 \r
2568                 if( this.rootElement.innerHTML && this.rootElement.innerHTML.length > 0 ){\r
2569                         SystemTimer.add( self, detect, 16 );\r
2570                 } else {\r
2571                         onOpen();\r
2572                 }\r
2573                 \r
2574                 function detect(){\r
2575                         if( self.rootElement.firstChild && fetchResource === 0 ){\r
2576                                 SystemTimer.remove( self, detect );\r
2577                                 onOpen();\r
2578                         };\r
2579                 };\r
2580                 \r
2581                 function onOpen(){\r
2582                         self.rootElement.style.display = '';\r
2583                         \r
2584                         if( self.MIN_WIDTH > _w || self.MIN_HEIGHT > _h ){\r
2585                                 if( Type.isHTMLElement( self.rootElement ) === true ){\r
2586                                         // 小さすぎる!、と表示\r
2587                                 }\r
2588                         }\r
2589                         if( bootParams.length > 2 ){\r
2590                                 self.onOpen.apply( self, bootParams );\r
2591                         } else {\r
2592                                 self.onOpen( _w, _h );\r
2593                         }\r
2594                         phase = 4;                      \r
2595                 };\r
2596         };\r
2597         this.resize = function( _w, _h ){\r
2598                 if( phase !== 4 ) return;\r
2599                 if( self.MIN_WIDTH > _w || self.MIN_HEIGHT > _h ){\r
2600                         if( Type.isHTMLElement( self.rootElement ) === true ){\r
2601                                 // 小さすぎる!、と表示\r
2602                         };\r
2603                         return;\r
2604                 };\r
2605                 self.onPaneResize( _w, _h );\r
2606         };\r
2607         this.close = function(){\r
2608                 phase = 5;\r
2609                 if( self.onClose() === false ){\r
2610                         return false;\r
2611                 };\r
2612                 MouseEvent.remove( self );\r
2613                 KeyEvent.remove( self );\r
2614                 SystemTimer.remove( self );\r
2615                 AsyncCall.remove( self );\r
2616                 StyleSheet.unload( self );\r
2617                 \r
2618                 while( uiList.length > 0 ){\r
2619                         uiList.shift().destroy();\r
2620                 };\r
2621                 while( finderList.length > 0 ){\r
2622                         finderList.shift().destroy();\r
2623                 };\r
2624                 var elm = self.rootElement;\r
2625                 Util.removeAllChildren( elm );\r
2626                 elm.parentNode.removeChild( elm );\r
2627                 self.rootElement = null;\r
2628                 \r
2629                 Application.shutdown( self, isOverlay );\r
2630                 \r
2631                 appClass === Page.appClass && Page.hide();\r
2632                 \r
2633                 self = appClass = uiList = null;\r
2634                 \r
2635                 phase = 6;\r
2636         };\r
2637         this.createUIGroup = function(){\r
2638                 var _ui = UI.createUIGroup( self );\r
2639                 uiList.push( _ui );\r
2640                 return _ui;\r
2641         };\r
2642         this.createFinder = function( _elmTarget, _tree, _header, _footer, _onSelect, _viewerOption, _editorOption ){\r
2643                 var _finder = Finder.create( self, _elmTarget, _tree, _header, _footer, _onSelect, _viewerOption, _editorOption );\r
2644                 finderList.push( _finder );\r
2645                 return _finder;\r
2646         };\r
2647         this.createBasicPane = function( _class, _options ){\r
2648                 if( Type.isFunction( _class ) === false ) return null;\r
2649                 _class.prototype = new AbstractBasicPane();\r
2650                 return new _class( _options );\r
2651         };\r
2652         this.createDHTML = function( _elm ){\r
2653                 return DHTML.create( self, _elm );\r
2654         };\r
2655         this.fetchCSS = function( _url, opt_onload, opt_onerror ){\r
2656                 if( phase === 1 ){\r
2657                         ++fetchResource;\r
2658                         StyleSheet.load( self, _url, fetchResourceComplete, fetchResourceComplete );\r
2659                 };\r
2660         };\r
2661         \r
2662         function fetchResourceComplete(){\r
2663                 --fetchResource;\r
2664         };\r
2665 };\r
2666 \r
2667 AbstractApplication.prototype = new AbstractBasicPane();\r
2668 AbstractApplication.prototype.onInit = function(){\r
2669         // overrride\r
2670 };      \r
2671 AbstractApplication.prototype.onOpen = function( _w, _h /*, _option */ ){\r
2672         // overrride\r
2673 };\r
2674 AbstractApplication.prototype.onClose = function(){\r
2675         // overrride\r
2676         return true;\r
2677 }; // false の場合、close の拒否 \r
2678 AbstractApplication.prototype.addEventListener = function( _element, _eventType, _handler ){\r
2679         MouseEvent.add( this, _element, _eventType, _handler );\r
2680 };\r
2681 AbstractApplication.prototype.removeMouseEventListener = function( _element, _eventType, _handler ){\r
2682         MouseEvent.remove( this, _element, _eventType, _handler );\r
2683 };\r
2684 AbstractApplication.prototype.addKeyEventListener = function( _eventType, _handler, _keyCode, _shift, _ctrl ){\r
2685         KeyEvent.add( this, _eventType, _handler, _keyCode, _shift, _ctrl );\r
2686 };\r
2687 AbstractApplication.prototype.removeKeyEventListener = function( _eventType, _handler, _keyCode, _shift, _ctrl ){\r
2688         KeyEvent.remove( this, _eventType, _handler, _keyCode, _shift, _ctrl );\r
2689 };\r
2690 AbstractApplication.prototype.shiftEnabled = function(){\r
2691         return KeyEvent.shiftEnabled;\r
2692 };\r
2693 AbstractApplication.prototype.ctrlEnabled = function(){\r
2694         return KeyEvent.ctrlEnabled;\r
2695 };\r
2696 AbstractApplication.prototype.addTimer = function( handler, time, once ){\r
2697         SystemTimer.add( this, handler, time, !!once );\r
2698 };\r
2699 AbstractApplication.prototype.removeTimer = function( handler ){\r
2700         SystemTimer.remove( this, handler );\r
2701 };\r
2702 AbstractApplication.prototype.addAsyncCall = function( _callback, _argments, _thisObject ){\r
2703         AsyncCall.add( this, _callback, _argments, _thisObject );\r
2704 };\r
2705 AbstractApplication.prototype.removeAsyncCall = function( _callback ){\r
2706         AsyncCall.remove( this, _callback );\r
2707 };\r
2708 AbstractApplication.prototype.fetchHTMLElement = function( id ){\r
2709         var elm = doc.getElementById( id );\r
2710         if( elm ){\r
2711                 elm.removeAttribute( 'id' );\r
2712                 elm.parentNode.removeChild( elm );\r
2713                 return elm;\r
2714         };\r
2715 };\r
2716 \r
2717 var Application = ( function(){\r
2718         \r
2719         var LIVE_APPLICATION_LIST = [];\r
2720         \r
2721         var currentApplication    = null,\r
2722                 coveredApplication    = null,\r
2723                 winW                  = 0,\r
2724                 winH                  = 0;\r
2725         \r
2726         var ApplicationReference = function( appClass, isOverlay, displayName, id, thumbnailUrl, tailColor ){\r
2727                 var self          = this;\r
2728                 var application   = null;\r
2729                 this.id           = id;\r
2730                 this.displayName  = displayName;\r
2731                 this.thumbnailUrl = thumbnailUrl;\r
2732                 this.tailColor    = tailColor;\r
2733                 this.getUID = function(){\r
2734                         return Util.getIndex( API_USER_LIST, appClass );\r
2735                 };\r
2736                 this.boot = function( /* _option */ ){\r
2737                         application = Application.boot( displayName, self.getUID(), appClass, isOverlay, Util.copyArray( arguments ) );\r
2738                 };\r
2739                 this.shutdown = function(){\r
2740                         if( !application ) return false;\r
2741                         \r
2742                         if( ( isOverlay === true ? Overlay.hide() : application.close() ) === false ) return false;\r
2743                         application = null;\r
2744                 };\r
2745         };\r
2746         \r
2747         function asyncBootHome(){\r
2748                 currentApplication === null && Home.boot();\r
2749         };\r
2750         function asyncOpen( /* arguments */ ){\r
2751                 var _arg = Util.copyArray( arguments );\r
2752                 _arg.unshift( winW, winH );\r
2753                 currentApplication.open.apply( currentApplication, _arg );\r
2754         };\r
2755         return {\r
2756                 register: function( _class, _overlay, _tail, _displayName, _id, _thumbnailUrl, _tailColor ){\r
2757                         APPLICATION_LIST.push( _class );\r
2758                         API_USER_LIST.push( _class );\r
2759                         var _ref = new ApplicationReference( _class, _overlay, _displayName, _id, _thumbnailUrl, _tailColor );\r
2760                         _tail === true && Home.add( _ref );\r
2761                         return _ref;\r
2762                 },\r
2763                 isBasicPaneInstance: function( _basicPane ){\r
2764                         return  _basicPane instanceof AbstractBasicPane;\r
2765                 },\r
2766                 isApplicationInstance: function( _application ){\r
2767                         return _application instanceof AbstractApplication;\r
2768                 },\r
2769                 isApplicationReference: function( _reference ){\r
2770                         return _reference instanceof ApplicationReference;\r
2771                 },\r
2772                 isCurrentAppplication: function( _application ){\r
2773                         return true\r
2774                 },\r
2775                 boot: function( displayName, uid, appClass, isOverlay, arg ){\r
2776                         if( currentApplication ){\r
2777                                 if( currentApplication.getUID() === uid ) return null;\r
2778                                 if( isOverlay === false && currentApplication.close() === false ) return null;\r
2779                         };\r
2780 \r
2781                         appClass.prototype = new AbstractApplication( displayName, appClass, isOverlay );\r
2782                         var application = new appClass(); // new は boot で\r
2783                         \r
2784                         coveredApplication = isOverlay === true ? currentApplication : null;\r
2785                         \r
2786                         Application.onCurrentApplicationChange( application );\r
2787                         \r
2788                         if( isOverlay === false ){\r
2789                                 body.style.backgroundColor = application.bgColor;\r
2790                                 \r
2791                                 body.appendChild( application.rootElement );\r
2792                                 application.rootElement.style.display = 'none';\r
2793                                 application.init();\r
2794 \r
2795                                 application.addAsyncCall( asyncOpen, arg );\r
2796                         } else {\r
2797                                 Overlay.show( application, arg );\r
2798                         }\r
2799                         \r
2800                         return application;\r
2801                 },\r
2802                 shutdown: function( _application, isOverlay ){\r
2803                         if( isOverlay === false ){\r
2804                                 currentApplication = null;\r
2805                                 AsyncCall.add( SUPER_USER_KEY, asyncBootHome );\r
2806                         } else {\r
2807                                 Application.onCurrentApplicationChange( coveredApplication );\r
2808                                 coveredApplication = null;\r
2809                         };\r
2810                 },\r
2811                 onCurrentApplicationChange: function( _application ){\r
2812                         if( Application.isApplicationInstance( _application ) === false ) return;\r
2813                         if( currentApplication === _application ) return;\r
2814                         currentApplication = _application;\r
2815                         MouseEvent.onCurrentApplicationChange( _application );\r
2816                         KeyEvent.updateCurrentListener( _application );\r
2817                 },\r
2818                 onApplicationShutdown: function( _application ){\r
2819                         LIVE_APPLICATION_LIST.splice( Util.getIndex(  LIVE_APPLICATION_LIST, _application ) );\r
2820                 },\r
2821                 onWindowResize: function( w, h ){\r
2822                         winW = w;\r
2823                         winH = h;\r
2824                         currentApplication && currentApplication.resize( w, h );\r
2825                         Overlay.onWindowResize( w, h );\r
2826                         UI.onWindowResize( w, h );\r
2827                 },\r
2828                 onSystemShutdown: function(){\r
2829                         \r
2830                 }\r
2831         }\r
2832 })();\r
2833 \r
2834 /* --------------------------------------------------------------\r
2835  * Home\r
2836  * \r
2837  */\r
2838         var Home = ( function(){\r
2839                 var APP_REF_LIST    = [];\r
2840                 var ELM_TAIL_ORIGIN = ( function(){\r
2841                         var ret = document.createElement( 'div' ),\r
2842                                 h2  = document.createElement( 'h2' );\r
2843                         ret.className = 'tail-wrapper';\r
2844                         ret.appendChild( h2 );\r
2845                         h2.appendChild( document.createTextNode( 'appName' ) );\r
2846                         return ret;\r
2847                 })();\r
2848                 \r
2849                 var TailClass = function( appRef ){\r
2850                         this.elm = ELM_TAIL_ORIGIN.cloneNode( true );\r
2851                         this.destroy = function(){\r
2852                                 appRef = self = elmName = null;\r
2853                         };                      \r
2854                         \r
2855                         var self    = this,\r
2856                                 elmName = this.elm.getElementsByTagName( 'h2' )[ 0 ].firstChild;\r
2857                         \r
2858                         this.elm.style.backgroundColor = appRef.tailColor;\r
2859                         elmName.data = appRef.displayName;\r
2860                 };\r
2861                 \r
2862                 var ref = Application.register( function(){\r
2863                         var self     = this,\r
2864                                 winW     = 0,\r
2865                                 winH     = 0,\r
2866                                 tailList = [],\r
2867                                 elmContainer, elmHeader;\r
2868                         \r
2869                         function draw(){\r
2870                                 var tail, elm;\r
2871                                 for( var i=0, l=APP_REF_LIST.length; i<l; ++i ){\r
2872                                         tail = new TailClass( APP_REF_LIST[ i ] );\r
2873                                         tailList.push( tail );\r
2874                                         elm  = tail.elm;\r
2875                                         elmContainer.appendChild( elm );\r
2876                                         self.addEventListener( elm, 'click', onTailClick );\r
2877                                 };\r
2878                         };\r
2879                         \r
2880                         function onTailClick( e ){\r
2881                                 var _children = elmContainer.getElementsByTagName( 'div' );\r
2882                                 for( var i=0, l=_children.length; i<l; ++i ){\r
2883                                         if( this === _children[ i ] ){\r
2884                                                 APP_REF_LIST[ i ].boot();\r
2885                                                 break;\r
2886                                         };\r
2887                                 };\r
2888                         };\r
2889                         \r
2890                         this.bgColor     = '#0F6D39';\r
2891                         this.MIN_WIDTH   = 320;\r
2892                         this.MIN_HEIGHT  = 320;\r
2893                         this.onInit = function(){\r
2894                                 self.rootElement.id = 'home-root';\r
2895                                 \r
2896                                 elmContainer        = document.createElement( 'div' );\r
2897                                 self.rootElement.appendChild( elmContainer );\r
2898                                 elmContainer.id     = 'home-tail-container';\r
2899                                 \r
2900                                 elmHeader           = document.createElement( 'div' );\r
2901                                 self.rootElement.appendChild( elmHeader );\r
2902                                 elmHeader.id        = 'home-header';\r
2903                         };\r
2904                         this.onOpen = function( _w, _h ){\r
2905                                 winW = _w;\r
2906                                 winH = _h;\r
2907                                 draw();\r
2908                         };\r
2909                         this.onPaneResize = function( _w, _h ){\r
2910                                 \r
2911                         };\r
2912                         this.onClose = function(){\r
2913                                 self.removeMouseEventListener();\r
2914                                 while( tailList.length > 0 ){\r
2915                                         tailList.shift().destroy();\r
2916                                 }\r
2917                                 self = tailList = elmContainer = null;\r
2918                         };\r
2919                 }, false, false, 'home', 'home', null );\r
2920                 \r
2921                 return {\r
2922                         add: function( _appRef ){\r
2923                                 if( Application.isApplicationReference( _appRef ) === false ) return;\r
2924                                 Util.getIndex( APP_REF_LIST, _appRef ) === -1 && APP_REF_LIST.push( _appRef );\r
2925                         },\r
2926                         boot: function(){\r
2927                                 ref.boot();\r
2928                         }\r
2929                 }\r
2930         })();\r
2931 \r
2932         var Page = ( function(){\r
2933                 var pageNodes = [],\r
2934                         appClass, ref,\r
2935                         ignoreTagList = [ 'script', 'noscript', 'style' ];\r
2936                 \r
2937                 var MemoryClass = function( node ){\r
2938                         this.node = node;\r
2939                 };\r
2940                 MemoryClass.prototype = {\r
2941                         init: function(){\r
2942                                 var node      = this.node,\r
2943                                         _nodeType = node.nodeType;\r
2944                                 if( _nodeType === 1 && Util.getIndex( ignoreTagList, node.tagName.toLowerCase() ) === -1 ){\r
2945                                         this.type    = _nodeType;\r
2946                                         this.display = node.style.display;\r
2947                                 } else\r
2948                                 if( _nodeType === 3 ){\r
2949                                         if( node.data.replace( /\s/g, '' ).length !== 0 ){\r
2950                                                 this.type    = _nodeType;\r
2951                                                 this.before  = pageNodes.length === 0 ? null : pageNodes[ pageNodes.length - 1 ].node;\r
2952                                         } else {\r
2953                                                 body.removeChild( node );\r
2954                                                 return false;\r
2955                                         }\r
2956                                 } else {\r
2957                                         // body.removeChild( node );\r
2958                                         return false;\r
2959                                 };\r
2960                         },\r
2961                         show: function(){\r
2962                                 if( this.type === 1 ){\r
2963                                         if( this.display ){\r
2964                                                 this.node.style.display = this.display;\r
2965                                         } else {\r
2966                                                 this.node.style.display = '';\r
2967                                         }\r
2968                                 } else {\r
2969                                         if( this.before ){\r
2970                                                 body.insertBefore( this.node, this.before );\r
2971                                         } else {\r
2972                                                 body.appendChild( this.node );\r
2973                                         };\r
2974                                 };\r
2975                         },\r
2976                         hide: function(){\r
2977                                 if( !this.node.parentNode ){\r
2978                                         return;\r
2979                                 };\r
2980                                 if( this.type === 1 ){\r
2981                                         this.node.style.display = 'none';\r
2982                                 } else {\r
2983                                         body.removeChild( this.node );\r
2984                                 };\r
2985                         }\r
2986                 };\r
2987                 \r
2988                 return {\r
2989                         onReady: function(){\r
2990                                 var _children = Util.copyArray( body.childNodes ),\r
2991                                         _mem;\r
2992                                 for( var i = 0, l = _children.length; i<l; ++i ){\r
2993                                         _mem = new MemoryClass( _children[ i ] );\r
2994                                         _mem.init() !== false && pageNodes.push( _mem );\r
2995                                 };\r
2996                                 if( pageNodes.length !== 0 ){\r
2997                                         if( Type.isFunction( gOS.PageApplicationClass ) === true ){\r
2998                                                 Page.appClass = gOS.PageApplicationClass;\r
2999                                                 Page.appClass.bgColor    = Page.appClass.bgColor;\r
3000                                                 Page.appClass.MIN_WIDTH  = Page.appClass.MIN_WIDTH  || 240;\r
3001                                                 Page.appClass.MIN_HEIGHT = Page.appClass.MIN_HEIGHT || 240;\r
3002                                         } else {\r
3003                                                 Page.appClass = function(){\r
3004                                                         var self     = this;\r
3005                                                         \r
3006                                                         this.bgColor      = '#ffffff';\r
3007                                                         this.MIN_WIDTH    = 200;\r
3008                                                         this.MIN_HEIGHT   = 200;\r
3009                                                         this.onInit       = function(){};\r
3010                                                         this.onOpen       = function( _w, _h ){\r
3011                                                                 KeyEvent.add( self, Const.KEY.EVENT.KEY_DOWN, ref.shutdown, 27 ); // 27.esc\r
3012                                                         };\r
3013                                                         this.onPaneResize = function( _w, _h ){};\r
3014                                                         this.onClose      = function(){};\r
3015                                                 };\r
3016                                         };\r
3017                                         ref = Application.register( Page.appClass, false, true, document.title, 'page', null, Page.appClass.tailColor || '#999999' );\r
3018                                         if( Type.isFunction( gOS.PageApplicationClass ) === true ){\r
3019                                                 gOS.PageApplicationRef = ref;\r
3020                                         };\r
3021                                 };\r
3022                                 delete Page.onReady;\r
3023                         },\r
3024                         show: function(){\r
3025                                 for( var i = pageNodes.length; i; ){\r
3026                                         pageNodes[ --i ].show();\r
3027                                 };\r
3028                         },\r
3029                         hide: function(){\r
3030                                 for( var i = pageNodes.length; i; ){\r
3031                                         pageNodes[ --i ].hide();\r
3032                                 };                              \r
3033                         },\r
3034                         boot: function(){\r
3035                                 ref && ref.boot();\r
3036                         },\r
3037                         registered: function(){\r
3038                                 return !!ref;\r
3039                         },\r
3040                         appClass: null\r
3041                 }\r
3042         })();\r
3043 \r
3044 /* --------------------------------------------------------------\r
3045  * Event\r
3046  * \r
3047  *  screenX\r
3048  *  スクリーン座標は、コンピュータのディスプレイの左上を原点とする座標系である。screenX, screenY属性で取得できる。Javascritpでは、同名のプロパティとして実装されている。\r
3049  *  しかし、これは、現実的には、何の役に立たない。ブラウザ自体がディスプレイのどの位置にいるのかがわからないので、画面上の位置を知ったところで、何にもならないからだ。 \r
3050  * \r
3051  *  clientX\r
3052  *  ウインドウ座標とは、現在のブラウザのウインドウの、ドキュメントを表示している部分の左上原点とした座標である。\r
3053  *  問題は、ウインドウは、必ずしもドキュメント全体を表示するとは限らない。スクロールと呼ばれるUIによって、ドキュメントの一部だけを表示しているかもしれない。\r
3054  */\r
3055         var XBrowserEvent = ( function(){\r
3056                 var wrappedHandlerClass,\r
3057                         wrappedEventClass,\r
3058                         tmp;\r
3059                 \r
3060                 if( window.addEventListener ){\r
3061                         wrappedHandlerClass = function( element, handler ){\r
3062                                 this.handler = function( e ){\r
3063                                         if( handler.call( element, e ) !== false ) return;\r
3064                                         e.preventDefault();\r
3065                                         e.stopPropagation();\r
3066                                         return false;\r
3067                                 };\r
3068                                 this.destroy = function(){\r
3069                                         element = handler = null;\r
3070                                         delete this.handler;\r
3071                                         delete this.destroy;\r
3072                                 };\r
3073                         };\r
3074                 } else {\r
3075                         wrappedEventClass = function( e, element ){\r
3076                                 this._event        = e;\r
3077                                 this.type          = e.type;\r
3078                                 this.target        = e.srcElement;\r
3079                                 this.currentTarget = element;\r
3080                                 this.relatedTarget = e.formElement ? e.formElement : e.toElement;\r
3081                                 this.eventPhase    = e.srcElement === element ? 2: 3;\r
3082                                 \r
3083                                 this.clientX       = e.clientX;\r
3084                                 this.clientY       = e.clientY;\r
3085                                 this.screenX       = e.screenX;\r
3086                                 this.screenY       = e.screenY;\r
3087                                 \r
3088                                 this.keyCode       = e.keyCode;\r
3089                                 this.altKey        = e.altKey;\r
3090                                 this.ctrlKey       = e.ctrlKey;\r
3091                                 this.shiftKey      = e.shiftKey;\r
3092                                 \r
3093                                 this.wheelDelta    = e.wheelDelta;\r
3094                                 \r
3095                                 e = element = null;\r
3096                         };\r
3097                         wrappedEventClass.prototype.stopPropagation = function(){\r
3098                                 this._event.cancelBubble = true;\r
3099                         };\r
3100                         wrappedEventClass.prototype.preventDefault  = function(){\r
3101                                 this._event.returnValue = false;\r
3102                         };\r
3103 \r
3104                         if( doc.attachEvent ){\r
3105                                 wrappedHandlerClass = function( element, handler ){\r
3106                                         this.handler = function(){\r
3107                                                 var e = new wrappedEventClass( window.event, element );\r
3108                                                 if( handler.call( element, e ) !== false ) return;\r
3109                                                 e.preventDefault();\r
3110                                                 e.stopPropagation();\r
3111                                                 return false;\r
3112                                         };\r
3113                                         this.destroy = function(){\r
3114                                                 element = handler = null;\r
3115                                                 delete this.handler;\r
3116                                                 delete this.destroy;\r
3117                                         };\r
3118                                 };\r
3119                         } else {\r
3120                                 tmp = {\r
3121                                         list: [],\r
3122                                         find: function( _ticket ){\r
3123                                                 for( var i=0, l= tmp.list.length, _item; i<l; ++i ){\r
3124                                                         _item = tmp.list[ i ];\r
3125                                                         if( _item.match( _ticket.element, _ticket.eventType ) === true ){\r
3126                                                                 return _item;\r
3127                                                         };\r
3128                                                 };\r
3129                                                 return null;\r
3130                                         }\r
3131                                 };\r
3132                                 tmp.ticketClass = function( _ticket ){\r
3133                                         var self = this;\r
3134                                         this.element   = _ticket.element;\r
3135                                         this.eventType = _ticket.eventType;\r
3136                                         this.handlers  = [ _ticket.handler ];\r
3137                                         this.element[ 'on' + this.eventType ] = function( e ){\r
3138                                                 return self.fire( self, e );\r
3139                                         };\r
3140                                         this.clean = function(){\r
3141                                                 self = null;\r
3142                                         };\r
3143                                         _ticket = null;\r
3144                                 };\r
3145                                 tmp.ticketClass.prototype = {\r
3146                                         add: function( _ticket ){\r
3147                                                 this.match( _ticket.element, _ticket.eventType ) === true && \r
3148                                                         this.match( null, null, _ticket.handler ) === false &&\r
3149                                                                 this.handlers.push( _ticket.handler );\r
3150                                         },\r
3151                                         remove: function( _ticket ){\r
3152                                                 if( this.match( _ticket.element, _ticket.eventType, _ticket.handler ) === true ){\r
3153                                                         var i = Util.getIndex( this.handlers, handler );\r
3154                                                         i !== 0 && this.handlers.splice( i, 1 );\r
3155                                                         this.handlers.length === 0 && this.destroy();\r
3156                                                 }\r
3157                                         },\r
3158                                         fire: function( self, e ){\r
3159                                                 e = e || new wrappedEventClass( window.event, self.element );\r
3160                                                 for( var i=self.handlers.length, cancel; i; ){\r
3161                                                         self.element._currentHandler = self.handlers[ --i ];\r
3162                                                         if( self.element._currentHandler( e ) === false ) cancel = false;\r
3163                                                         delete self.element._currentHandler;\r
3164                                                 };\r
3165                                                 return cancel;\r
3166                                         },\r
3167                                         match: function( element, eventType, handler ){\r
3168                                                 if( handler && Util.getIndex( this.handlers, handler ) === -1 ) return false;\r
3169                                                 if( eventType && this.eventType !== eventType ) return false;\r
3170                                                 if( element && this.element !== element ) return false;\r
3171                                                 return true;\r
3172                                         },\r
3173                                         destroy: function(){\r
3174                                                 this.clean();\r
3175                                                 this.element[ 'on' + this.eventType ] = '';\r
3176                                                 tmp.list.splice( Util.getIndex( tmp.list, this ), 1 );\r
3177                                                 delete this.element;\r
3178                                                 delete this.eventType;\r
3179                                                 delete this.handlers;\r
3180                                                 delete this.clean;\r
3181                                         }\r
3182                                 };\r
3183                         };\r
3184                 };\r
3185 \r
3186                 return {\r
3187                         add: function( _ticket ){\r
3188                                 if( doc.addEventListener ){\r
3189                                         XBrowserEvent.add = function( _ticket ){\r
3190                                                 _ticket.wrappedHandler = new wrappedHandlerClass( _ticket.element, _ticket.handler );\r
3191                                                 _ticket.element.addEventListener( _ticket.eventType, _ticket.wrappedHandler.handler, false );\r
3192                                         }\r
3193                                 } else\r
3194                                 if( doc.attachEvent ){\r
3195                                         XBrowserEvent.add = function( _ticket ){\r
3196                                                 _ticket.wrappedHandler = new wrappedHandlerClass( _ticket.element, _ticket.handler );\r
3197                                                 _ticket.element.attachEvent( 'on' + _ticket.eventType, _ticket.wrappedHandler.handler );\r
3198                                         };\r
3199                                 } else {\r
3200                                         XBrowserEvent.add = function( _ticket ){\r
3201                                                 var t = tmp.find( _ticket );\r
3202                                                 if( t !== null ){\r
3203                                                         t.add( _ticket );\r
3204                                                 } else {\r
3205                                                         tmp.list.push( new tmp.ticketClass( _ticket ) );\r
3206                                                 };\r
3207                                         };\r
3208                                 }\r
3209                                 \r
3210                                 XBrowserEvent.add( _ticket );\r
3211                         },\r
3212                         remove: function( _ticket ){\r
3213                                 if( doc.removeEventListener ){\r
3214                                         XBrowserEvent.remove = function( _ticket ){\r
3215                                                 _ticket.element.removeEventListener( _ticket.eventType, _ticket.wrappedHandler.handler, false );\r
3216                                                 _ticket.wrappedHandler.destroy();\r
3217                                         };\r
3218                                 } else\r
3219                                 if( doc.detachEvent ){\r
3220                                         XBrowserEvent.remove = function( _ticket ){\r
3221                                                 _ticket.element.detachEvent( 'on' + _ticket.eventType, _ticket.wrappedHandler.handler );\r
3222                                                 _ticket.wrappedHandler.destroy();\r
3223                                         };\r
3224                                 } else {\r
3225                                         XBrowserEvent.remove = function( _ticket ){\r
3226                                                 var t = tmp.find( _ticket );\r
3227                                                 if( t !== null ){\r
3228                                                         t.remove( _ticket );\r
3229                                                 };\r
3230                                         };\r
3231                                 };\r
3232                                 \r
3233                                 XBrowserEvent.remove( _ticket );\r
3234                         }\r
3235                 }\r
3236         })();\r
3237 \r
3238 /*\r
3239  * EventTicketClass\r
3240  */\r
3241         var EventTicketClass = function( _element, _eventType, _handler ){\r
3242                 this.element        = _element;\r
3243                 this.eventType      = _eventType;\r
3244                 this.handler        = _handler;\r
3245                 this.wrappedHandler = null; // for ie\r
3246                 \r
3247                 XBrowserEvent.add( this );\r
3248                 \r
3249                 _element = _eventType = _handler = null;\r
3250         };\r
3251         EventTicketClass.prototype = {\r
3252                 match: function( _element, _eventType, _handler ){\r
3253                         if( _handler   && _handler   !== this.handler )   return false;\r
3254                         if( _eventType && _eventType !== this.eventType ) return false;\r
3255                         if( _element   && _element   !== this.element )   return false;\r
3256                         \r
3257                         return true;\r
3258                 },\r
3259                 destroy: function( _element, _eventType, _handler ){\r
3260                         if( this.match( _element, _eventType, _handler ) === false ) return false;\r
3261                         \r
3262                         XBrowserEvent.remove( this );\r
3263                         \r
3264                         delete this.element;\r
3265                         delete this.eventType;\r
3266                         delete this.handler;\r
3267                         delete this.wrappedHandler;\r
3268                         \r
3269                         return true;\r
3270                 }\r
3271         };\r
3272 \r
3273 var ReadyEvent = ( function(){\r
3274         var ticketReady,\r
3275                 ticketLoad;\r
3276 \r
3277         function webkitDetect(){\r
3278                 var state = document.readyState;\r
3279                 if( state === 'loaded' || state === 'complete' ){\r
3280                         SystemTimer.remove( SUPER_USER_KEY, webkitDetect );\r
3281                         timer = null;\r
3282                         onReady();\r
3283                 };\r
3284         };\r
3285         function ieDetect(){\r
3286                 if( this.readyState === 'complete' ){ // this.readyState === 'loaded' || \r
3287                         this.onreadystatechange = new Function();\r
3288                         this.onreadystatechange = null;\r
3289                         AsyncCall.remove( SUPER_USER_KEY, ieScroll );\r
3290                         onReady();\r
3291                 };\r
3292         };\r
3293         function ieScroll(){\r
3294                 try {\r
3295                         document.documentElement.doScroll( 'left' );\r
3296                 } catch( e ){\r
3297                         AsyncCall.add( SUPER_USER_KEY, ieScroll );\r
3298                         return;\r
3299                 };\r
3300                 // no errors, fire\r
3301                 document.onreadystatechange = new Function();\r
3302                 document.onreadystatechange = null;\r
3303                 onReady();              \r
3304         };\r
3305                 \r
3306         function onReady(){\r
3307                 ticketReady && ticketReady.destroy();\r
3308                 ticketLoad  && ticketLoad.destroy();\r
3309                 ticketReady = ticketLoad = null;\r
3310                 Page.onReady();\r
3311                 if( Page.registered() === true ){\r
3312                         Page.boot();\r
3313                 } else {\r
3314                         Home.boot();\r
3315                 };\r
3316         };\r
3317         \r
3318         // Apple WebKit (Safari, OmniWeb, ...)\r
3319         if( doc.readyState && !!UA.WEBKIT ){\r
3320                 SystemTimer.add( SUPER_USER_KEY, webkitDetect, 50 );\r
3321         /* } else\r
3322                 if( document.readyState && UA.isIE && UA.ieVersion < 9 ){\r
3323                 ieScroll();\r
3324                 document.onreadystatechange = ieDetect; */\r
3325         } else {\r
3326                 ticketReady = new EventTicketClass( document, 'DOMContentLoaded', onReady );\r
3327                 ticketLoad  = new EventTicketClass( window, 'load', onReady );\r
3328         };\r
3329 })();\r
3330 \r
3331 \r
3332 \r
3333 \r
3334 /* =====================================================\r
3335  *  ResizeEvent\r
3336  * \r
3337  */\r
3338 \r
3339 var ResizeEvent = ( function(){\r
3340         var _globalLock = 0;\r
3341         var _resize;\r
3342         var root = window;\r
3343         var w = 0, h = 0;\r
3344         \r
3345         function getInnerSize(){\r
3346                 return {\r
3347                         w : root.innerWidth || root.clientWidth,\r
3348                         h : root.innerHeight || root.clientHeight\r
3349                 };\r
3350         }\r
3351         function unlock(){\r
3352                 _globalLock = 0;\r
3353         }\r
3354         \r
3355         if( document.uniqueID ){\r
3356                 _resize = function(){\r
3357                         root = (doc.compatMode || "") !== "CSS1Compat" ? doc.body : doc.documentElement;\r
3358 \r
3359                         // resize agent\r
3360                         function loop(){\r
3361                                 if( !_globalLock++ ){\r
3362                                         var size = getInnerSize();\r
3363                                         if( w !== size.w || h !== size.h ){// resized\r
3364                                                 w = size.w;\r
3365                                                 h = size.h;\r
3366                                                 // update\r
3367                                                 Application.onWindowResize( w, h );\r
3368                                         }\r
3369                                         window.setTimeout( unlock, 0 );\r
3370                                         // delay unlock\r
3371                                 }\r
3372                                 window.setTimeout( loop, 100 );\r
3373                         }\r
3374                         loop();\r
3375                 };\r
3376         } else {\r
3377                 _resize = function(){\r
3378                         new EventTicketClass( window, 'resize', onResize );\r
3379                         \r
3380                         function onResize(){\r
3381                                 if( !_globalLock++ ) {\r
3382                                         var size = getInnerSize();\r
3383                                         if( w !== size.w || h !== size.h ){// resized\r
3384                                                 w = size.w;\r
3385                                                 h = size.h;\r
3386                                                 // update\r
3387                                                 Application.onWindowResize( w, h );\r
3388                                         }\r
3389                                         window.setTimeout( unlock, 0 );\r
3390                                 }\r
3391                         }\r
3392                         onResize();\r
3393                 };\r
3394         }\r
3395         AsyncCall.add( SUPER_USER_KEY, _resize );\r
3396         \r
3397         return {\r
3398                 getSize: getInnerSize,\r
3399                 onSystemShutdown: function(){\r
3400                         \r
3401                 }\r
3402         }\r
3403 })();\r
3404 \r
3405 \r
3406 /* =====================================================\r
3407  *  MouseEvent\r
3408  * \r
3409  */\r
3410         var MouseEvent = ( function(){\r
3411                 var CLICK_OFFSET   = 2 * 2;             \r
3412                 \r
3413                 var EVENT_LIST_MAP = [],\r
3414                         TMP = {},\r
3415                         currentEventList;\r
3416 \r
3417                 /* ClickHelper\r
3418                  * mousedown, mouseup, の移動距離を調べて clickハンドラ を呼ぶ\r
3419                  */\r
3420                 var ClickEventTicketClass = function( element, clickhandler ){\r
3421                         var startX, startY,\r
3422                                 mousedownTicket = new EventTicketClass( element, 'mousedown', mousedownHandler ),\r
3423                                 mouseupTicket, mouseoutTicket;\r
3424                         \r
3425                         function mousedownHandler( e ){\r
3426                                 startX = e.clientX;\r
3427                                 startY = e.clientY;\r
3428                                 \r
3429                                 mouseupTicket  = new EventTicketClass( element, 'mouseup', mouseupHandler );\r
3430                                 mouseoutTicket = new EventTicketClass( element, 'mouseout', mouseoutHandler );                          \r
3431                         }\r
3432                         \r
3433                         function mouseupHandler( e ){\r
3434                                 var offsetX = e.clientX - startX,\r
3435                                         offsetY = e.clientY - startY;\r
3436                                 mouseoutHandler();\r
3437                                 if( offsetX * offsetX + offsetY * offsetY < CLICK_OFFSET ){\r
3438                                         if( Function.prototype.call ){\r
3439                                                 return clickhandler.call( element, e );\r
3440                                         }\r
3441                                         element._currentHandler = clickhandler;\r
3442                                         var ret = element._currentHandler( e );\r
3443                                         delete element._currentHandler;\r
3444                                         return ret;\r
3445                                 };\r
3446                         };\r
3447                         function mouseoutHandler( e ){\r
3448                                 mouseupTicket && mouseupTicket.destroy();\r
3449                                 mouseoutTicket && mouseoutTicket.destroy();\r
3450                                 mouseupTicket = mouseoutTicket = null;\r
3451                         };\r
3452                         \r
3453                         this.element = element;\r
3454                         this.handler = clickhandler;            \r
3455                         this.destroy = function( _element, _eventType, _handler ){\r
3456                                 if( this.match( _element, _eventType, _handler ) === false ) return false;\r
3457                                 \r
3458                                 mouseoutHandler();\r
3459                                 mousedownTicket.destroy();\r
3460                                 element = clickhandler = mousedownTicket = null;\r
3461                                 \r
3462                                 delete this.element;\r
3463                                 delete this.eventType;\r
3464                                 delete this.handler;\r
3465                                 \r
3466                                 return true;\r
3467                         };\r
3468                 };\r
3469                 ClickEventTicketClass.prototype = {\r
3470                         eventType: 'click',\r
3471                         match    : EventTicketClass.prototype.match\r
3472                 };\r
3473                 \r
3474                 /* WheelHelper\r
3475                  */\r
3476                 var WheelEventTicketClass = ( function(){\r
3477                         if( UA.GECKO ){\r
3478                                 return function( element, wheelhandler ){\r
3479                                         this.wheelTicket = new EventTicketClass( element, 'DOMMouseScroll', onWheel );\r
3480                                         this.element     = element;\r
3481                                         this.handler     = wheelhandler;\r
3482                                         this.destroy     = function( _element, _eventType, _handler ){\r
3483                                                 if( this.match( _element, _eventType, _handler ) === false ) return false;\r
3484                                                 element = wheelhandler = null;\r
3485                                                 \r
3486                                                 this.wheelTicket && this.wheelTicket.destroy();\r
3487                                                 \r
3488                                                 delete this.wheelTicket;\r
3489                                                 delete this.element;\r
3490                                                 delete this.handler;\r
3491                                                 \r
3492                                                 return true;\r
3493                                         };\r
3494                                         \r
3495                                         function onWheel( e ){\r
3496                                                 e.wheelDelta = e.detail * -40;\r
3497                                                 return wheelhandler.call( element, e );\r
3498                                         }\r
3499                                 };\r
3500                         } else\r
3501                         if( true || UA.isIE ){\r
3502                                 return function( element, wheelhandler ){\r
3503                                         this.wheelTicket    = new EventTicketClass( element, 'mousewheel', wheelhandler );\r
3504                                         this.element        = element;\r
3505                                         this.handler        = wheelhandler;\r
3506                                         element = wheelhandler = null;\r
3507                                 };\r
3508                         } else {\r
3509                                 TMP.wheelList   = [];\r
3510                                 //TMP.wheelLegacy = undefined;\r
3511                                 TMP.onWheel   = function( e ){\r
3512                                         e = e || window.event;\r
3513                                         var cancel = true,\r
3514                                                 f = TMP.wheelLegacy;\r
3515                                         if( f ) cancel = f.call( this, e );\r
3516                                         \r
3517                                         for( i = TMP.wheelList.length; i; ){\r
3518                                                 if( TMP.wheelList[ --i ].call( this, e ) === false ) cancel = false;\r
3519                                         }\r
3520                                         return cancel;\r
3521                                 };\r
3522                                 return function( element, wheelhandler ){\r
3523                                         this.wheelTicket    = null;\r
3524                                         this.element        = element;\r
3525                                         this.handler        = wheelhandler;\r
3526                                         this.destroy        = function( _element, _eventType, _handler ){\r
3527                                                 if( this.match( _element, _eventType, _handler ) === false ) return false;\r
3528                                                 \r
3529                                                 TMP.wheelList.splice( Util.getIndex( TMP.wheelList, this.handler ) );\r
3530                                                 if( TMP.wheelList.length === 0 ) this.element.onmousewheel = '';\r
3531                                                 \r
3532                                                 delete this.element;\r
3533                                                 delete this.handler;\r
3534                                                 \r
3535                                                 return true;\r
3536                                         };\r
3537                                         \r
3538                                         if( TMP.wheelList.length === 0 ){\r
3539                                                 //TMP.wheelLegacy     = Type.isFunction( window.onmousewheel ) === true ? window.onmousewheel : undefined;\r
3540                                                 element.onmousewheel = TMP.onWheel;\r
3541                                         };\r
3542                                         TMP.wheelList.push( wheelhandler );\r
3543                                         element = wheelhandler = null;\r
3544                                 };\r
3545                         }\r
3546                 })();\r
3547                 WheelEventTicketClass.prototype = {\r
3548                         eventType : 'mousewheel',\r
3549                         match     : EventTicketClass.prototype.match,\r
3550                         destroy   : function( _element, _eventType, _handler ){\r
3551                                 if( this.match( _element, _eventType, _handler ) === false ) return false;\r
3552                                 \r
3553                                 this.wheelTicket && this.wheelTicket.destroy();\r
3554                                 \r
3555                                 delete this.wheelTicket;\r
3556                                 delete this.element;\r
3557                                 delete this.handler;\r
3558                                 \r
3559                                 return true;\r
3560                         }\r
3561                 };\r
3562                 \r
3563                 \r
3564                 return {\r
3565                         add: function( _apiuser, _element, _eventType, _handler ){\r
3566                                 if( isApiUser( _apiuser ) === true &&\r
3567                                         ( Type.isHTMLElement( _element ) === true || _element === window || _element === doc ) &&\r
3568                                         Type.isString( _eventType ) === true &&\r
3569                                         Type.isFunction( _handler ) === true\r
3570                                 ){\r
3571                                         var _uid    = _apiuser.getUID(),\r
3572                                                 _events = EVENT_LIST_MAP[ _uid ];\r
3573                                         if( Type.isArray( _events ) === false ){\r
3574                                                 _events = EVENT_LIST_MAP[ _uid ] = [];\r
3575                                         } else {\r
3576                                                 // 2重登録の禁止\r
3577                                                 for( var i=0, l=_events.length; i<l; ++i ){\r
3578                                                         if( _events[ i ].match( _element, _eventType, _handler ) === true ) return;\r
3579                                                 }\r
3580                                         };\r
3581                                         if( _eventType === 'click' ){\r
3582                                                 _events.push( new ClickEventTicketClass( _element, _handler ) );\r
3583                                         } else\r
3584                                         if( _eventType === 'mousewheel' ){\r
3585                                                 _events.push( new WheelEventTicketClass( _element, _handler ) );\r
3586                                         } else {\r
3587                                                 _events.push( new EventTicketClass( _element, _eventType, _handler ) );\r
3588                                         };\r
3589                                 };\r
3590                         },\r
3591                         remove: function( _apiuser, _element, _eventType, _handler ){\r
3592                                 if( isApiUser( _apiuser ) === true ){\r
3593                                         var _uid    = _apiuser.getUID(),\r
3594                                                 _events = EVENT_LIST_MAP[ _uid ],\r
3595                                                 _removed,\r
3596                                                 i = 0;\r
3597                                         if( Type.isArray( _events ) === false ) return;\r
3598                                         for( ;i < _events.length; ){\r
3599                                                 if( _events[ i ].destroy( _element, _eventType, _handler ) === true ){\r
3600                                                         _events.splice( i, 1 );\r
3601                                                 } else {\r
3602                                                         ++i;\r
3603                                                 }\r
3604                                         }\r
3605                                         if( _events.length === 0 ){\r
3606                                                 _events = EVENT_LIST_MAP[ _uid ] = null;\r
3607                                         }\r
3608                                 }\r
3609                         },\r
3610                         onCurrentApplicationChange: function(){\r
3611                                 \r
3612                         },\r
3613                         onApplicationShutdown: function(){\r
3614                                 \r
3615                         },\r
3616                         onSystemShutdown: function(){\r
3617                                 \r
3618                         }\r
3619                 }\r
3620         })();\r
3621 \r
3622 /* ----------------------------------------\r
3623  * KEY\r
3624  * \r
3625  *  - EDITABLE_TEXT_CONTROL\r
3626  * \r
3627  *    .SHIFT_DOWN_EVENT:        'shiftDown',\r
3628  *    .SHIFT_UP_EVENT:          'shiftUp',\r
3629  *    .CTRL_DOWN_EVENT:         'ctrlDown',\r
3630  *    .CTRL_UP_EVENT:           'ctrlUp',\r
3631  *    .SPACE_DOWN_EVENT:        'spaceDown',\r
3632  *    .SPACE_UP_EVENT:          'spaceUp',\r
3633  *    .init:                            function,\r
3634  *    .addKeyDownEvent:         function,\r
3635  *    .keyEventDispatcher:      function,\r
3636  * \r
3637  * ショートカットキーの監視とテキスト入力(input, textarea)、チェックボックスを管理する。\r
3638  * キー入力はdocumentで受けて、テキスト編集中(input, textarea)はそちらにキーイベント流す。\r
3639  * \r
3640  */\r
3641 var KeyEvent = ( function(){\r
3642         var EVENT_LIST_MAP = [],\r
3643                 LOCK_UP        = [],\r
3644                 LOCK_DOWN      = [],\r
3645                 application    = null,\r
3646                 currentList    = null;\r
3647 \r
3648         window.focus();\r
3649         \r
3650         var focusTicket    = null,\r
3651                 keydownTicket  = null,\r
3652                 keyupTicket    = null,\r
3653                 keyPress       = null,\r
3654                 keypressTicket = null;\r
3655         \r
3656         function unlock( lock, key ){\r
3657                 lock.splice( Util.getIndex( lock, key ), 1 );\r
3658         };\r
3659         \r
3660         function onKeyChange( e ){\r
3661                 var cancel         = false,\r
3662                         type           = e.type,\r
3663                         key            = e.keyCode, // || e.which,\r
3664                         shift          = Type.isBoolean( e.shiftKey ) === true ? e.shiftKey : ( e.modifiers & Event.SHIFT_MASK ),\r
3665                         ctrl           = Type.isBoolean( e.ctrlKey  ) === true ? e.ctrlKey  : ( e.modifiers & Event.CONTROL_MASK ),\r
3666                         lock           = type === 'keyup' ? LOCK_UP : LOCK_DOWN;\r
3667                         \r
3668                 // block chattering\r
3669                 if( Util.getIndex( lock, key ) !== -1 ) return;\r
3670                 lock.push( key );\r
3671                 AsyncCall.add( SUPER_USER_KEY, unlock, [ lock, key ] );\r
3672                 \r
3673                 if( key === 16 || shift === true ){\r
3674                         KeyEvent.shiftEnabled = type !== 'keyup';\r
3675                 };\r
3676                 if( key === 17 || ctrl === true ){\r
3677                         KeyEvent.ctrlEnabled  = type !== 'keyup';\r
3678                 };\r
3679                 for( var i=currentList.length, t; t = currentList[ --i ]; ){\r
3680                         if( Type.isFunction( t[ type ] ) === true && t.keyCode === key && ( t.shift === undefined || t.shift === shift ) && ( t.ctrl === undefined || t.ctrl === ctrl )){\r
3681                                 AsyncCall.add( t.apiuser, t[ type ], e );\r
3682                                 cancel = true;\r
3683                         };\r
3684                 };\r
3685                 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
3686                         return false;\r
3687                 };\r
3688         };\r
3689         \r
3690         if( UA.isIE === true && UA.ieRenderingVersion < 9 ){\r
3691                 keyPress = function( e ){\r
3692                         var key = e.keyCode;\r
3693                         if( key === 13 || key === 27 ){\r
3694                                 e.type = 'keydown';\r
3695                                 return onKeyChange( e );\r
3696                         };\r
3697                 };\r
3698         };\r
3699         \r
3700         var KeyEventTicketClass = function( _apiuser, _type, _onKeydown, _onKeyup, _keyCode, _shift, _ctrl ){\r
3701                 this.apiuser = _apiuser;\r
3702                 this.type    = _type;\r
3703                 this.keydown = _onKeydown;\r
3704                 this.keyup   = _onKeyup;                \r
3705                 this.keyCode = _keyCode;\r
3706                 this.shift   = _shift;\r
3707                 this.ctrl    = _ctrl;\r
3708                 _apiuser = _onKeydown = _onKeyup = null;\r
3709         }\r
3710         KeyEventTicketClass.prototype = {\r
3711                 match: function( _apiuser, _type, _handler, _keyCode, _shift, _ctrl ){\r
3712                         if( _apiuser  && _apiuser  !== this.apiuser ) return false;\r
3713                         if( _type     && _type     !== this.type )    return false;\r
3714                         if( _handler ){\r
3715                                 if( this.type === 'keydown' ){\r
3716                                         if( _handler !== this.keydown ) return false;\r
3717                                 } else {\r
3718                                         if( _handler !== this.keyup )   return false;\r
3719                                 };\r
3720                         };\r
3721                         if( _keyCode  && _keyCode  !== this.keyCode ) return false;\r
3722                         if( _shift    && _shift    !== this.shift )   return false;\r
3723                         if( _ctrl     && _ctrl     !== this.ctrl )    return false;\r
3724                         return true;\r
3725                 },\r
3726                 destroy: function( _apiuser, _type, _handler, _keyCode, _shift, _ctrl ){\r
3727                         if( this.match( _apiuser, _type, _handler, _keyCode, _shift, _ctrl ) === false ) return false;\r
3728                         \r
3729                         delete this.apiuser;\r
3730                         delete this.keydown;\r
3731                         delete this.keyup;\r
3732                         \r
3733                         return true;\r
3734                 }\r
3735         };\r
3736         \r
3737         function registerEvent( _apiuser, _type, _onKeydown, _onKeyup, _keyCode, _shift, _ctrl ){\r
3738                 var _uid  = _apiuser.getUID(),\r
3739                         _list = EVENT_LIST_MAP[ _uid ];\r
3740                 if( Type.isArray( _list ) === false ){\r
3741                         _list = EVENT_LIST_MAP[ _uid ] = [];\r
3742                 }\r
3743                 for( var i=0, l=_list.length; i<l; ++i ){\r
3744                         if( _list[ i ].match( _apiuser, _type, _onKeydown || _onKeyup, _keyCode, _shift, _ctrl ) === true ) return;\r
3745                 }\r
3746                 _list.push( new KeyEventTicketClass( _apiuser, _type, _onKeydown, _onKeyup, _keyCode, _shift, _ctrl ));\r
3747                 \r
3748                 if( _apiuser === application ) KeyEvent.updateCurrentListener( _apiuser );\r
3749         };\r
3750         \r
3751         return {\r
3752                 add: function( _apiuser, _type, _handler, _keyCode, _shift, _ctrl ){\r
3753                         if( _type === 'keydown' ){\r
3754                                 registerEvent( _apiuser, _type, _handler, null, _keyCode, _shift, _ctrl );\r
3755                         } else\r
3756                         if( _type === 'keyup' ){\r
3757                                 registerEvent( _apiuser, _type, null, _handler, _keyCode, _shift, _ctrl );\r
3758                         } else\r
3759                         if( _type === 'keychange' ){\r
3760                                 registerEvent( _apiuser, _type, _handler, _handler, _keyCode, _shift, _ctrl );\r
3761                         } else\r
3762                         if( _type === 'cursol' ){\r
3763                                 \r
3764                         };\r
3765                 },\r
3766                 remove: function( _apiuser, _type, _handler, _keyCode, _shift, _ctrl ){\r
3767                         var _list = EVENT_LIST_MAP[ _apiuser.getUID() ],\r
3768                                 i = 0;\r
3769                         if( Type.isArray( _list ) === true ){\r
3770                                 while( i < _list.length ){\r
3771                                         if( _list[ i ].destroy( _apiuser, _type, _handler, _keyCode, _shift, _ctrl ) === true ){\r
3772                                                 _list.splice( i, 1 );\r
3773                                         } else {\r
3774                                                 ++i;\r
3775                                         }\r
3776                                 }\r
3777                         }\r
3778                         if( _apiuser === application ) KeyEvent.updateCurrentListener( _apiuser );\r
3779                 },\r
3780                 shiftEnabled: false,\r
3781                 ctrlEnabled:  false,\r
3782                 /*\r
3783                  * currentListener\r
3784                  *  currrentApplication ( overlay Application ) or\r
3785                  *  superuser ( UI )\r
3786                  */\r
3787                 updateCurrentListener: function( _apiuser ){\r
3788                         application = _apiuser;\r
3789                         var _uid    = _apiuser.getUID();\r
3790                         currentList = EVENT_LIST_MAP[ _uid ] || ( EVENT_LIST_MAP[ _uid ] = [] );\r
3791                         \r
3792                         var _ticket,\r
3793                                 _down = false,\r
3794                                 _up   = false;\r
3795                         for( var i=currentList.length; _ticket = currentList[ --i ]; ){\r
3796                                 if( _down === false ) _down = !!_ticket.keydown;\r
3797                                 if( _up   === false ) _up   = !!_ticket.keyup;\r
3798                                 if( _down && _up ) break;\r
3799                         }\r
3800                         if( _down === true ){\r
3801                                 keydownTicket = new EventTicketClass( document, 'keydown', onKeyChange );\r
3802                                 keypressTicket = keyPress !== null ? new EventTicketClass( doc, 'keypress', keyPress ) : null;\r
3803                         } else {\r
3804                                 keydownTicket && keydownTicket.destroy();\r
3805                                 keypressTicket && keypressTicket.destroy();\r
3806                                 keydownTicket = keypressTicket = null;\r
3807                         }\r
3808                         if( _up === true ){\r
3809                                 keyupTicket   = new EventTicketClass( document, 'keyup', onKeyChange );\r
3810                         } else {\r
3811                                 keyupTicket && keyupTicket.destroy();\r
3812                                 keyupTicket = null;\r
3813                         }\r
3814                         \r
3815                         if( _down === true || _up === true ){\r
3816                                 focusTicket   = new EventTicketClass( document, 'mouseenter', window.focus );\r
3817                         } else {\r
3818                                 focusTicket && focusTicket.destroy();\r
3819                                 focusTicket = null;\r
3820                         }\r
3821                 },\r
3822                 onApplicationShutdown: function( _apiuser ){\r
3823                         KeyEvent.remove( _apiuser );\r
3824                 },\r
3825                 onSystemShutdown: function(){\r
3826                         \r
3827                 }\r
3828         }\r
3829 })();\r
3830 \r
3831 /**\r
3832  * \r
3833  * http://thudjs.tumblr.com/post/637855087/stylesheet-onload-or-lack-thereof\r
3834  */\r
3835 \r
3836 var StyleSheet = ( function(){\r
3837         var head = doc.getElementsByTagName( 'head' )[ 0 ];\r
3838         \r
3839         var TICKET_LIST = [];\r
3840         var STATE_LIST  = 'loaded,complete,uninitialized'.split( ',' );\r
3841         \r
3842         var cssRules, sheet;\r
3843         \r
3844         var FetchCssTicketClass = function( _apiuser, _url, _elm, _onload, _onerror ){\r
3845                 this.apiusers = [ _apiuser ];\r
3846                 this.url      = _url;\r
3847                 this.elm      = _elm;\r
3848                 this.onload   = [ _onload ];\r
3849                 this.onerror  = [ _onerror ];\r
3850                 this.time     = 0;\r
3851         };\r
3852         FetchCssTicketClass.prototype = {\r
3853                 match: function( _apiuser, _url ){\r
3854                         if( _apiuser  && Util.getIndex( this.apiusers, _apiuser ) === -1 ) return false;\r
3855                         if( _url      && _url      !== this.url     ) return false;\r
3856                         return true;\r
3857                 },\r
3858                 destroy: function( _apiuser, _url ){\r
3859                         if( this.match( _apiuser, _url ) === false ) return false;\r
3860                         \r
3861                         var i = Util.getIndex( this.apiusers, _apiuser );\r
3862                         \r
3863                         this.apiusers.splice( i, 1 );\r
3864                         this.onload.splice( i, 1 );\r
3865                         this.onerror.splice( i, 1 );\r
3866                         \r
3867                         if( this.apiusers.length !== 0 ) return false;\r
3868                         \r
3869                         head.removeChild( this.elm );\r
3870                         this.elm.onreadystatechange = new Function();\r
3871                         this.elm.onload = null;\r
3872                         \r
3873                         delete this.apiusers;\r
3874                         delete this.url;\r
3875                         delete this.elm;\r
3876                         delete this.onload;\r
3877                         delete this.onerror;\r
3878                         delete this.time;\r
3879                         \r
3880                         return true;\r
3881                 },\r
3882                 loaded: function(){\r
3883                 for( var i = this.onload.length, f; i; ){\r
3884                         f = this.onload[ --i ];\r
3885                         Type.isFunction( f ) === true && AsyncCall.add( this.apiusers[ i ], f, this.url );\r
3886                         this.onload[ i ] = this.onerror[ i ] = null;\r
3887                 };\r
3888                 },\r
3889                 error: function(){\r
3890                 for( var i = this.onerror.length, f; i; ){\r
3891                         f = this.onerror[ --i ];\r
3892                         Type.isFunction( f ) === true && AsyncCall.add( this.apiusers[ i ], f, this.url );\r
3893                         this.onload[ i ] = this.onerror[ i ] = null;\r
3894                 };\r
3895                 },\r
3896                 check: function(){\r
3897                         var el = this.elm;\r
3898                         try {\r
3899                                 return el[ sheet ] && el[ sheet ][ cssRules ].length > 0;\r
3900                         } catch( e ){\r
3901                                 return false;\r
3902                         };\r
3903                 },\r
3904                 done: false\r
3905         };\r
3906         \r
3907         function getTicket( elm ){\r
3908                 for( var i = TICKET_LIST.length, t; i; ){\r
3909                         t = TICKET_LIST[ --i ];\r
3910                         if( t.elm === elm ) return t;\r
3911                 };\r
3912         };\r
3913         \r
3914         function detect(){\r
3915                 var t = getTicket( this ), rs = this.readyState, c;\r
3916                 if( t && t.done === false && ( !rs || Util.getIndex( STATE_LIST, rs ) !== -1 ) ){\r
3917                         t.done = true;\r
3918                 t.loaded();\r
3919                 this.onreadystatechange = new Function();\r
3920                 this.onload = null;\r
3921                 };\r
3922         };\r
3923         \r
3924         function checkTimer(){\r
3925                 var l = TICKET_LIST.length,\r
3926                         n = 0;\r
3927                 for( var i = 0; i < l; ++i ){\r
3928                         t = TICKET_LIST[ i ];\r
3929                         ++t.time;\r
3930                         if( t.check() === true ){\r
3931                                 t.loaded();\r
3932                                 ++n;\r
3933                         } else\r
3934                         if( t.time > 99 ){\r
3935                                 t.error();\r
3936                         } else {\r
3937                                 \r
3938                         };\r
3939                 };\r
3940                 l === n && SystemTimer.remove( SUPER_USER_KEY, checkTimer );\r
3941         };\r
3942         \r
3943         return {\r
3944                 load: function( _apiuser, _url, opt_onload, opt_onerror ){\r
3945                         _url = Util.getAbsolutePath( _url );\r
3946                         var t;\r
3947                         for( var i=TICKET_LIST.length; i; ){\r
3948                                 t = TICKET_LIST[ --i ];\r
3949                                 if( t.match( null, _url ) === true ){\r
3950                                         if( t.match( _apiuser, _url ) === false ){\r
3951                                                 t.apiusers.push( _apiuser );\r
3952                                                 t.onload.push( opt_onload );\r
3953                                                 t.onerror.push( opt_onerror );\r
3954                                         };\r
3955                                         SystemTimer.add( SUPER_USER_KEY, checkTimer, 333 );\r
3956                                         return;\r
3957                                 };\r
3958                         };\r
3959                         var elm = doc.createElement( 'link' );\r
3960                         head.appendChild( elm );\r
3961                         elm.rel  = 'stylesheet';\r
3962                         elm.type = 'text\/css';\r
3963                         elm.onreadystatechange = elm.onload = detect;\r
3964                         elm.href = _url;\r
3965                         \r
3966                         if( !sheet ){ // only assign these once\r
3967                                 cssRules = 'cssRules';\r
3968                                 sheet    = 'sheet';\r
3969                                 if ( !( sheet in elm ) ) { // MSIE uses non-standard property names\r
3970                                         cssRules = 'rules';\r
3971                                         sheet    = 'styleSheet';\r
3972                                 };\r
3973                         };\r
3974                         \r
3975                         TICKET_LIST.push( new FetchCssTicketClass( _apiuser, _url, elm, opt_onload, opt_onerror ) );\r
3976                         \r
3977                         SystemTimer.add( SUPER_USER_KEY, checkTimer, 333 );\r
3978                 },\r
3979                 unload: function( _apiuser, _url ){\r
3980                         _url = _url ? Util.getAbsolutePath( _url ) : null;\r
3981                         for( var i = 0; i < TICKET_LIST.length; ){\r
3982                                 t = TICKET_LIST[ i ];\r
3983                                 if( t.destroy( _apiuser, _url ) === true ){\r
3984                                         TICKET_LIST.splice( i, 1 );\r
3985                                 } else {\r
3986                                         ++i;\r
3987                                 }\r
3988                         };\r
3989                         if( TICKET_LIST.length === 0 ){\r
3990                                 SystemTimer.remove( SUPER_USER_KEY, checkTimer );\r
3991                         }\r
3992                 }\r
3993         }\r
3994 })();\r
3995 \r
3996 /*\r
3997  * AssetLoader\r
3998  * fetchCSS\r
3999  * fetchJson\r
4000  * fetchHtml\r
4001  * fetchImage\r
4002  * fetchLocalFile\r
4003  * fetchLocalStorage
4004  */\r
4005 \r
4006 var Image = ( function(){\r
4007         var TASK_LIST = [];\r
4008         /* \r
4009          * FetchClass original is\r
4010          * \r
4011          * LICENSE: MIT?\r
4012          *  URL: http://d.hatena.ne.jp/uupaa/20080413/1208067631\r
4013          *  AUTHOR: uupaa.js@gmail.com\r
4014          * \r
4015          */\r
4016         function detect(){\r
4017                 for( var i=0, t; i < TASK_LIST.length; ){\r
4018                         t = TASK_LIST[ i ];\r
4019                         if( t.complete() === true ){\r
4020                                 TASK_LIST.splice( i, 1 );\r
4021                         } else {\r
4022                                 ++i;\r
4023                         };\r
4024                 };\r
4025                 TASK_LIST.length === 0 && SystemTimer.remove( SUPER_USER_KEY, detect );\r
4026         };\r
4027         function getTask( img ){\r
4028                 for( var i = TASK_LIST.length; i; ){\r
4029                         if( TASK_LIST[ --i ].img === img ) return TASK_LIST[ i ];\r
4030                 };\r
4031         };\r
4032         function onError(){\r
4033                 var task = getTask( this );\r
4034                 if( task.finish === true ) return;\r
4035                 task.finish = true;\r
4036                 AsyncCall.add( task.apiuser, task.asyncCallback, null, task );\r
4037         };\r
4038         function onLoad(){\r
4039                 // if( finish === true ) return; // これがあると firefox3.6 で駄目、、、\r
4040                 // if( timer ) return; // これがあると safari3.2 で駄目、、、\r
4041                 var task = getTask( this );\r
4042                 task.finish = true;\r
4043                 TASK_LIST.splice( Util.getIndex( TASK_LIST, task ), 1 );\r
4044                 if( window.opera && !task.img.complete ){\r
4045                         AsyncCall.add( task.apiuser, task.asyncCallback, null, task );\r
4046                         return;\r
4047                 };\r
4048                 task.size = Util.getImageSize( this );\r
4049                 AsyncCall.add( task.apiuser, task.asyncCallback, null, task );\r
4050         };\r
4051 \r
4052 \r
4053         var FetchClass = function( apiuser, abspath, onLoadCallback, onErrorCallback, timeout ){\r
4054                 this.apiuser         = apiuser;\r
4055                 this.abspath         = abspath;\r
4056                 this.onLoadCallback  = onLoadCallback;\r
4057                 this.onErrorCallback = onErrorCallback;\r
4058                 this.timeout         = timeout;\r
4059                 this.tick            = 0;\r
4060         };\r
4061         FetchClass.prototype = {\r
4062                 img: null,\r
4063                 size: null,\r
4064                 tick: 0,\r
4065                 finish: false,\r
4066                 load: function(){\r
4067                         var img     = this.img = document.createElement( 'img' ); //var img = new Image(); ではieでimgのsizeが取れない、、、removeChildも失敗し、imgSizeGetterにimgが残る\r
4068                         img.onabort = img.onerror = onError;\r
4069                         img.onload  = onLoad;\r
4070                         img.src     = this.abspath;\r
4071                 },\r
4072                 complete: function(){\r
4073                         if( this.finish === true ) return true;\r
4074                         if( this.img.complete ){\r
4075                                 this.finish = true;\r
4076                                 if( this.img.width ) return true;\r
4077                                 AsyncCall.add( this.apiuser, this.asyncCallback, null, this );\r
4078                                 return true;\r
4079                         };\r
4080                         if( ( this.tick += 250 ) > this.timeout ){\r
4081                                 this.finish = true;\r
4082                                 AsyncCall.add( this.apiuser, this.asyncCallback, null, this );\r
4083                                 return true;\r
4084                         };\r
4085                 },\r
4086                 asyncCallback: function(){\r
4087                         this.size ? this.onLoadCallback( this.abspath, this.size.width, this.size.height ) : this.onErrorCallback( this.abspath );\r
4088                         this.destroy();\r
4089                 },\r
4090                 destroy: function(){\r
4091                         this.finish  = true;\r
4092                         this.img.src = this.img.onload = this.img.onabort = this.img.onerror = '';\r
4093                         delete this.img;\r
4094                         delete this.size;\r
4095                         delete this.onLoadCallback;\r
4096                         delete this.onErrorCallback;\r
4097                 },\r
4098                 stop: function(){\r
4099                         timer !== null && window.clearTimeout( timer );\r
4100                         destroy();\r
4101                 }\r
4102         };\r
4103         \r
4104         return {\r
4105                 load: function( URLorELM, onLoad, onError, opt_timeout ){\r
4106                         var src, fetch;\r
4107                         if( Type.isString( URLorELM ) === true ){\r
4108                                 src = URLorELM;\r
4109                         } else\r
4110                         if( Type.isHTMLElement( URLorELM ) === true && URLorELM.tagName.toLowerCase() === 'img' ){\r
4111                                 src = URLorELM.src;\r
4112                         } else {\r
4113                                 return;\r
4114                         };\r
4115                         \r
4116                         fetch = new FetchClass(\r
4117                                 Util.getAbsolutePath( src ),\r
4118                                 onLoad, onError,\r
4119                                 Type.isFinite( opt_timeout ) === true ? opt_timeout : undefined\r
4120                         );\r
4121                         TASK_LIST.push( fetch );\r
4122                         \r
4123                         SystemTimer.add( SUPER_USER_KEY, detect, 250 );\r
4124                 },\r
4125                 unload: function(  ){\r
4126                         \r
4127                 }\r
4128         };\r
4129 })();\r
4130 \r
4131 \r
4132 /* ----------------------------------------\r
4133  * \r
4134  */\r
4135 \r
4136 var Overlay = ( function(){\r
4137         var elmContainer, elmShadow, elmCloseButton,\r
4138                 application    = null,\r
4139                 visible        = false,\r
4140                 bodyOverflow   = '',\r
4141                 windowW, windowH;\r
4142 \r
4143         function onCloseClick( e ){\r
4144                 Overlay.hide();\r
4145                 return false;\r
4146         };\r
4147         function asyncInit( /* arguments */ ){  \r
4148                 \r
4149                 //body.appendChild( application.rootElement );\r
4150                 elmContainer.insertBefore( application.rootElement, elmCloseButton );\r
4151                 application.rootElement.style.display = 'none';\r
4152                 application.init();\r
4153         };\r
4154         function asyncOpen( /* arguments */ ){\r
4155                 \r
4156                 var _arg = Util.copyArray( arguments );\r
4157                 _arg.unshift( windowW, windowH );\r
4158                 application.open.apply( application, _arg );\r
4159                 \r
4160                 elmContainer.style.cssText = "top:" + body.scrollTop + 'px;display:none;';\r
4161                 $( elmContainer ).stop().fadeIn( onFadeInComplete );            \r
4162         };\r
4163         function onFadeInComplete(){\r
4164                 KeyEvent.add( application, Const.KEY.EVENT.KEY_DOWN, Overlay.hide, 27 ); // 27.esc\r
4165                 MouseEvent.add( application, elmCloseButton, 'click', onCloseClick );\r
4166         };\r
4167         function onFadeOutComplete(){   \r
4168                 Util.removeAllChildren( elmContainer );\r
4169                 body.removeChild( elmContainer );\r
4170                 elmContainer = elmShadow = elmCloseButton = null;\r
4171         };\r
4172         return {\r
4173                 show: function( _application, _bootParams ){\r
4174                         if( visible === true && application === _application ) return;\r
4175                         if( Application.isApplicationInstance( _application ) === false ) return;\r
4176                         \r
4177                         elmContainer = document.createElement( 'div' );\r
4178                         body.appendChild( elmContainer );\r
4179                         \r
4180                         elmContainer.id = 'overlay-container';\r
4181                         \r
4182                         bodyOverflow        = body.style.overflow;\r
4183                         body.style.overflow = 'hidden';\r
4184                         \r
4185                         elmShadow = document.createElement( 'div' );\r
4186                         elmContainer.appendChild( elmShadow );\r
4187                         elmShadow.id = 'overlay-shadow';\r
4188                         \r
4189                         elmCloseButton  = document.createElement( 'div' );\r
4190                         elmContainer.appendChild( elmCloseButton );\r
4191                         elmCloseButton.id = 'overlay-close-button';\r
4192                         elmCloseButton.appendChild( document.createTextNode( 'x' ) );\r
4193                         \r
4194                         elmContainer.style.display = 'none'; // hide for fadeIn\r
4195                         \r
4196                         _application.addAsyncCall( asyncInit );\r
4197                         _application.addAsyncCall( asyncOpen, _bootParams );\r
4198                         \r
4199                         visible     = true;\r
4200                         application = _application;\r
4201                 },\r
4202                 hide: function(){\r
4203                         if( visible === false ) return;\r
4204                         if( application.close() === false ) return false;\r
4205                         \r
4206                         body.style.overflow = bodyOverflow;\r
4207                         \r
4208                         $( elmContainer ).stop().css( {\r
4209                                 filter:         '',\r
4210                                 opacity:        ''\r
4211                         }).fadeOut( onFadeOutComplete );\r
4212                         visible = false;\r
4213                         \r
4214                         KeyEvent.remove( application, Const.KEY.EVENT.KEY_DOWN, Overlay.hide ); // 27.esc\r
4215                         MouseEvent.remove( application, elmCloseButton );\r
4216                         \r
4217                         application = null;\r
4218                 },\r
4219                 onWindowResize: function( _windowW, _windowH ){\r
4220                         windowW = _windowW;\r
4221                         windowH = _windowH;                     \r
4222                         \r
4223                         if( application === null ) return;\r
4224                         \r
4225                         elmContainer.style.height = _windowH + 'px';\r
4226                         elmContainer.style.top    = body.scrollTop + 'px';\r
4227 \r
4228                         elmShadow.style.height = _windowH + 'px';\r
4229 \r
4230                         AsyncCall.add( application, application.resize, [ _windowW, _windowH ] );\r
4231                 }\r
4232         }\r
4233 })();\r
4234 \r
4235 /* ----------------------------------------\r
4236  * UI\r
4237  * \r
4238  * keyEventRellay\r
4239  *  form -> overlay -> view\r
4240  * \r
4241  */\r
4242 \r
4243 var UI = ( function(){\r
4244         var UI_LIST     = [],\r
4245                 currentUser = null,\r
4246                 currentList = null,\r
4247                 currentUi   = null,\r
4248                 currentItem = null,\r
4249                 windowW     = 0,\r
4250                 windowH     = 0;\r
4251 \r
4252         var CLASSNAME_COMBOBOX_OPTION = 'combobox-option',\r
4253                 CLASSNAME_COMBOBOX_OPTION_CURRENT = CLASSNAME_COMBOBOX_OPTION + ' combobox-option-current',\r
4254                 ELM_A_ORIGIN = ( function(){\r
4255                         var ret = document.createElement( 'a' );\r
4256                         ret.href = '#';\r
4257                         return ret;\r
4258                 })(),\r
4259                 ELM_INPUT_TEXT = ( function(){\r
4260                         var ret = document.createElement( 'input' );\r
4261                         ret.type = 'text';\r
4262                         return ret;\r
4263                 })(),\r
4264                 ELM_COMBOBOX = ( function(){\r
4265                         var ret       = document.createElement( 'a' ),\r
4266                                 elmToggle = document.createElement( 'span' ),\r
4267                                 elmValue  = document.createElement( 'span' );\r
4268                         ret.href = '#';\r
4269                         ret.appendChild( elmToggle );\r
4270                         ret.appendChild( elmValue );\r
4271                         elmToggle.className = 'combobox-toggle';\r
4272                         elmValue.className  = 'combobox-value';\r
4273                         \r
4274                         elmToggle.appendChild( document.createTextNode( '▼' ));\r
4275                         elmValue.appendChild( document.createTextNode( 'null' ));\r
4276                         return ret;\r
4277                 })();\r
4278                 \r
4279         var InputTextClass = function( apiuser, uiGroup, elmWrapper, elmValue, onUpdate, validater ){\r
4280                 var elmA     = ELM_A_ORIGIN.cloneNode( true ),\r
4281                         instance = this,\r
4282                         focus    = false,\r
4283                         visible  = true,\r
4284                         enabled  = true,\r
4285                         value    = elmValue.innerHTML;\r
4286                 elmValue.innerHTML = '';\r
4287                 elmValue.className += ' editable-text';\r
4288                 elmValue.appendChild( elmA );\r
4289                 \r
4290                 this.value = function( _value ){\r
4291                         if( Type.isString( _value ) === true || Type.isNumber( _value ) === true ){\r
4292                                 value = '' + _value;\r
4293                                 elmA.innerHTML = '' + _value;\r
4294                                 if( focus === true ){\r
4295                                         ELM_INPUT_TEXT.value = '' + value;\r
4296                                 };\r
4297                         };\r
4298                         focus === true && instance.blur();\r
4299                         return value;\r
4300                 };\r
4301                 this.focus = function( e ){\r
4302                         focus = true;\r
4303                         start( apiuser, uiGroup, instance );\r
4304                         elmA.style.display = 'none';\r
4305                         \r
4306                         elmValue.appendChild( ELM_INPUT_TEXT );\r
4307                         ELM_INPUT_TEXT.value = value;\r
4308                         ELM_INPUT_TEXT.focus();\r
4309                         ELM_INPUT_TEXT.select();\r
4310 \r
4311                         return false;\r
4312                 };\r
4313                 this.blur = function( keep ){\r
4314                         var _newValue = ELM_INPUT_TEXT.value,\r
4315                                 _validated = Type.isFunction( validater ) === true ? '' + validater( _newValue ) : _newValue;\r
4316                         _newValue = keep !== 27 ? _validated : value; // 27:ESC\r
4317 \r
4318                         elmValue.removeChild( ELM_INPUT_TEXT );\r
4319                         \r
4320                         elmA.innerHTML     = _newValue;\r
4321                         elmA.style.display = 'block';\r
4322                         \r
4323                         onUpdate && _newValue !== value && AsyncCall.add( apiuser, onUpdate, [ _newValue, value ], instance );\r
4324                         \r
4325                         value = _newValue;\r
4326                         focus = false;\r
4327                         finish( apiuser, uiGroup, instance );\r
4328                 };\r
4329                 this.enabled = function(){\r
4330                         return enabled;\r
4331                 };\r
4332                 this.visible = function( _visible ){\r
4333                         if( Type.isBoolean( _visible ) === true ){\r
4334                                 elmWrapper.style.display = _visible ? '' : 'none';\r
4335                                 visible = _visible;\r
4336                         }\r
4337                         return visible;\r
4338                 };\r
4339                 this.destroy = function(){\r
4340                         if( focus === true ){\r
4341                                 elmValue.removeChild( ELM_INPUT_TEXT );\r
4342                         }\r
4343                         MouseEvent.remove( apiuser, elmWrapper );\r
4344                         \r
4345                         apiuser = uiGroup = elmWrapper = elmValue = elmA = onUpdate = validater = instance = null;\r
4346                 };\r
4347                 instance.value( value );\r
4348                 MouseEvent.add( apiuser, elmWrapper, 'click', instance.focus );\r
4349         };\r
4350         \r
4351         var ButtonClass = function( apiuser, uiGroup, elmWrapper, onUpdate ){\r
4352                 var instance  = this,\r
4353                         focus     = false,\r
4354                         visible   = true,\r
4355                         enabled   = true;\r
4356                 MouseEvent.add( apiuser, elmWrapper, 'click', onClick );\r
4357                 \r
4358                 function onClick(){\r
4359                         focus = true;\r
4360                         // onUpdate();\r
4361                         AsyncCall.add( apiuser, onUpdate, null, instance );\r
4362                         return false;\r
4363                 };\r
4364                 this.focus = function(){\r
4365                         focus = true;\r
4366                         Util.addClass( elmWrapper, 'button-has-focus' );\r
4367                         start( apiuser, uiGroup, instance );\r
4368                 };\r
4369                 this.blur = function( keyCode ){\r
4370                         keyCode === 13 && onClick();\r
4371                         Util.removeClass( elmWrapper, 'button-has-focus' );\r
4372                         focus = false;\r
4373                         finish( apiuser, uiGroup, instance );\r
4374                 };\r
4375                 this.enabled = function( _enabled ){\r
4376                         if( Type.isBoolean( _enabled ) === true && enabled !== _enabled ){\r
4377                                 _enabled === true ? Util.removeClass( elmWrapper, 'button-disabled' ) : Util.addClass( elmWrapper, 'button-disabled' );\r
4378                                 enabled = _enabled;\r
4379                         };\r
4380                         return enabled;\r
4381                 };\r
4382                 this.visible = function( _visible ){\r
4383                         if( Type.isBoolean( _visible ) === true ){\r
4384                                 elmWrapper.style.display = _visible ? '' : 'none';\r
4385                                 visible = _visible;\r
4386                         };\r
4387                         return visible;\r
4388                 };\r
4389                 this.destroy = function(){\r
4390                         MouseEvent.remove( apiuser, elmWrapper );\r
4391                         apiuser = uiGroup = elmWrapper = onUpdate = instance = null;\r
4392                 };\r
4393         };\r
4394 \r
4395         var ComboBoxClass = function( apiuser, uiGroup, elmWrapper, onUpdate ){\r
4396                 var elmBox     = Util.getElementsByClassName( elmWrapper, 'combobox' )[ 0 ],\r
4397                         elmA       = ELM_COMBOBOX.cloneNode( true ),\r
4398                         elmToggle  = Util.getElementsByClassName( elmA, 'combobox-toggle' )[ 0 ],\r
4399                         elmValue   = Util.getElementsByClassName( elmA, 'combobox-value' )[ 0 ].firstChild,\r
4400                         index      = 0,\r
4401                         optionList = [],\r
4402                         instance   = this,\r
4403                         focus      = false,\r
4404                         visible    = true,\r
4405                         enabled    = true,\r
4406                         value;\r
4407                 elmBox.appendChild( elmA );\r
4408 \r
4409                 this.elm = elmBox;\r
4410                 this.focus = function( e ){\r
4411                         MouseEvent.remove( apiuser, elmWrapper, 'click', instance.focus );\r
4412                         focus = true;\r
4413                         elmA.className = 'combobox-has-focus';\r
4414                         start( apiuser, uiGroup, instance );\r
4415                         OptionControl.show( apiuser, instance, optionList );\r
4416                         return false;\r
4417                 };\r
4418                 this.blur = function( keyCode ){\r
4419                         OptionControl.hide( instance );\r
4420                         focus = false;\r
4421                         elmA.className = '';\r
4422                         finish( apiuser, uiGroup, instance );\r
4423                         MouseEvent.add( apiuser, elmWrapper, 'click', instance.focus );\r
4424                 };\r
4425                 this.enabled = function(){\r
4426                         return enabled;\r
4427                 };\r
4428                 this.visible = function( _visible ){\r
4429                         if( Type.isBoolean( _visible ) === true ){\r
4430                                 elmWrapper.style.display = _visible ? '' : 'none';\r
4431                                 visible = _visible;\r
4432                         };\r
4433                         return visible;\r
4434                 };\r
4435                 this.value = function( _value ){\r
4436                         if( Type.isString( _value ) === true && value !== _value ){\r
4437                                 for( var i=0, l = optionList.length, _option; i<l; ++i ){\r
4438                                         _option = optionList[ i ];\r
4439                                         if( _value === _option.value ){\r
4440                                                 value = _value;\r
4441                                                 index = i;\r
4442                                                 elmValue.data = _option.displayValue;\r
4443                                                 if( focus === true ){\r
4444                                                         OptionControl.update( instance, _value );\r
4445                                                 };\r
4446                                                 Type.isFunction( onUpdate ) === true && AsyncCall.add( apiuser, onUpdate, _value, instance );\r
4447                                                 break;\r
4448                                         };\r
4449                                 };\r
4450                         };\r
4451                         return value;\r
4452                 };\r
4453                 this.selectIndex = function(){\r
4454                         return index;\r
4455                 };\r
4456                 this.createOption = function( _displayValue, _value, _isSelected ){\r
4457                         var option = null,\r
4458                                 _option, i;\r
4459                         _value      = _value || _displayValue;\r
4460                         _isSelected = !!_isSelected;\r
4461                         for( i = optionList.length; i; ){\r
4462                                 _option = optionList[ --i ];\r
4463                                 if( _value === _option.value ){\r
4464                                         option = _option;\r
4465                                         break;\r
4466                                 };\r
4467                         };\r
4468                         if( _isSelected === true ){\r
4469                                 index = optionList.length;\r
4470                                 elmValue.data = _displayValue;\r
4471                         };                      \r
4472                         if( option === null ){\r
4473                                 option = new OptionDataClass( _displayValue, _value, _isSelected );\r
4474                                 optionList.push( option );\r
4475                         };\r
4476                 };\r
4477                 this.destroy = function(){\r
4478                         instance.blur();\r
4479                         MouseEvent.remove( apiuser, elmWrapper );\r
4480                         optionList.length = 0;\r
4481                         apiuser = uiGroup = elmWrapper = onUpdate = elmBox = elmA = elmToggle = elmValue = optionList = instance = null;\r
4482                 };\r
4483                 MouseEvent.add( apiuser, elmWrapper, 'click', instance.focus );\r
4484         };\r
4485         var OptionDataClass = function( displayValue, value, isCurrent ){\r
4486                 this.displayValue = displayValue;\r
4487                 this.value        = value || displayValue;\r
4488                 this.current      = isCurrent;\r
4489                 displayValue = value = null;\r
4490         };\r
4491 \r
4492         var OptionControl = ( function(){\r
4493                 var ELM_OPTION_WRAPPER = ( function(){\r
4494                                 var ret = document.createElement( 'div' );\r
4495                                 ret.className = 'option-container';\r
4496                                 return ret;\r
4497                         })(),\r
4498                         ELM_OPTION_ORIGIN = ( function(){\r
4499                                 var ret = document.createElement( 'a' );\r
4500                                 ret.appendChild( document.createTextNode( 'option' ) );\r
4501                                 ret.href = '#';\r
4502                                 return ret;\r
4503                         })();\r
4504 \r
4505                 var OptionClass = function( option ){\r
4506                         this.elm     = ELM_OPTION_ORIGIN.cloneNode( true );\r
4507                         this.data    = option;\r
4508                         this.init();\r
4509                 };\r
4510                 OptionClass.prototype = {\r
4511                         init: function(){\r
4512                                 ELM_OPTION_WRAPPER.appendChild( this.elm );\r
4513                                 this.elm.firstChild.data = this.data.displayValue;\r
4514                                 this.current( this.data.current );\r
4515                                 MouseEvent.add( SUPER_USER_KEY, this.elm, 'mousedown', onOptionSelect );// onclick では 選択ボックス 隠すように body に設定した onmouseup が先に動いてしまう!\r
4516                         },\r
4517                         current: function( _current ){\r
4518                                 this.elm.className = _current === true ? CLASSNAME_COMBOBOX_OPTION_CURRENT : CLASSNAME_COMBOBOX_OPTION;\r
4519                                 this.data.current  = _current;\r
4520                                 currentOption      = _current === true ? this : currentOption;\r
4521                         },\r
4522                         destroy: function(){\r
4523                                 MouseEvent.remove( SUPER_USER_KEY, this.elm );\r
4524                                 Util.removeAllChildren( this.elm );\r
4525                                 ELM_OPTION_WRAPPER.removeChild( this.elm );\r
4526                                 delete this.elm;\r
4527                                 delete this.data;\r
4528                         }\r
4529                 };\r
4530                 \r
4531                 function onOptionSelect( e ){\r
4532                         for( var i = 0, l = OPTION_LIST.length, _option; i < l; ++i){\r
4533                                 _option = OPTION_LIST[ i ];\r
4534                                 if( this === _option.elm ){\r
4535                                         updateCurrrentOption(  _option.data.value, true );\r
4536                                         currentCombobox.blur();\r
4537                                         break;\r
4538                                 };\r
4539                         };\r
4540                         return false;\r
4541                 };\r
4542                 \r
4543                 var OPTION_LIST     = [],\r
4544                         currentCombobox = null,\r
4545                         apiuser,\r
4546                         elm,\r
4547                         currentOption,\r
4548                         currentIndex;\r
4549                 \r
4550                 function updateCurrrentOption( _value, _updateCombobox ){\r
4551                         var _option;\r
4552                         for( var i = OPTION_LIST.length; i; ){\r
4553                                 _option = OPTION_LIST[ --i ];\r
4554                                 if( _value === _option.data.value ){\r
4555                                         currentOption && currentOption.current( false );\r
4556                                         _option.current( true );\r
4557                                         currentOption = _option;\r
4558                                         currentIndex  = i;\r
4559                                         _updateCombobox === true && currentCombobox.value( _value );\r
4560                                         \r
4561                                         break;\r
4562                                 };\r
4563                         };\r
4564                 };\r
4565                 function bodyMouseupHandler(){\r
4566                         currentCombobox.blur();\r
4567                         OptionControl.hide( currentCombobox );\r
4568                 };\r
4569                 function updateWrapperPosition(){\r
4570                         var position = Util.getAbsolutePosition( elm );\r
4571 \r
4572                         ELM_OPTION_WRAPPER.style.cssText = [\r
4573                                         'width:', elm.offsetWidth - 2, 'px;',\r
4574                                         'left:', position.x, 'px;',\r
4575                                         'top:', position.y + elm.offsetHeight, 'px;'\r
4576                                 ].join( '' );\r
4577                 };\r
4578                 function change( e ){\r
4579                         var l   = OPTION_LIST.length,\r
4580                                 i   = currentIndex + ( e.keyCode === 40 ? -1 : 1 );\r
4581                         if( currentCombobox === null || l < 2 ) return;\r
4582                         i = i < 0 ?\r
4583                                         l - 1 :\r
4584                                         i < l ? i : 0;\r
4585                         updateCurrrentOption( OPTION_LIST[ i ].data.value, true );\r
4586                         return false;\r
4587                 };\r
4588                 return {\r
4589                         show: function( _apiuser, _combobox, _optionList ){\r
4590                                 if( currentItem !== _combobox || currentCombobox === _combobox ) return;\r
4591                                 currentCombobox && currentCombobox.blur();\r
4592                                 \r
4593                                 apiuser         = _apiuser;\r
4594                                 currentCombobox = _combobox;\r
4595                                 elm             = _combobox.elm;\r
4596                                 \r
4597                                 for( var i = 0, l = _optionList.length; i<l; ++i ){\r
4598                                         OPTION_LIST.unshift( new OptionClass( _optionList[ i ] ) );\r
4599                                 };\r
4600                                 MouseEvent.add( SUPER_USER_KEY, document, 'mouseup', bodyMouseupHandler );\r
4601                                 KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, change, 38 );\r
4602                                 KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, change, 40 );\r
4603                                 //KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onEnter, 13 );\r
4604                                 //KeyEvent.updateCurrentListener( SUPER_USER_KEY );\r
4605                                 \r
4606                                 body.appendChild( ELM_OPTION_WRAPPER );\r
4607                                 \r
4608                                 updateCurrrentOption( _combobox.value(), false );\r
4609                                 updateWrapperPosition();\r
4610                                 \r
4611                                 SystemTimer.add( SUPER_USER_KEY, updateWrapperPosition, 500 );\r
4612                         },\r
4613                         hide: function( _combobox ){\r
4614                                 if( currentCombobox !== _combobox || currentCombobox === null ) return;\r
4615 \r
4616                                 var _option;\r
4617                                 while( _option = OPTION_LIST.shift() ){\r
4618                                         _option.destroy();\r
4619                                 };\r
4620                                 \r
4621                                 body.removeChild( ELM_OPTION_WRAPPER );\r
4622                                 \r
4623                                 MouseEvent.remove( SUPER_USER_KEY, doc, 'mouseup', bodyMouseupHandler );\r
4624                                 KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, change );\r
4625                                 KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, change );\r
4626                                 //KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onEnter );\r
4627                                 //KeyEvent.updateCurrentListener( apiuser );\r
4628                                 \r
4629                                 SystemTimer.remove( SUPER_USER_KEY, updateWrapperPosition, 500 );\r
4630                                 \r
4631                                 apiuser         = null;\r
4632                                 currentCombobox = null;\r
4633                                 currentOption   = null;\r
4634                                 currentIndex    = 0;                            \r
4635                         },\r
4636                         onEnter: function(){\r
4637                                 currentCombobox.value( currentOption.data.value );\r
4638                                 //currentCombobox.blur();\r
4639                                 //OptionControl.hide( currentCombobox );\r
4640                         },\r
4641                         update: function( _combobox, _value ){\r
4642                                 if( currentCombobox !== _combobox || currentItem !== _combobox ) return;\r
4643                                 if( currentOption.data.value === _value ) return;\r
4644                                 updateCurrrentOption( _value, true );\r
4645                         },\r
4646                         onWindowResize: function( _w, _h ){\r
4647                                 currentCombobox && AsyncCall.add( apiuser, updateWrapperPosition );\r
4648                         }\r
4649                 };\r
4650         })();\r
4651 \r
4652         var UIGroupClass = function( apiuser ){\r
4653                 var self        = this,\r
4654                         itemList    = [],\r
4655                         windowW, windowH;\r
4656 \r
4657                 this.focus = function( _value ){\r
4658                         /*\r
4659                         if( _value === true ){\r
4660                                 if( currentItem ){\r
4661                                         start( apiuser, self, currentItem );\r
4662                                 } else\r
4663                                 if( itemList.length > 0 ){\r
4664                                         start( apiuser, self, itemList[ 0 ] );\r
4665                                 };\r
4666                         } else\r
4667                         if( _value === false ){\r
4668                                 finish( apiuser, self, currentItem );\r
4669                         } else\r
4670                         */\r
4671                         if( _value && Util.getIndex( itemList, _value ) !== -1 ){\r
4672                                 // currentItem = _value;\r
4673                                 currentList = itemList;\r
4674                         };\r
4675                         return currentUi === self; \r
4676                 };\r
4677                 this.blur = function(){\r
4678                         if( currentList === itemList ){\r
4679                                 currentList = null;\r
4680                         };\r
4681                 };\r
4682                 this.createInputText = function( _elmWrapper, _onUpdate, _validater ){\r
4683                         var _elmValue = Util.getElementsByClassName( _elmWrapper, 'editable-value' )[ 0 ];\r
4684                         if( _elmValue ){\r
4685                                 var ret = new InputTextClass( apiuser, self, _elmWrapper, _elmValue, _onUpdate, _validater );\r
4686                                 itemList.push( ret );\r
4687                                 return ret;\r
4688                         }\r
4689                         alert( 'error createInputText' );\r
4690                 };\r
4691                 this.createButton = function( _elm, _onClick ){\r
4692                         var ret = new ButtonClass( apiuser, self, _elm, _onClick );\r
4693                         itemList.push( ret );\r
4694                         return ret;\r
4695                 };\r
4696                 this.createFileInput = function( _elm, _onUpdate, _validater, _elmFileInput ){\r
4697                         var ret = FileInputClass( apiuser, self, _elm, _onUpdate, _validater, _elmFileInput );\r
4698                         itemList.push( ret );\r
4699                         return ret;\r
4700                 };\r
4701                 this.createCombobox = function( _elm, _onUpdate, _optionList ){\r
4702                         var ret = new ComboBoxClass( apiuser, self, _elm, _onUpdate, _optionList );\r
4703                         itemList.push( ret );\r
4704                         return ret;\r
4705                 };\r
4706                 this.createCheckBox = function(){\r
4707                         \r
4708                 };\r
4709                 this.createRadio = function(){\r
4710                         \r
4711                 };\r
4712                 this.createSlider = function(){\r
4713                         \r
4714                 };\r
4715                 this.destroy = function(){\r
4716                         var _item;\r
4717                         while( _item = itemList.shift() ){\r
4718                                 _item.destroy();\r
4719                         };\r
4720                         if( currentUi === this ){\r
4721                                 currentItem = null;\r
4722                                 currentUi   = null;\r
4723                                 currentUser = null;\r
4724                                 currentList = null;\r
4725                         };\r
4726                         apiuser = self = null;\r
4727                 };\r
4728         };\r
4729         \r
4730         function start( _apiuser, _uigroup, _item ){\r
4731                 if( currentItem !== _item ){\r
4732                         currentUi !== _uigroup && currentUi && currentUi.blur();\r
4733                         \r
4734                         currentItem !== null && currentItem.blur();\r
4735                         \r
4736                         currentUser = _apiuser;\r
4737                         currentUi   = _uigroup;\r
4738                         currentItem = _item;\r
4739                         \r
4740                         _uigroup.focus( _item );\r
4741                         \r
4742                         // if( currentUser !== _apiuser ) {\r
4743                                 KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 13 );\r
4744                                 KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 27 );\r
4745                                 KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown,  9 );\r
4746                                 KeyEvent.updateCurrentListener( SUPER_USER_KEY );\r
4747                         // };\r
4748                 };\r
4749         }\r
4750         function finish( _apiuser, _uigroup, _item ){\r
4751                 if( currentItem === _item ){\r
4752                         _uigroup.blur();\r
4753                         \r
4754                         currentUser = null;\r
4755                         currentUi   = null;\r
4756                         currentItem = null;\r
4757                         currentList = null;\r
4758                         \r
4759                         KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 13 );\r
4760                         KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 27 );\r
4761                         KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown,  9 );\r
4762                         KeyEvent.updateCurrentListener( _apiuser );\r
4763                 };\r
4764         };\r
4765 \r
4766         function onKeyDown( e ){\r
4767                 if( currentItem === null ) return true;\r
4768                 var keyCode = e.keyCode,\r
4769                         _index  = Util.getIndex( currentList, currentItem );\r
4770                 if( keyCode === 13 || keyCode === 27 || keyCode === 9 || keyCode === 18 || e.altKey === true ){ // 13.return 27.esc 9.tab 18.alt\r
4771                         keyCode === 9  && tabShift( _index, e.shiftKey === true ? -1 : 1 );\r
4772                         keyCode === 13 && currentItem instanceof ComboBoxClass && OptionControl.onEnter();\r
4773                         keyCode === 13 && tabShift( _index, 1 );                        \r
4774                         currentItem && currentItem.blur( keyCode );\r
4775                 };\r
4776                 return false;\r
4777         };\r
4778 \r
4779         function tabShift( _index, _way ){\r
4780                 var l = currentList.length,\r
4781                         i = _index + _way,\r
4782                         _item;\r
4783                 if( l < 2 ) return;\r
4784                 while( i !== _index ){\r
4785                         i = i < 0 ?\r
4786                                 l - 1 :\r
4787                                 i < l ? i : 0; // 0 < i < l\r
4788                         _item = currentList[ i ];\r
4789                         if( _item.enabled() === true && _item.visible() === true ){\r
4790                                 AsyncCall.add( currentUser, _item.focus, null, _item );\r
4791                                 return;\r
4792                         };\r
4793                         i += _way;\r
4794                 };\r
4795         };\r
4796         \r
4797         return {\r
4798                 createUIGroup: function( _apiuser ){\r
4799                         var _uid  = _apiuser.getUID(),\r
4800                                 _list = UI_LIST[ _uid ],\r
4801                                 _ui   = new UIGroupClass( _apiuser );\r
4802                         if( Type.isArray( _list ) === false ){\r
4803                                 _list = UI_LIST[ _uid ] = [];\r
4804                         }\r
4805                         _list.push( _ui );\r
4806                         return _ui;\r
4807                 },\r
4808                 onWindowResize: function( w, h ){\r
4809                         windowW = w;\r
4810                         windowH = h;\r
4811                         currentItem instanceof ComboBoxClass && OptionControl.onWindowResize( w, h );\r
4812                 },\r
4813                 onCurrentApplicationChange: function( _apiuser ){\r
4814                         currentList = UI_LIST[ _apiuser.getUID() ];\r
4815                 },\r
4816                 onApplicationShutdown: function( _apiuser ){\r
4817                         KeyEvent.remove( _apiuser );\r
4818                 },\r
4819                 onSystemShutdown: function(){\r
4820                         \r
4821                 }\r
4822         }\r
4823 })();\r
4824 \r
4825 \r
4826 var Finder = ( function(){\r
4827         var HTML_FINDER_ICON = ( function(){\r
4828                 return ( UA.isIE === true && UA.ieVersion < 8 ?\r
4829                 [\r
4830                         '<div class="finder-icon fnder-icon-ie7">',\r
4831                                 '<a href="#" class="finder-icon-main">',\r
4832                                         '<span class="finder-icon-handle"></span>',\r
4833                                         '<span class="finder-icon-thumbnail"></span>',\r
4834                                         '<span class="finder-icon-cell finder-icon-ie-filename">',\r
4835                                                 '<span class="finder-icon-vertical-middle-outer">',\r
4836                                                         '<span class="finder-icon-vertical-middle-inner">',\r
4837                                                                 '<span class="finder-icon-filename break-word">file name</span>',\r
4838                                                         '</span>',\r
4839                                                 '</span>',\r
4840                                         '</span>',\r
4841                                         '<span class="finder-icon-cell finder-icon-ie-summary">',\r
4842                                                 '<span class="finder-icon-vertical-middle-outer">',\r
4843                                                         '<span class="finder-icon-vertical-middle-inner">',\r
4844                                                                 '<span class="finder-icon-summary break-word">file descriptiion</span>',\r
4845                                                         '</span>',\r
4846                                                 '</span>',\r
4847                                         '</span>',\r
4848                                 '</a>',\r
4849                                 '<div class="finder-icon-console">',\r
4850                                         '<a href="#" class="finder-icon-console-action"></a>',\r
4851                                         '<a href="#" class="finder-icon-console-editor-apps"></a>',\r
4852                                         '<a href="#" class="finder-icon-console-viewer-apps"></a>',\r
4853                                 '</div>',\r
4854                         '</div>'\r
4855                 ] :\r
4856                 [\r
4857                         '<div class="finder-icon fnder-icon-modern">',\r
4858                                 '<span class="finder-icon-handle"></span>',\r
4859                                 '<span class="finder-icon-thumbnail"></span>',\r
4860                                 '<span class="finder-icon-filename break-word">file name</span>',\r
4861                                 '<span class="finder-icon-summary break-word">file descriptiion</span>',\r
4862                                 '<div class="finder-icon-console">',\r
4863                                         '<a href="#" class="finder-icon-console-action"></a>',\r
4864                                         '<a href="#" class="finder-icon-console-editor-apps"></a>',\r
4865                                         '<a href="#" class="finder-icon-console-viewer-apps"></a>',\r
4866                                 '</div>',\r
4867                         '</div>'\r
4868                 ] ).join( '' );\r
4869         })();\r
4870 \r
4871         \r
4872         var FINDER_ARRAY                    = [],\r
4873                 ELM_ORIGIN_FINDER_LOCATION_ITEM = Util.pullHtmlAsTemplete( '<li id="templete-finder-location-item" class="finder-location-item"><a href="#"></a></li>'),\r
4874                 ELM_ORIGIN_FINDER_ICON          = Util.pullHtmlAsTemplete( HTML_FINDER_ICON ),\r
4875                 ELM_ORIGIN_CONTAINER            = Util.pullHtmlAsTemplete( [\r
4876                         '<div id="templete-finder-container" class="finder-container">',\r
4877                                 '<div class="finder-header">',\r
4878                                         '<ul class="finder-location"></ul>',\r
4879                                         '<div class="finder-sidebar-switch button">side</div>',\r
4880                                         '<div class="finder-style-switch button">style</div>',\r
4881                                         '<div class="finder-action-switch button">action</div>',\r
4882                                 '</div>',\r
4883                                 '<div class="finder-body"></div>',\r
4884                         '</div>'\r
4885                 ].join( '' ) ),\r
4886                 ICON_HEIGHT                     = Util.getElementSize( ELM_ORIGIN_FINDER_ICON ).height,\r
4887                 ICON_CLASSNAME                  = 'finder-icon-thumbnail',\r
4888                 FINDER_ICON_POOL                = [],\r
4889                 BREAD_OBJECT_POOL               = [];\r
4890         \r
4891         var FinderIconClass = function(){\r
4892                 var elmContainer,\r
4893                         ELM_WRAPPER       = ELM_ORIGIN_FINDER_ICON.cloneNode( true),\r
4894                         ELM_THUMBNAIL     = Util.getElementsByClassName( ELM_WRAPPER, ICON_CLASSNAME )[ 0 ],\r
4895                         ELM_FILENAME      = Util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-filename' )[ 0 ],\r
4896                         ELM_DESCRIPTION   = Util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-summary' )[ 0 ],\r
4897                         ELM_EDITOR_BUTTON = Util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-console-editor-apps' )[ 0 ],\r
4898                         ELM_VIEWER_BUTTON = Util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-console-viewer-apps' )[ 0 ],\r
4899                         ELM_ACTION_BUTTON = Util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-console-action' )[ 0 ],\r
4900                         instansce         = this,\r
4901                         file, w, index, style,\r
4902                         onDownCallback, onEditorCallback, onViewerCallback, onActionCallback,\r
4903                         viewerList, editorList;\r
4904                 \r
4905                 MouseEvent.add( SUPER_USER_KEY, ELM_WRAPPER,       'click', onDownClick );\r
4906                 MouseEvent.add( SUPER_USER_KEY, ELM_EDITOR_BUTTON, 'click', onEditorClick );\r
4907                 MouseEvent.add( SUPER_USER_KEY, ELM_VIEWER_BUTTON, 'click', onViwerClick );\r
4908                 MouseEvent.add( SUPER_USER_KEY, ELM_ACTION_BUTTON, 'click', onActionClick );\r
4909                 function onDownClick(){\r
4910                         onDownCallback( index );\r
4911                         return false;\r
4912                 }\r
4913                 function onEditorClick(){\r
4914                         onEditorCallback( file, editorList[ 0 ] );\r
4915                         return false;\r
4916                 }\r
4917                 function onViwerClick(){\r
4918                         onViewerCallback( file, viewerList[ 0 ] );\r
4919                         return false;\r
4920                 }\r
4921                 function onActionClick(){\r
4922                         onActionCallback( file );\r
4923                         return false;\r
4924                 }\r
4925                 function draw(){\r
4926                         var _thumb = file.getThumbnail();\r
4927                         if( _thumb.image ){\r
4928                                 ELM_THUMBNAIL.className = ICON_CLASSNAME + ' has-thumbnail';\r
4929                                 ELM_THUMBNAIL.style.backgroundImage = [ 'url(', _thumb.image, ')'].join( '');\r
4930                         } else {\r
4931                                 ELM_THUMBNAIL.className = ICON_CLASSNAME + ' ' + _thumb.className;\r
4932                                 ELM_THUMBNAIL.style.backgroundImage = '';\r
4933                         }\r
4934                         ELM_FILENAME.firstChild.data = file.getName();\r
4935                         ELM_DESCRIPTION.firstChild.data = file.getSummary();\r
4936                         \r
4937                         if( Type.isArray( viewerList ) === true && viewerList.length > 0 ){\r
4938                                 ELM_VIEWER_BUTTON.style.display = '';\r
4939                         } else {\r
4940                                 ELM_VIEWER_BUTTON.style.display = 'none';\r
4941                         };\r
4942                         if( Type.isArray( editorList ) === true && editorList.length > 0 ){\r
4943                                 ELM_EDITOR_BUTTON.style.display = '';\r
4944                         } else {\r
4945                                 ELM_EDITOR_BUTTON.style.display = 'none';\r
4946                         };\r
4947                 }\r
4948                 function resize(){\r
4949                         // ELM_WRAPPER.style.top = (index * ICON_HEIGHT) +'px';\r
4950                 }\r
4951                 function onCollect(){\r
4952                         elmContainer.removeChild( ELM_WRAPPER );\r
4953                         elmContainer = null;\r
4954                         FINDER_ICON_POOL.push( instansce );\r
4955                 }\r
4956                 \r
4957                 this.init = function( _file, _elmContainer, _w, _index, _style, _onDownCallback, _onEditorCallback, _onViewerCallback, _onActionCallback ){\r
4958                         if( elmContainer !== _elmContainer){\r
4959                                 _elmContainer.appendChild( ELM_WRAPPER );\r
4960                                 elmContainer = _elmContainer;\r
4961                         }\r
4962                         if( file !== _file ){\r
4963                                 file && file.destroy();\r
4964                                 file       = _file;\r
4965                                 viewerList = file.viewerApplicationList();\r
4966                                 editorList = file.editorApplicationList();\r
4967                                 draw();\r
4968                         }\r
4969                         if( index !== _index){\r
4970                                 index = _index;\r
4971                                 resize();\r
4972                         }\r
4973                         onDownCallback   = _onDownCallback;\r
4974                         onEditorCallback = _onEditorCallback;\r
4975                         onViewerCallback = _onViewerCallback;\r
4976                         onActionCallback = _onActionCallback;\r
4977                 };\r
4978                 this.elm = ELM_WRAPPER,\r
4979                 this.index = function( _index){ \r
4980                         return index;\r
4981                 };\r
4982                 this.style = function( _style ){\r
4983                         return style;\r
4984                 };\r
4985                 this.onResize = function( w ){\r
4986                         \r
4987                 };\r
4988                 this.destroy = function(){\r
4989                         //MouseEvent.remove( SUPER_USER_KEY, ELM_WRAPPER,       'click', onDownClick );\r
4990                         //MouseEvent.remove( SUPER_USER_KEY, ELM_EDITOR_BUTTON, 'click', onEditorClick );\r
4991                         //MouseEvent.remove( SUPER_USER_KEY, ELM_VIEWER_BUTTON, 'click', onViwerClick );\r
4992                         //MouseEvent.remove( SUPER_USER_KEY, ELM_ACTION_BUTTON, 'click', onActionClick );\r
4993                         elmContainer.removeChild( ELM_WRAPPER );\r
4994                         file && file.destroy();\r
4995                         file = elmContainer = onDownCallback = onEditorCallback = onViewerCallback = onActionCallback = viewerList = editorList = null;\r
4996                         FINDER_ICON_POOL.push( instansce );\r
4997                 };\r
4998         }\r
4999         function updateIconPosition( _style, _w, _index, _elm ){\r
5000                 \r
5001         }\r
5002         var BreadcrumbClass = function(){\r
5003                 var elmContainer,\r
5004                         ELM_WRAPPER  = ELM_ORIGIN_FINDER_LOCATION_ITEM.cloneNode( true ),\r
5005                         ELM_FILENAME = ELM_WRAPPER.getElementsByTagName( 'a' )[ 0 ],\r
5006                         instansce    = this,\r
5007                         file, w, index,\r
5008                         callback;\r
5009                 MouseEvent.add( SUPER_USER_KEY, ELM_WRAPPER, 'click', onClick );\r
5010                 function draw(){\r
5011                         ELM_FILENAME.className = 'file-icon-' + file.getType();\r
5012                         ELM_FILENAME.innerHTML = file.getName();\r
5013                 }\r
5014                 function resize( index ){\r
5015                         ELM_WRAPPER.style.left = ( index * 90 ) + 'px';\r
5016                 }\r
5017                 function onClick(){\r
5018                         callback( index );\r
5019                         return false;\r
5020                 }\r
5021                 this.init = function( _file, _elmContainer, _index, _callback ){\r
5022                         instansce;\r
5023                         if( elmContainer !== _elmContainer ){\r
5024                                 _elmContainer.appendChild( ELM_WRAPPER );\r
5025                                 elmContainer = _elmContainer;\r
5026                         }\r
5027                         if( file !== _file){\r
5028                                 file = _file;\r
5029                                 draw();\r
5030                         }\r
5031                         if( index !== _index){\r
5032                                 index = _index;\r
5033                                 resize( index );\r
5034                         }\r
5035                         callback = _callback;\r
5036                 };\r
5037                 this.elm = ELM_WRAPPER;\r
5038                 this.index = function( _index ){\r
5039                         return index;\r
5040                 };\r
5041                 this.onResize = function( w ){\r
5042                         \r
5043                 };\r
5044                 this.destroy = function(){\r
5045                         elmContainer.removeChild( ELM_WRAPPER );\r
5046                         file = elmContainer = null;\r
5047                         BREAD_OBJECT_POOL.push( this );\r
5048                 };\r
5049         }\r
5050         \r
5051         var FinderClass = function( application, elmRoot, tree, header, footer, onSelect, viewerOption, editorOption ){\r
5052                 var ICON_ARRAY       = [],\r
5053                         BREAD_ARRAY      = [],\r
5054                         elmContainer     = ELM_ORIGIN_CONTAINER.cloneNode( true ),\r
5055                         elmLocation      = elmContainer.getElementsByTagName( 'ul' )[ 0 ],\r
5056                         nodesDiv         = elmContainer.getElementsByTagName( 'div' ),\r
5057                         elmSidebarButton = nodesDiv[ 1 ],\r
5058                         elmStyleButton   = nodesDiv[ 2 ],\r
5059                         elmActionButton  = nodesDiv[ 3 ],\r
5060                         elmBody          = nodesDiv[ nodesDiv.length -1 ],\r
5061                         headX,\r
5062                         headY,\r
5063                         headH            = Util.getElementSize( nodesDiv[ 0 ] ).height,\r
5064                         bodyY,\r
5065                         currentFile      = null,\r
5066                         breadW           = 90,\r
5067                         size             = Util.getElementSize( ELM_ORIGIN_FINDER_ICON ),\r
5068                         iconW            = size.width,\r
5069                         iconH            = size.height,\r
5070                         style            = 0,\r
5071                         w, h, bodyH,\r
5072                         instance         = this;\r
5073                         \r
5074                 tree.addTreeEventListener( Const.TREE.EVENT.UPDATE, draw );\r
5075                 elmRoot.appendChild( elmContainer );\r
5076                 \r
5077                 function draw( _w, _h ){\r
5078                         w = Type.isFinite( _w ) === true ? _w : w;\r
5079                         h = Type.isFinite( _h ) === true ? _h : h;\r
5080                         bodyH = h - headH;\r
5081                         var     l = tree.hierarchy() + 1,\r
5082                                 m = BREAD_ARRAY.length,\r
5083                                 _file, _bread;\r
5084                         for( var i=0; i<l; ++i ){\r
5085                                 _file = i !== l-1 ? tree.getParentFileAt( i ) : tree.getCurrentFile();\r
5086                                 if( i < m ){\r
5087                                         BREAD_ARRAY[ i ].init( _file, elmLocation, i, onHeadClick );\r
5088                                 } else {\r
5089                                         BREAD_ARRAY.push( getBreadcrumb( _file, elmLocation, i, onHeadClick ));\r
5090                                 }\r
5091                         };\r
5092                         while( l < BREAD_ARRAY.length ){\r
5093                                 BREAD_ARRAY.pop().destroy();\r
5094                         };\r
5095                         \r
5096                         l = _file.getChildFileLength();\r
5097                         m = ICON_ARRAY.length;\r
5098 \r
5099                         for( i=0; i<l; ++i ){\r
5100                                 if( i < m ){\r
5101                                         ICON_ARRAY[ i ].init( _file.getChildFileByIndex( i ), elmBody, w, i, style, onDown, onEditor, onViwer, onAction );\r
5102                                 } else {\r
5103                                         ICON_ARRAY.push( getFinderIcon( _file.getChildFileByIndex( i ), elmBody, _w, i, style, onDown, onEditor, onViwer, onAction ));\r
5104                                 }\r
5105                         };\r
5106                         if( _file.getState() === Const.FILE.STATE.LOADING ){\r
5107                                 elmBody.className = 'finder-body loading';\r
5108                         } else {\r
5109                                 elmBody.className = 'finder-body';\r
5110                         };\r
5111                         \r
5112                         elmBody.style.height = bodyH + 'px';\r
5113                         \r
5114                         while( l < ICON_ARRAY.length && ICON_ARRAY.length > 0 ){\r
5115                                 ICON_ARRAY.pop().destroy();\r
5116                         };\r
5117                 };\r
5118                 \r
5119                 function onHeadClick( i ){\r
5120                         var l = BREAD_ARRAY.length - 1;\r
5121                         if( i < l){\r
5122                                 var _file = tree.getParentFileAt( i);\r
5123                                 if( _file !== null){\r
5124                                         tree.up( i);\r
5125                                         draw( w, h );\r
5126                                 };\r
5127                         };\r
5128                 };\r
5129                 function onDown( i ){\r
5130                         if( i < ICON_ARRAY.length ){\r
5131                                 var _file = tree.getCurrentFile().getChildFileByIndex( i );\r
5132                                 if( _file !== null && ( _file.getChildFileLength() !== -1 || _file.getType() === Const.FILE.TYPE.FOLDER )){\r
5133                                         tree.down( i );\r
5134                                         draw( w, h );\r
5135                                 } else {\r
5136                                         Type.isFunction( onSelect ) === true && onSelect( _file );\r
5137                                 };\r
5138                                 _file.destroy();\r
5139                         };\r
5140                 };\r
5141                 function onEditor( _file, _app, editorOption ){\r
5142                         _app.boot( _file, editorOption );\r
5143                 };\r
5144                 function onViwer( _file, _app ){\r
5145                         _app.boot( _file, viewerOption );\r
5146                 };\r
5147                 function onAction( _file ){\r
5148 \r
5149                 };\r
5150                 this.MIN_WIDTH     = 240;\r
5151                 this.MIN_HEIGHT    = 240;\r
5152                 this.onInit = function(){\r
5153                         var position = Util.getAbsolutePosition( elmLocation );\r
5154                         headX = position.x;\r
5155                         headY = position.y;\r
5156                         bodyY = Util.getAbsolutePosition( elmBody ).y;\r
5157                 };\r
5158                 this.onPaneResize = function( _w, _h ){\r
5159                         draw( _w, _h );                 \r
5160                         \r
5161                         w = _w;\r
5162                         h = _h;\r
5163                         elmBody.style.height = ( _h - headH ) + 'px';\r
5164                         \r
5165                         for( var i = ICON_ARRAY.length; i; ){\r
5166                                 ICON_ARRAY[ --i ].onResize( _w );\r
5167                         };\r
5168                 };\r
5169                 this.destroy = function(){\r
5170                         tree.removeTreeEventListener( Const.TREE.EVENT.UPDATE, draw );\r
5171                         \r
5172                         while( BREAD_ARRAY.length > 0 ){\r
5173                                 BREAD_ARRAY.shift().destroy();\r
5174                         };\r
5175                         while( ICON_ARRAY.length > 0 ){\r
5176                                 ICON_ARRAY.shift().destroy();\r
5177                         };\r
5178                         \r
5179                         FINDER_ARRAY.splice( Util.getIndex( FINDER_ARRAY, instance ), 1 );\r
5180                 };\r
5181         };\r
5182         FinderClass.prototype = new AbstractBasicPane();\r
5183         \r
5184         function getFinderIcon( _file, _elmContainer, w, index, style, onDown, onEditor, onViwer, onAction ){\r
5185                 var _icon;\r
5186                 if( FINDER_ICON_POOL.length > 0){\r
5187                         _icon = FINDER_ICON_POOL.shift();\r
5188                 } else {\r
5189                         _icon = new FinderIconClass();\r
5190                 };\r
5191                 _icon.init( _file, _elmContainer, w, index, style, onDown, onEditor, onViwer, onAction );\r
5192                 return _icon;\r
5193         };\r
5194         \r
5195         function getBreadcrumb( _file, _elmContainer, index, callback ){\r
5196                 var _bread;\r
5197                 if( BREAD_OBJECT_POOL.length > 0 ){\r
5198                         _bread = BREAD_OBJECT_POOL.shift();\r
5199                 } else {\r
5200                         _bread = new BreadcrumbClass();\r
5201                 };\r
5202                 _bread.init( _file, _elmContainer, index, callback );\r
5203                 return _bread;\r
5204         };\r
5205 \r
5206         return {\r
5207                 init: function(){\r
5208                         \r
5209                 },\r
5210                 create: function( _application, _elmTarget, _tree, _header, _footer, _onSelect, _viewerOption, _editorOption ){\r
5211                         //if( Application.isApplicationInstance( _application ) === false ) return;\r
5212                         \r
5213                         var _finder = new FinderClass( _application, _elmTarget, _tree, _header, _footer, _onSelect, _viewerOption, _editorOption );\r
5214                         _finder.init();\r
5215                         FINDER_ARRAY.push( _finder );\r
5216                         return _finder;\r
5217                 },\r
5218                 registerFinderHead: function(){\r
5219                         \r
5220                 },\r
5221                 registerFinderPane: function( _finderPane ){\r
5222                         \r
5223                 },\r
5224                 isFinderInstance: function( _finder ){\r
5225                         return _finder instanceof FinderClass;\r
5226                 },\r
5227                 isFinderPaneInstance: function(){\r
5228                         \r
5229                 },\r
5230                 isFinderHeadInstance: function(){\r
5231                 }\r
5232         };\r
5233 })();\r
5234 \r
5235 \r
5236 /*\r
5237  * -- len, %\r
5238  * marginBottom, marginLeft, marginRight, marginTop, margin\r
5239  * padding, paddingBottom, paddingLeft, paddingRight, paddingTop\r
5240  * fontSize, textIndent\r
5241  * height, width\r
5242  * bottom, left, right, top                     (len, %)\r
5243  *\r
5244  * -- len\r
5245  * borderBottomWidth, borderLeftWidth, borderRightWidth, borderTopWidth, borderWidth,\r
5246  * letterSpacing\r
5247  *\r
5248  * -- color\r
5249  * backgroundColor\r
5250  * borderBottomColor, borderLeftColor, borderRightColor, borderTopColor, borderColor\r
5251  * color\r
5252  *\r
5253  * -- special\r
5254  * clip                 rect(0px, 40px, 40px, 0px);\r
5255  * backgroundPosition   (len, %)\r
5256  * opacity\r
5257  * lineHeight           (len, %, num)\r
5258  * zIndex                       ( order )\r
5259  */\r
5260 \r
5261 var DHTML = ( function(){\r
5262         \r
5263         var ANIMATION_TICKET_ARRAY = [],\r
5264                 fpms                   = 50,\r
5265                 round                  = Math.round,\r
5266                 cround                 = function ( v ){ return round( v * 100 ) / 100 };\r
5267         \r
5268         function startAnimation( _elm, _cssObject, _onComplete, _onEnterFrame, _numFrames ){\r
5269                 var _ticket, i = ANIMATION_TICKET_ARRAY.length;\r
5270                 for( ; i; ){\r
5271                         _ticket = ANIMATION_TICKET_ARRAY[ --i ];\r
5272                         if( _ticket.elm === _elm ){\r
5273                                 return;\r
5274                         };\r
5275                 };\r
5276                 \r
5277                 var _currentValues     = [],\r
5278                         _offsetValues      = [],\r
5279                         _endValues         = [],\r
5280                         _targetProperties  = [],\r
5281                         _units             = [];\r
5282                 var target, current,\r
5283                         inlineStyle    = CSS.getInlineStyle( _elm ),\r
5284                         currentStyle   = CSS.getWrappedStyle( _elm ),\r
5285                         targetStyle    = CSS.getWrappedStyle( _elm, _cssObject );\r
5286                         targetStyle.pxPerEm = currentStyle.get( 'fontSize' )._toPx();\r
5287                 for( var p in _cssObject ){\r
5288                         p       = Util.camelize( p );\r
5289                         target  = targetStyle.get( p );\r
5290                         current = currentStyle.get( p );\r
5291 \r
5292                         if( target.isValid() === false || current.isValid() === false || current.equal( target ) !== false ){\r
5293                                 target.clear();\r
5294                                 current.clear();\r
5295                                 continue;\r
5296                         };\r
5297                         \r
5298                         current.convert( target );\r
5299                         // alert( current.getValue() + ' , ' + target.getValue() )\r
5300                         _currentValues.push( current.getValue() );\r
5301                         _offsetValues.push( current.getOffset( target ) );\r
5302                         _endValues.push( target.getValue() );\r
5303                         _targetProperties.push( p );\r
5304                         _units.push( target.getUnit() );\r
5305 \r
5306                         // IE has trouble with opacity if it does not have layout\r
5307                         // Force it by setting the zoom level                   \r
5308                         if( p === 'opacity' && SPECIAL.hasLayout ){\r
5309                                 if( SPECIAL.hasLayout( _elm ) === false ) inlineStyle.zoom = 1;\r
5310                                 inlineStyle.filter = current.getValueText();\r
5311                         } else {\r
5312                                 inlineStyle[ p ]   = current.getValueText();\r
5313                         };\r
5314                         \r
5315                         target.clear();\r
5316                         current.clear();\r
5317                 };\r
5318                 \r
5319                 var i, _cssTextArray = [];\r
5320                 for( i = 0; i < _numFrames; ++i ){\r
5321                         if( i < _numFrames - 1 ){\r
5322                                 tickValue( _currentValues, _offsetValues, _numFrames );\r
5323                                 createCssText( _currentValues, _targetProperties, targetStyle, inlineStyle, _cssTextArray );\r
5324                         } else {\r
5325                                 createCssText( _endValues, _targetProperties, targetStyle, inlineStyle, _cssTextArray );\r
5326                         };\r
5327                 };\r
5328                 \r
5329                 ANIMATION_TICKET_ARRAY.push( new AnimationTaskClass(\r
5330                         _elm, _cssTextArray,\r
5331                         Type.isFunction( _onComplete ) === true   ? _onComplete   : null,\r
5332                         Type.isFunction( _onEnterFrame ) === true ? _onEnterFrame : null,\r
5333                         _numFrames\r
5334                 ) );\r
5335                 \r
5336                 currentStyle.clear();\r
5337                 targetStyle.clear();            \r
5338                 SystemTimer.add( SUPER_USER_KEY, onEnterFrame, 1000 / fpms );\r
5339         };\r
5340         \r
5341         function tickValue( current, offset, numFrames ){\r
5342                 if( Type.isArray( current ) === true ){\r
5343                         var ret, i = current.length;\r
5344                         for( ; i; ){\r
5345                                 --i;\r
5346                                 ret = tickValue( current[ i ], offset[ i ], numFrames );\r
5347                                 if( Type.isNumber( ret ) === true ) current[ i ] = ret;\r
5348                         };\r
5349                 } else {\r
5350                         return current + offset / numFrames;\r
5351                 };\r
5352         };\r
5353         function createCssText( update, props, style, inline, cssTextArray ){\r
5354                 var prop;\r
5355                 for( var i = props.length; i; ){\r
5356                         prop = style.get( props[ --i ] );\r
5357                         prop.setValue( update[ i ] );\r
5358                         inline[ Util.uncamelize( prop.name ) ] = prop.getValueText();\r
5359                         //if( prop.name === 'backgroundColor' ) alert( prop.getValueText() + '|' + update[ i ].join( ',') )\r
5360                         prop.clear();\r
5361                 };\r
5362                 cssTextArray.push( CSS.toCssText( inline ) );\r
5363         };\r
5364         \r
5365         function onEnterFrame(){\r
5366                 var _ticket, l,\r
5367                         i = 0;\r
5368                 while( i < ANIMATION_TICKET_ARRAY.length ){\r
5369                         _ticket = ANIMATION_TICKET_ARRAY[ i ];\r
5370                         l       = _ticket.cssTexts.length;\r
5371                         _ticket.elm.style.cssText = _ticket.cssTexts.shift();\r
5372                         if( l === 1 ){\r
5373                                 _ticket.onComplete && _ticket.onComplete();\r
5374                                 delete _ticket.elm;\r
5375                                 delete _ticket.cssTexts;\r
5376                                 delete _ticket.onComplete;\r
5377                                 delete _ticket.onEnterFrame;\r
5378                                 delete _ticket.numFrame;\r
5379                                 ANIMATION_TICKET_ARRAY.splice( i, 1 );\r
5380                         } else {\r
5381                                 _ticket.onEnterFrame && _ticket.onEnterFrame( l / _ticket.numFrame );\r
5382                                 ++i;\r
5383                         };\r
5384                 };\r
5385                 if( ANIMATION_TICKET_ARRAY.length === 0 ){\r
5386                         SystemTimer.remove( SUPER_USER_KEY, onEnterFrame );\r
5387                 };\r
5388         };\r
5389         \r
5390         var AnimationTaskClass = function( elm, cssTexts, onEnterFrame, onComplete, numFrame ){\r
5391                 this.elm          = elm;\r
5392                 this.cssTexts     = cssTexts;\r
5393                 this.onEnterFrame = onEnterFrame;\r
5394                 this.onComplete   = onComplete;\r
5395                 this.numFrame     = numFrame;\r
5396         };\r
5397         \r
5398         var VisualEffectClass = function( elm ){\r
5399                 var isHtmlElement;\r
5400                 \r
5401                 function registerAnime( _cssObject, _onComplete, _onEnterFrame, _time ){\r
5402                         var _numFrames = Math.floor( _time / fpms );\r
5403                         startAnimation( elm, _cssObject, _onComplete, _onEnterFrame, _numFrames );\r
5404                 };\r
5405                 function startFadeIn(){\r
5406                         \r
5407                 };\r
5408                 function startFadeOut(){\r
5409                         \r
5410                 };\r
5411                 function update( _x, _y, _w, _h ){\r
5412                         var _cssText = elm.style.cssText;\r
5413                         \r
5414                 };\r
5415                 \r
5416                 this.anime   = registerAnime;\r
5417                 this.fadeIn  = startFadeIn;\r
5418                 this.fadeOut = startFadeOut;\r
5419                 this.update  = update;\r
5420         };\r
5421         \r
5422         return {\r
5423                 create: function( application, _elm ){\r
5424                         return new VisualEffectClass( _elm );\r
5425                 },\r
5426                 isInstanceOfVisualEffect: function( _instance){\r
5427                         return _instance instanceof VisualEffectClass;\r
5428                 }\r
5429         }\r
5430 })();\r
5431 \r
5432 \r
5433 /* --------------------------------------------\r
5434  * \r
5435  */\r
5436 \r
5437         Application.onCurrentApplicationChange( SUPER_USER_KEY );\r
5438         \r
5439         SERVICE_LIST.push( MouseEvent );\r
5440         \r
5441         new EventTicketClass( window, 'unload', function(){\r
5442                 var _service;\r
5443                 while( SERVICE_LIST.length > 0 ){\r
5444                         _service = SERVICE_LIST.shift();\r
5445                         Type.isFunction( _service.onSystemShutdown ) === true && _service.onSystemShutdown();\r
5446                 }\r
5447         });\r
5448         // beforeunload\r
5449 \r
5450 \r
5451 /* ---------------------------------------------\r
5452  * broadcast to global\r
5453  */\r
5454         window.gOS = {};\r
5455         \r
5456         gOS.registerApplication = Application.register;\r
5457         gOS.registerDriver      = File.registerDriver;\r
5458         \r
5459 })( window, document );\r
5460 \r
5461 \r
5462 \r
5463 gOS.PageApplicationRef = null;\r
5464 gOS.PageApplicationClass = function(){\r
5465         var app      = this;\r
5466         this.bgColor = '#FFF';\r
5467         this.onOpen = function(){\r
5468                 var button = document.getElementById( 'server-page-close-button' );\r
5469                 if( button ){\r
5470                         app.addEventListener( button, 'click', gOS.PageApplicationRef.shutdown );\r
5471                 };\r
5472                 var msg = document.getElementById( 'esc-msg' );\r
5473                 if( msg ){\r
5474                         app.addEventListener( msg, 'click', gOS.PageApplicationRef.shutdown );\r
5475                 };\r
5476                 app.addKeyEventListener( 'keydown', gOS.PageApplicationRef.shutdown, 27 ); // 27.esc\r
5477         };\r
5478 };