2 * http://pettanr.sourceforge.jp/test/type.html
\r
5 isObject : function(v) {
\r
6 return v !== null && typeof v === 'object';
\r
8 isFunction : function(v) {
\r
9 return typeof v === 'function';
\r
11 isArray : function(v) {
\r
12 return Object.prototype.toString.call(v) === "[object Array]";
\r
14 isBoolean : function(v) {
\r
15 return typeof v === 'boolean';
\r
17 isString : function(v) {
\r
18 return typeof v === 'string';
\r
20 isNumber : function(v) {
\r
21 return typeof v === 'number';
\r
23 isFinite : function(v){
\r
24 return Type.isNumber(v) === true && isFinite(v);
\r
26 isHTMLElement : function(v){
\r
27 if( 'HTMLElement' in window ){
\r
28 Type.isHTMLElement = function(v){
\r
29 return v instanceof HTMLElement;
\r
32 Type.isHTMLElement = function(v) {
\r
33 if( Type.isObject(v) === false ){
\r
37 if(v && v.nodeType === 1){
\r
39 r = v.cloneNode(false);
\r
43 if(r === v) return false;
\r
46 return r.nodeType === 1;
\r
53 return Type.isHTMLElement(v);
\r
56 isElementCollection : function(v) {
\r
57 return (Object.prototype.toString.call(v) === "[object HTMLCollection]");
\r
60 isNull : function(v) {
\r
63 isUndefined : function(v) {
\r
64 return typeof v === 'undefined';
\r
68 /* ----------------------------------------------------
\r
71 * extend( baseInstance, extend)
\r
72 * cleanCommnetNode()
\r
74 * getElementSize( _elm)
\r
77 * getGrobalObjectName()
\r
80 var Util = ( function(){
\r
81 var ELM_SIZE_GETTER = ( function(){
\r
82 var ret = document.createElement( 'DIV' ),
\r
84 ret.id = 'elmSizeGetter';
\r
85 style.position = 'absolute';
\r
87 style.top = '-9999px';
\r
88 style.visibility = 'hidden';
\r
89 document.body.appendChild( ret);
\r
92 IMG_SIZE_GETTER = ( function(){
\r
93 var ret = ELM_SIZE_GETTER.cloneNode( true );
\r
94 ret.id = 'imgSizeGetter';
\r
95 document.body.appendChild( ret);
\r
98 CLEAN_TARGET_ELEMENT = 'script,style,object,applet,embed,iframe,frame,base,bgsound,frameset,listing'.split( ',' );
\r
100 /* clean comment node */
\r
101 cleanCommnetNode();
\r
103 /* clean noscript */
\r
105 var nodeNoscript = document.getElementsByTagName( 'noscript' ),
\r
107 for( var i=0; i<nodeNoscript.length; ++i ){
\r
108 noscript = nodeNoscript[i];
\r
109 noscript.parentNode && noscript.parentNode.removeChild( noscript );
\r
113 function cleanCommnetNode( _targetElm ){
\r
114 search( _targetElm || document.body );
\r
116 function search( _elm ){
\r
117 if( !_elm ) return;
\r
118 if( _elm.nodeType === 8 ){
\r
119 _elm.parentNode.removeChild( _elm );
\r
122 var i, l, _children = _elm.childNodes, _array = [];
\r
123 if( _children && typeof _children.length === 'number' ){
\r
124 // liveNode > array
\r
125 for( i=0, l=_children.length; i<l; ++i ){
\r
126 _array.push( _children[ i ] );
\r
128 while( _array.length !== 0 ){
\r
129 search( _array.shift() );
\r
136 extend: function( baseInstance, extend ){
\r
137 for( var key in extend ){
\r
138 if( Type.isUndefined( baseInstance[ key ] ) === true ){
\r
139 baseInstance[ key ] = extend[ key ];
\r
141 if( typeof baseInstance[ key ] === typeof extend[ key ] ){
\r
142 baseInstance[ key ] = extend[ key ];
\r
144 alert( 'extend error' );
\r
147 return baseInstance;
\r
149 cleanCommnetNode: cleanCommnetNode,
\r
150 cleanElement: function( _targetElm ){
\r
151 var _nodes, _elm, _array, j, m;
\r
152 for( var i=0, l=CLEAN_TARGET_ELEMENT.length; i<l; ++i){
\r
153 _nodes = _targetElm.getElementsByTagName( CLEAN_TARGET_ELEMENT[ i]);
\r
155 for( j=0, m = _nodes.length; j<m; ++j){
\r
156 _array.push( _nodes[ j]);
\r
158 for( j=0, m = _array.length; j<m; ++j){
\r
160 _elm.parentNode && _elm.parentNode.removeChild( _elm);
\r
163 cleanCommnetNode( _targetElm );
\r
164 if( UA.isIE === false ) return;
\r
165 _nodes = _targetElm.all || _targetElm.getElementsByName( '*' );
\r
166 for( i=0, l = _nodes.length; i<l; ++i){
\r
167 _elm = _nodes[ i ];
\r
168 _elm.style.filter = '';
\r
169 _elm.style.behavior = '';
\r
172 getElementSize: function( _elm ){
\r
173 if( Type.isHTMLElement( _elm ) === false ){
\r
179 var parentElm = _elm.parentNode,
\r
180 prevElm = _elm.previousSibling,
\r
181 nextElm = _elm.nextSibling,
\r
182 displayNone = _elm.style.display === 'none';
\r
183 if( displayNone === true ) _elm.style.display = 'block';
\r
184 ELM_SIZE_GETTER.appendChild( _elm );
\r
186 width: _elm.offsetWidth,
\r
187 height: _elm.offsetHeight
\r
189 if( displayNone === true ) _elm.style.display = 'none';
\r
191 parentElm.insertBefore( _elm, nextElm );
\r
193 if( prevElm && prevElm.nextSibling ){
\r
194 parentElm.insertBefore( _elm, prevElm.nextSibling );
\r
196 parentElm && parentElm.appendChild( _elm );
\r
200 getImageSize: function( img ){
\r
201 var parentElm = img.parentNode,
\r
202 prevElm = img.previousSibling,
\r
203 nextElm = img.nextSibling,
\r
204 displayNone = img.style.display === 'none';
\r
205 if( displayNone === true ) img.style.display = '';
\r
206 IMG_SIZE_GETTER.appendChild( img );
\r
208 var size = getActualDimension( img );
\r
210 IMG_SIZE_GETTER.removeChild( img );
\r
211 if( displayNone === true ) img.style.display = 'none';
\r
213 parentElm.insertBefore( img, nextElm );
\r
215 if( prevElm && prevElm.nextSibling ){
\r
216 parentElm.insertBefore( img, prevElm.nextSibling );
\r
218 parentElm && parentElm.appendChild( img );
\r
222 * AUTHOR: uupaa.js@gmail.com
\r
224 function getActualDimension(image) {
\r
225 var run, mem, w, h, key = "actual";
\r
227 // for Firefox, Safari, Google Chrome
\r
228 if ("naturalWidth" in image) {
\r
230 width: image.naturalWidth,
\r
231 height: image.naturalHeight
\r
235 if ("src" in image) { // HTMLImageElement
\r
236 if (image[key] && image[key].src === image.src) {
\r
239 if (document.uniqueID) { // for IE
\r
240 run = image.runtimeStyle;
\r
241 mem = { w: run.width, h: run.height }; // keep runtimeStyle
\r
242 run.width = "auto"; // override
\r
243 run.height = "auto";
\r
246 run.width = mem.w; // restore
\r
247 run.height = mem.h;
\r
248 } else { // for Opera and Other
\r
249 mem = { w: image.width, h: image.height }; // keep current style
\r
250 image.removeAttribute("width");
\r
251 image.removeAttribute("height");
\r
254 image.width = mem.w; // restore
\r
255 image.height = mem.h;
\r
257 return image[key] = { width: w, height: h, src: image.src }; // bond
\r
259 // HTMLCanvasElement
\r
260 return { width: image.width, height: image.height };
\r
265 getAbsolutePath: function( path) {
\r
266 var e = document.createElement("div");
\r
267 e.innerHTML = '<a href=\"' + path + '\" />';
\r
268 return e.firstChild.href;
\r
270 getAbsolutePosition: function( _elm){
\r
271 // Find the destination's position
\r
272 var destx = _elm.offsetLeft,
\r
273 desty = _elm.offsetTop,
\r
275 body = document.body;
\r
276 while (thisNode.offsetParent && thisNode.offsetParent !== body){
\r
277 thisNode = thisNode.offsetParent;
\r
278 destx += thisNode.offsetLeft;
\r
279 desty += thisNode.offsetTop;
\r
286 pullHtmlAsTemplete: function( html ){
\r
287 var elm = document.createElement( 'div' );
\r
288 elm.innerHTML = html;
\r
289 return elm.firstChild;
\r
291 getElementsByClassName: function( _elm, _className, opt_tagName){
\r
292 var _all = !opt_tagName || opt_tagName === '*',
\r
293 _nodes = _all === true ? ( _elm.all || _elm.getElementsByTagName( '*')) : _elm.getElementsByTagName( opt_tagName),
\r
294 _node, _classes, ret = [];
\r
295 for( var i=0, l = _nodes.length; i<l; ++i){
\r
296 _node = _nodes[ i];
\r
297 _node.nodeType === 1 && this.hasClassName( _node, _className) === true && ret.push( _node);
\r
301 getChildIndex: function( _parent, _child ){
\r
302 var _children = _parent.getElementsByTagName( _child.tagName ),
\r
303 l = _children.length;
\r
304 for(var i=0; i<l; ++i){
\r
305 if( _children[ i] === _child) return i;
\r
309 hasClassName: function( _elm, _className){
\r
310 var _classes = ( _elm.className || '').split( ' ');
\r
311 for( var i=0, l=_classes.length; i<l; ++i){
\r
312 if( _classes[ i] === _className) return true;
\r
316 removeAllChildren: function ( _elm){
\r
317 while( _elm.firstChild){
\r
318 remove( _elm.firstChild);
\r
320 function remove( _node){
\r
321 while( _node.firstChild){
\r
322 remove( _node.firstChild);
\r
324 _node.parentNode && _node.parentNode.removeChild( _node);
\r
327 getIndex: function( _array, _element){
\r
328 if( Array.prototype.indexof ){
\r
329 Util.getIndex = function( _array, _element){
\r
330 return _array.indexof( _element);
\r
333 Util.getIndex = function( _array, _element){
\r
334 for( var i=0, l = _array.length; i<l; ++i){
\r
335 if( _array[ i] === _element) return i;
\r
340 return Util.getIndex( _array, _element);
\r
342 copyArray: function( _array ){
\r
343 var ret = new Array( l );
\r
344 for( var i=0, l = _array.length; i<l; ++i ){
\r
345 ret[ i ] = _array[ i ];
\r
352 createGlobalFunction: function( _func ){
\r
353 var randomKey = null;
\r
355 randomKey = '_glovalFunction_' + ( '' + Math.random()).replace( /\./,'');
\r
356 if( eval( 'typeof '+randomKey) === 'undefined') {
\r
360 window[ randomKey ] = _func;
\r
363 createGlobalFunc: function( func){
\r
364 var randomKey = null;
\r
366 randomKey = 'hogeGlovalFunc_'+(''+Math.random()).replace(/\./,'');
\r
367 if(eval('typeof '+randomKey) == 'undefined') {
\r
371 eval(randomKey+'='+((typeof func=='string') ? func : func.toString()));
\r
374 createGlobalVar: function( obj){
\r
375 var randomKey = null;
\r
377 randomKey = 'hogeGlovalVar_'+(''+Math.random()).replace(/\./,'');
\r
378 if(eval('typeof '+randomKey+'') == 'undefined') {
\r
382 var globalObj = eval(randomKey+'={}');
\r
383 globalObj.value = obj;
\r
386 createGlobalUniqueName: function(){
\r
387 var randomKey = null;
\r
389 randomKey = '_uniqueName'+(''+Math.random()).replace(/\./,'');
\r
390 if( typeof window[randomKey] === 'undefined'){
\r
396 createIframe: function( id, callback){
\r
398 var el = document.createElement( ua.isIE ? '<iframe name="' + id + '" frameborder="0" scrolling="no">' : 'iframe');
\r
401 el.onreadystatechange = detect;
\r
403 // iron(chrome) の場合、append の前に onload を指定しないと onload が呼ばれない
\r
404 el.onload = onLoad;
\r
405 //setTimeout( asynkCallback, 0 );
\r
408 document.body.appendChild( el);
\r
409 el.id = el.name = id;
\r
410 el.setAttribute( 'name', id);
\r
411 el.style.cssText = 'width:1px;height:1px;visibility:hidden;position:absolute;top:1px;left:1px;';
\r
412 // http://d.hatena.ne.jp/onozaty/20070830/p1
\r
413 // [JavaScript]IE6ではJavaScriptで動的に作成したiframeに対してsubmitできない(IE7は未確認) ->解決
\r
414 el.contentWindow.name = id;
\r
419 if ( this.readyState === "complete" ){
\r
420 this.onreadystatechange = new Function();
\r
421 this.onreadystatechange = null;
\r
422 setTimeout( asynkCallback, 0 );
\r
427 setTimeout( asynkCallback, 0 );
\r
429 function asynkCallback(){
\r
443 var UA = ( function(){
\r
444 var ua = (function(){
\r
448 var dua = n.userAgent;
\r
449 var dav = n.appVersion;
\r
450 var tv = parseFloat(dav);
\r
451 acme.isOpera = (dua.indexOf("Opera") >= 0) ? tv: undefined;
\r
452 acme.isKhtml = (dav.indexOf("Konqueror") >= 0) ? tv : undefined;
\r
453 acme.isWebKit = parseFloat(dua.split("WebKit\/")[1]) || undefined;
\r
454 acme.isChrome = parseFloat(dua.split("Chrome\/")[1]) || undefined;
\r
455 acme.isGecko = (dua.indexOf("Gecko\/") >= 0) ? parseFloat(dua.split("rv:")[1].replace( /^(\d*\.\d*)\.(\d*)/, '$1$2' )) : undefined;
\r
456 var index = Math.max(dav.indexOf("WebKit"), dav.indexOf("Safari"), 0);
\r
457 if(index && !acme.isChrome){
\r
458 acme.isSafari = parseFloat(dav.split("Version/")[1]);
\r
459 if(!acme.isSafari || parseFloat(dav.substr(index + 7)) <= 419.3){
\r
463 if(document.all && !acme.isOpera){
\r
464 acme.isIE = parseFloat(dav.split("MSIE ")[1]) || undefined;
\r
469 isIE = navigator.userAgent.toLowerCase().indexOf( 'msie') !== -1,
\r
470 ieVersion = isIE === true ? parseInt( navigator.appVersion.toLowerCase().replace( /.*msie[ ]/, '').match( /^[0-9]+/)) : 0,
\r
471 ieRenderingVersion = ieVersion === 8 ? document.documentMode : ieVersion,
\r
472 isStanderdMode = document.compatMode === 'CSS1Compat',
\r
473 ActiveX = ( function(){
\r
474 if( isIE === false || ieVersion > 8 ) return false;
\r
475 var b = document.body,
\r
476 c = b.className || '',
\r
478 ret = undefined, //pettanr.URL_PARAMS.ActiveX,
\r
479 ns = 'pettanr-ActiveX-',
\r
480 enabled = 'enabled',
\r
481 disabled = 'disabled';
\r
482 if( ret !== true && ret !== false){
\r
483 if( Util.hasClassName( b, ns + enabled) === true ) return true;
\r
484 if( Util.hasClassName( b, ns + disabled) === true ) return false;
\r
485 x = document.createElement( 'div' );
\r
487 x.style.cssText = 'width:1px;height:1px;line-height:1px;filter:progid:DXImageTransform.Microsoft.Shadow()';
\r
488 ret = x.offsetHeight > 1;
\r
491 b.className += [ c !== '' ? ' ' : c, ns, ret === true ? enabled : disabled ].join( '');
\r
494 VML = ( function(){
\r
495 if( ActiveX === false || isIE === false || ieVersion > 8) return false;
\r
496 var globalObjectName = Util.createGlobalUniqueName(),
\r
499 document.write( [ '<!--[if gte vml 1]><script id="', id, '">window', '.', globalObjectName, '=1;<\/script><![endif]-->'].join( ''));
\r
500 if( window[globalObjectName] === 1){
\r
501 script = document.getElementById( id);
\r
502 script.parentNode.removeChild( script);
\r
503 window[globalObjectName] = null;
\r
508 isStandAloneMode = ( function(){
\r
509 if( isIE === false) return false;
\r
510 if( VML === true) return false;
\r
511 var globalObjectName = Util.createGlobalUniqueName(),
\r
513 id = 'detectStandAlone';
\r
514 document.write( [ '<!--[if IE ', Math.floor( ieVersion ), ']><script id="', id, '">window', '.', globalObjectName, '=1;<\/script><![endif]-->'].join( ''));
\r
515 if( window[globalObjectName] === 1){
\r
516 script = document.getElementById( id);
\r
517 script.parentNode.removeChild( script);
\r
518 window[globalObjectName] = null;
\r
528 WEBKIT: ua.isWebKit,
\r
529 CHROME: ua.isChrome,
\r
531 ieVersion: ieVersion,
\r
532 ieRenderingVersion: ieRenderingVersion,
\r
533 isStanderdMode: isStanderdMode,
\r
536 STANDALONE: isStandAloneMode,
\r
537 VENDER_PREFIX: ( function() {
\r
538 var ua = navigator.userAgent.toLowerCase();
\r
539 if ( ua.indexOf('opera') !== -1 ){
\r
541 } else if ( ua.indexOf('msie') !== -1 ){
\r
543 } else if ( ua.indexOf('webkit') !== -1 ){
\r
545 } else if ( navigator.product === 'Gecko' ){
\r
550 startVML: function(){
\r
551 delete UA.startVML;
\r
552 if( UA.VML !== true) return false;
\r
553 if (!document.namespaces["v"]) {
\r
554 document.namespaces.add("v", "urn:schemas-microsoft-com:vml", "#default#VML");
\r
556 document.createStyleSheet().cssText = "v\:shape,v\:image{behavior:url(#default#VML);display:block;};";
\r
563 /* ----------------------------------------------------
\r
568 ( function( window, undefined ){
\r
570 var doc = window.document;
\r
571 var body = doc.getElementsByTagName( 'body' )[ 0 ]; //( doc.compatMode || '' ) !== 'CSS1Compat' ? doc.body : doc.documentElement;//
\r
573 var SERVICE_LIST = [];
\r
574 var SUPER_USER_KEY = { getUID: function(){ return 0; }};
\r
575 var API_USER_LIST = [ SUPER_USER_KEY ];
\r
576 var numApiUser = 1;
\r
578 function isApiUser( _user ){
\r
579 if( _user === SUPER_USER_KEY ) return true;
\r
580 if( File.isDriver( _user ) === true ) return true;
\r
581 if( Application.isApplicationInstance( _user ) === true ) return true;
\r
605 _____: parseInt( '00000', 2 ),
\r
606 ____C: parseInt( '00001', 2 ), // hasCreateMenu
\r
607 ___W_: parseInt( '00010', 2 ), // isWritable
\r
608 ___WC: parseInt( '00011', 2 ), // isWritable
\r
609 __R__: parseInt( '00100', 2 ), // isRenamable
\r
610 __R_C: parseInt( '00101', 2 ), // hasCreateMenu
\r
611 __RW_: parseInt( '00110', 2 ), // isWritable
\r
612 __RWC: parseInt( '00111', 2 ), // isWritable
\r
613 _S___: parseInt( '01000', 2 ), // childrenIsSortable
\r
614 _S__C: parseInt( '01001', 2 ),
\r
615 _S_W_: parseInt( '01010', 2 ),
\r
616 _S_WC: parseInt( '01011', 2 ),
\r
617 _SR__: parseInt( '01100', 2 ),
\r
618 _SR_C: parseInt( '01101', 2 ),
\r
619 _SRW_: parseInt( '01110', 2 ),
\r
620 _SRWC: parseInt( '01111', 2 ),
\r
621 D____: parseInt( '10000', 2 ),
\r
622 D___C: parseInt( '10001', 2 ), // hasCreateMenu
\r
623 D__W_: parseInt( '10010', 2 ), // isWritable
\r
624 D__WC: parseInt( '10011', 2 ), // isWritable
\r
625 D_R__: parseInt( '10100', 2 ), // isRenamable
\r
626 D_R_C: parseInt( '10101', 2 ), // hasCreateMenu
\r
627 D_RW_: parseInt( '10110', 2 ), // isWritable
\r
628 D_RWC: parseInt( '10111', 2 ), // isWritable
\r
629 DS___: parseInt( '11000', 2 ), // childrenIsSortable
\r
630 DS__C: parseInt( '11001', 2 ),
\r
631 DS_W_: parseInt( '11010', 2 ),
\r
632 DS_WC: parseInt( '11011', 2 ),
\r
633 DSR__: parseInt( '11100', 2 ),
\r
634 DSR_C: parseInt( '11101', 2 ),
\r
635 DSRW_: parseInt( '11110', 2 ),
\r
636 DSRWC: parseInt( '11111', 2 ),
\r
644 UPDATE_ATTRIVUTE: 'onFileUpdate',
\r
645 GET_SEQENTIAL_FILES:'gotSeqentilFiles'
\r
647 DATA_PROPERTY_RESERVED: [
\r
648 'children', 'driver', 'state', 'type'
\r
653 UPDATE: 'onTreeUpdate'
\r
658 KEY_DOWN: 'keydown',
\r
660 KEY_CHANGE: 'keychange',
\r
666 var EX = ( function(){
\r
667 var F = new Function();
\r
669 function clone( src ) {
\r
671 if( Type.isArray(src) === true ){
\r
674 if( Type.isObject(src) === true ){
\r
677 if( Type.isNumber(src) === true || Type.isString(src) === true || Type.isBoolean( src ) === true ){
\r
682 for( var key in src ){
\r
683 ret[ key ] = clone( src[ key ]);
\r
689 extend: function( base, extend ){
\r
690 F.prototype = base;
\r
692 for( var p in extend ){
\r
693 ret[ p ] = extend[ p ];
\r
697 clone: function( obj ){
\r
698 return clone( obj );
\r
701 var self = this, v;
\r
703 if( self.hasOwnProperty && !self.hasOwnProperty( p ) ) continue;
\r
705 v && v instanceof TicketBase && self.kill();
\r
712 var TicketBase = function(){
\r
713 this.kill = function(){
\r
716 if( t.hasOwnProperty && !t.hasOwnProperty( p ) ) continue;
\r
718 v && v instanceof TicketBase && v.kill();
\r
726 /* --------------------------------------------------------------
\r
731 var SystemTimer = ( function(){
\r
732 var setTimeout = window.setTimeout;
\r
733 var clearTimeout = window.clearTimeout;
\r
734 var INTERVAL_TIME = 16;
\r
735 var TICKET_LIST = [];
\r
736 var timerId = undefined;
\r
740 for( var i = 0; i < TICKET_LIST.length; ) {
\r
741 if( TICKET_LIST[ i ].call( next ) !== false ) ++i;
\r
743 timerId = undefined;
\r
747 var l = TICKET_LIST.length,
\r
751 timerId !== undefined && clearTimeout( timerId );
\r
752 timerId = undefined;
\r
755 for( var i = 0; i<l; i++ ){
\r
756 c = TICKET_LIST[ i ].count;
\r
759 if( next > n || timerId === undefined ){
\r
760 timerId !== undefined && clearTimeout( timerId );
\r
761 timerId = setTimeout( loop, INTERVAL_TIME * n );
\r
766 var TimerTicketClass = function( _apiuser, _callback, _time, _once ){
\r
767 this.apiuser = _apiuser;
\r
768 this.callback = _callback;
\r
770 this.count = _time;
\r
772 _apiuser = _callback = null;
\r
774 TimerTicketClass.prototype = new TicketBase();
\r
775 TimerTicketClass.prototype.call = function( c ){
\r
777 if( this.count <= 0 ){
\r
779 if( this.once === true ){
\r
781 TICKET_LIST.splice( Util.getIndex( TICKET_LIST, this ), 1 );
\r
784 this.count = this.time;
\r
788 TimerTicketClass.prototype.destroy = function( _apiuser, _callback ){
\r
789 if( _apiuser && _apiuser !== this.apiuser ) return false;
\r
790 if( _callback && _callback !== this.callback ) return false;
\r
797 add: function( _apiuser, _handler, _time, _once ){
\r
798 if( Type.isNumber( _time ) === false || _time < INTERVAL_TIME ) _time = INTERVAL_TIME;
\r
800 var _ticket = new TimerTicketClass( _apiuser, _handler, Math.ceil( _time / INTERVAL_TIME ), _once );
\r
801 TICKET_LIST.push( _ticket );
\r
805 remove: function( _apiuser, _handler ) {
\r
808 while( _ticket = TICKET_LIST[ i ] ){
\r
809 if( _ticket.destroy( _apiuser, _handler ) === true ){
\r
810 TICKET_LIST.splice( i, 1 );
\r
820 /* --------------------------------------------------------------
\r
824 var AsyncCall = ( function(){
\r
825 var CALLBACK_LIST = [];
\r
827 var CallbackTicketClass = function( _apiuser, _callback, _argments ){
\r
828 this.apiuser = _apiuser;
\r
829 this.callback = _callback;
\r
830 this.argments = _argments;
\r
831 _apiuser = _callback = _argments = null;
\r
833 CallbackTicketClass.prototype = new TicketBase();
\r
834 CallbackTicketClass.prototype.call = function(){
\r
835 var f = this.callback,
\r
837 if( Type.isArray( a ) === true ){
\r
838 f.apply( this.apiuser, a );
\r
843 CallbackTicketClass.prototype.destroy = function( _apiuser, _callback ){
\r
844 if( _apiuser && _apiuser !== this.apiuser ) return false;
\r
845 if( _callback && _callback !== this.callback ) return false;
\r
851 function dispatch(){
\r
852 var _ticket = CALLBACK_LIST.shift();
\r
856 CALLBACK_LIST.length !== 0 && SystemTimer.add( SUPER_USER_KEY, dispatch, 1, true );
\r
861 add: function( _apiuser, _callback, _argments ){
\r
862 CALLBACK_LIST.length === 0 && SystemTimer.add( SUPER_USER_KEY, dispatch, 1, true );
\r
863 CALLBACK_LIST.push( new CallbackTicketClass( _apiuser, _callback, _argments ) );
\r
865 remove: function( _apiuser, _callback ){
\r
868 while( _ticket = CALLBACK_LIST[ i ] ){
\r
869 if( _ticket.destroy( _apiuser, _callback ) === true ){
\r
870 CALLBACK_LIST.splice( i, 1 );
\r
879 /* -----------------------------------------------------------
\r
881 * お気に入り画像一覧 > tag:ペン次郎 > ペン次郎:笑う
\r
882 * 最近アップロードされた画像 > images
\r
883 * 最近使われた画像 > images
\r
884 * キャラクター画像庫 > アニマル系 > tag:ペン次郎 > ペン次郎:笑う
\r
891 var File = ( function(){
\r
892 var DRIVER_LIST = [];
\r
894 var FILE_TYPE_IS_FOLDER = Const.FILE.TYPE.FOLDER,
\r
895 numFileType = Const.FILE.TYPE.XML,
\r
896 FILEDATA_RESITER = [], // store all of fileData( json object )
\r
897 FILEDATA_ACCESS = [], // file operations for Kernel only ! hide from Out of File
\r
898 FILE_OBJECT_POOL = [],
\r
899 EVENT_LISTENER_REGISTER = [],
\r
901 TREE_ACCESS_ARRAY = [];
\r
903 var REQUEST_CONTROLER = ( function(){
\r
904 var REQUEST_TICKET_RESISTER = [],
\r
905 currentTicket = null,
\r
906 currentData = null,
\r
907 DATA_TYPE_ARRAY = 'json,xml,html,text'.split( ','),
\r
914 var RequestTicketClass = function( _apiuser, _type, _data, _url, _onLoad, _onError ){
\r
915 this.apiuser = _apiuser;
\r
919 this.onLoad = _onLoad;
\r
920 this.onError = _onError;
\r
922 _apiuser = _type = _data = _onLoad = _onError = null;
\r
924 RequestTicketClass.prototype = new TicketBase();
\r
925 RequestTicketClass.prototype.load = function( _data ){
\r
926 AsyncCall.add( this.apiuser, this.onLoad, [ this.data, _data ] );
\r
928 RequestTicketClass.prototype.error = function(){
\r
929 AsyncCall.add( this.apiuser, this.onError, this.data );
\r
932 function request(){
\r
933 if( currentTicket !== null || REQUEST_TICKET_RESISTER.length === 0 ) return;
\r
934 currentTicket = REQUEST_TICKET_RESISTER.shift();
\r
936 url: currentTicket.url,
\r
937 dataType: DATA_TYPE_ARRAY[ currentTicket.type ],
\r
938 success: onSuccess,
\r
942 function onSuccess( _data ){
\r
943 currentTicket.load( _data );
\r
944 currentTicket.kill();
\r
945 currentTicket = null;
\r
948 function onError(){
\r
950 currentTicket.error();
\r
951 currentTicket.kill(); // retry
\r
952 currentTicket = null;
\r
957 getNumTask: function(){
\r
958 return REQUEST_TICKET_RESISTER.length;
\r
960 getNumError: function(){
\r
963 getJson: function( _apiuser, _data, _url, _onLoad, _onError ){
\r
964 REQUEST_TICKET_RESISTER.push( new RequestTicketClass( _apiuser, DATA_IS_JSON, _data, _url, _onLoad, _onError ));
\r
965 currentTicket === null && request();
\r
970 var FILE_CONTROLER = {
\r
971 createTree: function( _apiuser, _rootFileData ){
\r
972 var _tree = new TreeClass( _apiuser, _rootFileData );
\r
973 TREE_ARRAY.push( _tree );
\r
976 getFileUID: function( FILEDATAorFILE ){
\r
977 if( FILEDATAorFILE instanceof FileClass ){
\r
978 return FILEDATAorFILE.getUID();
\r
981 var uid = Util.getIndex( FILEDATA_RESITER, FILEDATAorFILE );
\r
983 uid = FILEDATA_RESITER.length;
\r
984 FILEDATA_RESITER.push( FILEDATAorFILE );
\r
988 getFileDataAccess: function( UIDorFILEorFILEDATA ){
\r
989 var _uid, _data = FILE_CONTROLER.getFileData( UIDorFILEorFILEDATA ), _access;
\r
991 if( _data === null || typeof _data !== 'object' ) return null;
\r
992 for( var i=0, l = FILEDATA_ACCESS.length; i<l; ++i ){
\r
993 _access = FILEDATA_ACCESS[ i ];
\r
994 if( _access.DATA === _data ) return _access;
\r
998 getFileData: function( UIDorFILEorFILEDATA ){
\r
999 if( typeof UIDorFILEorFILEDATA === 'number' ){
\r
1000 return FILEDATA_RESITER[ UIDorFILEorFILEDATA ] || null;
\r
1002 if( UIDorFILEorFILEDATA instanceof FileClass ){
\r
1003 return FILEDATA_RESITER[ UIDorFILEorFILEDATA.getUID() ] || null;
\r
1005 if( Util.getIndex( FILEDATA_RESITER, UIDorFILEorFILEDATA ) !== -1 ){
\r
1006 return UIDorFILEorFILEDATA;
\r
1010 getChildren: function( UIDorFILEorFILEDATA ){
\r
1011 var _data = FILE_CONTROLER.getFileData( UIDorFILEorFILEDATA );
\r
1012 return _data !== null ? _data.children || null : null;
\r
1014 getDriver: function( _file ){
\r
1015 var _data = FILE_CONTROLER.getFileData( _file );
\r
1016 return _data !== null && _data.driver ? _data.driver : BASE_DRIVER;
\r
1018 getUpdateFlag: function( _file, _bit ){
\r
1019 var _driver = FILE_CONTROLER.getDriver( _file ),
\r
1021 if( typeof _driver.getUpdatePolicy === 'function' ){
\r
1022 _policy = _driver.getUpdatePolicy( _file );
\r
1025 if( typeof _policy !== 'number' ) {
\r
1026 _policy = BASE_DRIVER.getUpdatePolicy( _file )
\r
1028 return _policy % ( _bit * 2 ) >= _bit;
\r
1030 move: function( _prentUID, _targetfile, _newFolder, _newIndex, _opt_callback ){
\r
1031 var _parentData = FILE_CONTROLER.getFileDataAccess( _prentUID ),
\r
1032 _parentType = _parentData.TYPE,
\r
1033 _targetData = FILE_CONTROLER.getFileDataAccess( _targetfile ),
\r
1034 _targetType = _targetData.TYPE;
\r
1036 replace: function( _uid, _file, _newIndex ){
\r
1039 addEventListener: function( FILEorNULL, _eventType, _callback ){
\r
1040 var _uid = FILEorNULL instanceof FileClass ? FILEorNULL.getUID() : FILEorNULL;
\r
1041 EVENT_LISTENER_REGISTER.push( new FileEventTicketClass( _uid, _eventType, _callback ));
\r
1043 removeEventListener: function( FILEorNULL, _eventType, _callback ){
\r
1044 var _uid = FILEorNULL instanceof FileClass ? FILEorNULL.getUID() : FILEorNULL,
\r
1046 for(var i=0, l = EVENT_LISTENER_REGISTER.length; i<l; ++i ){
\r
1047 _ticket = EVENT_LISTENER_REGISTER[ i ];
\r
1048 if( _ticket.fileUID === _uid && _ticket.eventType === _eventType && _ticket.callBack === _callback ){
\r
1049 EVENT_LISTENER_REGISTER.splice( i, 1 );
\r
1054 getTreeAccess: function(){
\r
1057 fileEventRellay: function( _uid, _event ){
\r
1058 var _fileAccess = FILE_CONTROLER.getFileDataAccess( _uid );
\r
1059 if( _fileAccess === null ) return;
\r
1060 var _treeUID = _fileAccess.TREE.getUID(),
\r
1061 _treeAccess = TREE_ACCESS_ARRAY[ _treeUID ],
\r
1062 _data = _fileAccess.DATA,
\r
1064 if( !_treeAccess ) return;
\r
1065 _treeAccess.dispatchFileEvent( _event );
\r
1066 for( var i=0, l = TREE_ARRAY.length; i<l; ++i ){
\r
1067 if( i !== _treeUID ){
\r
1068 _tree = TREE_ARRAY[ i ];
\r
1069 if( FILE_CONTROLER.getFileData( _tree.getCurrentFile() ) === _data ){
\r
1070 _treeAccess = TREE_ACCESS_ARRAY[ _tree.getUID() ];
\r
1071 _treeAccess && _treeAccess.dispatchFileEvent( _event );
\r
1078 var TreeClass = function( apiuser, rootFileData ){
\r
1079 var PARENT_FILE_RESITER = [],
\r
1081 apiuser : apiuser,
\r
1082 dispatchFileEvent: dispatchFileEvent
\r
1084 EVENT_LISTENER_ARRAY = [],
\r
1086 rootFile = new FileClass( instance, null, rootFileData ),
\r
1087 currentFile = rootFile;
\r
1089 currentFile.getSeqentialFiles();
\r
1090 TREE_ACCESS_ARRAY.push( ACCESS );
\r
1092 function dispatchFileEvent( e ){
\r
1093 var _eventType = e.eventType,
\r
1094 _targetFile = e.targetFile,
\r
1095 _uid = _targetFile.getUID(),
\r
1096 _ticket, _type, _callback;
\r
1097 for( var i=0, l = EVENT_LISTENER_REGISTER.length; i<l; ++i ){
\r
1098 _ticket = EVENT_LISTENER_REGISTER[ i ];
\r
1099 _type = _ticket.eventType;
\r
1100 _callback = _ticket.callBack;
\r
1101 if( _eventType === _type && _uid === _ticket.fileUID ){
\r
1102 AsyncCall.add( apiuser, _callback, [ _eventType, _targetFile, e.key, e.value ] );
\r
1104 if( _type === Const.TREE.EVENT.UPDATE && _eventType === Const.FILE.EVENT.GET_SEQENTIAL_FILES ){
\r
1105 //_callback( _eventType, _targetFile );
\r
1106 AsyncCall.add( apiuser, _callback, [ _eventType, _targetFile ] );
\r
1111 this.getUID = function(){
\r
1112 return Util.getIndex( TREE_ACCESS_ARRAY, ACCESS );
\r
1114 this.getRootFile = function(){
\r
1117 this.getCurrentFile = function(){
\r
1118 return currentFile;
\r
1120 this.hierarchy = function(){
\r
1121 return PARENT_FILE_RESITER.length;
\r
1123 this.getParentFileAt = function( _index ){
\r
1124 var l = PARENT_FILE_RESITER.length;
\r
1125 if( typeof _index !== 'number' || _index < 0 || _index >= l ) return null;
\r
1126 return PARENT_FILE_RESITER[ l -1 -_index ];
\r
1128 this.down = function( _index ){
\r
1129 if( typeof _index !== 'number' || _index < 0 || _index >= currentFile.getChildFileLength()) return;
\r
1130 PARENT_FILE_RESITER.unshift( currentFile );
\r
1131 currentFile = currentFile.getChildFileByIndex( _index );
\r
1132 currentFile.getSeqentialFiles();
\r
1133 return currentFile;
\r
1135 this.up = function( _index ){
\r
1136 var l = PARENT_FILE_RESITER.length;
\r
1137 if( l === 0) return null;
\r
1139 if( currentFile ){
\r
1140 var _currentFile = currentFile;
\r
1141 currentFile = null;
\r
1142 _currentFile.destroy();
\r
1144 if( typeof _index === 'number'){
\r
1145 if( _index >= l) return null;
\r
1146 currentFile = this.getParentFileAt( _index );
\r
1147 PARENT_FILE_RESITER.splice( 0, l -_index);
\r
1149 currentFile = PARENT_FILE_RESITER.shift();
\r
1151 currentFile.getSeqentialFiles();
\r
1152 return currentFile;
\r
1154 this.addTreeEventListener = function( _eventType, _callback ){
\r
1155 FILE_CONTROLER.addEventListener( null, _eventType, _callback );
\r
1157 this.removeTreeEventListener = function( _eventType, _callback ){
\r
1158 FILE_CONTROLER.removeEventListener( null, _eventType, _callback );
\r
1160 this.destroy = function( _apiuser ){
\r
1161 if( _apiuser && apiuser !== _apiuser ) return false;
\r
1163 var _currentFile = currentFile;
\r
1164 currentFile = rootFile = rootFileData = null;
\r
1165 // currentFile, rootFile を null にしないと .File.destroy() ができない.
\r
1166 _currentFile.destroy();
\r
1167 while( PARENT_FILE_RESITER.length > 0 ){
\r
1168 _currentFile = PARENT_FILE_RESITER.shift();
\r
1169 _currentFile.destroy();
\r
1172 AsyncCall.remove( apiuser );
\r
1173 instance = apiuser = null;
\r
1178 var FileEventTicketClass = function( _uid, _eventType, _callback ){
\r
1179 this.fileUID = _uid;
\r
1180 this.eventType = _eventType;
\r
1181 this.callBack = _callback;
\r
1182 _uid = _eventType = _callback = undefined;
\r
1184 FileEventTicketClass.prototype = new TicketBase();
\r
1186 var FileEventClass = function( eventType, file, key, value ){
\r
1187 this.eventType = eventType;
\r
1188 this.targetFile = file;
\r
1189 this.updatedAttribute = key;
\r
1190 this.updatedValue = value;
\r
1194 * file の data は object で保持している。
\r
1195 * File の外からファイルをみるときは、FileClassを通して操作する。
\r
1196 * fileの変更、それに付随して追加されたイベントは、TreeClassで管理される。
\r
1197 * treeがdestryされると、fileのイベントリスナーも全て削除される。
\r
1198 * 他の tree も data の共通する currentFile に対してのみは、file の変更イベントを受け取って流す.
\r
1202 var FileClass = function( tree, parentData, data ){
\r
1203 var uid = FILE_CONTROLER.getFileUID( data );
\r
1205 FILEDATA_ACCESS.push( {
\r
1207 parentData: parentData,
\r
1211 tree = parentData = data = null;
\r
1213 this.getUID = function(){
\r
1218 FileClass.prototype = {
\r
1219 isChildFile: function( _FILEorFILEDATA ){
\r
1220 return this.getChildFileIndex( _FILEorFILEDATA) !== -1;
\r
1222 getSeqentialFiles: function(){
\r
1223 var _driver = FILE_CONTROLER.getDriver( this );
\r
1224 if( _driver !== null && typeof _driver.getSeqentialFiles === 'function' ){
\r
1225 _driver.getSeqentialFiles( this );
\r
1228 addEventListener: function( _eventType, _callback ){
\r
1229 FILE_CONTROLER.addEventListener( this, _eventType, _callback );
\r
1231 removeEventListener: function( _eventType, _callback ){
\r
1232 FILE_CONTROLER.removeEventListener( this, _eventType, _callback );
\r
1234 dispatchEvent: function( e ){
\r
1235 e instanceof FileEventClass && FILE_CONTROLER.fileEventRellay( this.getUID(), e );
\r
1237 getChildFileLength: function(){
\r
1238 var children = FILE_CONTROLER.getChildren( this );
\r
1239 return Type.isArray( children ) === true ? children.length : -1;
\r
1241 getChildFileIndex: function( _FILEorFILEDATA ){
\r
1242 var children = FILE_CONTROLER.getChildren( this );
\r
1243 if( Type.isArray( children ) === false ) return -1;
\r
1244 var l = children.length,
\r
1245 _fileData = FILE_CONTROLER.getFileData( _FILEorFILEDATA );
\r
1246 if( _fileData === null ) return -1;
\r
1247 for( var i=0; i<l; ++i ){
\r
1248 if( children[ i ] === _fileData ) return i;
\r
1252 getChildFileByIndex: function( _index ){
\r
1253 var _access = FILE_CONTROLER.getFileDataAccess( this ),
\r
1254 _children = FILE_CONTROLER.getChildren( this );
\r
1255 if( typeof _index !== 'number' || _index < 0 || Type.isArray( _children ) === false || _index >= _children.length) return null;
\r
1256 var _file = new FileClass( _access.TREE, _access.DATA, _children[ _index ]);
\r
1260 getName: function(){
\r
1261 var driver = FILE_CONTROLER.getDriver( this );
\r
1262 if( typeof driver.getName === 'function'){
\r
1263 return driver.getName( this );
\r
1265 return BASE_DRIVER.getName( this);
\r
1267 getThumbnail: function(){
\r
1268 var driver = FILE_CONTROLER.getDriver( this );
\r
1269 if( typeof driver.getThumbnail === 'function'){
\r
1270 return driver.getThumbnail( this );
\r
1272 return BASE_DRIVER.getThumbnail( this );
\r
1274 getType: function(){
\r
1275 var _data = FILE_CONTROLER.getFileData( this );
\r
1276 return typeof _data.type === 'number' ? _data.type : Const.FILE.TYPE.UNKNOWN;
\r
1278 getState: function(){
\r
1279 var _data = FILE_CONTROLER.getFileData( this );
\r
1280 return typeof _data.state === 'number' ? _data.state : Const.FILE.STATE.OK;
\r
1282 getSummary: function(){
\r
1283 var driver = FILE_CONTROLER.getDriver( this );
\r
1284 if( typeof driver.getSummary === 'function'){
\r
1285 return driver.getSummary( this );
\r
1287 return BASE_DRIVER.getSummary( this );
\r
1289 isWritable: function(){
\r
1290 return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.WRITE );
\r
1292 isSortable: function(){
\r
1293 return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.SORT );
\r
1295 isCreatable: function(){
\r
1296 return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.CREATE );
\r
1298 isRenamable: function(){
\r
1299 return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.RENAME );
\r
1301 isDeletable: function(){
\r
1302 return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.DELETE );
\r
1306 var driver = FILE_CONTROLER.getDriver( this ),
\r
1308 if( typeof driver.read === 'function'){
\r
1309 data = driver.read( this );
\r
1311 return BASE_DRIVER.read( data || this );
\r
1313 write: function( _newData, _onUpdateFunction ){
\r
1314 var driver = FILE_CONTROLER.getDriver( this );
\r
1315 if( typeof driver.write === 'function'){
\r
1316 return driver.write( this, _newData, _onUpdateFunction );
\r
1318 return BASE_DRIVER.write( this, _newData, _onUpdateFunction );
\r
1320 viewerApplicationList: function(){
\r
1321 var driver = FILE_CONTROLER.getDriver( this );
\r
1322 if( typeof driver.viewerApplicationList === 'function'){
\r
1323 return driver.viewerApplicationList( this );
\r
1325 return BASE_DRIVER.viewerApplicationList( this );
\r
1327 editorApplicationList: function(){
\r
1328 var driver = FILE_CONTROLER.getDriver( this );
\r
1329 if( typeof driver.editorApplicationList === 'function'){
\r
1330 return driver.editorApplicationList( this );
\r
1332 return BASE_DRIVER.viwerApps( this );
\r
1334 create: function(){
\r
1340 onCopy: function(){
\r
1343 onDelete: function(){
\r
1346 move: function( _newFolder, _newIndex, opt_callback ){
\r
1347 var _access = FILE_CONTROLER.getFileDataAccess( this );
\r
1348 _access.TREE.move( _access.parentData, this.getUID(), _newFolder, _newIndex, opt_callback );
\r
1350 replace: function( _newIndex, opt_callback ){
\r
1351 var _access = FILE_CONTROLER.getFileDataAccess( this );
\r
1352 _access.TREE.replace( _access.parentData, this.getUID(), _newIndex, opt_callback);
\r
1356 * 探しているファイルの属性と値を指定.一致する child の index を配列で返す.
\r
1358 search: function( obj, rule ){
\r
1359 var _children = FILE_CONTROLER.getChildren( this ),
\r
1362 for( var i=0, l=_children.length; i<l; ++i ){
\r
1363 _child = _children[ i ];
\r
1366 if( obj[ k ] !== _child[ k ] ){
\r
1371 c === true && ret.push( i );
\r
1375 destroy: function(){
\r
1376 var _access = FILE_CONTROLER.getFileDataAccess( this );
\r
1377 var _tree = _access.TREE;
\r
1378 if( _tree.getCurrentFile() === this ) return;
\r
1379 if( _tree.getRootFile() === this ) return;
\r
1380 for( var i=0, l = _tree.hierarchy(); i<l; ++i ){
\r
1381 if( _tree.getParentFileAt( i ) === this ){
\r
1385 var _index = Util.getIndex( FILEDATA_ACCESS, _access );
\r
1386 if( _index === -1 ) return;
\r
1388 FILEDATA_ACCESS.splice( _index, 1 );
\r
1389 delete _access.DATA;
\r
1390 delete _access.TREE;
\r
1391 delete _access.parentData;
\r
1398 var FileDriverBase = function( driverClass ){
\r
1399 this.getUID = function(){
\r
1400 return Util.getIndex( API_USER_LIST, driverClass );
\r
1402 this.getSeqentialFiles = function( _file ){
\r
1404 this.getName = function( _file ){
\r
1405 var _data = FILE_CONTROLER.getFileData( _file );
\r
1406 return _data.name || 'No Name';
\r
1408 this.getThumbnail = function( _file ){
\r
1409 var _data = FILE_CONTROLER.getFileData( _file ),
\r
1410 _type = _data.type,
\r
1412 if( _type === Const.FILE.TYPE.FOLDER){
\r
1413 _className = 'folder';
\r
1415 if( _type === Const.FILE.TYPE.IMAGE){
\r
1418 if( _type === Const.FILE.TYPE.TEXT){
\r
1421 if( _type === Const.FILE.TYPE.HTML){
\r
1424 if( _type === Const.FILE.TYPE.CSV){
\r
1427 if( _type === Const.FILE.TYPE.JSON){
\r
1430 if( _type === Const.FILE.TYPE.XML){
\r
1435 className: ' file-type-' + _className
\r
1438 this.getSummary = function( _file ){
\r
1439 var _data = FILE_CONTROLER.getFileData( _file ),
\r
1440 _type = _data.type;
\r
1441 if( _type === Const.FILE.TYPE.FOLDER ){
\r
1444 if( _type === Const.FILE.TYPE.IMAGE ){
\r
1445 return 'image file';
\r
1447 if( _type === Const.FILE.TYPE.TEXT ){
\r
1448 return 'text file';
\r
1450 if( _type === Const.FILE.TYPE.HTML ){
\r
1451 return 'html document file';
\r
1453 if( _type === Const.FILE.TYPE.CSV ){
\r
1454 return 'csv daat file';
\r
1456 if( _type === Const.FILE.TYPE.JSON ){
\r
1457 return 'json data file';
\r
1459 if( _type === Const.FILE.TYPE.XML ){
\r
1460 return 'xml data file';
\r
1464 this.getUpdatePolicy = function( _file ){
\r
1465 // debug用 全てのメニューを許可
\r
1466 return Const.FILE.UPDATE_POLICY.DSRWC;
\r
1468 this.read = function( _FILEorDATA ){
\r
1470 protects = Const.FILE.DATA_PROPERTY_RESERVED;
\r
1471 if( _FILEorDATA instanceof FileClass ){
\r
1472 data = FILE_CONTROLER.getFileData( _FILEorDATA )
\r
1474 data = _FILEorDATA;
\r
1477 function clone( src ) {
\r
1479 if( Type.isArray(src) === true ){
\r
1482 if( Type.isObject(src) === true ){
\r
1485 if( Type.isNumber(src) === true || Type.isString(src) === true || Type.isBoolean( src ) === true ){
\r
1490 for( var key in src ){
\r
1491 if( Util.getIndex( protects, key ) === -1 ){
\r
1493 ret[ key ] = clone( src[ key ]);
\r
1499 return clone( data );
\r
1501 this.write = function( _file, _newData, _onUpdateFunction ){
\r
1502 var _data = FILE_CONTROLER.getFileData( _file ),
\r
1503 _type = _data.type;
\r
1506 this.viewerApplicationList = function(){
\r
1509 this.editorApplicationList = function(){
\r
1512 this.onCreate = function(){
\r
1515 this.onSort = function(){
\r
1518 this.onCopy = function(){
\r
1521 this.onDelete = function(){
\r
1526 var BASE_DRIVER = new FileDriverBase();
\r
1528 var ROOT_FILEDATA = {
\r
1529 name: 'system root',
\r
1530 type: FILE_TYPE_IS_FOLDER,
\r
1533 SYSTEM_TREE = FILE_CONTROLER.createTree( SUPER_USER_KEY, ROOT_FILEDATA ),
\r
1534 ROOT_FILE = SYSTEM_TREE.getRootFile();
\r
1536 function createFileTypeID(){
\r
1537 return ++numFileType;
\r
1540 var FileAPIClass = function( driver ){
\r
1542 this.createFolderUnderRoot = function( _fileData ){
\r
1543 if( _fileData !== null && Type.isObject( _fileData ) === true ){
\r
1544 ROOT_FILEDATA.children.push( _fileData );
\r
1545 ROOT_FILE.dispatchEvent( new FileEventClass( Const.FILE.EVENT.GET_SEQENTIAL_FILES, ROOT_FILE, 'children', null ));
\r
1548 this.createFileEvent = function( _eventType, _file, _key, _value ){
\r
1549 return new FileEventClass( _eventType, _file, _key, _value );
\r
1551 this.createFileTypeID = createFileTypeID;
\r
1552 this.getFileDataAccess = FILE_CONTROLER.getFileDataAccess;
\r
1553 this.getFileData = FILE_CONTROLER.getFileData;
\r
1554 this.getJson = function( _data, _url, _onLoad, _onError ){
\r
1555 REQUEST_CONTROLER.getJson( driver, _data, _url, _onLoad, _onError );
\r
1557 this.createTree = function( _rootFile ){
\r
1558 return FILE_CONTROLER.createTree( driver, _rootFile );
\r
1560 this.isTreeInstance = function( _tree ){
\r
1561 return _tree instanceof TreeClass;
\r
1563 this.isFileInstance = function( _file ){
\r
1564 return _file instanceof FileClass;
\r
1566 this.isFileEvent = function( _event ){
\r
1567 return _event instanceof FileEventClass;
\r
1569 this.getConst = function(){
\r
1570 return Const; // constObject = constObject || clone( Const )
\r
1575 registerDriver: function( _class ){
\r
1576 _class.prototype = new FileDriverBase( _class );
\r
1577 var _driver = new _class();
\r
1579 DRIVER_LIST.push( _driver );
\r
1580 API_USER_LIST.push( _class );
\r
1582 return new FileAPIClass( _driver );
\r
1584 isDriver: function( _driver ){
\r
1585 return _driver instanceof FileDriverBase;
\r
1587 isTreeInstance: function( _tree ){
\r
1588 return _tree instanceof TreeClass;
\r
1590 isFileInstance: function( _file ){
\r
1591 return _file instanceof FileClass;
\r
1597 /* ----------------------------------------------------
\r
1598 * ApplicationManager
\r
1599 * window resize event, overlayApplication currentAplication に流す
\r
1602 var APPLICATION_LIST = [];
\r
1604 var AbstractBasicPane = function(){
\r
1605 var instance = null;
\r
1606 this.MIN_WIDTH = 240;
\r
1607 this.MIN_HEIGHT = 240;
\r
1608 this.init = function(){
\r
1610 instance.onInit();
\r
1612 this.onInit = function(){};
\r
1613 this.resize = function( _w, _h ){
\r
1614 if( instance.MIN_WIDTH > _w || instance.MIN_HEIGHT > _h ){
\r
1615 if( Type.isHTMLElement( instance.rootElement ) === true ){
\r
1620 instance.onPaneResize( _w, _h );
\r
1622 this.onPaneResize = function( _w, _h ){};
\r
1623 this.close = function(){
\r
1624 instance.onClose();
\r
1629 var AbstractApplication = function( displayName, appClass, isOverlay ){
\r
1630 var self = null, // init で設定
\r
1633 this.rootElement = document.createElement( 'div' );
\r
1634 this.bgColor = '#C1CACF';
\r
1635 this.getUID = function(){
\r
1636 return Util.getIndex( API_USER_LIST, appClass );
\r
1638 this.init = function(){
\r
1642 this.open = function( _w, _h /*, _option */ ){
\r
1643 if( self.MIN_WIDTH > _w || self.MIN_HEIGHT > _h ){
\r
1644 if( Type.isHTMLElement( self.rootElement ) === true ){
\r
1648 if( arguments.length > 2 ){
\r
1649 self.onOpen.apply( self, arguments );
\r
1651 self.onOpen( _w, _h );
\r
1654 this.resize = function( _w, _h ){
\r
1655 if( self.MIN_WIDTH > _w || self.MIN_HEIGHT > _h ){
\r
1656 if( Type.isHTMLElement( self.rootElement ) === true ){
\r
1661 self.onPaneResize( _w, _h );
\r
1663 this.close = function(){
\r
1664 if( self.onClose() === false ){
\r
1667 MouseEvent.remove( self );
\r
1668 KeyEvent.remove( self );
\r
1669 SystemTimer.remove( self );
\r
1670 AsyncCall.remove( self );
\r
1672 while( uiList.length > 0 ){
\r
1673 uiList.shift().destroy();
\r
1675 while( finderList.length > 0 ){
\r
1676 finderList.shift().destroy();
\r
1678 var elm = self.rootElement;
\r
1679 Util.removeAllChildren( elm );
\r
1680 elm.parentNode.removeChild( elm );
\r
1681 self.rootElement = null;
\r
1683 Application.shutdown( self, isOverlay );
\r
1684 self = appClass = uiList = null;
\r
1686 this.createUIGroup = function(){
\r
1687 var _ui = UI.createUIGroup( self );
\r
1688 uiList.push( _ui );
\r
1691 this.createFinder = function( _elmTarget, _tree, _header, _footer, _onSelect, _viewerOption, _editorOption ){
\r
1692 var _finder = Finder.create( self, _elmTarget, _tree, _header, _footer, _onSelect, _viewerOption, _editorOption );
\r
1693 finderList.push( _finder );
\r
1696 this.createBasicPane = function( _class, _options ){
\r
1697 if( Type.isFunction( _class ) === false ) return null;
\r
1698 _class.prototype = new AbstractBasicPane();
\r
1699 return new _class( _options );
\r
1703 AbstractApplication.prototype = new AbstractBasicPane();
\r
1704 AbstractApplication.prototype.onInit = function(){
\r
1707 AbstractApplication.prototype.onOpen = function( _w, _h /*, _option */ ){
\r
1710 AbstractApplication.prototype.onClose = function(){
\r
1713 }; // false の場合、close の拒否
\r
1714 AbstractApplication.prototype.addMouseEventListener = function( _element, _eventType, _handler ){
\r
1715 MouseEvent.add( this, _element, _eventType, _handler );
\r
1717 AbstractApplication.prototype.removeMouseEventListener = function( _element, _eventType, _handler ){
\r
1718 MouseEvent.remove( this, _element, _eventType, _handler );
\r
1720 AbstractApplication.prototype.addKeyEventListener = function( _eventType, _handler, _keyCode, _shift, _ctrl ){
\r
1721 KeyEvent.add( this, _eventType, _handler, _keyCode, _shift, _ctrl );
\r
1723 AbstractApplication.prototype.removeKeyEventListener = function( _eventType, _handler, _keyCode, _shift, _ctrl ){
\r
1724 KeyEvent.remove( this, _eventType, _handler, _keyCode, _shift, _ctrl );
\r
1726 AbstractApplication.prototype.shiftEnabled = function(){
\r
1727 return KeyEvent.shiftEnabled;
\r
1729 AbstractApplication.prototype.ctrlEnabled = function(){
\r
1730 return KeyEvent.ctrlEnabled;
\r
1732 AbstractApplication.prototype.addTimer = function( handler, time, once ){
\r
1733 SystemTimer.add( this, handler, time, !!once );
\r
1735 AbstractApplication.prototype.removeTimer = function( handler ){
\r
1736 SystemTimer.remove( this, handler );
\r
1738 AbstractApplication.prototype.addAsyncCall = function( _callback, _argments ){
\r
1739 AsyncCall.add( this, _callback, _argments );
\r
1741 AbstractApplication.prototype.removeAsyncCall = function( _callback ){
\r
1742 AsyncCall.remove( this, _callback );
\r
1744 AbstractApplication.prototype.fetchHTMLElement = function( id ){
\r
1745 var elm = doc.getElementById( id );
\r
1747 elm.removeAttribute( 'id' );
\r
1748 elm.parentNode.removeChild( elm );
\r
1753 var Application = ( function(){
\r
1755 var LIVE_APPLICATION_LIST = [];
\r
1757 var currentApplication = null,
\r
1758 coveredApplication = null,
\r
1762 var ApplicationReference = function( appClass, isOverlay, displayName, id, thumbnailUrl, tailColor ){
\r
1764 var application = null;
\r
1766 this.displayName = displayName;
\r
1767 this.thumbnailUrl = thumbnailUrl;
\r
1768 this.tailColor = tailColor;
\r
1769 this.getUID = function(){
\r
1770 return Util.getIndex( API_USER_LIST, appClass );
\r
1772 this.boot = function( /* _option */ ){
\r
1773 application = Application.boot( displayName, self.getUID(), appClass, isOverlay, Util.copyArray( arguments ) );
\r
1775 this.shutdown = function(){
\r
1776 if( !application ) return false;
\r
1778 if( ( isOverlay === true ? Overlay.hide() : application.close() ) === false ) return false;
\r
1779 application = null;
\r
1783 function asyncBootHome(){
\r
1784 currentApplication === null && Home.boot();
\r
1786 function asyncOpen( /* arguments */ ){
\r
1787 var _arg = Util.copyArray( arguments );
\r
1788 _arg.unshift( winW, winH );
\r
1789 currentApplication.open.apply( currentApplication, _arg );
\r
1792 register: function( _class, _overlay, _tail, _displayName, _id, _thumbnailUrl, _tailColor ){
\r
1793 APPLICATION_LIST.push( _class );
\r
1794 API_USER_LIST.push( _class );
\r
1795 var _ref = new ApplicationReference( _class, _overlay, _displayName, _id, _thumbnailUrl, _tailColor );
\r
1796 _tail === true && Home.add( _ref );
\r
1799 isBasicPaneInstance: function( _basicPane ){
\r
1800 return _basicPane instanceof AbstractBasicPane;
\r
1802 isApplicationInstance: function( _application ){
\r
1803 return _application instanceof AbstractApplication;
\r
1805 isApplicationReference: function( _reference ){
\r
1806 return _reference instanceof ApplicationReference;
\r
1808 isCurrentAppplication: function( _application ){
\r
1811 boot: function( displayName, uid, appClass, isOverlay, arg ){
\r
1812 if( currentApplication ){
\r
1813 if( currentApplication.getUID() === uid ) return null;
\r
1814 if( isOverlay === false && currentApplication.close() === false ) return null;
\r
1817 appClass.prototype = new AbstractApplication( displayName, appClass, isOverlay );
\r
1818 var application = new appClass(); // new は boot で
\r
1820 coveredApplication = isOverlay === true ? currentApplication : null;
\r
1822 Application.onCurrentApplicationChange( application );
\r
1824 if( isOverlay === false ){
\r
1825 body.style.backgroundColor = application.bgColor;
\r
1827 body.appendChild( application.rootElement );
\r
1828 application.init();
\r
1830 application.addAsyncCall( asyncOpen, arg );
\r
1832 Overlay.show( application, arg );
\r
1835 return application;
\r
1837 shutdown: function( _application, isOverlay ){
\r
1838 if( isOverlay === false ){
\r
1839 currentApplication = null;
\r
1840 AsyncCall.add( SUPER_USER_KEY, asyncBootHome );
\r
1842 Application.onCurrentApplicationChange( coveredApplication );
\r
1843 coveredApplication = null;
\r
1846 onCurrentApplicationChange: function( _application ){
\r
1847 if( Application.isApplicationInstance( _application ) === false ) return;
\r
1848 if( currentApplication === _application ) return;
\r
1849 currentApplication = _application;
\r
1850 MouseEvent.onCurrentApplicationChange( _application );
\r
1851 KeyEvent.updateCurrentListener( _application );
\r
1853 onApplicationShutdown: function( _application ){
\r
1854 LIVE_APPLICATION_LIST.splice( Util.getIndex( LIVE_APPLICATION_LIST, _application ) );
\r
1856 onWindowResize: function( w, h ){
\r
1859 currentApplication && currentApplication.resize( w, h );
\r
1860 Overlay.onWindowResize( w, h );
\r
1861 UI.onWindowResize( w, h );
\r
1863 onSystemShutdown: function(){
\r
1869 /* --------------------------------------------------------------
\r
1873 var Home = ( function(){
\r
1874 var APP_REF_LIST = [];
\r
1875 var ELM_TAIL_ORIGIN = ( function(){
\r
1876 var ret = document.createElement( 'div' ),
\r
1877 h2 = document.createElement( 'h2' );
\r
1878 ret.className = 'tail-wrapper';
\r
1879 ret.appendChild( h2 );
\r
1880 h2.appendChild( document.createTextNode( 'appName' ) );
\r
1884 var TailClass = function( appRef ){
\r
1885 this.elm = ELM_TAIL_ORIGIN.cloneNode( true );
\r
1886 this.destroy = function(){
\r
1887 appRef = self = elmName = null;
\r
1891 elmName = this.elm.getElementsByTagName( 'h2' )[ 0 ].firstChild;
\r
1893 this.elm.style.backgroundColor = appRef.tailColor;
\r
1894 elmName.data = appRef.displayName;
\r
1897 var ref = Application.register( function(){
\r
1906 for( var i=0, l=APP_REF_LIST.length; i<l; ++i ){
\r
1907 tail = new TailClass( APP_REF_LIST[ i ] );
\r
1908 tailList.push( tail );
\r
1910 elmContainer.appendChild( elm );
\r
1911 self.addMouseEventListener( elm, 'click', onTailClick );
\r
1915 function onTailClick( e ){
\r
1916 var _children = elmContainer.getElementsByTagName( 'div' );
\r
1917 for( var i=0, l=_children.length; i<l; ++i ){
\r
1918 if( this === _children[ i ] ){
\r
1919 APP_REF_LIST[ i ].boot();
\r
1925 this.bgColor = '#0F6D39';
\r
1926 this.MIN_WIDTH = 320;
\r
1927 this.MIN_HEIGHT = 320;
\r
1928 this.onInit = function(){
\r
1929 self.rootElement.id = 'home-root';
\r
1930 elmContainer = document.createElement( 'div' );
\r
1931 self.rootElement.appendChild( elmContainer );
\r
1932 elmContainer.id = 'home-tail-container';
\r
1934 this.onOpen = function( _w, _h ){
\r
1939 this.onPaneResize = function( _w, _h ){
\r
1942 this.onClose = function(){
\r
1943 self.removeMouseEventListener();
\r
1944 while( tailList.length > 0 ){
\r
1945 tailList.shift().destroy();
\r
1947 self = tailList = elmContainer = null;
\r
1949 }, false, false, 'home', 'home', null );
\r
1952 add: function( _appRef ){
\r
1953 if( Application.isApplicationReference( _appRef ) === false ) return;
\r
1954 Util.getIndex( APP_REF_LIST, _appRef ) === -1 && APP_REF_LIST.push( _appRef );
\r
1962 /* --------------------------------------------------------------
\r
1966 * スクリーン座標は、コンピュータのディスプレイの左上を原点とする座標系である。screenX, screenY属性で取得できる。Javascritpでは、同名のプロパティとして実装されている。
\r
1967 * しかし、これは、現実的には、何の役に立たない。ブラウザ自体がディスプレイのどの位置にいるのかがわからないので、画面上の位置を知ったところで、何にもならないからだ。
\r
1970 * ウインドウ座標とは、現在のブラウザのウインドウの、ドキュメントを表示している部分の左上原点とした座標である。
\r
1971 * 問題は、ウインドウは、必ずしもドキュメント全体を表示するとは限らない。スクロールと呼ばれるUIによって、ドキュメントの一部だけを表示しているかもしれない。
1973 var XBrowserEvent = ( function(){
\r
1974 var wrappedHandlerClass,
\r
1975 wrappedEventClass,
\r
1978 if( window.addEventListener ){
\r
1979 wrappedHandlerClass = function( element, handler ){
\r
1980 this.handler = function( e ){
\r
1981 if( handler.call( element, e ) !== false ) return;
\r
1982 e.preventDefault();
\r
1983 e.stopPropagation();
\r
1986 this.destroy = function(){
\r
1987 element = handler = null;
\r
1988 delete this.handler;
\r
1989 delete this.destroy;
\r
1993 wrappedEventClass = function( e, element ){
\r
1995 this.type = e.type;
\r
1996 this.target = e.srcElement;
\r
1997 this.currentTarget = element;
\r
1998 this.relatedTarget = e.formElement ? e.formElement : e.toElement;
\r
1999 this.eventPhase = e.srcElement === element ? 2: 3;
\r
2001 this.clientX = e.clientX;
\r
2002 this.clientY = e.clientY;
\r
2003 this.screenX = e.screenX;
\r
2004 this.screenY = e.screenY;
\r
2006 this.altKey = e.altKey;
\r
2007 this.ctrlKey = e.ctrlKey;
\r
2008 this.shiftKey = e.shiftKey;
\r
2009 this.charCode = e.keyCode;
\r
2011 this.wheelDelta = e.wheelDelta;
\r
2013 e = element = null;
\r
2015 wrappedEventClass.prototype.stopPropagation = function(){
\r
2016 this._event.cancelBubble = true;
\r
2018 wrappedEventClass.prototype.preventDefault = function(){
\r
2019 this._event.returnValue = false;
\r
2022 if( doc.attachEvent ){
\r
2023 wrappedHandlerClass = function( element, handler ){
\r
2024 this.handler = function(){
\r
2025 var e = new wrappedEventClass( window.event, element );
\r
2026 if( handler.call( element, e ) !== false ) return;
\r
2027 e.preventDefault();
\r
2028 e.stopPropagation();
\r
2029 e._event.keyCode = 0;
\r
2032 this.destroy = function(){
\r
2033 element = handler = null;
\r
2034 delete this.handler;
\r
2035 delete this.destroy;
\r
2041 find: function( _ticket ){
\r
2042 for( var i=0, l= tmp.list.length, _item; i<l; ++i ){
\r
2043 _item = tmp.list[ i ];
\r
2044 if( _item.match( _ticket.element, _ticket.eventType ) === true ){
\r
2051 tmp.ticketClass = function( _ticket ){
\r
2053 this.element = _ticket.element;
\r
2054 this.eventType = _ticket.eventType;
\r
2055 this.handlers = [ _ticket.handler ];
\r
2056 this.element[ 'on' + this.eventType ] = function( e ){
\r
2057 return self.fire( self, e );
\r
2061 tmp.ticketClass.prototype = {
\r
2062 add: function( _ticket ){
\r
2063 this.match( _ticket.element, _ticket.eventType ) === true &&
\r
2064 this.match( null, null, _ticket.handler ) === false &&
\r
2065 this.handlers.push( _ticket.handler );
\r
2067 remove: function( _ticket ){
\r
2068 if( this.match( _ticket.element, _ticket.eventType, _ticket.handler ) === true ){
\r
2069 var i = Util.getIndex( this.handlers, handler );
\r
2070 i !== 0 && this.handlers.splice( i, 1 );
\r
2071 this.handlers.length === 0 && this.destroy();
\r
2074 fire: function( self, e ){
\r
2075 e = e || new wrappedEventClass( window.event, self.element );
\r
2076 for( var i=self.handlers.length, cancel; i; ){
\r
2077 self.element._currentHandler = self.handlers[ --i ];
\r
2078 if( self.element._currentHandler( e ) === false ) cancel = false;
\r
2079 delete self.element._currentHandler;
\r
2083 match: function( element, eventType, handler ){
\r
2084 if( handler && Util.getIndex( this.handlers, handler ) === -1 ) return false;
\r
2085 if( eventType && this.eventType !== eventType ) return false;
\r
2086 if( element && this.element !== element ) return false;
\r
2089 destroy: function(){
\r
2090 this.element[ 'on' + this.eventType ] = '';
\r
2091 tmp.list.splice( Util.getIndex( tmp.list, this ), 1 );
\r
2092 delete this.element;
\r
2093 delete this.eventType;
\r
2094 delete this.handlers;
\r
2101 add: function( _ticket ){
\r
2102 if( doc.addEventListener ){
\r
2103 XBrowserEvent.add = function( _ticket ){
\r
2104 _ticket.wrappedHandler = new wrappedHandlerClass( _ticket.element, _ticket.handler );
\r
2105 _ticket.element.addEventListener( _ticket.eventType, _ticket.wrappedHandler.handler, false );
\r
2108 if( doc.attachEvent ){
\r
2109 XBrowserEvent.add = function( _ticket ){
\r
2110 _ticket.wrappedHandler = new wrappedHandlerClass( _ticket.element, _ticket.handler );
\r
2111 _ticket.element.attachEvent( 'on' + _ticket.eventType, _ticket.wrappedHandler.handler );
\r
2114 XBrowserEvent.add = function( _ticket ){
\r
2115 var t = tmp.find( _ticket );
\r
2119 tmp.list.push( new tmp.ticketClass( _ticket ) );
\r
2124 XBrowserEvent.add( _ticket );
\r
2126 remove: function( _ticket ){
\r
2127 if( doc.removeEventListener ){
\r
2128 XBrowserEvent.remove = function( _ticket ){
\r
2129 _ticket.element.removeEventListener( _ticket.eventType, _ticket.wrappedHandler.handler, false );
\r
2130 _ticket.wrappedHandler.destroy();
\r
2133 if( doc.detachEvent ){
\r
2134 XBrowserEvent.remove = function( _ticket ){
\r
2135 _ticket.element.detachEvent( 'on' + _ticket.eventType, _ticket.wrappedHandler.handler );
\r
2136 _ticket.wrappedHandler.destroy();
\r
2139 XBrowserEvent.remove = function( _ticket ){
\r
2140 var t = tmp.find( _ticket );
\r
2142 t.remove( _ticket );
\r
2147 XBrowserEvent.remove( _ticket );
\r
2153 * EventTicketClass
\r
2155 var EventTicketClass = function( _element, _eventType, _handler ){
\r
2156 this.element = _element;
\r
2157 this.eventType = _eventType;
\r
2158 this.handler = _handler;
\r
2159 this.wrappedHandler = null; // for ie
\r
2161 XBrowserEvent.add( this );
\r
2163 _element = _eventType = _handler = null;
\r
2165 EventTicketClass.prototype = {
\r
2166 match: function( _element, _eventType, _handler ){
\r
2167 if( _handler && _handler !== this.handler ) return false;
\r
2168 if( _eventType && _eventType !== this.eventType ) return false;
\r
2169 if( _element && _element !== this.element ) return false;
\r
2173 destroy: function( _element, _eventType, _handler ){
\r
2174 if( this.match( _element, _eventType, _handler ) === false ) return false;
\r
2176 XBrowserEvent.remove( this );
\r
2178 delete this.element;
\r
2179 delete this.eventType;
\r
2180 delete this.handler;
\r
2181 delete this.wrappedHandler;
\r
2187 var ReadyEvent = ( function(){
\r
2193 function detect(){
\r
2194 var state = document.readyState;
\r
2195 if( state === 'loaded' || state === 'complete' ){
\r
2196 timer && window.clearInterval( timer );
\r
2201 function ieDetect(){
\r
2202 if( this.readyState === 'loaded' || this.readyState === 'complete' ){
\r
2203 this.onreadystatechange = new Function();
\r
2204 this.onreadystatechange = null;
\r
2205 this.parentNode.removeChild( this );
\r
2211 function onReady(){
\r
2213 ticketReady && ticketReady.destroy();
\r
2214 ticketLoad && ticketLoad.destroy();
\r
2215 ticketReady = ticketLoad = null;
\r
2218 // Apple WebKit (Safari, OmniWeb, ...)
\r
2219 if( doc.readyState && !!UA.WEBKIT ){
\r
2220 timer = window.setInterval( detect, 50 );
\r
2222 if( document.readyState && UA.isIE ){
\r
2223 document.write('<script type="text/javascript" defer="defer" id="ieDOMContentLoaded" src="' +
\r
2224 ( ( window.location.protocol === 'https:' ) ? '://0' : 'javascript:void(0)' ) +
\r
2226 script = document.getElementById( 'ieDOMContentLoaded' );
\r
2227 script.onreadystatechange = ieDetect;
\r
2229 ticketReady = new EventTicketClass( doc, 'DOMContentLoaded', onReady );
\r
2230 ticketLoad = new EventTicketClass( doc, 'load', onReady );
\r
2237 /* =====================================================
\r
2242 var ResizeEvent = ( function(){
\r
2243 var _globalLock = 0;
\r
2245 var root = window;
\r
2248 function getInnerSize(){
\r
2250 w : root.innerWidth || root.clientWidth,
\r
2251 h : root.innerHeight || root.clientHeight
\r
2254 function unlock(){
\r
2258 if( document.uniqueID ){
\r
2259 _resize = function(){
\r
2260 root = (doc.compatMode || "") !== "CSS1Compat" ? doc.body : doc.documentElement;
\r
2264 if( !_globalLock++ ){
\r
2265 var size = getInnerSize();
\r
2266 if( w !== size.w || h !== size.h ){// resized
\r
2270 Application.onWindowResize( w, h );
\r
2272 window.setTimeout( unlock, 0 );
\r
2275 window.setTimeout( loop, 100 );
\r
2280 _resize = function(){
\r
2281 new EventTicketClass( window, 'resize', onResize );
\r
2283 function onResize(){
\r
2284 if( !_globalLock++ ) {
\r
2285 var size = getInnerSize();
\r
2286 if( w !== size.w || h !== size.h ){// resized
\r
2290 Application.onWindowResize( w, h );
\r
2292 window.setTimeout( unlock, 0 );
\r
2298 AsyncCall.add( SUPER_USER_KEY, _resize );
\r
2301 getSize: getInnerSize,
\r
2302 onSystemShutdown: function(){
\r
2309 /* =====================================================
\r
2313 var MouseEvent = ( function(){
\r
2314 var CLICK_OFFSET = 2 * 2;
\r
2316 var EVENT_LIST_MAP = [],
\r
2321 * mousedown, mouseup, の移動距離を調べて clickハンドラ を呼ぶ
\r
2323 var ClickEventTicketClass = function( element, clickhandler ){
\r
2324 var startX, startY,
\r
2325 mousedownTicket = new EventTicketClass( element, 'mousedown', mousedownHandler ),
\r
2326 mouseupTicket, mouseoutTicket;
\r
2328 function mousedownHandler( e ){
\r
2329 startX = e.clientX;
\r
2330 startY = e.clientY;
\r
2332 mouseupTicket = new EventTicketClass( element, 'mouseup', mouseupHandler );
\r
2333 mouseoutTicket = new EventTicketClass( element, 'mouseout', mouseoutHandler );
\r
2336 function mouseupHandler( e ){
\r
2337 var offsetX = e.clientX - startX,
\r
2338 offsetY = e.clientY - startY;
\r
2339 mouseoutHandler();
\r
2340 if( offsetX * offsetX + offsetY * offsetY < CLICK_OFFSET ){
\r
2341 if( Function.prototype.call ){
\r
2342 return clickhandler.call( element, e );
\r
2344 element._currentHandler = clickhandler;
\r
2345 var ret = element._currentHandler( e );
\r
2346 delete element._currentHandler;
\r
2350 function mouseoutHandler( e ){
\r
2351 mouseupTicket && mouseupTicket.destroy();
\r
2352 mouseoutTicket && mouseoutTicket.destroy();
\r
2353 mouseupTicket = mouseoutTicket = null;
\r
2356 this.element = element;
\r
2357 this.handler = clickhandler;
\r
2358 this.destroy = function( _element, _eventType, _handler ){
\r
2359 if( this.match( _element, _eventType, _handler ) === false ) return false;
\r
2361 mouseoutHandler();
\r
2362 mousedownTicket.destroy();
\r
2363 element = clickhandler = mousedownTicket = null;
\r
2365 delete this.element;
\r
2366 delete this.eventType;
\r
2367 delete this.handler;
\r
2372 ClickEventTicketClass.prototype = {
\r
2373 eventType: 'click',
\r
2374 match : EventTicketClass.prototype.match
\r
2379 var WheelEventTicketClass = ( function(){
\r
2381 return function( element, wheelhandler ){
\r
2382 this.wheelTicket = new EventTicketClass( element, 'DOMMouseScroll', onWheel );
\r
2383 this.element = element;
\r
2384 this.handler = wheelhandler;
\r
2385 this.destroy = function( _element, _eventType, _handler ){
\r
2386 if( this.match( _element, _eventType, _handler ) === false ) return false;
\r
2387 element = wheelhandler = null;
\r
2389 this.wheelTicket && this.wheelTicket.destroy();
\r
2391 delete this.wheelTicket;
\r
2392 delete this.element;
\r
2393 delete this.handler;
\r
2398 function onWheel( e ){
\r
2399 e.wheelDelta = e.detail * -40;
\r
2400 return wheelhandler.call( element, e );
\r
2404 if( true || UA.isIE ){
\r
2405 return function( element, wheelhandler ){
\r
2406 this.wheelTicket = new EventTicketClass( element, 'mousewheel', wheelhandler );
\r
2407 this.element = element;
\r
2408 this.handler = wheelhandler;
\r
2409 element = wheelhandler = null;
\r
2412 TMP.wheelList = [];
\r
2413 //TMP.wheelLegacy = undefined;
\r
2414 TMP.onWheel = function( e ){
\r
2415 e = e || window.event;
\r
2416 var cancel = true,
\r
2417 f = TMP.wheelLegacy;
\r
2418 if( f ) cancel = f.call( this, e );
\r
2420 for( i = TMP.wheelList.length; i; ){
\r
2421 if( TMP.wheelList[ --i ].call( this, e ) === false ) cancel = false;
\r
2425 return function( element, wheelhandler ){
\r
2426 this.wheelTicket = null;
\r
2427 this.element = element;
\r
2428 this.handler = wheelhandler;
\r
2429 this.destroy = function( _element, _eventType, _handler ){
\r
2430 if( this.match( _element, _eventType, _handler ) === false ) return false;
\r
2432 TMP.wheelList.splice( Util.getIndex( TMP.wheelList, this.handler ) );
\r
2433 if( TMP.wheelList.length === 0 ) this.element.onmousewheel = '';
\r
2435 delete this.element;
\r
2436 delete this.handler;
\r
2441 if( TMP.wheelList.length === 0 ){
\r
2442 //TMP.wheelLegacy = Type.isFunction( window.onmousewheel ) === true ? window.onmousewheel : undefined;
\r
2443 element.onmousewheel = TMP.onWheel;
\r
2445 TMP.wheelList.push( wheelhandler );
\r
2446 element = wheelhandler = null;
\r
2450 WheelEventTicketClass.prototype = {
\r
2451 eventType : 'mousewheel',
\r
2452 match : EventTicketClass.prototype.match,
\r
2453 destroy : function( _element, _eventType, _handler ){
\r
2454 if( this.match( _element, _eventType, _handler ) === false ) return false;
\r
2456 this.wheelTicket && this.wheelTicket.destroy();
\r
2458 delete this.wheelTicket;
\r
2459 delete this.element;
\r
2460 delete this.handler;
\r
2468 add: function( _apiuser, _element, _eventType, _handler ){
\r
2469 if( isApiUser( _apiuser ) === true &&
\r
2470 ( Type.isHTMLElement( _element ) === true || _element === window || _element === doc ) &&
\r
2471 Type.isString( _eventType ) === true &&
\r
2472 Type.isFunction( _handler ) === true
\r
2474 var _uid = _apiuser.getUID(),
\r
2475 _events = EVENT_LIST_MAP[ _uid ];
\r
2476 if( Type.isArray( _events ) === false ){
\r
2477 _events = EVENT_LIST_MAP[ _uid ] = [];
\r
2480 for( var i=0, l=_events.length; i<l; ++i ){
\r
2481 if( _events[ i ].match( _element, _eventType, _handler ) === true ) return;
\r
2484 if( _eventType === 'click' ){
\r
2485 _events.push( new ClickEventTicketClass( _element, _handler ) );
\r
2487 if( _eventType === 'mousewheel' ){
\r
2488 _events.push( new WheelEventTicketClass( _element, _handler ) );
\r
2490 _events.push( new EventTicketClass( _element, _eventType, _handler ) );
\r
2494 remove: function( _apiuser, _element, _eventType, _handler ){
\r
2495 if( isApiUser( _apiuser ) === true ){
\r
2496 var _uid = _apiuser.getUID(),
\r
2497 _events = EVENT_LIST_MAP[ _uid ],
\r
2500 if( Type.isArray( _events ) === false ) return;
\r
2501 for( ;i < _events.length; ){
\r
2502 if( _events[ i ].destroy( _element, _eventType, _handler ) === true ){
\r
2503 _events.splice( i, 1 );
\r
2508 if( _events.length === 0 ){
\r
2509 _events = EVENT_LIST_MAP[ _uid ] = null;
\r
2513 onCurrentApplicationChange: function(){
\r
2516 onApplicationShutdown: function(){
\r
2519 onSystemShutdown: function(){
\r
2525 /* ----------------------------------------
\r
2528 * - EDITABLE_TEXT_CONTROL
\r
2530 * .SHIFT_DOWN_EVENT: 'shiftDown',
\r
2531 * .SHIFT_UP_EVENT: 'shiftUp',
\r
2532 * .CTRL_DOWN_EVENT: 'ctrlDown',
\r
2533 * .CTRL_UP_EVENT: 'ctrlUp',
\r
2534 * .SPACE_DOWN_EVENT: 'spaceDown',
\r
2535 * .SPACE_UP_EVENT: 'spaceUp',
\r
2536 * .init: function,
\r
2537 * .addKeyDownEvent: function,
\r
2538 * .keyEventDispatcher: function,
\r
2540 * ショートカットキーの監視とテキスト入力(input, textarea)、チェックボックスを管理する。
\r
2541 * キー入力はdocumentで受けて、テキスト編集中(input, textarea)はそちらにキーイベント流す。
\r
2544 var KeyEvent = ( function(){
\r
2545 var EVENT_LIST_MAP = [],
\r
2546 application = null,
\r
2547 currentList = null;
\r
2551 var focusTicket = null,
\r
2552 keydownTicket = null,
\r
2553 keyupTicket = null,
\r
2555 keypressTicket = null;
\r
2557 function onKeyChange( e ){
\r
2558 var cancel = false,
\r
2560 key = e.keyCode || e.charCode || e.which,
\r
2561 shift = Type.isBoolean( e.shiftKey ) === true ? e.shiftKey : ( e.modifiers & Event.SHIFT_MASK ),
\r
2562 ctrl = Type.isBoolean( e.ctrlKey ) === true ? e.ctrlKey : ( e.modifiers & Event.CONTROL_MASK ),
\r
2565 if( key === 16 || shift === true ){
\r
2566 KeyEvent.shiftEnabled = type !== 'keyup';
\r
2568 if( key === 17 || ctrl === true ){
\r
2569 KeyEvent.ctrlEnabled = type !== 'keyup';
\r
2572 for( var i=currentList.length; t = currentList[ --i ]; ){
\r
2573 if( Type.isFunction( t[ type ] ) === true && t.keyCode === key && ( t.shift === undefined || t.shift === shift ) && ( t.ctrl === undefined || t.ctrl === ctrl )){
\r
2574 AsyncCall.add( t.apiuser, t[ type ], e );
\r
2578 if( cancel === true || key === 18 || key === 9 || key === 27 || e.altKey === true ){ // 13.enter 18.esc 9.tab 27.esc || ( key === 13 && overlayEnabled === false)
\r
2583 if( UA.isIE === true && UA.ieRenderingVersion < 9 ){
\r
2584 keyPress = function( e ){
\r
2585 var key = e.charCode;
\r
2586 if( key === 13 || key === 27 ){
\r
2587 e.type = 'keydown';
\r
2588 return onKeyChange( e );
\r
2593 var KeyEventTicketClass = function( _apiuser, _type, _onKeydown, _onKeyup, _keyCode, _shift, _ctrl ){
\r
2594 this.apiuser = _apiuser;
\r
2595 this.type = _type;
\r
2596 this.keydown = _onKeydown;
\r
2597 this.keyup = _onKeyup;
\r
2598 this.keyCode = _keyCode;
\r
2599 this.shift = _shift;
\r
2600 this.ctrl = _ctrl;
\r
2601 _apiuser = _onKeydown = _onKeyup = null;
\r
2603 KeyEventTicketClass.prototype = {
\r
2604 match: function( _apiuser, _type, _handler, _keyCode, _shift, _ctrl ){
\r
2605 if( _apiuser && _apiuser !== this.apiuser ) return false;
\r
2606 if( _type && _type !== this.type ) return false;
\r
2608 if( this.type === 'keydown' ){
\r
2609 if( _handler !== this.keydown ) return false;
\r
2611 if( _handler !== this.keyup ) return false;
\r
2614 if( _keyCode && _keyCode !== this.keyCode ) return false;
\r
2615 if( _shift && _shift !== this.shift ) return false;
\r
2616 if( _ctrl && _ctrl !== this.ctrl ) return false;
\r
2619 destroy: function( _apiuser, _type, _handler, _keyCode, _shift, _ctrl ){
\r
2620 if( this.match( _apiuser, _type, _handler, _keyCode, _shift, _ctrl ) === false ) return false;
\r
2622 delete this.apiuser;
\r
2623 delete this.keydown;
\r
2624 delete this.keyup;
\r
2630 function registerEvent( _apiuser, _type, _onKeydown, _onKeyup, _keyCode, _shift, _ctrl ){
\r
2631 var _uid = _apiuser.getUID(),
\r
2632 _list = EVENT_LIST_MAP[ _uid ];
\r
2633 if( Type.isArray( _list ) === false ){
\r
2634 _list = EVENT_LIST_MAP[ _uid ] = [];
\r
2636 for( var i=0, l=_list.length; i<l; ++i ){
\r
2637 if( _list[ i ].match( _apiuser, _type, _onKeydown || _onKeyup, _keyCode, _shift, _ctrl ) === true ) return;
\r
2639 _list.push( new KeyEventTicketClass( _apiuser, _type, _onKeydown, _onKeyup, _keyCode, _shift, _ctrl ));
\r
2641 if( _apiuser === application ) KeyEvent.updateCurrentListener( _apiuser );
\r
2645 add: function( _apiuser, _type, _handler, _keyCode, _shift, _ctrl ){
\r
2646 if( _type === 'keydown' ){
\r
2647 registerEvent( _apiuser, _type, _handler, null, _keyCode, _shift, _ctrl );
\r
2649 if( _type === 'keyup' ){
\r
2650 registerEvent( _apiuser, _type, null, _handler, _keyCode, _shift, _ctrl );
\r
2652 if( _type === 'keychange' ){
\r
2653 registerEvent( _apiuser, _type, _handler, _handler, _keyCode, _shift, _ctrl );
\r
2655 if( _type === 'cursol' ){
\r
2659 remove: function( _apiuser, _type, _handler, _keyCode, _shift, _ctrl ){
\r
2660 var _list = EVENT_LIST_MAP[ _apiuser.getUID() ],
\r
2662 if( Type.isArray( _list ) === true ){
\r
2663 while( i < _list.length ){
\r
2664 if( _list[ i ].destroy( _apiuser, _type, _handler, _keyCode, _shift, _ctrl ) === true ){
\r
2665 _list.splice( i, 1 );
\r
2671 if( _apiuser === application ) KeyEvent.updateCurrentListener( _apiuser );
\r
2673 shiftEnabled: false,
\r
2674 ctrlEnabled: false,
\r
2677 * currrentApplication ( overlay Application ) or
\r
2680 updateCurrentListener: function( _apiuser ){
\r
2681 application = _apiuser;
\r
2682 currentList = EVENT_LIST_MAP[ _apiuser.getUID() ] || [];
\r
2687 for( var i=currentList.length; _ticket = currentList[ --i ]; ){
\r
2688 if( _down === false ) _down = !!_ticket.keydown;
\r
2689 if( _up === false ) _up = !!_ticket.keyup;
\r
2690 if( _down && _up ) break;
\r
2692 if( _down === true ){
\r
2693 keydownTicket = new EventTicketClass( doc, 'keydown', onKeyChange );
\r
2694 keypressTicket = keyPress !== null ? new EventTicketClass( doc, 'keypress', keyPress ) : null;
\r
2696 keydownTicket && keydownTicket.destroy();
\r
2697 keypressTicket && keypressTicket.destroy();
\r
2698 keydownTicket = keypressTicket = null;
\r
2700 if( _up === true ){
\r
2701 keyupTicket = new EventTicketClass( doc, 'keyup', onKeyChange );
\r
2703 keyupTicket && keyupTicket.destroy();
\r
2704 keyupTicket = null;
\r
2707 if( _down === true || _up === true ){
\r
2708 focusTicket = new EventTicketClass( doc, 'mouseenter', window.focus );
\r
2710 focusTicket && focusTicket.destroy();
\r
2711 focusTicket = null;
\r
2714 onApplicationShutdown: function( _apiuser ){
\r
2715 KeyEvent.remove( _apiuser );
\r
2717 onSystemShutdown: function(){
\r
2723 /* ----------------------------------------
\r
2727 var Overlay = ( function(){
\r
2728 var elmContainer, elmShadow, elmCloseButton,
\r
2729 application = null,
\r
2731 bodyOverflow = '',
\r
2734 function onCloseClick( e ){
\r
2738 function asyncInit( /* arguments */ ){
\r
2740 //body.appendChild( application.rootElement );
\r
2741 elmContainer.insertBefore( application.rootElement, elmCloseButton );
\r
2742 application.init();
\r
2746 function asyncOpen( /* arguments */ ){
\r
2748 var _arg = Util.copyArray( arguments );
\r
2749 _arg.unshift( windowW, windowH );
\r
2750 application.open.apply( application, _arg );
\r
2752 elmContainer.style.cssText = "top:" + body.scrollTop + 'px;display:none;';
\r
2753 $( elmContainer ).stop().fadeIn( onFadeInComplete );
\r
2755 function onFadeInComplete(){
\r
2756 KeyEvent.add( application, Const.KEY.EVENT.KEY_DOWN, Overlay.hide, 27 ); // 27.esc
\r
2757 MouseEvent.add( application, elmCloseButton, 'click', onCloseClick );
\r
2759 function onFadeOutComplete(){
\r
2760 Util.removeAllChildren( elmContainer );
\r
2761 body.removeChild( elmContainer );
\r
2762 elmContainer = elmShadow = elmCloseButton = null;
\r
2765 show: function( _application, _bootParams ){
\r
2766 if( visible === true && application === _application ) return;
\r
2767 if( Application.isApplicationInstance( _application ) === false ) return;
\r
2769 elmContainer = document.createElement( 'div' );
\r
2770 body.appendChild( elmContainer );
\r
2772 elmContainer.id = 'overlay-container';
\r
2774 bodyOverflow = body.style.overflow;
\r
2775 body.style.overflow = 'hidden';
\r
2777 elmShadow = document.createElement( 'div' );
\r
2778 elmContainer.appendChild( elmShadow );
\r
2779 elmShadow.id = 'overlay-shadow';
\r
2781 elmCloseButton = document.createElement( 'div' );
\r
2782 elmContainer.appendChild( elmCloseButton );
\r
2783 elmCloseButton.id = 'overlay-close-button';
\r
2784 elmCloseButton.appendChild( document.createTextNode( 'x' ) );
\r
2786 elmContainer.style.display = 'none'; // hide for fadeIn
\r
2788 _application.addAsyncCall( asyncInit );
\r
2789 _application.addAsyncCall( asyncOpen, _bootParams );
\r
2792 application = _application;
\r
2795 if( visible === false ) return;
\r
2796 if( application.close() === false ) return false;
\r
2798 body.style.overflow = bodyOverflow;
\r
2800 $( elmContainer ).stop().css( {
\r
2803 }).fadeOut( onFadeOutComplete );
\r
2806 KeyEvent.remove( application, Const.KEY.EVENT.KEY_DOWN, Overlay.hide ); // 27.esc
\r
2807 MouseEvent.remove( application, elmCloseButton );
\r
2809 application = null;
\r
2811 onWindowResize: function( _windowW, _windowH ){
\r
2812 windowW = _windowW;
\r
2813 windowH = _windowH;
\r
2815 if( application === null ) return;
\r
2817 elmContainer.style.height = _windowH + 'px';
\r
2818 elmContainer.style.top = body.scrollTop + 'px';
\r
2820 elmShadow.style.height = _windowH + 'px';
\r
2822 AsyncCall.add( application, application.resize, [ _windowW, _windowH ] );
\r
2827 /* ----------------------------------------
\r
2831 * form -> overlay -> view
\r
2835 var UI = ( function(){
\r
2837 currentUser = null,
\r
2838 currentList = null,
\r
2840 currentItem = null,
\r
2844 var CLASSNAME_COMBOBOX_OPTION = 'combobox-option',
\r
2845 ELM_A_ORIGIN = ( function(){
\r
2846 var ret = document.createElement( 'a' );
\r
2850 ELM_INPUT_TEXT = ( function(){
\r
2851 var ret = document.createElement( 'input' );
\r
2852 ret.type = 'text';
\r
2855 ELM_COMBOBOX = ( function(){
\r
2856 var ret = document.createElement( 'a' ),
\r
2857 elmToggle = document.createElement( 'span' ),
\r
2858 elmValue = document.createElement( 'span' );
\r
2860 ret.appendChild( elmToggle );
\r
2861 ret.appendChild( elmValue );
\r
2862 elmToggle.className = 'combobox-toggle';
\r
2863 elmValue.className = 'combobox-value';
\r
2865 elmToggle.appendChild( document.createTextNode( '▼' ));
\r
2866 elmValue.appendChild( document.createTextNode( 'null' ));
\r
2870 var InputTextClass = function( apiuser, uiGroup, elmWrapper, elmValue, onUpdate, validater ){
\r
2871 var elmA = ELM_A_ORIGIN.cloneNode( true ),
\r
2876 value = elmValue.innerHTML;
\r
2877 elmValue.innerHTML = '';
\r
2878 elmValue.className += ' editable-text';
\r
2879 elmValue.appendChild( elmA );
\r
2881 this.value = function( _value ){
\r
2882 if( Type.isString( _value ) === true ){
\r
2883 elmA.innerHTML = value = _value;
\r
2884 if( focus === true ){
\r
2885 ELM_INPUT_TEXT.value = value;
\r
2888 focus === true && instance.blur();
\r
2891 this.focus = function( e ){
\r
2893 start( apiuser, uiGroup, instance );
\r
2894 elmA.style.display = 'none';
\r
2895 elmValue.appendChild( ELM_INPUT_TEXT );
\r
2896 ELM_INPUT_TEXT.value = value;
\r
2898 ELM_INPUT_TEXT.focus();
\r
2899 ELM_INPUT_TEXT.select();
\r
2906 this.blur = function( keep ){
\r
2907 var _newValue = ELM_INPUT_TEXT.value,
\r
2908 _validated = Type.isFunction( validater ) === true ? '' + validater( _newValue ) : _newValue;
\r
2909 _newValue = keep !== 27 ? _validated : value; // 27:ESC
\r
2911 elmValue.removeChild( ELM_INPUT_TEXT );
\r
2913 elmA.innerHTML = _newValue;
\r
2914 elmA.style.display = 'block';
\r
2916 onUpdate && _newValue !== value && onUpdate( _newValue, value );
\r
2918 value = _newValue;
\r
2920 finish( apiuser, uiGroup, instance );
\r
2922 this.enabled = function(){
\r
2925 this.visible = function( _visible ){
\r
2926 if( Type.isBoolean( _visible ) === true ){
\r
2927 elmWrapper.style.display = _visible ? '' : 'none';
\r
2928 visible = _visible;
\r
2932 this.destroy = function(){
\r
2933 if( focus === true ){
\r
2934 elmValue.removeChild( ELM_INPUT_TEXT );
\r
2936 MouseEvent.remove( apiuser, elmWrapper );
\r
2937 apiuser = uiGroup = elmWrapper = elmValue = elmA = onUpdate = validater = instance = null;
\r
2939 instance.value( value );
\r
2940 MouseEvent.add( apiuser, elmWrapper, 'click', instance.focus );
\r
2943 var ButtonClass = function( apiuser, uiGroup, elmWrapper, onUpdate ){
\r
2944 var className = elmWrapper.className || '',
\r
2949 MouseEvent.add( apiuser, elmWrapper, 'click', onClick );
\r
2951 function onClick(){
\r
2956 this.focus = function(){
\r
2958 elmWrapper.className = className + ' button-has-focus';
\r
2959 start( apiuser, uiGroup, instance );
\r
2961 this.blur = function( keyCode ){
\r
2962 keyCode === 13 && onClick();
\r
2963 elmWrapper.className = className;
\r
2965 finish( apiuser, uiGroup, instance );
\r
2967 this.enabled = function(){
\r
2970 this.visible = function( _visible ){
\r
2971 if( Type.isBoolean( _visible ) === true ){
\r
2972 elmWrapper.style.display = _visible ? '' : 'none';
\r
2973 visible = _visible;
\r
2977 this.destroy = function(){
\r
2978 MouseEvent.remove( apiuser, elmWrapper );
\r
2979 apiuser = uiGroup = elmWrapper = onUpdate = instance = null;
\r
2983 var FileInputClass = function( apiuser, uiGroup, elmWrapper, onUpdate, validater, elmFileInput ){
\r
2984 var elmFilePath = Util.getElementsByClassName( elmWrapper, 'file-path' )[ 0 ],
\r
2988 index = GROUP_ID ? itemList[ GROUP_ID ].length : -1,
\r
2991 elmFileInput = elmWrapper.getElementsByTagName('input')[0] || elmFileInput || document.createElement( 'input');
\r
2992 elmFileInput.type = 'file';
\r
2993 elmFileInput.style.visivility = 'hidden';
\r
2995 elmWrapper.onclick = onClick;
\r
2996 elmFileInput.onchange = onChange;
\r
2998 function onChange(){
\r
2999 elmFilePath.innerHTML = elmFileInput.value;
\r
3006 focus: function( e ){
\r
3008 start( apiuser, uiGroup, instance );
\r
3009 elmFileInput.click();
\r
3012 blur: function( keep ){
\r
3015 enabled: function(){
\r
3018 visible: function( _visible ){
\r
3019 if( Type.isBoolean( _visible ) === true ){
\r
3020 elmWrapper.style.display = _visible ? '' : 'none';
\r
3021 visible = _visible;
\r
3029 var ComboBoxClass = function( apiuser, uiGroup, elmWrapper, onUpdate ){
\r
3030 var elmBox = Util.getElementsByClassName( elmWrapper, 'combobox' )[ 0 ],
\r
3031 elmA = ELM_COMBOBOX.cloneNode( true ),
\r
3032 elmToggle = Util.getElementsByClassName( elmA, 'combobox-toggle' )[ 0 ],
\r
3033 elmValue = Util.getElementsByClassName( elmA, 'combobox-value' )[ 0 ].firstChild,
\r
3041 elmBox.appendChild( elmA );
\r
3043 this.elm = elmBox;
\r
3044 this.focus = function( e ){
\r
3045 MouseEvent.remove( apiuser, elmWrapper, 'click', instance.focus );
\r
3047 elmA.className = 'combobox-has-focus';
\r
3048 start( apiuser, uiGroup, instance );
\r
3049 OptionControl.show( apiuser, instance, optionList );
\r
3052 this.blur = function( keyCode ){
\r
3053 OptionControl.hide( instance );
\r
3055 elmA.className = '';
\r
3056 finish( apiuser, uiGroup, instance );
\r
3057 MouseEvent.add( apiuser, elmWrapper, 'click', instance.focus );
\r
3059 this.enabled = function(){
\r
3062 this.visible = function( _visible ){
\r
3063 if( Type.isBoolean( _visible ) === true ){
\r
3064 elmWrapper.style.display = _visible ? '' : 'none';
\r
3065 visible = _visible;
\r
3069 this.value = function( _value ){
\r
3070 if( Type.isString( _value ) === true && value !== _value ){
\r
3071 for( var i=0, l = optionList.length, _option; i<l; ++i ){
\r
3072 _option = optionList[ i ];
\r
3073 if( _value === _option.value ){
\r
3076 elmValue.data = _option.displayValue;
\r
3077 if( focus === true ){
\r
3078 OptionControl.update( instance, _value );
\r
3086 this.selectIndex = function(){
\r
3089 this.createOption = function( _displayValue, _value, _isSelected ){
\r
3090 var option = null,
\r
3093 _value = _value || _displayValue;
\r
3094 for( var i = 0, l = optionList.length; i < l; ++i ){
\r
3095 _option = optionList[ i ];
\r
3096 if( _value === _option.value ){
\r
3100 _option.current = _option.value === _value;
\r
3103 if( option === null ){
\r
3104 option = new OptionClass( instance, _displayValue, _value, _isSelected );
\r
3105 _index = optionList.length;
\r
3106 optionList.push( option );
\r
3108 if( _isSelected === true ){
\r
3109 elmValue.data = _displayValue;
\r
3112 this.destroy = function(){
\r
3114 MouseEvent.remove( apiuser, elmWrapper );
\r
3115 optionList.length = 0;
\r
3116 apiuser = uiGroup = elmWrapper = onUpdate = elmBox = elmA = elmToggle = elmValue = optionList = instance = null;
\r
3118 MouseEvent.add( apiuser, elmWrapper, 'click', instance.focus );
\r
3120 var OptionClass = function( combobox, displayValue, value, isCurrent ){
\r
3121 this.displayValue = displayValue;
\r
3122 this.value = value = value || displayValue;
\r
3123 this.current = isCurrent;
\r
3124 displayValue = value = null;
\r
3127 var OptionControl = ( function(){
\r
3128 var ELM_OPTION_WRAPPER = ( function(){
\r
3129 var ret = document.createElement( 'div' );
\r
3130 ret.className = 'option-container';
\r
3133 ELM_OPTION_ORIGIN = ( function(){
\r
3134 var ret = document.createElement( 'a' );
\r
3135 ret.appendChild( document.createTextNode( 'option' ) );
\r
3140 var OptionClass = function( apiuser, option ){
\r
3141 this.elm = ELM_OPTION_ORIGIN.cloneNode( true );
\r
3142 this.data = option;
\r
3143 this.current = function( _current ){
\r
3144 this.elm.className = CLASSNAME_COMBOBOX_OPTION;
\r
3145 option.current = _current;
\r
3146 currentOption = this;
\r
3148 this.destroy = function(){
\r
3149 MouseEvent.remove( apiuser, this.elm );
\r
3150 apiuser = option = null;
\r
3151 ELM_OPTION_WRAPPER.removeChild( this.elm );
\r
3156 ELM_OPTION_WRAPPER.appendChild( this.elm );
\r
3157 this.elm.firstChild.data = option.displayValue;
\r
3158 this.current( option.current );
\r
3159 MouseEvent.add( SUPER_USER_KEY, this.elm, 'mousedown', onOptionSelect );// onclick では 選択ボックス 隠すように body に設定した onmouseup が先に動いてしまう!
\r
3162 function onOptionSelect( e ){
\r
3163 for( var i = 0, l = OPTION_LIST.length, _option; i < l; ++i){
\r
3164 _option = OPTION_LIST[ i ];
\r
3166 if( this === _option.elm ){
\r
3167 //currentOption = _option;
\r
3168 // alert( i +' ' + OPTION_LIST.length )
\r
3169 //OptionControl.update( currentCombobox, _option.data.value );
\r
3170 updateCurrrentOption( _option.data.value, true );
\r
3171 // OptionControl.hide( currentCombobox );
\r
3172 currentCombobox.blur();
\r
3179 var OPTION_LIST = [],
\r
3180 currentCombobox = null,
\r
3186 function updateCurrrentOption( _value, _updateCombobox ){
\r
3188 for( var i = OPTION_LIST.length; i; ){
\r
3189 _option = OPTION_LIST[ --i ];
\r
3190 if( _value === _option.data.value ){
\r
3191 currentOption && currentOption.current( false );
\r
3192 _option.current( true );
\r
3193 currentOption = _option;
\r
3195 _updateCombobox === true && currentCombobox.value( _value );
\r
3201 function bodyMouseupHandler(){
\r
3202 currentCombobox.blur();
\r
3203 OptionControl.hide( currentCombobox );
\r
3205 function updateWrapperPosition(){
\r
3206 var position = Util.getAbsolutePosition( elm );
\r
3208 ELM_OPTION_WRAPPER.style.cssText = [
\r
3209 'width:', elm.offsetWidth - 2, 'px;',
\r
3210 'left:', position.x, 'px;',
\r
3211 'top:', position.y + elm.offsetHeight, 'px;'
\r
3214 function change( e ){
\r
3215 var l = OPTION_LIST.length,
\r
3216 i = currentIndex + e.keyCode === 40 ? 1 : -1;
\r
3217 if( currentCombobox === null || l < 2 ) return;
\r
3221 updateCurrrentOption( OPTION_LIST[ i ].data.value, true );
\r
3225 show: function( _apiuser, _combobox, _optionList ){
\r
3226 if( currentItem !== _combobox || currentCombobox === _combobox ) return;
\r
3227 currentCombobox && currentCombobox.blur();
\r
3229 apiuser = _apiuser;
\r
3230 currentCombobox = _combobox;
\r
3231 elm = _combobox.elm;
\r
3233 for( var i = _optionList.length; i; ){
\r
3234 OPTION_LIST.unshift( new OptionClass( _apiuser, _optionList[ --i ] ) );
\r
3236 MouseEvent.add( SUPER_USER_KEY, doc, 'mouseup', bodyMouseupHandler );
\r
3237 KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, change, 38 );
\r
3238 KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, change, 40 );
\r
3239 //KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onEnter, 13 );
\r
3240 //KeyEvent.updateCurrentListener( SUPER_USER_KEY );
\r
3242 body.appendChild( ELM_OPTION_WRAPPER );
\r
3244 updateCurrrentOption( _combobox.value(), false );
\r
3245 updateWrapperPosition();
\r
3247 hide: function( _combobox ){
\r
3248 if( currentCombobox !== _combobox || currentCombobox === null ) return;
\r
3251 while( _option = OPTION_LIST.shift() ){
\r
3252 _option.destroy();
\r
3255 body.removeChild( ELM_OPTION_WRAPPER );
\r
3257 MouseEvent.remove( SUPER_USER_KEY, doc, 'mouseup', bodyMouseupHandler );
\r
3258 KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, change );
\r
3259 KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, change );
\r
3260 //KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onEnter );
\r
3261 //KeyEvent.updateCurrentListener( apiuser );
\r
3264 currentCombobox = null;
\r
3265 currentOption = null;
\r
3266 currentIndex = 0;
\r
3268 onEnter: function(){
\r
3269 currentCombobox.value( currentOption.data.value );
\r
3270 //currentCombobox.blur();
\r
3271 //OptionControl.hide( currentCombobox );
\r
3273 update: function( _combobox, _value ){
\r
3274 if( currentCombobox !== _combobox || currentItem !== _combobox ) return;
\r
3275 if( currentOption.data.value === _value ) return;
\r
3276 updateCurrrentOption( _value, true );
\r
3278 onWindowResize: function( _w, _h ){
\r
3279 currentCombobox && AsyncCall.add( apiuser, updateWrapperPosition );
\r
3284 var UIGroupClass = function( apiuser ){
\r
3287 currentItem = null,
\r
3290 this.focus = function( _value ){
\r
3291 if( _value === true ){
\r
3292 if( currentItem ){
\r
3293 start( apiuser, self, currentItem );
\r
3295 if( itemList.length > 0 ){
\r
3296 start( apiuser, self, itemList[ 0 ] );
\r
3299 if( _value === false ){
\r
3300 finish( apiuser, self, currentItem );
\r
3302 if( _value && Util.getIndex( itemList, _value ) !== -1 ){
\r
3303 currentItem = _value;
\r
3304 currentList = itemList;
\r
3306 return currentUi === self;
\r
3308 this.blur = function(){
\r
3309 if( currentList === itemList ){
\r
3310 currentList = null;
\r
3313 this.createInputText = function( _elmWrapper, _onUpdate, _validater ){
\r
3314 var _elmValue = Util.getElementsByClassName( _elmWrapper, 'editable-value' )[ 0 ];
\r
3316 var ret = new InputTextClass( apiuser, self, _elmWrapper, _elmValue, _onUpdate, _validater );
\r
3317 itemList.push( ret );
\r
3320 alert( 'error createInputText' );
\r
3322 this.createButton = function( _elm, _onClick ){
\r
3323 var ret = new ButtonClass( apiuser, self, _elm, _onClick );
\r
3324 itemList.push( ret );
\r
3327 this.createFileInput = function( _elm, _onUpdate, _validater, _elmFileInput ){
\r
3328 var ret = FileInputClass( apiuser, self, _elm, _onUpdate, _validater, _elmFileInput );
\r
3329 itemList.push( ret );
\r
3332 this.createCombobox = function( _elm, _onUpdate, _optionList ){
\r
3333 var ret = new ComboBoxClass( apiuser, self, _elm, _onUpdate, _optionList );
\r
3334 itemList.push( ret );
\r
3337 this.createCheckBox = function(){
\r
3340 this.createRadio = function(){
\r
3343 this.createSlider = function(){
\r
3346 this.destroy = function(){
\r
3348 while( _item = itemList.shift() ){
\r
3354 function start( _apiuser, _uigroup, _item ){
\r
3355 if( currentItem !== _item ){
\r
3356 currentItem !== null && currentItem.blur();
\r
3358 if( currentUser !== _apiuser ) {
\r
3359 KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 13 );
\r
3360 KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 27 );
\r
3361 KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 9 );
\r
3362 KeyEvent.updateCurrentListener( SUPER_USER_KEY );
\r
3364 if( currentUi !== _uigroup ){
\r
3365 currentUi && currentUi.blur();
\r
3367 currentUser = _apiuser;
\r
3368 currentUi = _uigroup;
\r
3369 currentItem = _item;
\r
3371 _uigroup.focus( _item );
\r
3374 function finish( _apiuser, _uigroup, _item ){
\r
3375 if( currentItem === _item ){
\r
3378 currentUser = null;
\r
3380 currentItem = null;
\r
3382 KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 13 );
\r
3383 KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 27 );
\r
3384 KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 9 );
\r
3385 KeyEvent.updateCurrentListener( _apiuser );
\r
3389 function onKeyDown( e ){
\r
3390 if( currentItem === null ) return true;
\r
3391 var keyCode = e.keyCode,
\r
3392 _index = Util.getIndex( currentList, currentItem );
\r
3393 if( keyCode === 13 || keyCode === 27 || keyCode === 9 || keyCode === 18 || e.altKey === true ){ // 13.return 27.esc 9.tab 18.alt
\r
3394 keyCode === 9 && tabShift( _index, e.shiftKey === true ? -1 : 1 );
\r
3395 keyCode === 13 && currentItem instanceof ComboBoxClass && OptionControl.onEnter();
\r
3396 keyCode === 13 && tabShift( _index, 1 );
\r
3397 currentItem && currentItem.blur( keyCode );
\r
3402 function tabShift( _index, _way ){
\r
3403 var l = currentList.length,
\r
3404 i = _index + _way,
\r
3406 if( l < 2 ) return;
\r
3407 while( i !== _index ){
\r
3410 i < l ? i : 0; // 0 < i < l
\r
3411 _item = currentList[ i ];
\r
3412 if( _item.enabled() === true && _item.visible() === true ){
\r
3413 AsyncCall.add( currentUser, _item.focus );
\r
3421 createUIGroup: function( _apiuser ){
\r
3422 var _uid = _apiuser.getUID(),
\r
3423 _list = UI_LIST[ _uid ],
\r
3424 _ui = new UIGroupClass( _apiuser );
\r
3425 if( Type.isArray( _list ) === false ){
\r
3426 _list = UI_LIST[ _uid ] = [];
\r
3428 _list.push( _ui );
\r
3431 onWindowResize: function( w, h ){
\r
3434 currentItem instanceof ComboBoxClass && OptionControl.onWindowResize( w, h );
\r
3436 onCurrentApplicationChange: function( _apiuser ){
\r
3437 currentList = UI_LIST[ _apiuser.getUID() ];
\r
3439 onApplicationShutdown: function( _apiuser ){
\r
3440 KeyEvent.remove( _apiuser );
\r
3442 onSystemShutdown: function(){
\r
3449 var Finder = ( function(){
\r
3450 var HTML_FINDER_ICON = ( function(){
\r
3451 return ( UA.isIE === true && UA.ieVersion < 8 ?
\r
3453 '<div class="finder-icon fnder-icon-ie7">',
\r
3454 '<a href="#" class="finder-icon-main">',
\r
3455 '<span class="finder-icon-handle"></span>',
\r
3456 '<span class="finder-icon-thumbnail"></span>',
\r
3457 '<span class="finder-icon-cell finder-icon-ie-filename">',
\r
3458 '<span class="finder-icon-vertical-middle-outer">',
\r
3459 '<span class="finder-icon-vertical-middle-inner">',
\r
3460 '<span class="finder-icon-filename break-word">file name</span>',
\r
3464 '<span class="finder-icon-cell finder-icon-ie-summary">',
\r
3465 '<span class="finder-icon-vertical-middle-outer">',
\r
3466 '<span class="finder-icon-vertical-middle-inner">',
\r
3467 '<span class="finder-icon-summary break-word">file descriptiion</span>',
\r
3472 '<div class="finder-icon-console">',
\r
3473 '<a href="#" class="finder-icon-console-action"></a>',
\r
3474 '<a href="#" class="finder-icon-console-editor-apps"></a>',
\r
3475 '<a href="#" class="finder-icon-console-viewer-apps"></a>',
\r
3480 '<div class="finder-icon fnder-icon-modern">',
\r
3481 '<span class="finder-icon-handle"></span>',
\r
3482 '<span class="finder-icon-thumbnail"></span>',
\r
3483 '<span class="finder-icon-filename break-word">file name</span>',
\r
3484 '<span class="finder-icon-summary break-word">file descriptiion</span>',
\r
3485 '<div class="finder-icon-console">',
\r
3486 '<a href="#" class="finder-icon-console-action"></a>',
\r
3487 '<a href="#" class="finder-icon-console-editor-apps"></a>',
\r
3488 '<a href="#" class="finder-icon-console-viewer-apps"></a>',
\r
3495 var FINDER_ARRAY = [],
\r
3496 ELM_ORIGIN_FINDER_LOCATION_ITEM = Util.pullHtmlAsTemplete( '<li id="templete-finder-location-item" class="finder-location-item"><a href="#"></a></li>'),
\r
3497 ELM_ORIGIN_FINDER_ICON = Util.pullHtmlAsTemplete( HTML_FINDER_ICON ),
\r
3498 ELM_ORIGIN_CONTAINER = Util.pullHtmlAsTemplete( [
\r
3499 '<div id="templete-finder-container" class="finder-container">',
\r
3500 '<div class="finder-header">',
\r
3501 '<ul class="finder-location"></ul>',
\r
3502 '<div class="finder-sidebar-switch button">side</div>',
\r
3503 '<div class="finder-style-switch button">style</div>',
\r
3504 '<div class="finder-action-switch button">action</div>',
\r
3506 '<div class="finder-body"></div>',
\r
3509 ICON_HEIGHT = Util.getElementSize( ELM_ORIGIN_FINDER_ICON ).height,
\r
3510 ICON_CLASSNAME = 'finder-icon-thumbnail',
\r
3511 FINDER_ICON_POOL = [],
\r
3512 BREAD_OBJECT_POOL = [];
\r
3514 var FinderIconClass = function(){
\r
3516 ELM_WRAPPER = ELM_ORIGIN_FINDER_ICON.cloneNode( true),
\r
3517 ELM_THUMBNAIL = Util.getElementsByClassName( ELM_WRAPPER, ICON_CLASSNAME )[ 0 ],
\r
3518 ELM_FILENAME = Util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-filename' )[ 0 ],
\r
3519 ELM_DESCRIPTION = Util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-summary' )[ 0 ],
\r
3520 ELM_EDITOR_BUTTON = Util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-console-editor-apps' )[ 0 ],
\r
3521 ELM_VIEWER_BUTTON = Util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-console-viewer-apps' )[ 0 ],
\r
3522 ELM_ACTION_BUTTON = Util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-console-action' )[ 0 ],
\r
3524 file, w, index, style,
\r
3525 onDownCallback, onEditorCallback, onViewerCallback, onActionCallback,
\r
3526 viewerList, editorList;
\r
3528 MouseEvent.add( SUPER_USER_KEY, ELM_WRAPPER, 'click', onDownClick );
\r
3529 MouseEvent.add( SUPER_USER_KEY, ELM_EDITOR_BUTTON, 'click', onEditorClick );
\r
3530 MouseEvent.add( SUPER_USER_KEY, ELM_VIEWER_BUTTON, 'click', onViwerClick );
\r
3531 MouseEvent.add( SUPER_USER_KEY, ELM_ACTION_BUTTON, 'click', onActionClick );
\r
3532 function onDownClick(){
\r
3533 onDownCallback( index );
\r
3536 function onEditorClick(){
\r
3537 onEditorCallback( file, editorList[ 0 ] );
\r
3540 function onViwerClick(){
\r
3541 onViewerCallback( file, viewerList[ 0 ] );
\r
3544 function onActionClick(){
\r
3545 onActionCallback( file );
\r
3549 var _thumb = file.getThumbnail();
\r
3550 if( _thumb.image ){
\r
3551 ELM_THUMBNAIL.className = ICON_CLASSNAME + ' has-thumbnail';
\r
3552 ELM_THUMBNAIL.style.backgroundImage = [ 'url(', _thumb.image, ')'].join( '');
\r
3554 ELM_THUMBNAIL.className = ICON_CLASSNAME + ' ' + _thumb.className;
\r
3555 ELM_THUMBNAIL.style.backgroundImage = '';
\r
3557 ELM_FILENAME.firstChild.data = file.getName();
\r
3558 ELM_DESCRIPTION.firstChild.data = file.getSummary();
\r
3560 if( Type.isArray( viewerList ) === true && viewerList.length > 0 ){
\r
3561 ELM_VIEWER_BUTTON.style.display = '';
\r
3563 ELM_VIEWER_BUTTON.style.display = 'none';
\r
3565 if( Type.isArray( editorList ) === true && editorList.length > 0 ){
\r
3566 ELM_EDITOR_BUTTON.style.display = '';
\r
3568 ELM_EDITOR_BUTTON.style.display = 'none';
\r
3571 function resize(){
\r
3572 // ELM_WRAPPER.style.top = (index * ICON_HEIGHT) +'px';
\r
3574 function onCollect(){
\r
3575 elmContainer.removeChild( ELM_WRAPPER );
\r
3576 elmContainer = null;
\r
3577 FINDER_ICON_POOL.push( instansce );
\r
3580 this.init = function( _file, _elmContainer, _w, _index, _style, _onDownCallback, _onEditorCallback, _onViewerCallback, _onActionCallback ){
\r
3581 if( elmContainer !== _elmContainer){
\r
3582 _elmContainer.appendChild( ELM_WRAPPER );
\r
3583 elmContainer = _elmContainer;
\r
3585 if( file !== _file ){
\r
3586 file && file.destroy();
\r
3588 viewerList = file.viewerApplicationList();
\r
3589 editorList = file.editorApplicationList();
\r
3592 if( index !== _index){
\r
3596 onDownCallback = _onDownCallback;
\r
3597 onEditorCallback = _onEditorCallback;
\r
3598 onViewerCallback = _onViewerCallback;
\r
3599 onActionCallback = _onActionCallback;
\r
3601 this.elm = ELM_WRAPPER,
\r
3602 this.index = function( _index){
\r
3605 this.style = function( _style ){
\r
3608 this.onResize = function( w ){
\r
3611 this.destroy = function(){
\r
3612 //MouseEvent.remove( SUPER_USER_KEY, ELM_WRAPPER, 'click', onDownClick );
\r
3613 //MouseEvent.remove( SUPER_USER_KEY, ELM_EDITOR_BUTTON, 'click', onEditorClick );
\r
3614 //MouseEvent.remove( SUPER_USER_KEY, ELM_VIEWER_BUTTON, 'click', onViwerClick );
\r
3615 //MouseEvent.remove( SUPER_USER_KEY, ELM_ACTION_BUTTON, 'click', onActionClick );
\r
3616 elmContainer.removeChild( ELM_WRAPPER );
\r
3617 file && file.destroy();
\r
3618 file = elmContainer = onDownCallback = onEditorCallback = onViewerCallback = onActionCallback = viewerList = editorList = null;
\r
3619 FINDER_ICON_POOL.push( instansce);
\r
3622 function updateIconPosition( _style, _w, _index, _elm ){
\r
3625 var BreadcrumbClass = function(){
\r
3627 ELM_WRAPPER = ELM_ORIGIN_FINDER_LOCATION_ITEM.cloneNode( true ),
\r
3628 ELM_FILENAME = ELM_WRAPPER.getElementsByTagName( 'a' )[ 0 ],
\r
3632 MouseEvent.add( SUPER_USER_KEY, ELM_WRAPPER, 'click', onClick );
\r
3634 ELM_FILENAME.className = 'file-icon-' + file.getType();
\r
3635 ELM_FILENAME.innerHTML = file.getName();
\r
3637 function resize( index ){
\r
3638 ELM_WRAPPER.style.left = ( index * 90 ) + 'px';
\r
3640 function onClick(){
\r
3641 callback( index );
\r
3644 this.init = function( _file, _elmContainer, _index, _callback ){
\r
3646 if( elmContainer !== _elmContainer ){
\r
3647 _elmContainer.appendChild( ELM_WRAPPER );
\r
3648 elmContainer = _elmContainer;
\r
3650 if( file !== _file){
\r
3654 if( index !== _index){
\r
3658 callback = _callback;
\r
3660 this.elm = ELM_WRAPPER;
\r
3661 this.index = function( _index ){
\r
3664 this.onResize = function( w ){
\r
3667 this.destroy = function(){
\r
3668 elmContainer.removeChild( ELM_WRAPPER );
\r
3669 file = elmContainer = null;
\r
3670 BREAD_OBJECT_POOL.push( this );
\r
3674 var FinderClass = function( application, elmRoot, tree, header, footer, onSelect, viewerOption, editorOption ){
\r
3675 var ICON_ARRAY = [],
\r
3677 elmContainer = ELM_ORIGIN_CONTAINER.cloneNode( true ),
\r
3678 elmLocation = elmContainer.getElementsByTagName( 'ul' )[ 0 ],
\r
3679 nodesDiv = elmContainer.getElementsByTagName( 'div' ),
\r
3680 elmSidebarButton = nodesDiv[ 1 ],
\r
3681 elmStyleButton = nodesDiv[ 2 ],
\r
3682 elmActionButton = nodesDiv[ 3 ],
\r
3683 elmBody = nodesDiv[ nodesDiv.length -1 ],
\r
3686 headH = Util.getElementSize( nodesDiv[ 0 ] ).height,
\r
3688 currentFile = null,
\r
3690 size = Util.getElementSize( ELM_ORIGIN_FINDER_ICON ),
\r
3691 iconW = size.width,
\r
3692 iconH = size.height,
\r
3697 tree.addTreeEventListener( Const.TREE.EVENT.UPDATE, draw );
\r
3698 elmRoot.appendChild( elmContainer );
\r
3700 function draw( _w, _h ){
\r
3701 w = Type.isFinite( _w ) === true ? _w : w;
\r
3702 h = Type.isFinite( _h ) === true ? _h : h;
\r
3703 bodyH = h - headH;
\r
3704 var l = tree.hierarchy() + 1,
\r
3705 m = BREAD_ARRAY.length,
\r
3707 for( var i=0; i<l; ++i ){
\r
3708 _file = i !== l-1 ? tree.getParentFileAt( i ) : tree.getCurrentFile();
\r
3710 BREAD_ARRAY[ i ].init( _file, elmLocation, i, onHeadClick );
\r
3712 BREAD_ARRAY.push( getBreadcrumb( _file, elmLocation, i, onHeadClick ));
\r
3715 while( l < BREAD_ARRAY.length ){
\r
3716 BREAD_ARRAY.pop().destroy();
\r
3719 l = _file.getChildFileLength();
\r
3720 m = ICON_ARRAY.length;
\r
3722 for( i=0; i<l; ++i ){
\r
3724 ICON_ARRAY[ i ].init( _file.getChildFileByIndex( i ), elmBody, w, i, style, onDown, onEditor, onViwer, onAction );
\r
3726 ICON_ARRAY.push( getFinderIcon( _file.getChildFileByIndex( i ), elmBody, _w, i, style, onDown, onEditor, onViwer, onAction ));
\r
3729 if( _file.getState() === Const.FILE.STATE.LOADING ){
\r
3730 elmBody.className = 'finder-body loading';
\r
3732 elmBody.className = 'finder-body';
\r
3735 elmBody.style.height = bodyH + 'px';
\r
3737 while( l < ICON_ARRAY.length && ICON_ARRAY.length > 0 ){
\r
3738 ICON_ARRAY.pop().destroy();
\r
3742 function onHeadClick( i){
\r
3743 var l = BREAD_ARRAY.length -1;
\r
3745 var _file = tree.getParentFileAt( i);
\r
3746 if( _file !== null){
\r
3752 function onDown( i ){
\r
3753 if( i < ICON_ARRAY.length ){
\r
3754 var _file = tree.getCurrentFile().getChildFileByIndex( i );
\r
3755 if( _file !== null && ( _file.getChildFileLength() !== -1 || _file.getType() === Const.FILE.TYPE.FOLDER )){
\r
3759 Type.isFunction( onSelect ) === true && onSelect( _file );
\r
3764 function onEditor( _file, _app, editorOption ){
\r
3765 _app.boot( _file, editorOption );
\r
3767 function onViwer( _file, _app ){
\r
3768 _app.boot( _file, viewerOption );
\r
3770 function onAction( _file ){
\r
3773 this.MIN_WIDTH = 240;
\r
3774 this.MIN_HEIGHT = 240;
\r
3775 this.onInit = function(){
\r
3776 var position = Util.getAbsolutePosition( elmLocation );
\r
3777 headX = position.x;
\r
3778 headY = position.y;
\r
3779 bodyY = Util.getAbsolutePosition( elmBody ).y;
\r
3781 this.onPaneResize = function( _w, _h ){
\r
3786 elmBody.style.height = ( _h - headH ) + 'px';
\r
3788 for( var i=0, l=ICON_ARRAY.length; i<l; ++i ){
\r
3789 ICON_ARRAY[ i].onResize( _w );
\r
3792 this.destroy = function(){
\r
3793 tree.removeTreeEventListener( Const.TREE.EVENT.UPDATE, draw );
\r
3795 while( BREAD_ARRAY.length > 0 ){
\r
3796 BREAD_ARRAY.shift().destroy();
\r
3798 while( ICON_ARRAY.length > 0 ){
\r
3799 ICON_ARRAY.shift().destroy();
\r
3803 FinderClass.prototype = new AbstractBasicPane();
\r
3805 function getFinderIcon( _file, _elmContainer, w, index, style, onDown, onEditor, onViwer, onAction){
\r
3807 if( FINDER_ICON_POOL.length > 0){
\r
3808 _icon = FINDER_ICON_POOL.shift();
\r
3810 _icon = new FinderIconClass();
\r
3812 _icon.init( _file, _elmContainer, w, index, style, onDown, onEditor, onViwer, onAction );
\r
3816 function getBreadcrumb( _file, _elmContainer, index, callback ){
\r
3818 if( BREAD_OBJECT_POOL.length > 0 ){
\r
3819 _bread = BREAD_OBJECT_POOL.shift();
\r
3821 _bread = new BreadcrumbClass();
\r
3823 _bread.init( _file, _elmContainer, index, callback );
\r
3831 create: function( _application, _elmTarget, _tree, _header, _footer, _onSelect, _viewerOption, _editorOption ){
\r
3832 //if( Application.isApplicationInstance( _application ) === false ) return;
\r
3834 var _finder = new FinderClass( _application, _elmTarget, _tree, _header, _footer, _onSelect, _viewerOption, _editorOption );
\r
3836 FINDER_ARRAY.push( _finder );
\r
3839 registerFinderHead: function(){
\r
3842 registerFinderPane: function( _finderPane ){
\r
3845 isFinderInstance: function( _finder ){
\r
3846 return _finder instanceof FinderClass;
\r
3848 isFinderPaneInstance: function(){
\r
3851 isFinderHeadInstance: function(){
\r
3857 /* --------------------------------------------
\r
3861 Application.onCurrentApplicationChange( SUPER_USER_KEY );
\r
3863 SERVICE_LIST.push( MouseEvent );
\r
3865 new EventTicketClass( window, 'unload', function(){
\r
3867 while( SERVICE_LIST.length > 0 ){
\r
3868 _service = SERVICE_LIST.shift();
\r
3869 Type.isFunction( _service.onSystemShutdown ) === true && _service.onSystemShutdown();
\r
3875 /* ---------------------------------------------
\r
3876 * broadcast to global
3880 gOS.registerApplication = Application.register;
\r
3881 gOS.registerDriver = File.registerDriver;
\r