23 * http://pettanr.sourceforge.jp/test/type.html
\r
26 isObject : function(v) {
\r
27 return v !== null && typeof v === 'object';
\r
29 isFunction : function(v) {
\r
30 return typeof v === 'function';
\r
32 isArray : function(v) {
\r
33 return Object.prototype.toString.call(v) === "[object Array]";
\r
35 isBoolean : function(v) {
\r
36 return typeof v === 'boolean';
\r
38 isString : function(v) {
\r
39 return typeof v === 'string';
\r
41 isNumber : function(v) {
\r
42 return typeof v === 'number';
\r
44 isFinite : function(v){
\r
45 return Type.isNumber(v) === true && isFinite(v);
\r
47 isHTMLElement : function(v){
\r
48 if( 'HTMLElement' in window ){
\r
49 Type.isHTMLElement = function(v){
\r
50 return v instanceof HTMLElement;
\r
53 Type.isHTMLElement = function(v) {
\r
54 if( Type.isObject(v) === false ){
\r
58 if(v && v.nodeType === 1 ){
\r
60 r = v.cloneNode(false);
\r
64 if(r === v) return false;
\r
67 return r.nodeType === 1;
\r
74 return Type.isHTMLElement(v);
\r
77 isElementCollection : function(v) {
\r
78 return (Object.prototype.toString.call(v) === "[object HTMLCollection]");
\r
81 isNull : function(v) {
\r
84 isUndefined : function(v) {
\r
85 return typeof v === 'undefined';
\r
95 var UA = ( function(){
\r
96 var ua = (function(){
\r
100 var dua = n.userAgent;
\r
101 var dav = n.appVersion;
\r
102 var tv = parseFloat(dav);
\r
103 acme.isOpera = (dua.indexOf("Opera") >= 0) ? tv: undefined;
\r
104 acme.isKhtml = (dav.indexOf("Konqueror") >= 0) ? tv : undefined;
\r
105 acme.isWebKit = parseFloat(dua.split("WebKit\/")[1]) || undefined;
\r
106 acme.isChrome = parseFloat(dua.split("Chrome\/")[1]) || undefined;
\r
107 acme.isGecko = (dua.indexOf("Gecko\/") >= 0) ? parseFloat(dua.split("rv:")[1].replace( /^(\d*\.\d*)\.(\d*)/, '$1$2' )) : undefined;
\r
108 var index = Math.max(dav.indexOf("WebKit"), dav.indexOf("Safari"), 0);
\r
109 if(index && !acme.isChrome){
\r
110 acme.isSafari = parseFloat(dav.split("Version/")[1]);
\r
111 if(!acme.isSafari || parseFloat(dav.substr(index + 7)) <= 419.3){
\r
115 if(document.all && !acme.isOpera){
\r
116 acme.isIE = parseFloat(dav.split("MSIE ")[1]) || undefined;
\r
121 isIE = navigator.userAgent.toLowerCase().indexOf( 'msie') !== -1,
\r
122 ieVersion = isIE === true ? parseInt( navigator.appVersion.toLowerCase().replace( /.*msie[ ]/, '').match( /^[0-9]+/)) : 0,
\r
123 ieRenderingVersion = ieVersion === 8 ? document.documentMode : ieVersion,
\r
124 isStanderdMode = document.compatMode === 'CSS1Compat',
\r
125 ActiveX = ( function(){
\r
126 if( isIE === false || ieVersion > 8 ) return false;
\r
127 var b = document.body,
\r
128 c = b.className || '',
\r
130 ret = undefined, //pettanr.URL_PARAMS.ActiveX,
\r
131 ns = 'pettanr-ActiveX-',
\r
132 enabled = 'enabled',
\r
133 disabled = 'disabled';
\r
134 if( ret !== true && ret !== false){
\r
135 if( b.className.indexOf( ns + enabled ) !== -1 ) return true;
\r
136 if( b.className.indexOf( ns + disabled ) !== -1 ) return false;
\r
137 x = document.createElement( 'div' );
\r
139 x.style.cssText = 'width:1px;height:1px;line-height:1px;filter:progid:DXImageTransform.Microsoft.Shadow()';
\r
140 ret = x.offsetHeight > 1;
\r
143 b.className += [ c !== '' ? ' ' : c, ns, ret === true ? enabled : disabled ].join( '');
\r
146 VML = ( function(){
\r
147 if( ActiveX === false || isIE === false || ieVersion > 8) return false;
\r
148 var globalObjectName = 'detect_activex',//Util.createGlobalUniqueName(),
\r
151 document.write( [ '<!--[if gte vml 1]><script id="', id, '">window', '.', globalObjectName, '=1;<\/script><![endif]-->'].join( ''));
\r
152 if( window[ globalObjectName ] === 1 ){
\r
153 script = document.getElementById( id );
\r
154 script.parentNode.removeChild( script );
\r
155 window[ globalObjectName ] = null;
\r
160 isStandAloneMode = ( function(){
\r
161 if( isIE === false) return false;
\r
162 if( VML === true) return false;
\r
163 var globalObjectName = 'detect_standalone', //Util.createGlobalUniqueName(),
\r
165 id = 'detectStandAlone';
\r
166 document.write( [ '<!--[if IE ', Math.floor( ieVersion ), ']><script id="', id, '">window', '.', globalObjectName, '=1;<\/script><![endif]-->'].join( ''));
\r
167 if( window[globalObjectName] === 1){
\r
168 script = document.getElementById( id);
\r
169 script.parentNode.removeChild( script);
\r
170 window[globalObjectName] = null;
\r
180 WEBKIT: ua.isWebKit,
\r
181 CHROME: ua.isChrome,
\r
183 ieVersion: ieVersion,
\r
184 ieRenderingVersion: ieRenderingVersion,
\r
185 isStanderdMode: isStanderdMode,
\r
188 STANDALONE: isStandAloneMode,
\r
189 VENDER_PREFIX: ( function() {
\r
190 var ua = navigator.userAgent.toLowerCase();
\r
191 if ( ua.indexOf('opera') !== -1 ){
\r
193 } else if ( ua.indexOf('msie') !== -1 ){
\r
195 } else if ( ua.indexOf('webkit') !== -1 ){
\r
197 } else if ( navigator.product === 'Gecko' ){
\r
202 startVML: function(){
\r
203 delete UA.startVML;
\r
204 if( UA.VML !== true) return false;
\r
205 if (!document.namespaces["v"]) {
\r
206 document.namespaces.add("v", "urn:schemas-microsoft-com:vml", "#default#VML");
\r
208 document.createStyleSheet().cssText = "v\:shape,v\:image{behavior:url(#default#VML);display:block;};";
\r
214 /* ----------------------------------------------------
\r
217 * extend( baseInstance, extend)
\r
218 * cleanCommnetNode()
\r
220 * getElementSize( _elm)
\r
222 * getAbsolutePath()
\r
223 * getGrobalObjectName()
\r
226 var Util = ( function( window, document, undefined ){
\r
227 var body = document.getElementsByTagName( 'body' )[ 0 ];
\r
229 var ELM_SIZE_GETTER = ( function(){
\r
230 var ret = document.createElement( 'div' );
\r
231 body.appendChild( ret );
\r
233 ret.id = 'elmSizeGetter';
\r
234 ret.style.cssText = 'position:absolute;left:0;top:-9999px;visibility:hidden';
\r
236 body.removeChild( ret );
\r
239 CLEAN_TARGET_ELEMENT = 'script,style,object,applet,embed,iframe,frame,base,bgsound,frameset,listing'.split( ',' );
\r
241 var UNIT_RATIO = ( function( elm ){
\r
244 units = 'cm,mm,in,pt,pc'.split( ',' );
\r
246 body.appendChild( elm );
\r
248 for( var i=units.length; i; ){
\r
249 unit = units[ --i ];
\r
250 elm.style.width = 1000 + unit;
\r
251 ret[ unit ] = elm.offsetWidth / 1000;
\r
253 elm.style.cssText = '';
\r
255 body.removeChild( elm );
\r
257 })( ELM_SIZE_GETTER );
\r
259 var FONT_SIZE_RATIO = ( function( elm ){
\r
262 list = 'xx-large,x-large,large,larger,medium,small,smaller,x-small,xx-small'.split( ',' );
\r
264 body.appendChild( elm );
\r
265 elm.style.cssText = 'font-size:100px;line-height:1em;';
\r
266 elm.appendChild( document.createTextNode( 'X' ) );
\r
268 base = elm.offsetHeight;
\r
270 for( var i = list.length; i; ){
\r
271 size = list[ --i ];
\r
272 elm.style.fontSize = size;
\r
273 ret[ size ] = elm.offsetHeight;// / base;
\r
276 elm.style.cssText = '';
\r
277 elm.removeChild( elm.firstChild );
\r
278 body.removeChild( elm );
\r
280 })( ELM_SIZE_GETTER );
\r
282 var REG_LARGE = /[A-Z]/g;
\r
284 /* clean comment node */
\r
285 window.setTimeout( function(){
\r
286 Util.cleanCommnetNode();
\r
288 /* clean noscript */
\r
290 var noscripts = Util.copyArray( document.getElementsByTagName( 'noscript' ) ),
\r
292 for( var i = noscripts.length; i; ){
\r
293 ns = noscripts[ --i ];
\r
294 ns.parentNode && ns.parentNode.removeChild( ns );
\r
298 function clone( src ) {
\r
300 if( Type.isArray(src) === true ){
\r
303 if( Type.isObject(src) === true ){
\r
306 if( Type.isNumber(src) === true || Type.isString(src) === true || Type.isBoolean( src ) === true ){
\r
311 for( var key in src ){
\r
312 ret[ key ] = clone( src[ key ]);
\r
318 parse: function( v ){
\r
319 if( Type.isString( v ) === true ){
\r
320 if( v === 'true' ) return true;
\r
321 if( v === 'false' ) return false;
\r
322 if( v === 'null' ) return null;
\r
323 if( v === 'undefined' ) return undefined;
\r
324 if( v === 'NaN' ) return NaN;
\r
325 if( v === '' ) return v;
\r
326 var _v = v.split( ' ' ).join( '' ),
\r
328 if( '' + n === _v || '' + n === '0' + _v ) return n - 0;
\r
332 extend: function( baseInstance, extend ){
\r
333 for( var key in extend ){
\r
334 if( Type.isUndefined( baseInstance[ key ] ) === true ){
\r
335 baseInstance[ key ] = extend[ key ];
\r
337 if( typeof baseInstance[ key ] === typeof extend[ key ] ){
\r
338 baseInstance[ key ] = extend[ key ];
\r
340 alert( 'extend error' );
\r
343 return baseInstance;
\r
345 copy: function( objOrArray ){
\r
346 return clone( objOrArray );
\r
348 cleanCommnetNode: function ( _targetElm ){
\r
349 search( _targetElm || body );
\r
351 function search( _elm ){
\r
352 if( !_elm ) return;
\r
353 if( _elm.nodeType === 8 ){
\r
354 _elm.parentNode.removeChild( _elm );
\r
357 if( _elm.nodeType === 1 ){
\r
358 var _array = Util.copyArray( _elm.childNodes ); // liveNode > array
\r
359 while( _array.length > 0 ) search( _array.shift() );
\r
363 cleanElement: function( _targetElm ){
\r
364 var _array, _elm, j, _css;
\r
365 for( var i = CLEAN_TARGET_ELEMENT.length; i; ){
\r
366 _array = Util.copyArray( _targetElm.getElementsByTagName( CLEAN_TARGET_ELEMENT[ --i ] ) );
\r
367 for( j = _array.length; j; ){
\r
368 _elm = _nodes[ --j ];
\r
369 _elm.parentNode && _elm.parentNode.removeChild( _elm );
\r
372 Util.cleanCommnetNode( _targetElm );
\r
374 if( UA.isIE === false ) return;
\r
375 _nodes = _targetElm.all || _targetElm.getElementsByTagName( '*' );
\r
376 for( i = _nodes.length; i; ){
\r
377 _elm = _nodes[ --i ];
\r
378 _css = Util.getInlineStyle( _elm );
\r
379 _css.filter = null;
\r
380 _css.behavior = null;
\r
381 _elm.style.cssText = Util.toCssText( _css );
\r
384 camelize: function( cssProp ){
\r
385 var parts = cssProp.split( ' ' ).join( '' ).split( '-' ),
\r
387 if( l === 1 ) return parts[ 0 ];
\r
389 var camelized = cssProp.charAt(0) === '-'
\r
390 ? parts[ 0 ].charAt( 0 ).toUpperCase() + parts[ 0 ].substring( 1 )
\r
393 for( var i = 1; i < l; ++i ){
\r
394 camelized += parts[ i ].charAt( 0 ).toUpperCase() + parts[ i ].substring( 1 );
\r
398 uncamelize: function( str ){
\r
399 return str.split( ' ' ).join( '' ).replace( REG_LARGE, '-$&' ).toLowerCase();
\r
401 pxTo: function( _px, _unit ){
\r
402 return _px / ( UNIT_RATIO[ _unit ] || 1 );
\r
404 toPx: function( x, _unit ){
\r
405 return x * ( UNIT_RATIO[ _unit ] || 1 );
\r
407 absoluteFontSizeToPx: function( fontsize ){
\r
408 return FONT_SIZE_RATIO[ fontsize ] || 0;
\r
410 getElementSize: function( _elm ){
\r
411 if( Type.isHTMLElement( _elm ) === false ){
\r
417 var parentElm = _elm.parentNode,
\r
418 prevElm = _elm.previousSibling,
\r
419 nextElm = _elm.nextSibling,
\r
420 displayNone = _elm.style.display === 'none';
\r
421 if( displayNone === true ) _elm.style.display = 'block';
\r
423 body.appendChild( ELM_SIZE_GETTER );
\r
424 ELM_SIZE_GETTER.appendChild( _elm );
\r
427 width: _elm.offsetWidth,
\r
428 height: _elm.offsetHeight
\r
430 if( displayNone === true ) _elm.style.display = 'none';
\r
432 parentElm.insertBefore( _elm, nextElm );
\r
434 if( prevElm && prevElm.nextSibling ){
\r
435 parentElm.insertBefore( _elm, prevElm.nextSibling );
\r
437 parentElm && parentElm.appendChild( _elm );
\r
439 body.removeChild( ELM_SIZE_GETTER );
\r
443 getImageSize: function( img ){
\r
444 var parentElm = img.parentNode,
\r
445 prevElm = img.previousSibling,
\r
446 nextElm = img.nextSibling,
\r
447 displayNone = img.style.display === 'none';
\r
448 if( displayNone === true ) img.style.display = '';
\r
450 body.appendChild( ELM_SIZE_GETTER );
\r
451 ELM_SIZE_GETTER.appendChild( img );
\r
453 var size = getActualDimension( img );
\r
455 if( displayNone === true ) img.style.display = 'none';
\r
457 parentElm.insertBefore( img, nextElm );
\r
459 if( prevElm && prevElm.nextSibling ){
\r
460 parentElm.insertBefore( img, prevElm.nextSibling );
\r
462 parentElm && parentElm.appendChild( img );
\r
464 body.removeChild( ELM_SIZE_GETTER );
\r
467 * AUTHOR: uupaa.js@gmail.com
\r
469 function getActualDimension(image) {
\r
470 var run, mem, w, h, key = "actual";
\r
472 // for Firefox, Safari, Google Chrome
\r
473 if( "naturalWidth" in image ){
\r
475 width: image.naturalWidth,
\r
476 height: image.naturalHeight
\r
480 if( "src" in image ){ // HTMLImageElement
\r
481 if (image[key] && image[key].src === image.src) {
\r
484 if( document.uniqueID ){ // for IE
\r
485 run = image.runtimeStyle;
\r
486 mem = { w: run.width, h: run.height }; // keep runtimeStyle
\r
487 run.width = "auto"; // override
\r
488 run.height = "auto";
\r
491 run.width = mem.w; // restore
\r
492 run.height = mem.h;
\r
493 } else { // for Opera and Other
\r
494 mem = { w: image.width, h: image.height }; // keep current style
\r
495 image.removeAttribute("width");
\r
496 image.removeAttribute("height");
\r
499 image.width = mem.w; // restore
\r
500 image.height = mem.h;
\r
502 return image[key] = { width: w, height: h, src: image.src }; // bond
\r
504 // HTMLCanvasElement
\r
505 return { width: image.width, height: image.height };
\r
510 getAbsolutePath: function( path ){
\r
511 var elm = document.createElement('div');
\r
512 body.appendChild( elm );
\r
513 elm.innerHTML = '<a href=\"' + path + '\" />';
\r
514 body.removeChild( elm );
\r
515 return elm.firstChild.href;
\r
517 getAbsolutePosition: function( _elm ){
\r
518 // Find the destination's position
\r
519 // need html, body { fontfamily: "MS PGothic", "MS Gothic" } for ie6.
\r
520 var destx = _elm.offsetLeft,
\r
521 desty = _elm.offsetTop,
\r
523 body = document.body;
\r
524 while( thisNode.offsetParent && thisNode !== body ){
\r
525 thisNode = thisNode.offsetParent;
\r
526 destx += thisNode.offsetLeft;
\r
527 desty += thisNode.offsetTop;
\r
534 pullHtmlAsTemplete: function( html ){
\r
535 var elm = document.createElement( 'div' );
\r
536 body.appendChild( elm );
\r
537 elm.innerHTML = html;
\r
538 body.removeChild( elm );
\r
539 return elm.firstChild;
\r
541 getElementsByClassName: function( _elm, _className, opt_tagName ){
\r
542 var _all = !opt_tagName || opt_tagName === '*',
\r
543 _livenodes = _all === true ? ( _elm.all || _elm.getElementsByTagName( '*' )) : _elm.getElementsByTagName( opt_tagName ),
\r
544 _nodes = Util.copyArray( _livenodes );
\r
545 for( var j = 0; j < _nodes.length; ){
\r
546 _node = _nodes[ j ];
\r
547 if( _node.nodeType !== 1 || Util.hasClassName( _node, _className ) === false ){
\r
548 _nodes.splice( j, 1 );
\r
555 getChildIndex: function( _parent, _child ){
\r
556 var _children = _parent.getElementsByTagName( _child.tagName );
\r
557 for( var i = _children.length; i; ){
\r
558 if( _children[ --i ] === _child ) return i;
\r
562 hasClassName: function( _elm, _className ){
\r
563 var cnames = ( _elm.className || '' ).split( ' ' ),
\r
564 _cnames = _className.split( ' ' ),
\r
566 for( var i = _cnames.length; i; ){
\r
567 cname = _cnames[ --i ];
\r
568 if( cname === '' ) continue;
\r
569 if( Util.getIndex( cnames, cname ) === -1 ) return false;
\r
573 addClass: function( _elm, _className ){
\r
574 if( Util.hasClassName( _elm, _className ) === false ){
\r
576 var _array = ( _elm.className || '' ).replace( /\s+/g, sp ).split( sp );
\r
577 _array.push( _className );
\r
578 _elm.className = _array.join( sp );
\r
581 removeClass: function( _elm, _className ){
\r
583 _array = _elm.className.replace( /\s+/g, sp ).split( sp ),
\r
584 i = Util.getIndex( _array, _className );
\r
586 _array.splice( i, 1 );
\r
587 _elm.className = _array.join( sp );
\r
590 toggleClass: function( _elm, _className ){
\r
591 Util.hasClassName( _elm, _className ) === false ? Util.addClass( _elm, _className ) : Util.removeClass( _elm, _className );
\r
593 removeAllChildren: function ( _elm){
\r
594 while( _elm.firstChild){
\r
595 remove( _elm.firstChild);
\r
597 function remove( _node){
\r
598 while( _node.firstChild){
\r
599 remove( _node.firstChild);
\r
601 _node.parentNode && _node.parentNode.removeChild( _node);
\r
604 getIndex: function( _array, _element ){
\r
605 if( Array.prototype.indexof ){
\r
606 Util.getIndex = function( _array, _element ){
\r
607 return _array.indexof( _element );
\r
610 Util.getIndex = function( _array, _element ){
\r
611 for( var i = _array.length; i; ){
\r
612 if( _array[ --i ] === _element ) return i;
\r
617 return Util.getIndex( _array, _element );
\r
619 copyArray: function( _array ){
\r
620 var l = _array.length,
\r
621 ret = new Array( l );
\r
622 for( var i=0; i<l; ++i ){
\r
623 ret[ i ] = _array[ i ];
\r
630 createGlobalUniqueName: function(){
\r
631 var randomKey = null;
\r
633 randomKey = '_uniqueName'+(''+Math.random()).replace(/\./,'');
\r
634 if( typeof window[randomKey] === 'undefined'){
\r
640 createIframe: function( id, callback){
\r
642 var el = document.createElement( ua.isIE ? '<iframe name="' + id + '" frameborder="0" scrolling="no">' : 'iframe');
\r
645 el.onreadystatechange = detect;
\r
647 // iron(chrome) の場合、append の前に onload を指定しないと onload が呼ばれない
\r
648 el.onload = onLoad;
\r
649 //setTimeout( asynkCallback, 0 );
\r
652 document.body.appendChild( el);
\r
653 el.id = el.name = id;
\r
654 el.setAttribute( 'name', id);
\r
655 el.style.cssText = 'width:1px;height:1px;visibility:hidden;position:absolute;top:1px;left:1px;';
\r
656 // http://d.hatena.ne.jp/onozaty/20070830/p1
\r
657 // [JavaScript]IE6ではJavaScriptで動的に作成したiframeに対してsubmitできない(IE7は未確認) ->解決
\r
658 el.contentWindow.name = id;
\r
663 if ( this.readyState === "complete" ){
\r
664 this.onreadystatechange = new Function();
\r
665 this.onreadystatechange = null;
\r
666 setTimeout( asynkCallback, 0 );
\r
671 setTimeout( asynkCallback, 0 );
\r
673 function asynkCallback(){
\r
678 })( window, document );
\r
681 var CSS = ( function( window, documwnt, undefined ){
\r
685 UNITS = 'px,cm,mm,in,pt,pc,em,%'.split( ',' ),
\r
686 CLIP_SEPARATOR = UA.isIE === true && UA.ieVersion < 8 ? ' ' : ',';
\r
688 var SPECIAL = ( function(){
\r
690 if( UA.isIE === true && UA.ieVersion < 9 ){
\r
691 if( UA.ACTIVEX === true ){
\r
692 // _special.opacity = 'ActiveXOpacity';
\r
693 _special.setFilters = function( style ){
\r
694 var filters = ( style.filter || '' ).split( ') ' ),
\r
696 i = filters.length,
\r
697 filter, names, props, prop, j, l, key, v;
\r
699 filter = filters[ --i ].split( ' ' ).join( '' ).split( '(' );
\r
700 if( filter.length !== 2 ) continue;
\r
701 names = filter[ 0 ].split( '.' ); // progid:DXImageTransform.Microsoft.Shadow(color=#666666,direction=120,strength=9)
\r
702 props = filter[ 1 ].split( ',' ); //
\r
704 for( j = 0, l = props.length; j < l; ++j ){
\r
705 prop = props[ j ].split( '=' );
\r
706 key = prop[ 0 ].toLowerCase();
\r
708 filter[ key ] = v; //v.charAt( 0 ) === '#' ? v : parseInt( v );
\r
710 data[ names[ names.length - 1 ] ] = filter;
\r
713 style.filter = data;
\r
714 style.opacity = data.alpha && data.alpha.opacity ? data.alpha.opacity / 100 : 1;
\r
716 _special.hasLayout = function( elm ){
\r
717 return elm.currentStyle.hasLayout;
\r
720 _special.opacity = null;
\r
723 var style = document.documentElement.style;
\r
724 _special.opacity = style.opacity !== undefined ? 'opacity' :
\r
725 style.MozOpacity !== undefined ? 'MozOpacity' :
\r
726 style.KhtmlOpacity !== undefined ? 'KhtmlOpacity' :
\r
727 style[ '-khtml-opacity' ] !== undefined ? 'KhtmlOpacity' : null;
\r
729 // if( style.backgroundPositionX === undefined ){
\r
730 _special.setBackgroundPositionXY = function( style ){
\r
731 var bgp = ( style.backgroundPosition || '' ).split( ' ' );
\r
732 style.backgroundPositionX = bgp[ 0 ] || 0;
\r
733 style.backgroundPositionY = bgp[ 1 ] || 0;
\r
736 if( style.clipTop === undefined && style[ 'clip-top' ] === undefined ){
\r
737 _special.setClipTopRightBottomLeft = function( style ){
\r
738 var clip = style.clip || '';
\r
739 if( clip.indexOf( 'rect(' ) === -1 ){
\r
741 style.clipRight = 0;
\r
742 style.clipBottom = 0;
\r
743 style.clipLeft = 0;
\r
746 clip = clip.split( '(' )[ 1 ].split( ')' )[ 0 ].split( clip.indexOf( ',' ) !== -1 ? ',' : ' ' );
\r
747 ret.clipTop = clip[ 0 ];
\r
748 ret.clipRight = clip[ 1 ];
\r
749 ret.clipBottom = clip[ 2 ];
\r
750 ret.clipLeft = clip[ 3 ];
\r
758 function cssToObject( css ){
\r
759 var ret = {}, i, nv, n, v, parse = Util.parse, isNumber = Type.isNumber;
\r
760 if( Type.isString( css ) === true ){
\r
761 css = css.split( ';' );
\r
762 for( i = css.length; i; ){
\r
763 nv = css[ --i ].split( ':' ); // filter の場合, progid: がくる
\r
765 if( isNumber( parse( n ) ) === true ) continue;
\r
767 while( v.charAt( 0 ) === ' ' ) v = v.substr( 1 );
\r
768 ret[ Util.camelize( n ) ] = parse( v );
\r
772 if( Type.isNumber( parse( n ) ) === false ) ret[ n ] = parse( css[ n ] );
\r
776 if( SPECIAL.setFilters ){
\r
777 SPECIAL.setFilters( ret );
\r
779 ret.opacity = SPECIAL.opacity !== null ? ret[ SPECIAL.opacity ] : 1;
\r
782 SPECIAL.setBackgroundPositionXY && SPECIAL.setBackgroundPositionXY( ret );
\r
783 SPECIAL.setClipTopRightBottomLeft && SPECIAL.setClipTopRightBottomLeft( ret );
\r
788 var COLOR = ( function(){
\r
789 var ret = {}, v, name,
\r
792 parseInt( 'FF0000', 16 ), 'RED',
\r
793 parseInt( '00FF00', 16 ), 'LIME',
\r
794 parseInt( '0000FF', 16 ), 'BLUE',
\r
795 parseInt( 'FFFF00', 16 ), 'YELLOW',
\r
796 parseInt( '00FFFF', 16 ), 'AQUA or CYAN',
\r
797 parseInt( 'FF00FF', 16 ), 'FUCHSIA or MAGENTA',
\r
798 parseInt( 'FFFFFF', 16 ), 'WHITE',
\r
799 parseInt( '008000', 16 ), 'GREEN',
\r
800 parseInt( '800080', 16 ), 'PURPLE',
\r
801 parseInt( '800000', 16 ), 'MAROON',
\r
802 parseInt( '000080', 16 ), 'NAVY',
\r
803 parseInt( '808000', 16 ), 'OLIVE',
\r
804 parseInt( '008080', 16 ), 'TEAL',
\r
805 parseInt( '808080', 16 ), 'GRAY',
\r
806 parseInt( 'C0C0C0', 16 ), 'SILVER',
\r
807 parseInt( '696969', 16 ), 'DIMGRAY',
\r
808 parseInt( '708090', 16 ), 'SLATEGRAY',
\r
809 parseInt( 'A9A9A9', 16 ), 'DARKGRAY',
\r
810 parseInt( 'DCDCDC', 16 ), 'GAINSBORO',
\r
811 parseInt( '191970', 16 ), 'MIDNIGHTBLUE',
\r
812 parseInt( '6A5ACD', 16 ), 'SLATEBLUE',
\r
813 parseInt( '0000CD', 16 ), 'MEDIUMBLUE',
\r
814 parseInt( '4169E1', 16 ), 'ROYALBLUE',
\r
815 parseInt( '1E90FF', 16 ), 'DODGERBLUE',
\r
816 parseInt( '87CEEB', 16 ), 'SKYBLUE',
\r
817 parseInt( '4682B4', 16 ), 'STEELBLUE',
\r
818 parseInt( 'ADD8E6', 16 ), 'LIGHTBLUE',
\r
819 parseInt( 'AFEEEE', 16 ), 'PALETURQUOISE',
\r
820 parseInt( '40E0D0', 16 ), 'TURQUOISE',
\r
821 parseInt( 'E0FFFF', 16 ), 'LIGHTCYAN',
\r
822 parseInt( '7FFFD4', 16 ), 'AQUAMARINE',
\r
823 parseInt( '006400', 16 ), 'DARKGREEN',
\r
824 parseInt( '2E8B57', 16 ), 'SEAGREEN',
\r
825 parseInt( '90EE90', 16 ), 'LIGHTGREEN',
\r
826 parseInt( '7FFF00', 16 ), 'CHARTREUSE',
\r
827 parseInt( 'ADFF2F', 16 ), 'GREENYELLOW',
\r
828 parseInt( '32CD32', 16 ), 'LIMEGREEN',
\r
829 parseInt( '9ACD32', 16 ), 'YELLOWGREEN',
\r
830 parseInt( '6B8E23', 16 ), 'OLIVEDRAB',
\r
831 parseInt( 'BCB76B', 16 ), 'DARKKHAKI',
\r
832 parseInt( 'EEE8AA', 16 ), 'PALEGOLDENROD',
\r
833 parseInt( 'FFFFE0', 16 ), 'LIGHTYELLOW',
\r
834 parseInt( 'FFD700', 16 ), 'GOLD',
\r
835 parseInt( 'DAA520', 16 ), 'GOLDENROD',
\r
836 parseInt( 'B8860B', 16 ), 'DARKGOLDENROD',
\r
837 parseInt( 'BC8F8F', 16 ), 'ROSYBROWN',
\r
838 parseInt( 'CD5C5C', 16 ), 'INDIANRED',
\r
839 parseInt( '8B4513', 16 ), 'SADDLEBROWN',
\r
840 parseInt( 'A0522D', 16 ), 'SIENNA',
\r
841 parseInt( 'CD853F', 16 ), 'PERU',
\r
842 parseInt( 'DEB887', 16 ), 'BURLYWOOD',
\r
843 parseInt( 'F5F5DC', 16 ), 'BEIGE',
\r
844 parseInt( 'F5DEB3', 16 ), 'WHEAT',
\r
845 parseInt( 'F4A460', 16 ), 'SANDYBROWN',
\r
846 parseInt( 'D2B48C', 16 ), 'TAN',
\r
847 parseInt( 'D2691E', 16 ), 'CHOCOLATE',
\r
848 parseInt( 'B22222', 16 ), 'FIREBRICK',
\r
849 parseInt( 'A52A2A', 16 ), 'BROWN',
\r
850 parseInt( 'FA8072', 16 ), 'SALMON',
\r
851 parseInt( 'FFA500', 16 ), 'ORANGE',
\r
852 parseInt( 'FF7F50', 16 ), 'CORAL',
\r
853 parseInt( 'FF6347', 16 ), 'TOMATO',
\r
854 parseInt( 'FF69B4', 16 ), 'HOTPINK',
\r
855 parseInt( 'FFC0CB', 16 ), 'PINK',
\r
856 parseInt( 'FF1493', 16 ), 'DEEPPINK',
\r
857 parseInt( 'DB7093', 16 ), 'PALEVIOLETRED',
\r
858 parseInt( 'EE82EE', 16 ), 'VIOLET',
\r
859 parseInt( 'DDA0DD', 16 ), 'PLUM',
\r
860 parseInt( 'DA70D6', 16 ), 'ORCHILD',
\r
861 parseInt( '9400D3', 16 ), 'DARKVIOLET',
\r
862 parseInt( '8A2BE2', 16 ), 'BLUEVIOLET',
\r
863 parseInt( '9370DB', 16 ), 'MEDIUMPURPLE',
\r
864 parseInt( 'D8BFD8', 16 ), 'THISTLE',
\r
865 parseInt( 'E6E6FA', 16 ), 'LAVENDER',
\r
866 parseInt( 'FFE4E1', 16 ), 'MISTYROSE',
\r
867 parseInt( 'FFFFF0', 16 ), 'IVORY',
\r
868 parseInt( 'FFFACD', 16 ), 'LEMONCHIFFON'
\r
870 for( i=list.length; i; ){
\r
872 name = list[ --i ];
\r
878 var PARAMS = ( function(){
\r
880 register( ret.percent = {},
\r
881 'marginBottom,marginLeft,marginRight,marginTop,paddingBottom,paddingLeft,paddingRight,paddingTop,fontSize,textIndent'
\r
883 register( ret.offset = {},
\r
884 'height,width,bottom,left,right,top'
\r
886 register( ret.size = {},
\r
887 'borderBottomWidth,borderLeftWidth,borderRightWidth,borderTopWidth,letterSpacing'
\r
889 register( ret.color = {},
\r
890 'backgroundColor,borderBottomColor,borderLeftColor,borderRightColor,borderTopColor,color'
\r
892 register( ret.region = {},
\r
893 'margin,padding,borderWidth,borderColor'
\r
895 register( ret.special = {},
\r
896 'clip,backgroundPosition,opacity,lineHeight,zIndex'
\r
898 register( ret.unit = {}, 'px,cm,mm,in,pt,pc,em,%' );
\r
900 register( ret.margin = {}, 'marginBottom,marginLeft,marginRight,marginTop,paddingBottom' );
\r
901 register( ret.padding = {}, 'paddingBottom,paddingLeft,paddingRight,paddingTop' );
\r
902 register( ret.borderWidth = {}, 'borderBottomWidth,borderLeftWidth,borderRightWidth,borderTopWidth' );
\r
903 register( ret.borderColor = {}, 'borderBottomColor,borderLeftColor,borderRightColor,borderTopColor' );
\r
905 function register( obj, params ){
\r
906 params = params.split( ',' );
\r
907 for( var i=params.length; i; ) obj[ params[ --i ] ] = true;
\r
915 var PropertyClass = function( name, value, unit, pxPerEm ){
\r
917 this.value = value;
\r
919 this.pxPerEm = pxPerEm; // XXpx = 1em;
\r
921 PropertyClass.prototype = {
\r
924 pxPerEm: 12, // 1em === ??px
\r
926 equal: function( prop ){
\r
927 if( this.unit === prop.unit ){
\r
928 return this.value === prop.value;
\r
930 return Math.abs( this._toPx() - prop._toPx() ) < 1;
\r
932 convert: function( prop ){
\r
933 var u = prop.unit, v;
\r
934 if( this.unit === u ) return;
\r
935 this.value = v = this._toPx();
\r
938 this.value = u === 'em' ? v / this.pxPerEm : Util.pxTo( v, u );
\r
941 setValue: function( v ){
\r
944 getValue: function(){
\r
947 getOffset: function( prop ){
\r
948 return prop.value - this.value;
\r
950 getUnit: function(){
\r
953 getValueText: function(){
\r
954 return this.value === 0 ? '0' : this.value + this.unit;
\r
959 if( t.hasOwnProperty && !t.hasOwnProperty( p ) ) continue;
\r
964 var v = this.value, u = this.unit;
\r
965 if( u === px ) return v;
\r
966 if( u === 'em' ) return v * this.pxPerEm;
\r
967 if( u === '' && this.name === 'lineHeight' ) return v * this.pxPerEm;
\r
968 return Util.toPx( v, u );
\r
970 isValid: function( t ){
\r
975 z = u !== '' ? true : v === 0;
\r
976 if( PARAMS.percent[ n ] === true ) return z;
\r
977 if( PARAMS.offset[ n ] === true ) return z;
\r
978 if( PARAMS.size[ n ] === true ) return z && u !== '%';
\r
979 if( PARAMS.special[ n ] === true ){
\r
980 if( n === 'lineHeight' ) return true;
\r
981 if( n === 'opacity' ) return 0 <= v && v <= 1 && u === '';
\r
982 if( n === 'zIndex' ) return u === '';
\r
989 * backgroundPosition, clip
\r
991 var PropertyGroupClass = function( name ){
\r
994 for( var i = 1, l = arguments.length; i<l; ++i ){
\r
995 this.props.push( arguments[ i ] );
\r
1000 * margin, padding, borderWidth, borderColor
\r
1002 var FrexiblePropertyClass = function( name ){
\r
1005 for( var i = 1, l = arguments.length; i<l; ++i ){
\r
1006 this.props.push( arguments[ i ] );
\r
1008 // top, bottom, left, right, topbottom, leftright, all
\r
1010 FrexiblePropertyClass.prototype = PropertyGroupClass.prototype = {
\r
1012 equal: function( prop ){
\r
1013 var ps = this.props, i = ps.length;
\r
1016 if( ps[ i ].equal( prop[ i ] ) === false ) return false;
\r
1020 convert: function( prop ){
\r
1021 var ps = this.props, i = ps.length;
\r
1024 ps[ i ].convert( prop[ i ] );
\r
1027 setValue: function( ary ){
\r
1028 var ps = this.props, i = 0, l = ps.length;
\r
1029 for( ; i<l; ++i ){
\r
1030 ps[ i ].setValue( ary[ i ] );
\r
1033 getValue: function(){
\r
1034 var ret = [], ps = this.props, i = 0, l = ps.length;
\r
1035 for( ; i<l; ++i ){
\r
1036 ret.push( ps[ i ].getValue() );
\r
1040 getOffset: function( prop ){
\r
1046 for( ; i<l; ++i ){
\r
1047 ret.push( ps[ i ].getOffset( _ps[ i ] ) );
\r
1051 getUnit: function(){
\r
1052 var ret = [], ps = this.props, i = 0, l = ps.length;
\r
1053 for( ; i<l; ++i ){
\r
1054 ret.push( ps[ i ].getUnit() );
\r
1058 getValueText: function(){
\r
1059 var ret = [], ps = this.props, i = 0, l = ps.length;
\r
1060 for( ; i<l; ++i ){
\r
1061 ret.push( ps[ i ].getValueText() );
\r
1063 if( this.name === 'clip' ){
\r
1064 return 'rect(' + ret.join( CLIP_SEPARATOR ) + ')';
\r
1066 return ret.join( ' ' );
\r
1068 clear: function(){
\r
1069 var ps = this.props, i = ps.length;
\r
1071 ps[ --i ].clear();
\r
1074 delete this.props;
\r
1076 isValid: function( t ){
\r
1078 var ps = t.props, i = ps.length;
\r
1081 if( ps[ i ].isValid() === false ) return false;
\r
1087 var ColorPropertyClass = function( name, r, g, b, pct ){
\r
1094 ColorPropertyClass.prototype = {
\r
1096 equal: function( prop ){
\r
1097 if( this.pct === prop.pct ){
\r
1098 return this.r === prop.r && this.g === prop.g && this.b === prop.b;
\r
1100 var rgb = this._toPct(),
\r
1101 _rgb = prop._toPct();
\r
1102 for( var i = rgb.length; i; ){
\r
1104 if( Math.abs( rgb[ i ] - _rgb[ i ] ) > 1 ) return false;
\r
1108 convert: function( prop ){
\r
1110 if( this.pct === u ) return;
\r
1111 var x = u === true ? 100 / 255 : 2.55;
\r
1117 setValue: function( rgb ){
\r
1118 this.r = rgb[ 0 ];
\r
1119 this.g = rgb[ 1 ];
\r
1120 this.b = rgb[ 2 ];
\r
1122 getValue: function(){
\r
1123 return [ this.r, this.g, this.b ];
\r
1125 getOffset: function( prop ){
\r
1126 return [ prop.r - this.r, prop.g - this.g, prop.b - this.b ];
\r
1128 getUnit: function(){
\r
1129 return this.pct === true ? '%' : '';
\r
1131 getValueText: function(){
\r
1132 if( this.pct === true ){
\r
1133 return [ 'rgb(', this.r, '%,', this.g, '%,', this.b, '%)' ].join( '' );
\r
1135 var round = Math.round;
\r
1136 //return [ 'rgb(', round( this.r ), ',', round( this.g ), ',', round( this.b ), ')' ].join( '' );
\r
1138 var rgb = '00000' + ( ( round( this.r ) << 16 ) + ( round( this.g ) << 8 ) + round( this.b ) ).toString( 16 );
\r
1139 return '#' + rgb.substr( rgb.length - 6 );
\r
1141 clear: function(){
\r
1144 if( t.hasOwnProperty && !t.hasOwnProperty( p ) ) continue;
\r
1148 _toPct: function(){
\r
1149 if( this.pct === true ) return [ this.r, this.g, this.b ];
\r
1150 return [ this.r / 2.55, this.g / 2.55, this.b / 2.55 ];
\r
1152 isValid: function( t ){
\r
1153 var isFinite = window.isFinite;
\r
1154 if( !isFinite( this.r ) || !isFinite( this.g ) || !isFinite( this.b ) ) return false;
\r
1155 if( 0 > this.r || 0 > this.g || 0 > this.b ) return false;
\r
1156 if( this.pct === true ){
\r
1157 return this.r <= 100 && this.g <= 100 && this.b <= 100;
\r
1159 return this.r <= 255 && this.g <= 255 && this.b <= 255;
\r
1163 var isString = Type.isString,
\r
1164 isNumber = Type.isNumber;
\r
1165 var REG_UINIT = /.*\d(\w{1,2})?/,
\r
1168 REG_XXXXXX = /^#[\da-fA-F]{6}?/,
\r
1169 REG_XXX = /^#[\da-fA-F]{3}?/;
\r
1171 var WrappedStyleClass = function( elm, style, pxPerEm ){
\r
1173 this.style = style;
\r
1174 this.pxPerEm = this.get( 'fontSize' )._toPx();
\r
1177 WrappedStyleClass.prototype = {
\r
1178 get: function( p ){
\r
1179 if( PARAMS.special[ p ] === true || PARAMS.region[ p ] === true ){
\r
1180 if( p === 'clip' ) return this.getClip();
\r
1181 if( p === 'margin' ) return this.getMarginPaddingBorder( p );
\r
1182 if( p === 'padding' ) return this.getMarginPaddingBorder( p );
\r
1183 if( p === 'borderWidth' ) return this.getMarginPaddingBorder( 'border', 'Width' );
\r
1184 if( p === 'borderColor' ) return this.getBorderColor( 'borderColor' );
\r
1185 if( p === 'backgroundPosition' ) return this.getBackgroundPosition( p );
\r
1186 // opacity, zindex, lineHeight
\r
1187 return new PropertyClass( p, this.getValue( x, p ), this.getUnit( x ), this.pxPerEm );
\r
1189 var x = this.style[ p ], e, v, u;
\r
1190 if( PARAMS.offset[ p ] === true ){
\r
1191 return new PropertyClass( p, this.getValue( x, p ), this.getUnit( x, p ), this.pxPerEm );
\r
1194 if( p === 'width' ) v = e.offsetWidth;
\r
1195 if( p === 'height' ) v = e.offsetHeight;
\r
1196 if( p === 'top' ) v = e.offsetTop;
\r
1197 if( p === 'bottom' ) v = e.offsetBottom;
\r
1198 if( p === 'left' ) v = e.offsetLeft;
\r
1199 if( p === 'right' ) v = e.offsetRight;
\r
1200 u = this.getUnit( x, p );
\r
1201 // alert( p + this.pxTo( v, u ) + u )
\r
1202 return new PropertyClass( p, this.pxTo( v, u ), u, this.pxPerEm ); */
\r
1204 if( p === 'fontSize' ){ // xx-small 等
\r
1205 v = Util.absoluteFontSizeToPx( x );
\r
1207 return new PropertyClass( p, v, px, this.pxPerEm );
\r
1210 if( PARAMS.percent[ p ] === true ){
\r
1211 // alert( p + ' , ' + x + ' , ' + this.getUnit( x, p ) )
\r
1212 return new PropertyClass( p, this.getValue( x, p ), this.getUnit( x, p ), this.pxPerEm );
\r
1214 if( PARAMS.size[ p ] === true ){
\r
1215 return new PropertyClass( p, this.getValue( x, p ), this.getUnit( x, p ), this.pxPerEm );
\r
1217 if( PARAMS.color[ p ] === true ){
\r
1218 return this.getColor( x, p );
\r
1221 pxTo: function( px, unit ){
\r
1222 if( unit === 'em' ) return px / this.pxPerEm;
\r
1223 return Util.pxTo( px, unit );
\r
1225 getValue: function( x, p ){
\r
1226 if( isString( x ) === true ){
\r
1227 return parseInt( x );
\r
1229 if( isNumber( x ) === true ){
\r
1234 getUnit: function( x, p ){
\r
1236 if( isString( x ) === true ){
\r
1237 u = x.replace( REG_UINIT, $1 );
\r
1238 if( p === 'lineHeight' ) return u;
\r
1239 if( PARAMS.unit[ u ] !== true ) return px;
\r
1244 getColor: function( x, p ){
\r
1245 var rgb = COLOR[ x.toUpperCase() ],
\r
1250 if( isNumber( rgb ) === true ){
\r
1251 r = ( rgb & 0xff0000 ) >> 16;
\r
1252 g = ( rgb & 0xff00 ) >> 8;
\r
1253 b = ( rgb & 0xff );
\r
1255 if( x.match( REG_XXXXXX ) ){
\r
1256 r = parseInt( x.charAt( 1 ) + x.charAt( 2 ), 16 );
\r
1257 g = parseInt( x.charAt( 3 ) + x.charAt( 4 ), 16 );
\r
1258 b = parseInt( x.charAt( 5 ) + x.charAt( 6 ), 16 );
\r
1259 //alert( x + ' g: ' + g )
\r
1261 if( x.match( REG_XXX ) ){
\r
1262 r = parseInt( x.charAt( 1 ) + x.charAt( 1 ), 16 );
\r
1263 g = parseInt( x.charAt( 2 ) + x.charAt( 2 ), 16 );
\r
1264 b = parseInt( x.charAt( 3 ) + x.charAt( 3 ), 16 );
\r
1266 if( x.indexOf( 'rgb(' ) === 0 ){
\r
1267 rgb = x.substr( 4 ).split( ',' );
\r
1268 r = parseFloat( rgb[ 0 ] );
\r
1269 g = parseFloat( rgb[ 1 ] );
\r
1270 b = parseFloat( rgb[ 2 ] );
\r
1271 if( x.indexOf( '%' ) !== -1 ){
\r
1279 return new ColorPropertyClass( p, r, g, b, pct );
\r
1281 getClip: function( name ){
\r
1282 // rect(...) クリップします。<top>, <bottom> は上端からの、 <right>, <left> は左端からのオフセットで指定します。Internet Explorer 4~7 では、カンマの代わりにスペースで区切る必要があります。
\r
1283 // position:absolute または position:fixed を適用した要素に対してのみ有効です。
\r
1284 var top = this.get( name + 'Top' ),
\r
1285 right = this.get( name + 'Right' ),
\r
1286 bottom = this.get( name + 'Bottom' ),
\r
1287 left = this.get( name + 'Left' ),
\r
1288 ret = new PropertyGroupClass( name, top, right, bottom, left );
\r
1289 if( ret.isValid() === true ) return ret;
\r
1291 all = this.style[ name ].split( '(' )[ 1 ].split( ')' )[ 0 ].split( CLIP_SEPARATOR );
\r
1292 return new PropertyGroupClass( name,
\r
1293 new PropertyClass( name + 'Top', all[ 0 ], px, this.pxPerEm ),
\r
1294 new PropertyClass( name + 'Right', all[ 1 ], px, this.pxPerEm ),
\r
1295 new PropertyClass( name + 'Bottom', all[ 2 ], px, this.pxPerEm ),
\r
1296 new PropertyClass( name + 'Left', all[ 3 ], px, this.pxPerEm )
\r
1299 getBackgroundPosition: function( name ){
\r
1300 var x = this.get( name + 'X' ),
\r
1301 y = this.get( name + 'Y' ),
\r
1302 ret = new PropertyGroupClass( name, x, y ),
\r
1304 if( ret.isValid() === true ) return ret;
\r
1306 xy = this.style[ name ].split( ' ' );
\r
1307 return new PropertyGroupClass( name,
\r
1308 new PropertyClass( name + 'X', this.getValue( xy[ 0 ] ), this.getUnit( xy[ 0 ] ), this.pxPerEm ),
\r
1309 new PropertyClass( name + 'Y', this.getValue( xy[ 1 ] ), this.getUnit( xy[ 1 ] ), this.pxPerEm )
\r
1312 getMarginPaddingBorder: function( name, widthOrColor ){
\r
1313 widthOrColor = widthOrColor || '';
\r
1314 var _class = PropertyClass;
\r
1315 top = this.get( name + 'Top' + widthOrColor ),
\r
1316 right = this.get( name + 'Right' + widthOrColor ),
\r
1317 bottom = this.get( name + 'Bottom' + widthOrColor ),
\r
1318 left = this.get( name + 'Left' + widthOrColor ),
\r
1319 ret = new FrexiblePropertyClass( name, top, right, bottom, left ),
\r
1322 if( ret.isValid() === true ) return ret;
\r
1324 all = this.style[ name + widthOrColor ].split( ' ' );
\r
1326 for( var i=0, l=all.length; i<l; ++i ){
\r
1328 v = this.getValue( x );
\r
1329 u = this.getUnit( x );
\r
1331 if( i === 0 ) top = new _class( name + 'Top' + widthOrColor, v, u, this.pxPerEm );
\r
1332 if( i === 1 ) right = new _class( name + 'Right' + widthOrColor, v, u, this.pxPerEm );
\r
1333 if( i === 2 ) bottom = new _class( name + 'Bottom' + widthOrColor, v, u, this.pxPerEm );
\r
1334 if( i === 3 ) left = new _class( name + 'Left' + widthOrColor, v, u, this.pxPerEm );
\r
1337 if( i === 0 ) top = new _class( name + 'Top' + widthOrColor, v, u, this.pxPerEm );
\r
1339 right = new _class( name + 'Right' + widthOrColor, v, u, this.pxPerEm );
\r
1340 left = new _class( name + 'Left' + widthOrColor, v, u, this.pxPerEm );
\r
1342 if( i === 2 ) bottom = new _class( name + 'Bottom' + widthOrColor , v, u, this.pxPerEm );
\r
1346 top = new _class( name + 'Top' + widthOrColor, v, u, this.pxPerEm );
\r
1347 bottom = new _class( name + 'Bottom' + widthOrColor, v, u, this.pxPerEm );
\r
1350 right = new _class( name + 'Right' + widthOrColor, v, u, this.pxPerEm );
\r
1351 left = new _class( name + 'Left' + widthOrColor, v, u, this.pxPerEm );
\r
1355 top = new _class( name + 'Top' + widthOrColor, v, u, this.pxPerEm );
\r
1356 bottom = new _class( name + 'Bottom' + widthOrColor, v, u, this.pxPerEm );
\r
1357 right = new _class( name + 'Right' + widthOrColor, v, u, this.pxPerEm );
\r
1358 left = new _class( name + 'Left' + widthOrColor, v, u, this.pxPerEm );
\r
1361 return new FrexiblePropertyClass( name, top, right, bottom, left );
\r
1363 getBorderColor: function( name ){
\r
1364 var getColor = this.getColor;
\r
1365 top = this.get( name + 'TopColor' ),
\r
1366 right = this.get( name + 'RightColor' ),
\r
1367 bottom = this.get( name + 'BottomColor' ),
\r
1368 left = this.get( name + 'LeftColor' ),
\r
1369 ret = new FrexiblePropertyClass( name, top, right, bottom, left ),
\r
1372 if( ret.isValid() === true ) return ret;
\r
1374 all = this.style[ name ].split( ' ' );
\r
1376 for( var i=0, l=all.length; i<l; ++i ){
\r
1379 if( i === 0 ) top = getColor( x, name + 'Top' );
\r
1380 if( i === 1 ) right = getColor( x, name + 'Right' );
\r
1381 if( i === 2 ) bottom = getColor( x, name + 'Bottom' );
\r
1382 if( i === 3 ) left = getColor( x, name + 'Left' );
\r
1385 if( i === 0 ) top = getColor( x, name + 'Top' );
\r
1387 right = getColor( x, name + 'Right' );
\r
1388 left = getColor( x, name + 'Left' );
\r
1390 if( i === 2 ) bottom = getColor( x, name + 'Bottom' );
\r
1394 top = getColor( x, name + 'Top' );
\r
1395 bottom = getColor( x, name + 'Bottom' );
\r
1398 right = getColor( x, name + 'Right' );
\r
1399 left = getColor( x, name + 'Left' );
\r
1403 top = getColor( x, name + 'Top' );
\r
1404 bottom = getColor( x, name + 'Bottom' );
\r
1405 right = getColor( x, name + 'Right' );
\r
1406 left = getColor( x, name + 'Left' );
\r
1409 return new FrexiblePropertyClass( name, top, right, bottom, left );
\r
1411 clear: function(){
\r
1414 if( t.hasOwnProperty && !t.hasOwnProperty( p ) ) continue;
\r
1419 function camelizeHash( obj ){
\r
1422 _p = Util.camelize( p );
\r
1423 if( _p === p ) continue;
\r
1424 obj[ _p ] = obj[ _p ] || obj[ p ];
\r
1430 getWrappedStyle: function( elm, opt_css ){
\r
1431 opt_css && camelizeHash( opt_css );
\r
1432 return new WrappedStyleClass( elm, opt_css || CSS.getComputedStyle( elm ) );
\r
1434 getInlineStyle: function( _elm ){
\r
1435 return cssToObject( _elm.style.cssText );
\r
1437 getComputedStyle: function( elm ){
\r
1438 /* if( window.getComputedStyle ){
\r
1439 CSS.getComputedStyle = function( elm ){
\r
1440 return cssToObject( window.getComputedStyle( elm, '' ) );
\r
1443 if( document.defaultView && document.defaultView.getComputedStyle ){
\r
1444 CSS.getComputedStyle = function( elm ){
\r
1445 var obj = document.defaultView.getComputedStyle( elm, '' );
\r
1446 return cssToObject( obj.cssText || obj );
\r
1449 CSS.getComputedStyle = function( elm ){
\r
1450 return cssToObject( elm.currentStyle );
\r
1453 return CSS.getComputedStyle( elm );
\r
1455 toCssText: function( _css ){
\r
1457 for( var p in _css ){
\r
1458 if( PARAMS.margin[ p ] === true && _css.margin ) continue;
\r
1459 if( PARAMS.padding[ p ] === true && _css.padding ) continue;
\r
1460 if( PARAMS.borderWidth[ p ] === true && _css.borderWidth ) continue;
\r
1461 if( PARAMS.borderColor[ p ] === true && _css.borderColor ) continue;
\r
1463 v && ret.push( [ Util.uncamelize( p ), v ].join( ':' ) );
\r
1465 return ret.join( ';' );
\r
1469 })( window, document );
\r
1472 /* ----------------------------------------------------
\r
1477 ( function( window, document, undefined ){
\r
1479 var doc = window.document;
\r
1480 var body = doc.getElementsByTagName( 'body' )[ 0 ]; //( doc.compatMode || '' ) !== 'CSS1Compat' ? doc.body : doc.documentElement;//
\r
1482 var SERVICE_LIST = [];
\r
1483 var SUPER_USER_KEY = { getUID: function(){ return 0; }};
\r
1484 var API_USER_LIST = [ SUPER_USER_KEY ];
\r
1485 var numApiUser = 1;
\r
1487 function isApiUser( _user ){
\r
1488 if( _user === SUPER_USER_KEY ) return true;
\r
1489 if( File.isDriver( _user ) === true ) return true;
\r
1490 if( Application.isApplicationInstance( _user ) === true ) return true;
\r
1514 _____: parseInt( '00000', 2 ),
\r
1515 ____C: parseInt( '00001', 2 ), // hasCreateMenu
\r
1516 ___W_: parseInt( '00010', 2 ), // isWritable
\r
1517 ___WC: parseInt( '00011', 2 ), // isWritable
\r
1518 __R__: parseInt( '00100', 2 ), // isRenamable
\r
1519 __R_C: parseInt( '00101', 2 ), // hasCreateMenu
\r
1520 __RW_: parseInt( '00110', 2 ), // isWritable
\r
1521 __RWC: parseInt( '00111', 2 ), // isWritable
\r
1522 _S___: parseInt( '01000', 2 ), // childrenIsSortable
\r
1523 _S__C: parseInt( '01001', 2 ),
\r
1524 _S_W_: parseInt( '01010', 2 ),
\r
1525 _S_WC: parseInt( '01011', 2 ),
\r
1526 _SR__: parseInt( '01100', 2 ),
\r
1527 _SR_C: parseInt( '01101', 2 ),
\r
1528 _SRW_: parseInt( '01110', 2 ),
\r
1529 _SRWC: parseInt( '01111', 2 ),
\r
1530 D____: parseInt( '10000', 2 ),
\r
1531 D___C: parseInt( '10001', 2 ), // hasCreateMenu
\r
1532 D__W_: parseInt( '10010', 2 ), // isWritable
\r
1533 D__WC: parseInt( '10011', 2 ), // isWritable
\r
1534 D_R__: parseInt( '10100', 2 ), // isRenamable
\r
1535 D_R_C: parseInt( '10101', 2 ), // hasCreateMenu
\r
1536 D_RW_: parseInt( '10110', 2 ), // isWritable
\r
1537 D_RWC: parseInt( '10111', 2 ), // isWritable
\r
1538 DS___: parseInt( '11000', 2 ), // childrenIsSortable
\r
1539 DS__C: parseInt( '11001', 2 ),
\r
1540 DS_W_: parseInt( '11010', 2 ),
\r
1541 DS_WC: parseInt( '11011', 2 ),
\r
1542 DSR__: parseInt( '11100', 2 ),
\r
1543 DSR_C: parseInt( '11101', 2 ),
\r
1544 DSRW_: parseInt( '11110', 2 ),
\r
1545 DSRWC: parseInt( '11111', 2 ),
\r
1553 UPDATE_ATTRIVUTE: 'onFileUpdate',
\r
1554 GET_SEQENTIAL_FILES:'gotSeqentilFiles'
\r
1556 DATA_PROPERTY_RESERVED: [
\r
1557 'children', 'driver', 'state', 'type'
\r
1562 UPDATE: 'onTreeUpdate'
\r
1567 KEY_DOWN: 'keydown',
\r
1569 KEY_CHANGE: 'keychange',
\r
1582 var EX = ( function(){
\r
1583 var F = new Function();
\r
1585 function clone( src ) {
\r
1587 if( Type.isArray(src) === true ){
\r
1590 if( Type.isObject(src) === true ){
\r
1593 if( Type.isNumber(src) === true || Type.isString(src) === true || Type.isBoolean( src ) === true ){
\r
1598 for( var key in src ){
\r
1599 ret[ key ] = clone( src[ key ]);
\r
1605 extend: function( base, extend ){
\r
1606 F.prototype = base;
\r
1608 for( var p in extend ){
\r
1609 ret[ p ] = extend[ p ];
\r
1613 clone: function( obj ){
\r
1614 return clone( obj );
\r
1617 var self = this, v;
\r
1618 for( var p in s ){
\r
1619 if( self.hasOwnProperty && !self.hasOwnProperty( p ) ) continue;
\r
1621 v && v instanceof TicketBase && self.kill();
\r
1628 var TicketBase = function(){
\r
1629 this.kill = function(){
\r
1631 for( var p in t ){
\r
1632 if( t.hasOwnProperty && !t.hasOwnProperty( p ) ) continue;
\r
1634 v && v instanceof TicketBase && v.kill();
\r
1642 /* --------------------------------------------------------------
\r
1647 var SystemTimer = ( function(){
\r
1648 var setTimeout = window.setTimeout;
\r
1649 var clearTimeout = window.clearTimeout;
\r
1650 var INTERVAL_TIME = 16;
\r
1651 var TICKET_LIST = [];
\r
1652 var timerId = undefined;
\r
1656 for( var i = 0; i < TICKET_LIST.length; ) {
\r
1657 if( TICKET_LIST[ i ].call( next ) !== false ) ++i;
\r
1659 timerId = undefined;
\r
1662 function update(){
\r
1663 var l = TICKET_LIST.length,
\r
1667 timerId !== undefined && clearTimeout( timerId );
\r
1668 timerId = undefined;
\r
1671 for( var i = 0; i<l; i++ ){
\r
1672 c = TICKET_LIST[ i ].count;
\r
1673 if( n > c ) n = c;
\r
1675 if( next > n || timerId === undefined ){
\r
1676 timerId !== undefined && clearTimeout( timerId );
\r
1677 timerId = setTimeout( loop, INTERVAL_TIME * n );
\r
1682 var TimerTicketClass = function( _apiuser, _callback, _time, _once ){
\r
1683 this.apiuser = _apiuser;
\r
1684 this.callback = _callback;
\r
1685 this.time = _time;
\r
1686 this.count = _time;
\r
1687 this.once = _once;
\r
1688 _apiuser = _callback = null;
\r
1690 TimerTicketClass.prototype = new TicketBase();
\r
1691 TimerTicketClass.prototype.call = function( c ){
\r
1693 if( this.count <= 0 ){
\r
1695 if( this.once === true ){
\r
1697 TICKET_LIST.splice( Util.getIndex( TICKET_LIST, this ), 1 );
\r
1700 this.count = this.time;
\r
1704 TimerTicketClass.prototype.destroy = function( _apiuser, _callback ){
\r
1705 if( _apiuser && _apiuser !== this.apiuser ) return false;
\r
1706 if( _callback && _callback !== this.callback ) return false;
\r
1713 add: function( _apiuser, _handler, _time, _once ){
\r
1714 if( Type.isNumber( _time ) === false || _time < INTERVAL_TIME ) _time = INTERVAL_TIME;
\r
1716 var _ticket = new TimerTicketClass( _apiuser, _handler, Math.ceil( _time / INTERVAL_TIME ), _once );
\r
1717 TICKET_LIST.push( _ticket );
\r
1721 remove: function( _apiuser, _handler ) {
\r
1724 while( _ticket = TICKET_LIST[ i ] ){
\r
1725 if( _ticket.destroy( _apiuser, _handler ) === true ){
\r
1726 TICKET_LIST.splice( i, 1 );
\r
1736 /* --------------------------------------------------------------
\r
1740 var AsyncCall = ( function(){
\r
1741 var CALLBACK_LIST = [];
\r
1743 var CallbackTicketClass = function( _apiuser, _callback, _argments, _thisObject ){
\r
1744 this.apiuser = _apiuser;
\r
1745 this.callback = _callback;
\r
1746 this.argments = _argments;
\r
1747 this.thisObject = _thisObject;
\r
1749 CallbackTicketClass.prototype = new TicketBase();
\r
1750 CallbackTicketClass.prototype.call = function(){
\r
1751 var f = this.callback,
\r
1752 a = this.argments,
\r
1753 t = this.thisObject;
\r
1755 if( Type.isArray( a ) === true ){
\r
1761 CallbackTicketClass.prototype.destroy = function( _apiuser, _callback ){
\r
1762 if( _apiuser && _apiuser !== this.apiuser ) return false;
\r
1763 if( _callback && _callback !== this.callback ) return false;
\r
1769 function dispatch(){
\r
1770 var _ticket = CALLBACK_LIST.shift();
\r
1773 CALLBACK_LIST.length !== 0 && SystemTimer.add( SUPER_USER_KEY, dispatch, 1, true );
\r
1778 add: function( _apiuser, _callback, _argments, _thisObject ){
\r
1779 CALLBACK_LIST.length === 0 && SystemTimer.add( SUPER_USER_KEY, dispatch, 1, true );
\r
1780 CALLBACK_LIST.push( new CallbackTicketClass( _apiuser, _callback, _argments, _thisObject || _apiuser ) );
\r
1782 remove: function( _apiuser, _callback ){
\r
1785 while( _ticket = CALLBACK_LIST[ i ] ){
\r
1786 if( _ticket.destroy( _apiuser, _callback ) === true ){
\r
1787 CALLBACK_LIST.splice( i, 1 );
\r
1796 /* -----------------------------------------------------------
\r
1798 * お気に入り画像一覧 > tag:ペン次郎 > ペン次郎:笑う
\r
1799 * 最近アップロードされた画像 > images
\r
1800 * 最近使われた画像 > images
\r
1801 * キャラクター画像庫 > アニマル系 > tag:ペン次郎 > ペン次郎:笑う
\r
1808 var File = ( function(){
\r
1809 var DRIVER_LIST = [];
\r
1811 var FILE_TYPE_IS_FOLDER = Const.FILE.TYPE.FOLDER,
\r
1812 numFileType = Const.FILE.TYPE.XML,
\r
1813 FILEDATA_RESITER = [], // store all of fileData( json object )
\r
1814 FILEDATA_ACCESS = [], // file operations for Kernel only ! hide from Out of File
\r
1815 FILE_OBJECT_POOL = [],
\r
1816 EVENT_LISTENER_REGISTER = [],
\r
1818 TREE_ACCESS_ARRAY = [];
\r
1820 var REQUEST_CONTROLER = ( function(){
\r
1821 var REQUEST_TICKET_RESISTER = [],
\r
1822 currentTicket = null,
\r
1823 currentData = null,
\r
1824 DATA_TYPE_ARRAY = 'json,xml,html,text'.split( ','),
\r
1831 var RequestTicketClass = function( _apiuser, _type, _data, _url, _onLoad, _onError ){
\r
1832 this.apiuser = _apiuser;
\r
1833 this.type = _type;
\r
1834 this.data = _data;
\r
1836 this.onLoad = _onLoad;
\r
1837 this.onError = _onError;
\r
1839 _apiuser = _type = _data = _onLoad = _onError = null;
\r
1841 RequestTicketClass.prototype = new TicketBase();
\r
1842 RequestTicketClass.prototype.load = function( _data ){
\r
1843 AsyncCall.add( this.apiuser, this.onLoad, [ this.data, _data ] );
\r
1845 RequestTicketClass.prototype.error = function(){
\r
1846 AsyncCall.add( this.apiuser, this.onError, this.data );
\r
1849 function request(){
\r
1850 if( currentTicket !== null || REQUEST_TICKET_RESISTER.length === 0 ) return;
\r
1851 currentTicket = REQUEST_TICKET_RESISTER.shift();
\r
1853 url: currentTicket.url,
\r
1854 dataType: DATA_TYPE_ARRAY[ currentTicket.type ],
\r
1855 success: onSuccess,
\r
1859 function onSuccess( _data ){
\r
1860 currentTicket.load( _data );
\r
1861 currentTicket.kill();
\r
1862 currentTicket = null;
\r
1865 function onError(){
\r
1867 currentTicket.error();
\r
1868 currentTicket.kill(); // retry
\r
1869 currentTicket = null;
\r
1874 getNumTask: function(){
\r
1875 return REQUEST_TICKET_RESISTER.length;
\r
1877 getNumError: function(){
\r
1880 getJson: function( _apiuser, _data, _url, _onLoad, _onError ){
\r
1881 REQUEST_TICKET_RESISTER.push( new RequestTicketClass( _apiuser, DATA_IS_JSON, _data, _url, _onLoad, _onError ));
\r
1882 currentTicket === null && request();
\r
1887 var FILE_CONTROLER = {
\r
1888 createTree: function( _apiuser, _rootFileData ){
\r
1889 var _tree = new TreeClass( _apiuser, _rootFileData );
\r
1890 TREE_ARRAY.push( _tree );
\r
1893 getFileUID: function( FILEDATAorFILE ){
\r
1894 if( FILEDATAorFILE instanceof FileClass ){
\r
1895 return FILEDATAorFILE.getUID();
\r
1898 var uid = Util.getIndex( FILEDATA_RESITER, FILEDATAorFILE );
\r
1900 uid = FILEDATA_RESITER.length;
\r
1901 FILEDATA_RESITER.push( FILEDATAorFILE );
\r
1905 getFileDataAccess: function( UIDorFILEorFILEDATA ){
\r
1906 var _uid, _data = FILE_CONTROLER.getFileData( UIDorFILEorFILEDATA ), _access;
\r
1908 if( _data === null || typeof _data !== 'object' ) return null;
\r
1909 for( var i=0, l = FILEDATA_ACCESS.length; i<l; ++i ){
\r
1910 _access = FILEDATA_ACCESS[ i ];
\r
1911 if( _access.DATA === _data ) return _access;
\r
1915 getFileData: function( UIDorFILEorFILEDATA ){
\r
1916 if( typeof UIDorFILEorFILEDATA === 'number' ){
\r
1917 return FILEDATA_RESITER[ UIDorFILEorFILEDATA ] || null;
\r
1919 if( UIDorFILEorFILEDATA instanceof FileClass ){
\r
1920 return FILEDATA_RESITER[ UIDorFILEorFILEDATA.getUID() ] || null;
\r
1922 if( Util.getIndex( FILEDATA_RESITER, UIDorFILEorFILEDATA ) !== -1 ){
\r
1923 return UIDorFILEorFILEDATA;
\r
1927 getChildren: function( UIDorFILEorFILEDATA ){
\r
1928 var _data = FILE_CONTROLER.getFileData( UIDorFILEorFILEDATA );
\r
1929 return _data !== null ? _data.children || null : null;
\r
1931 getDriver: function( _file ){
\r
1932 var _data = FILE_CONTROLER.getFileData( _file );
\r
1933 return _data !== null && _data.driver ? _data.driver : BASE_DRIVER;
\r
1935 getUpdateFlag: function( _file, _bit ){
\r
1936 var _driver = FILE_CONTROLER.getDriver( _file ),
\r
1938 if( typeof _driver.getUpdatePolicy === 'function' ){
\r
1939 _policy = _driver.getUpdatePolicy( _file );
\r
1942 if( typeof _policy !== 'number' ) {
\r
1943 _policy = BASE_DRIVER.getUpdatePolicy( _file )
\r
1945 return _policy % ( _bit * 2 ) >= _bit;
\r
1947 move: function( _prentUID, _targetfile, _newFolder, _newIndex, _opt_callback ){
\r
1948 var _parentData = FILE_CONTROLER.getFileDataAccess( _prentUID ),
\r
1949 _parentType = _parentData.TYPE,
\r
1950 _targetData = FILE_CONTROLER.getFileDataAccess( _targetfile ),
\r
1951 _targetType = _targetData.TYPE;
\r
1953 replace: function( _uid, _file, _newIndex ){
\r
1956 addEventListener: function( FILEorNULL, _eventType, _callback ){
\r
1957 var _uid = FILEorNULL instanceof FileClass ? FILEorNULL.getUID() : FILEorNULL;
\r
1958 EVENT_LISTENER_REGISTER.push( new FileEventTicketClass( _uid, _eventType, _callback ));
\r
1960 removeEventListener: function( FILEorNULL, _eventType, _callback ){
\r
1961 var _uid = FILEorNULL instanceof FileClass ? FILEorNULL.getUID() : FILEorNULL,
\r
1963 for(var i=0, l = EVENT_LISTENER_REGISTER.length; i<l; ++i ){
\r
1964 _ticket = EVENT_LISTENER_REGISTER[ i ];
\r
1965 if( _ticket.fileUID === _uid && _ticket.eventType === _eventType && _ticket.callBack === _callback ){
\r
1966 EVENT_LISTENER_REGISTER.splice( i, 1 );
\r
1971 getTreeAccess: function(){
\r
1974 fileEventRellay: function( _uid, _event ){
\r
1975 var _fileAccess = FILE_CONTROLER.getFileDataAccess( _uid );
\r
1976 if( _fileAccess === null ) return;
\r
1977 var _treeUID = _fileAccess.TREE.getUID(),
\r
1978 _treeAccess = TREE_ACCESS_ARRAY[ _treeUID ],
\r
1979 _data = _fileAccess.DATA,
\r
1981 if( !_treeAccess ) return;
\r
1982 _treeAccess.dispatchFileEvent( _event );
\r
1983 for( var i=0, l = TREE_ARRAY.length; i<l; ++i ){
\r
1984 if( i !== _treeUID ){
\r
1985 _tree = TREE_ARRAY[ i ];
\r
1986 if( FILE_CONTROLER.getFileData( _tree.getCurrentFile() ) === _data ){
\r
1987 _treeAccess = TREE_ACCESS_ARRAY[ _tree.getUID() ];
\r
1988 _treeAccess && _treeAccess.dispatchFileEvent( _event );
\r
1995 var TreeClass = function( apiuser, rootFileData ){
\r
1996 var PARENT_FILE_RESITER = [],
\r
1998 apiuser : apiuser,
\r
1999 dispatchFileEvent: dispatchFileEvent
\r
2001 EVENT_LISTENER_ARRAY = [],
\r
2003 rootFile = new FileClass( instance, null, rootFileData ),
\r
2004 currentFile = rootFile;
\r
2006 currentFile.getSeqentialFiles();
\r
2007 TREE_ACCESS_ARRAY.push( ACCESS );
\r
2009 function dispatchFileEvent( e ){
\r
2010 var _eventType = e.eventType,
\r
2011 _targetFile = e.targetFile,
\r
2012 _uid = _targetFile.getUID(),
\r
2013 _ticket, _type, _callback;
\r
2014 for( var i=0, l = EVENT_LISTENER_REGISTER.length; i<l; ++i ){
\r
2015 _ticket = EVENT_LISTENER_REGISTER[ i ];
\r
2016 _type = _ticket.eventType;
\r
2017 _callback = _ticket.callBack;
\r
2018 if( _eventType === _type && _uid === _ticket.fileUID ){
\r
2019 AsyncCall.add( apiuser, _callback, [ _eventType, _targetFile, e.key, e.value ], _targetFile );
\r
2021 if( _type === Const.TREE.EVENT.UPDATE && _eventType === Const.FILE.EVENT.GET_SEQENTIAL_FILES ){
\r
2022 //_callback( _eventType, _targetFile );
\r
2023 AsyncCall.add( apiuser, _callback, [ _eventType, _targetFile ], instance );
\r
2028 this.getUID = function(){
\r
2029 return Util.getIndex( TREE_ACCESS_ARRAY, ACCESS );
\r
2031 this.getRootFile = function(){
\r
2034 this.getCurrentFile = function(){
\r
2035 return currentFile;
\r
2037 this.hierarchy = function(){
\r
2038 return PARENT_FILE_RESITER.length;
\r
2040 this.getParentFileAt = function( _index ){
\r
2041 var l = PARENT_FILE_RESITER.length;
\r
2042 if( typeof _index !== 'number' || _index < 0 || _index >= l ) return null;
\r
2043 return PARENT_FILE_RESITER[ l -1 -_index ];
\r
2045 this.down = function( _index ){
\r
2046 if( typeof _index !== 'number' || _index < 0 || _index >= currentFile.getChildFileLength()) return;
\r
2047 PARENT_FILE_RESITER.unshift( currentFile );
\r
2048 currentFile = currentFile.getChildFileByIndex( _index );
\r
2049 currentFile.getSeqentialFiles();
\r
2050 return currentFile;
\r
2052 this.up = function( _index ){
\r
2053 var l = PARENT_FILE_RESITER.length;
\r
2054 if( l === 0) return null;
\r
2056 if( currentFile ){
\r
2057 var _currentFile = currentFile;
\r
2058 currentFile = null;
\r
2059 _currentFile.destroy();
\r
2061 if( typeof _index === 'number'){
\r
2062 if( _index >= l) return null;
\r
2063 currentFile = this.getParentFileAt( _index );
\r
2064 PARENT_FILE_RESITER.splice( 0, l -_index);
\r
2066 currentFile = PARENT_FILE_RESITER.shift();
\r
2068 currentFile.getSeqentialFiles();
\r
2069 return currentFile;
\r
2071 this.addTreeEventListener = function( _eventType, _callback ){
\r
2072 FILE_CONTROLER.addEventListener( null, _eventType, _callback );
\r
2074 this.removeTreeEventListener = function( _eventType, _callback ){
\r
2075 FILE_CONTROLER.removeEventListener( null, _eventType, _callback );
\r
2077 this.destroy = function( _apiuser ){
\r
2078 if( _apiuser && apiuser !== _apiuser ) return false;
\r
2080 var _currentFile = currentFile;
\r
2081 currentFile = rootFile = rootFileData = null;
\r
2082 // currentFile, rootFile を null にしないと .File.destroy() ができない.
\r
2083 _currentFile.destroy();
\r
2084 while( PARENT_FILE_RESITER.length > 0 ){
\r
2085 _currentFile = PARENT_FILE_RESITER.shift();
\r
2086 _currentFile.destroy();
\r
2089 AsyncCall.remove( apiuser );
\r
2090 instance = apiuser = null;
\r
2095 var FileEventTicketClass = function( _uid, _eventType, _callback ){
\r
2096 this.fileUID = _uid;
\r
2097 this.eventType = _eventType;
\r
2098 this.callBack = _callback;
\r
2099 _uid = _eventType = _callback = undefined;
\r
2101 FileEventTicketClass.prototype = new TicketBase();
\r
2103 var FileEventClass = function( eventType, file, key, value ){
\r
2104 this.eventType = eventType;
\r
2105 this.targetFile = file;
\r
2106 this.updatedAttribute = key;
\r
2107 this.updatedValue = value;
\r
2111 * file の data は object で保持している。
\r
2112 * File の外からファイルをみるときは、FileClassを通して操作する。
\r
2113 * fileの変更、それに付随して追加されたイベントは、TreeClassで管理される。
\r
2114 * treeがdestryされると、fileのイベントリスナーも全て削除される。
\r
2115 * 他の tree も data の共通する currentFile に対してのみは、file の変更イベントを受け取って流す.
\r
2119 var FileClass = function( tree, parentData, data ){
\r
2120 var uid = FILE_CONTROLER.getFileUID( data );
\r
2122 FILEDATA_ACCESS.push( {
\r
2124 parentData: parentData,
\r
2128 tree = parentData = data = null;
\r
2130 this.getUID = function(){
\r
2135 FileClass.prototype = {
\r
2136 isChildFile: function( _FILEorFILEDATA ){
\r
2137 return this.getChildFileIndex( _FILEorFILEDATA) !== -1;
\r
2139 getSeqentialFiles: function(){
\r
2140 var _driver = FILE_CONTROLER.getDriver( this );
\r
2141 if( _driver !== null && typeof _driver.getSeqentialFiles === 'function' ){
\r
2142 _driver.getSeqentialFiles( this );
\r
2145 addEventListener: function( _eventType, _callback ){
\r
2146 FILE_CONTROLER.addEventListener( this, _eventType, _callback );
\r
2148 removeEventListener: function( _eventType, _callback ){
\r
2149 FILE_CONTROLER.removeEventListener( this, _eventType, _callback );
\r
2151 dispatchEvent: function( e ){
\r
2152 e instanceof FileEventClass && FILE_CONTROLER.fileEventRellay( this.getUID(), e );
\r
2154 getChildFileLength: function(){
\r
2155 var children = FILE_CONTROLER.getChildren( this );
\r
2156 return Type.isArray( children ) === true ? children.length : -1;
\r
2158 getChildFileIndex: function( _FILEorFILEDATA ){
\r
2159 var children = FILE_CONTROLER.getChildren( this );
\r
2160 if( Type.isArray( children ) === false ) return -1;
\r
2161 var l = children.length,
\r
2162 _fileData = FILE_CONTROLER.getFileData( _FILEorFILEDATA );
\r
2163 if( _fileData === null ) return -1;
\r
2164 for( var i=0; i<l; ++i ){
\r
2165 if( children[ i ] === _fileData ) return i;
\r
2169 getChildFileByIndex: function( _index ){
\r
2170 var _access = FILE_CONTROLER.getFileDataAccess( this ),
\r
2171 _children = FILE_CONTROLER.getChildren( this );
\r
2172 if( typeof _index !== 'number' || _index < 0 || Type.isArray( _children ) === false || _index >= _children.length) return null;
\r
2173 var _file = new FileClass( _access.TREE, _access.DATA, _children[ _index ]);
\r
2177 getName: function(){
\r
2178 var driver = FILE_CONTROLER.getDriver( this );
\r
2179 if( typeof driver.getName === 'function'){
\r
2180 return driver.getName( this );
\r
2182 return BASE_DRIVER.getName( this);
\r
2184 getThumbnail: function(){
\r
2185 var driver = FILE_CONTROLER.getDriver( this );
\r
2186 if( typeof driver.getThumbnail === 'function'){
\r
2187 return driver.getThumbnail( this );
\r
2189 return BASE_DRIVER.getThumbnail( this );
\r
2191 getType: function(){
\r
2192 var _data = FILE_CONTROLER.getFileData( this );
\r
2193 return typeof _data.type === 'number' ? _data.type : Const.FILE.TYPE.UNKNOWN;
\r
2195 getState: function(){
\r
2196 var _data = FILE_CONTROLER.getFileData( this );
\r
2197 return typeof _data.state === 'number' ? _data.state : Const.FILE.STATE.OK;
\r
2199 getSummary: function(){
\r
2200 var driver = FILE_CONTROLER.getDriver( this );
\r
2201 if( typeof driver.getSummary === 'function'){
\r
2202 return driver.getSummary( this );
\r
2204 return BASE_DRIVER.getSummary( this );
\r
2206 isWritable: function(){
\r
2207 return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.WRITE );
\r
2209 isSortable: function(){
\r
2210 return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.SORT );
\r
2212 isCreatable: function(){
\r
2213 return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.CREATE );
\r
2215 isRenamable: function(){
\r
2216 return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.RENAME );
\r
2218 isDeletable: function(){
\r
2219 return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.DELETE );
\r
2223 var driver = FILE_CONTROLER.getDriver( this ),
\r
2225 if( typeof driver.read === 'function'){
\r
2226 data = driver.read( this );
\r
2228 return BASE_DRIVER.read( data || this );
\r
2230 write: function( _newData, _onUpdateFunction ){
\r
2231 var driver = FILE_CONTROLER.getDriver( this );
\r
2232 if( typeof driver.write === 'function'){
\r
2233 return driver.write( this, _newData, _onUpdateFunction );
\r
2235 return BASE_DRIVER.write( this, _newData, _onUpdateFunction );
\r
2237 viewerApplicationList: function(){
\r
2238 var driver = FILE_CONTROLER.getDriver( this );
\r
2239 if( typeof driver.viewerApplicationList === 'function'){
\r
2240 return driver.viewerApplicationList( this );
\r
2242 return BASE_DRIVER.viewerApplicationList( this );
\r
2244 editorApplicationList: function(){
\r
2245 var driver = FILE_CONTROLER.getDriver( this );
\r
2246 if( typeof driver.editorApplicationList === 'function'){
\r
2247 return driver.editorApplicationList( this );
\r
2249 return BASE_DRIVER.viwerApps( this );
\r
2251 create: function(){
\r
2257 onCopy: function(){
\r
2260 onDelete: function(){
\r
2263 move: function( _newFolder, _newIndex, opt_callback ){
\r
2264 var _access = FILE_CONTROLER.getFileDataAccess( this );
\r
2265 _access.TREE.move( _access.parentData, this.getUID(), _newFolder, _newIndex, opt_callback );
\r
2267 replace: function( _newIndex, opt_callback ){
\r
2268 var _access = FILE_CONTROLER.getFileDataAccess( this );
\r
2269 _access.TREE.replace( _access.parentData, this.getUID(), _newIndex, opt_callback);
\r
2273 * 探しているファイルの属性と値を指定.一致する child の index を配列で返す.
\r
2275 search: function( obj, rule ){
\r
2276 var _children = FILE_CONTROLER.getChildren( this ),
\r
2279 for( var i=0, l=_children.length; i<l; ++i ){
\r
2280 _child = _children[ i ];
\r
2283 if( obj[ k ] !== _child[ k ] ){
\r
2288 c === true && ret.push( i );
\r
2292 destroy: function(){
\r
2293 var _access = FILE_CONTROLER.getFileDataAccess( this );
\r
2294 var _tree = _access.TREE;
\r
2295 if( _tree.getCurrentFile() === this ) return;
\r
2296 if( _tree.getRootFile() === this ) return;
\r
2297 for( var i=0, l = _tree.hierarchy(); i<l; ++i ){
\r
2298 if( _tree.getParentFileAt( i ) === this ){
\r
2302 var _index = Util.getIndex( FILEDATA_ACCESS, _access );
\r
2303 if( _index === -1 ) return;
\r
2305 FILEDATA_ACCESS.splice( _index, 1 );
\r
2306 delete _access.DATA;
\r
2307 delete _access.TREE;
\r
2308 delete _access.parentData;
\r
2315 var FileDriverBase = function( driverClass ){
\r
2316 this.getUID = function(){
\r
2317 return Util.getIndex( API_USER_LIST, driverClass );
\r
2319 this.getSeqentialFiles = function( _file ){
\r
2321 this.getName = function( _file ){
\r
2322 var _data = FILE_CONTROLER.getFileData( _file );
\r
2323 return _data.name || 'No Name';
\r
2325 this.getThumbnail = function( _file ){
\r
2326 var _data = FILE_CONTROLER.getFileData( _file ),
\r
2327 _type = _data.type,
\r
2329 if( _type === Const.FILE.TYPE.FOLDER ){
\r
2330 _className = 'folder';
\r
2332 if( _type === Const.FILE.TYPE.IMAGE ){
\r
2335 if( _type === Const.FILE.TYPE.TEXT ){
\r
2338 if( _type === Const.FILE.TYPE.HTML ){
\r
2341 if( _type === Const.FILE.TYPE.CSV ){
\r
2344 if( _type === Const.FILE.TYPE.JSON ){
\r
2347 if( _type === Const.FILE.TYPE.XML ){
\r
2352 className: ' file-type-' + _className
\r
2355 this.getSummary = function( _file ){
\r
2356 var _data = FILE_CONTROLER.getFileData( _file ),
\r
2357 _type = _data.type;
\r
2358 if( _type === Const.FILE.TYPE.FOLDER ){
\r
2361 if( _type === Const.FILE.TYPE.IMAGE ){
\r
2362 return 'image file';
\r
2364 if( _type === Const.FILE.TYPE.TEXT ){
\r
2365 return 'text file';
\r
2367 if( _type === Const.FILE.TYPE.HTML ){
\r
2368 return 'html document file';
\r
2370 if( _type === Const.FILE.TYPE.CSV ){
\r
2371 return 'csv daat file';
\r
2373 if( _type === Const.FILE.TYPE.JSON ){
\r
2374 return 'json data file';
\r
2376 if( _type === Const.FILE.TYPE.XML ){
\r
2377 return 'xml data file';
\r
2381 this.getUpdatePolicy = function( _file ){
\r
2382 // debug用 全てのメニューを許可
\r
2383 return Const.FILE.UPDATE_POLICY.DSRWC;
\r
2385 this.read = function( _FILEorDATA ){
\r
2387 protects = Const.FILE.DATA_PROPERTY_RESERVED;
\r
2388 if( _FILEorDATA instanceof FileClass ){
\r
2389 data = FILE_CONTROLER.getFileData( _FILEorDATA )
\r
2391 data = _FILEorDATA;
\r
2394 function clone( src ) {
\r
2396 if( Type.isArray(src) === true ){
\r
2399 if( Type.isObject(src) === true ){
\r
2402 if( Type.isNumber(src) === true || Type.isString(src) === true || Type.isBoolean( src ) === true ){
\r
2407 for( var key in src ){
\r
2408 if( Util.getIndex( protects, key ) === -1 ){
\r
2409 ret[ key ] = clone( src[ key ]);
\r
2415 return clone( data );
\r
2417 this.write = function( _file, _newData, _onUpdateFunction ){
\r
2418 var _data = FILE_CONTROLER.getFileData( _file ),
\r
2419 _type = _data.type;
\r
2422 this.viewerApplicationList = function(){
\r
2425 this.editorApplicationList = function(){
\r
2428 this.onCreate = function(){
\r
2431 this.onSort = function(){
\r
2434 this.onCopy = function(){
\r
2437 this.onDelete = function(){
\r
2442 var BASE_DRIVER = new FileDriverBase();
\r
2444 var ROOT_FILEDATA = {
\r
2445 name: 'system root',
\r
2446 type: FILE_TYPE_IS_FOLDER,
\r
2449 SYSTEM_TREE = FILE_CONTROLER.createTree( SUPER_USER_KEY, ROOT_FILEDATA ),
\r
2450 ROOT_FILE = SYSTEM_TREE.getRootFile();
\r
2452 function createFileTypeID(){
\r
2453 return ++numFileType;
\r
2456 var FileAPIClass = function( driver ){
\r
2458 this.createFolderUnderRoot = function( _fileData ){
\r
2459 if( _fileData !== null && Type.isObject( _fileData ) === true ){
\r
2460 ROOT_FILEDATA.children.push( _fileData );
\r
2461 ROOT_FILE.dispatchEvent( new FileEventClass( Const.FILE.EVENT.GET_SEQENTIAL_FILES, ROOT_FILE, 'children', null ));
\r
2464 this.createFileEvent = function( _eventType, _file, _key, _value ){
\r
2465 return new FileEventClass( _eventType, _file, _key, _value );
\r
2467 this.createFileTypeID = createFileTypeID;
\r
2468 this.getFileDataAccess = FILE_CONTROLER.getFileDataAccess;
\r
2469 this.getFileData = FILE_CONTROLER.getFileData;
\r
2470 this.getJson = function( _data, _url, _onLoad, _onError ){
\r
2471 REQUEST_CONTROLER.getJson( driver, _data, _url, _onLoad, _onError );
\r
2473 this.createTree = function( _rootFile ){
\r
2474 return FILE_CONTROLER.createTree( driver, _rootFile );
\r
2476 this.isTreeInstance = function( _tree ){
\r
2477 return _tree instanceof TreeClass;
\r
2479 this.isFileInstance = function( _file ){
\r
2480 return _file instanceof FileClass;
\r
2482 this.isFileEvent = function( _event ){
\r
2483 return _event instanceof FileEventClass;
\r
2485 this.getConst = function(){
\r
2486 return Const; // constObject = constObject || clone( Const )
\r
2491 registerDriver: function( _class ){
\r
2492 _class.prototype = new FileDriverBase( _class );
\r
2493 var _driver = new _class();
\r
2495 DRIVER_LIST.push( _driver );
\r
2496 API_USER_LIST.push( _class );
\r
2498 return new FileAPIClass( _driver );
\r
2500 isDriver: function( _driver ){
\r
2501 return _driver instanceof FileDriverBase;
\r
2503 isTreeInstance: function( _tree ){
\r
2504 return _tree instanceof TreeClass;
\r
2506 isFileInstance: function( _file ){
\r
2507 return _file instanceof FileClass;
\r
2513 /* ----------------------------------------------------
\r
2514 * ApplicationManager
\r
2515 * window resize event, overlayApplication currentAplication に流す
\r
2518 var APPLICATION_LIST = [];
\r
2520 var AbstractBasicPane = function(){
\r
2521 var instance = null;
\r
2522 this.MIN_WIDTH = 240;
\r
2523 this.MIN_HEIGHT = 240;
\r
2524 this.init = function(){
\r
2526 instance.onInit();
\r
2528 this.onInit = function(){};
\r
2529 this.resize = function( _w, _h ){
\r
2530 if( instance.MIN_WIDTH > _w || instance.MIN_HEIGHT > _h ){
\r
2531 if( Type.isHTMLElement( instance.rootElement ) === true ){
\r
2536 instance.onPaneResize( _w, _h );
\r
2538 this.onPaneResize = function( _w, _h ){};
\r
2539 this.close = function(){
\r
2540 instance.onClose();
\r
2545 var AbstractApplication = function( displayName, appClass, isOverlay ){
\r
2546 var self = null, // init で設定
\r
2549 fetchResource = 0,
\r
2550 bootParams = null,
\r
2552 this.rootElement = document.createElement( 'div' );
\r
2553 this.bgColor = '#C1CACF';
\r
2554 this.getUID = function(){
\r
2555 return Util.getIndex( API_USER_LIST, appClass );
\r
2557 this.init = function(){
\r
2560 appClass === Page.appClass && Page.show();
\r
2564 this.open = function( _w, _h /*, _option */ ){
\r
2566 bootParams = Util.copyArray( arguments );
\r
2568 if( this.rootElement.innerHTML && this.rootElement.innerHTML.length > 0 ){
\r
2569 SystemTimer.add( self, detect, 16 );
\r
2574 function detect(){
\r
2575 if( self.rootElement.firstChild && fetchResource === 0 ){
\r
2576 SystemTimer.remove( self, detect );
\r
2581 function onOpen(){
\r
2582 self.rootElement.style.display = '';
\r
2584 if( self.MIN_WIDTH > _w || self.MIN_HEIGHT > _h ){
\r
2585 if( Type.isHTMLElement( self.rootElement ) === true ){
\r
2589 if( bootParams.length > 2 ){
\r
2590 self.onOpen.apply( self, bootParams );
\r
2592 self.onOpen( _w, _h );
\r
2597 this.resize = function( _w, _h ){
\r
2598 if( phase !== 4 ) return;
\r
2599 if( self.MIN_WIDTH > _w || self.MIN_HEIGHT > _h ){
\r
2600 if( Type.isHTMLElement( self.rootElement ) === true ){
\r
2605 self.onPaneResize( _w, _h );
\r
2607 this.close = function(){
\r
2609 if( self.onClose() === false ){
\r
2612 MouseEvent.remove( self );
\r
2613 KeyEvent.remove( self );
\r
2614 SystemTimer.remove( self );
\r
2615 AsyncCall.remove( self );
\r
2616 StyleSheet.unload( self );
\r
2618 while( uiList.length > 0 ){
\r
2619 uiList.shift().destroy();
\r
2621 while( finderList.length > 0 ){
\r
2622 finderList.shift().destroy();
\r
2624 var elm = self.rootElement;
\r
2625 Util.removeAllChildren( elm );
\r
2626 elm.parentNode.removeChild( elm );
\r
2627 self.rootElement = null;
\r
2629 Application.shutdown( self, isOverlay );
\r
2631 appClass === Page.appClass && Page.hide();
\r
2633 self = appClass = uiList = null;
\r
2637 this.createUIGroup = function(){
\r
2638 var _ui = UI.createUIGroup( self );
\r
2639 uiList.push( _ui );
\r
2642 this.createFinder = function( _elmTarget, _tree, _header, _footer, _onSelect, _viewerOption, _editorOption ){
\r
2643 var _finder = Finder.create( self, _elmTarget, _tree, _header, _footer, _onSelect, _viewerOption, _editorOption );
\r
2644 finderList.push( _finder );
\r
2647 this.createBasicPane = function( _class, _options ){
\r
2648 if( Type.isFunction( _class ) === false ) return null;
\r
2649 _class.prototype = new AbstractBasicPane();
\r
2650 return new _class( _options );
\r
2652 this.createDHTML = function( _elm ){
\r
2653 return DHTML.create( self, _elm );
\r
2655 this.fetchCSS = function( _url, opt_onload, opt_onerror ){
\r
2656 if( phase === 1 ){
\r
2658 StyleSheet.load( self, _url, fetchResourceComplete, fetchResourceComplete );
\r
2662 function fetchResourceComplete(){
\r
2667 AbstractApplication.prototype = new AbstractBasicPane();
\r
2668 AbstractApplication.prototype.onInit = function(){
\r
2671 AbstractApplication.prototype.onOpen = function( _w, _h /*, _option */ ){
\r
2674 AbstractApplication.prototype.onClose = function(){
\r
2677 }; // false の場合、close の拒否
\r
2678 AbstractApplication.prototype.addEventListener = function( _element, _eventType, _handler ){
\r
2679 MouseEvent.add( this, _element, _eventType, _handler );
\r
2681 AbstractApplication.prototype.removeMouseEventListener = function( _element, _eventType, _handler ){
\r
2682 MouseEvent.remove( this, _element, _eventType, _handler );
\r
2684 AbstractApplication.prototype.addKeyEventListener = function( _eventType, _handler, _keyCode, _shift, _ctrl ){
\r
2685 KeyEvent.add( this, _eventType, _handler, _keyCode, _shift, _ctrl );
\r
2687 AbstractApplication.prototype.removeKeyEventListener = function( _eventType, _handler, _keyCode, _shift, _ctrl ){
\r
2688 KeyEvent.remove( this, _eventType, _handler, _keyCode, _shift, _ctrl );
\r
2690 AbstractApplication.prototype.shiftEnabled = function(){
\r
2691 return KeyEvent.shiftEnabled;
\r
2693 AbstractApplication.prototype.ctrlEnabled = function(){
\r
2694 return KeyEvent.ctrlEnabled;
\r
2696 AbstractApplication.prototype.addTimer = function( handler, time, once ){
\r
2697 SystemTimer.add( this, handler, time, !!once );
\r
2699 AbstractApplication.prototype.removeTimer = function( handler ){
\r
2700 SystemTimer.remove( this, handler );
\r
2702 AbstractApplication.prototype.addAsyncCall = function( _callback, _argments, _thisObject ){
\r
2703 AsyncCall.add( this, _callback, _argments, _thisObject );
\r
2705 AbstractApplication.prototype.removeAsyncCall = function( _callback ){
\r
2706 AsyncCall.remove( this, _callback );
\r
2708 AbstractApplication.prototype.fetchHTMLElement = function( id ){
\r
2709 var elm = doc.getElementById( id );
\r
2711 elm.removeAttribute( 'id' );
\r
2712 elm.parentNode.removeChild( elm );
\r
2717 var Application = ( function(){
\r
2719 var LIVE_APPLICATION_LIST = [];
\r
2721 var currentApplication = null,
\r
2722 coveredApplication = null,
\r
2726 var ApplicationReference = function( appClass, isOverlay, displayName, id, thumbnailUrl, tailColor ){
\r
2728 var application = null;
\r
2730 this.displayName = displayName;
\r
2731 this.thumbnailUrl = thumbnailUrl;
\r
2732 this.tailColor = tailColor;
\r
2733 this.getUID = function(){
\r
2734 return Util.getIndex( API_USER_LIST, appClass );
\r
2736 this.boot = function( /* _option */ ){
\r
2737 application = Application.boot( displayName, self.getUID(), appClass, isOverlay, Util.copyArray( arguments ) );
\r
2739 this.shutdown = function(){
\r
2740 if( !application ) return false;
\r
2742 if( ( isOverlay === true ? Overlay.hide() : application.close() ) === false ) return false;
\r
2743 application = null;
\r
2747 function asyncBootHome(){
\r
2748 currentApplication === null && Home.boot();
\r
2750 function asyncOpen( /* arguments */ ){
\r
2751 var _arg = Util.copyArray( arguments );
\r
2752 _arg.unshift( winW, winH );
\r
2753 currentApplication.open.apply( currentApplication, _arg );
\r
2756 register: function( _class, _overlay, _tail, _displayName, _id, _thumbnailUrl, _tailColor ){
\r
2757 APPLICATION_LIST.push( _class );
\r
2758 API_USER_LIST.push( _class );
\r
2759 var _ref = new ApplicationReference( _class, _overlay, _displayName, _id, _thumbnailUrl, _tailColor );
\r
2760 _tail === true && Home.add( _ref );
\r
2763 isBasicPaneInstance: function( _basicPane ){
\r
2764 return _basicPane instanceof AbstractBasicPane;
\r
2766 isApplicationInstance: function( _application ){
\r
2767 return _application instanceof AbstractApplication;
\r
2769 isApplicationReference: function( _reference ){
\r
2770 return _reference instanceof ApplicationReference;
\r
2772 isCurrentAppplication: function( _application ){
\r
2775 boot: function( displayName, uid, appClass, isOverlay, arg ){
\r
2776 if( currentApplication ){
\r
2777 if( currentApplication.getUID() === uid ) return null;
\r
2778 if( isOverlay === false && currentApplication.close() === false ) return null;
\r
2781 appClass.prototype = new AbstractApplication( displayName, appClass, isOverlay );
\r
2782 var application = new appClass(); // new は boot で
\r
2784 coveredApplication = isOverlay === true ? currentApplication : null;
\r
2786 Application.onCurrentApplicationChange( application );
\r
2788 if( isOverlay === false ){
\r
2789 body.style.backgroundColor = application.bgColor;
\r
2791 body.appendChild( application.rootElement );
\r
2792 application.rootElement.style.display = 'none';
\r
2793 application.init();
\r
2795 application.addAsyncCall( asyncOpen, arg );
\r
2797 Overlay.show( application, arg );
\r
2800 return application;
\r
2802 shutdown: function( _application, isOverlay ){
\r
2803 if( isOverlay === false ){
\r
2804 currentApplication = null;
\r
2805 AsyncCall.add( SUPER_USER_KEY, asyncBootHome );
\r
2807 Application.onCurrentApplicationChange( coveredApplication );
\r
2808 coveredApplication = null;
\r
2811 onCurrentApplicationChange: function( _application ){
\r
2812 if( Application.isApplicationInstance( _application ) === false ) return;
\r
2813 if( currentApplication === _application ) return;
\r
2814 currentApplication = _application;
\r
2815 MouseEvent.onCurrentApplicationChange( _application );
\r
2816 KeyEvent.updateCurrentListener( _application );
\r
2818 onApplicationShutdown: function( _application ){
\r
2819 LIVE_APPLICATION_LIST.splice( Util.getIndex( LIVE_APPLICATION_LIST, _application ) );
\r
2821 onWindowResize: function( w, h ){
\r
2824 currentApplication && currentApplication.resize( w, h );
\r
2825 Overlay.onWindowResize( w, h );
\r
2826 UI.onWindowResize( w, h );
\r
2828 onSystemShutdown: function(){
\r
2834 /* --------------------------------------------------------------
\r
2838 var Home = ( function(){
\r
2839 var APP_REF_LIST = [];
\r
2840 var ELM_TAIL_ORIGIN = ( function(){
\r
2841 var ret = document.createElement( 'div' ),
\r
2842 h2 = document.createElement( 'h2' );
\r
2843 ret.className = 'tail-wrapper';
\r
2844 ret.appendChild( h2 );
\r
2845 h2.appendChild( document.createTextNode( 'appName' ) );
\r
2849 var TailClass = function( appRef ){
\r
2850 this.elm = ELM_TAIL_ORIGIN.cloneNode( true );
\r
2851 this.destroy = function(){
\r
2852 appRef = self = elmName = null;
\r
2856 elmName = this.elm.getElementsByTagName( 'h2' )[ 0 ].firstChild;
\r
2858 this.elm.style.backgroundColor = appRef.tailColor;
\r
2859 elmName.data = appRef.displayName;
\r
2862 var ref = Application.register( function(){
\r
2867 elmContainer, elmHeader;
\r
2871 for( var i=0, l=APP_REF_LIST.length; i<l; ++i ){
\r
2872 tail = new TailClass( APP_REF_LIST[ i ] );
\r
2873 tailList.push( tail );
\r
2875 elmContainer.appendChild( elm );
\r
2876 self.addEventListener( elm, 'click', onTailClick );
\r
2880 function onTailClick( e ){
\r
2881 var _children = elmContainer.getElementsByTagName( 'div' );
\r
2882 for( var i=0, l=_children.length; i<l; ++i ){
\r
2883 if( this === _children[ i ] ){
\r
2884 APP_REF_LIST[ i ].boot();
\r
2890 this.bgColor = '#0F6D39';
\r
2891 this.MIN_WIDTH = 320;
\r
2892 this.MIN_HEIGHT = 320;
\r
2893 this.onInit = function(){
\r
2894 self.rootElement.id = 'home-root';
\r
2896 elmContainer = document.createElement( 'div' );
\r
2897 self.rootElement.appendChild( elmContainer );
\r
2898 elmContainer.id = 'home-tail-container';
\r
2900 elmHeader = document.createElement( 'div' );
\r
2901 self.rootElement.appendChild( elmHeader );
\r
2902 elmHeader.id = 'home-header';
\r
2904 this.onOpen = function( _w, _h ){
\r
2909 this.onPaneResize = function( _w, _h ){
\r
2912 this.onClose = function(){
\r
2913 self.removeMouseEventListener();
\r
2914 while( tailList.length > 0 ){
\r
2915 tailList.shift().destroy();
\r
2917 self = tailList = elmContainer = null;
\r
2919 }, false, false, 'home', 'home', null );
\r
2922 add: function( _appRef ){
\r
2923 if( Application.isApplicationReference( _appRef ) === false ) return;
\r
2924 Util.getIndex( APP_REF_LIST, _appRef ) === -1 && APP_REF_LIST.push( _appRef );
\r
2932 var Page = ( function(){
\r
2933 var pageNodes = [],
\r
2935 ignoreTagList = [ 'script', 'noscript', 'style' ];
\r
2937 var MemoryClass = function( node ){
\r
2940 MemoryClass.prototype = {
\r
2942 var node = this.node,
\r
2943 _nodeType = node.nodeType;
\r
2944 if( _nodeType === 1 && Util.getIndex( ignoreTagList, node.tagName.toLowerCase() ) === -1 ){
\r
2945 this.type = _nodeType;
\r
2946 this.display = node.style.display;
\r
2948 if( _nodeType === 3 ){
\r
2949 if( node.data.replace( /\s/g, '' ).length !== 0 ){
\r
2950 this.type = _nodeType;
\r
2951 this.before = pageNodes.length === 0 ? null : pageNodes[ pageNodes.length - 1 ].node;
\r
2953 body.removeChild( node );
\r
2957 // body.removeChild( node );
\r
2962 if( this.type === 1 ){
\r
2963 if( this.display ){
\r
2964 this.node.style.display = this.display;
\r
2966 this.node.style.display = '';
\r
2969 if( this.before ){
\r
2970 body.insertBefore( this.node, this.before );
\r
2972 body.appendChild( this.node );
\r
2977 if( !this.node.parentNode ){
\r
2980 if( this.type === 1 ){
\r
2981 this.node.style.display = 'none';
\r
2983 body.removeChild( this.node );
\r
2989 onReady: function(){
\r
2990 var _children = Util.copyArray( body.childNodes ),
\r
2992 for( var i = 0, l = _children.length; i<l; ++i ){
\r
2993 _mem = new MemoryClass( _children[ i ] );
\r
2994 _mem.init() !== false && pageNodes.push( _mem );
\r
2996 if( pageNodes.length !== 0 ){
\r
2997 if( Type.isFunction( gOS.PageApplicationClass ) === true ){
\r
2998 Page.appClass = gOS.PageApplicationClass;
\r
2999 Page.appClass.bgColor = Page.appClass.bgColor;
\r
3000 Page.appClass.MIN_WIDTH = Page.appClass.MIN_WIDTH || 240;
\r
3001 Page.appClass.MIN_HEIGHT = Page.appClass.MIN_HEIGHT || 240;
\r
3003 Page.appClass = function(){
\r
3006 this.bgColor = '#ffffff';
\r
3007 this.MIN_WIDTH = 200;
\r
3008 this.MIN_HEIGHT = 200;
\r
3009 this.onInit = function(){};
\r
3010 this.onOpen = function( _w, _h ){
\r
3011 KeyEvent.add( self, Const.KEY.EVENT.KEY_DOWN, ref.shutdown, 27 ); // 27.esc
\r
3013 this.onPaneResize = function( _w, _h ){};
\r
3014 this.onClose = function(){};
\r
3017 ref = Application.register( Page.appClass, false, true, document.title, 'page', null, Page.appClass.tailColor || '#999999' );
\r
3018 if( Type.isFunction( gOS.PageApplicationClass ) === true ){
\r
3019 gOS.PageApplicationRef = ref;
\r
3022 delete Page.onReady;
\r
3025 for( var i = pageNodes.length; i; ){
\r
3026 pageNodes[ --i ].show();
\r
3030 for( var i = pageNodes.length; i; ){
\r
3031 pageNodes[ --i ].hide();
\r
3035 ref && ref.boot();
\r
3037 registered: function(){
\r
3044 /* --------------------------------------------------------------
\r
3048 * スクリーン座標は、コンピュータのディスプレイの左上を原点とする座標系である。screenX, screenY属性で取得できる。Javascritpでは、同名のプロパティとして実装されている。
\r
3049 * しかし、これは、現実的には、何の役に立たない。ブラウザ自体がディスプレイのどの位置にいるのかがわからないので、画面上の位置を知ったところで、何にもならないからだ。
\r
3052 * ウインドウ座標とは、現在のブラウザのウインドウの、ドキュメントを表示している部分の左上原点とした座標である。
\r
3053 * 問題は、ウインドウは、必ずしもドキュメント全体を表示するとは限らない。スクロールと呼ばれるUIによって、ドキュメントの一部だけを表示しているかもしれない。
\r
3055 var XBrowserEvent = ( function(){
\r
3056 var wrappedHandlerClass,
\r
3057 wrappedEventClass,
\r
3060 if( window.addEventListener ){
\r
3061 wrappedHandlerClass = function( element, handler ){
\r
3062 this.handler = function( e ){
\r
3063 if( handler.call( element, e ) !== false ) return;
\r
3064 e.preventDefault();
\r
3065 e.stopPropagation();
\r
3068 this.destroy = function(){
\r
3069 element = handler = null;
\r
3070 delete this.handler;
\r
3071 delete this.destroy;
\r
3075 wrappedEventClass = function( e, element ){
\r
3077 this.type = e.type;
\r
3078 this.target = e.srcElement;
\r
3079 this.currentTarget = element;
\r
3080 this.relatedTarget = e.formElement ? e.formElement : e.toElement;
\r
3081 this.eventPhase = e.srcElement === element ? 2: 3;
\r
3083 this.clientX = e.clientX;
\r
3084 this.clientY = e.clientY;
\r
3085 this.screenX = e.screenX;
\r
3086 this.screenY = e.screenY;
\r
3088 this.keyCode = e.keyCode;
\r
3089 this.altKey = e.altKey;
\r
3090 this.ctrlKey = e.ctrlKey;
\r
3091 this.shiftKey = e.shiftKey;
\r
3093 this.wheelDelta = e.wheelDelta;
\r
3095 e = element = null;
\r
3097 wrappedEventClass.prototype.stopPropagation = function(){
\r
3098 this._event.cancelBubble = true;
\r
3100 wrappedEventClass.prototype.preventDefault = function(){
\r
3101 this._event.returnValue = false;
\r
3104 if( doc.attachEvent ){
\r
3105 wrappedHandlerClass = function( element, handler ){
\r
3106 this.handler = function(){
\r
3107 var e = new wrappedEventClass( window.event, element );
\r
3108 if( handler.call( element, e ) !== false ) return;
\r
3109 e.preventDefault();
\r
3110 e.stopPropagation();
\r
3113 this.destroy = function(){
\r
3114 element = handler = null;
\r
3115 delete this.handler;
\r
3116 delete this.destroy;
\r
3122 find: function( _ticket ){
\r
3123 for( var i=0, l= tmp.list.length, _item; i<l; ++i ){
\r
3124 _item = tmp.list[ i ];
\r
3125 if( _item.match( _ticket.element, _ticket.eventType ) === true ){
\r
3132 tmp.ticketClass = function( _ticket ){
\r
3134 this.element = _ticket.element;
\r
3135 this.eventType = _ticket.eventType;
\r
3136 this.handlers = [ _ticket.handler ];
\r
3137 this.element[ 'on' + this.eventType ] = function( e ){
\r
3138 return self.fire( self, e );
\r
3140 this.clean = function(){
\r
3145 tmp.ticketClass.prototype = {
\r
3146 add: function( _ticket ){
\r
3147 this.match( _ticket.element, _ticket.eventType ) === true &&
\r
3148 this.match( null, null, _ticket.handler ) === false &&
\r
3149 this.handlers.push( _ticket.handler );
\r
3151 remove: function( _ticket ){
\r
3152 if( this.match( _ticket.element, _ticket.eventType, _ticket.handler ) === true ){
\r
3153 var i = Util.getIndex( this.handlers, handler );
\r
3154 i !== 0 && this.handlers.splice( i, 1 );
\r
3155 this.handlers.length === 0 && this.destroy();
\r
3158 fire: function( self, e ){
\r
3159 e = e || new wrappedEventClass( window.event, self.element );
\r
3160 for( var i=self.handlers.length, cancel; i; ){
\r
3161 self.element._currentHandler = self.handlers[ --i ];
\r
3162 if( self.element._currentHandler( e ) === false ) cancel = false;
\r
3163 delete self.element._currentHandler;
\r
3167 match: function( element, eventType, handler ){
\r
3168 if( handler && Util.getIndex( this.handlers, handler ) === -1 ) return false;
\r
3169 if( eventType && this.eventType !== eventType ) return false;
\r
3170 if( element && this.element !== element ) return false;
\r
3173 destroy: function(){
\r
3175 this.element[ 'on' + this.eventType ] = '';
\r
3176 tmp.list.splice( Util.getIndex( tmp.list, this ), 1 );
\r
3177 delete this.element;
\r
3178 delete this.eventType;
\r
3179 delete this.handlers;
\r
3180 delete this.clean;
\r
3187 add: function( _ticket ){
\r
3188 if( doc.addEventListener ){
\r
3189 XBrowserEvent.add = function( _ticket ){
\r
3190 _ticket.wrappedHandler = new wrappedHandlerClass( _ticket.element, _ticket.handler );
\r
3191 _ticket.element.addEventListener( _ticket.eventType, _ticket.wrappedHandler.handler, false );
\r
3194 if( doc.attachEvent ){
\r
3195 XBrowserEvent.add = function( _ticket ){
\r
3196 _ticket.wrappedHandler = new wrappedHandlerClass( _ticket.element, _ticket.handler );
\r
3197 _ticket.element.attachEvent( 'on' + _ticket.eventType, _ticket.wrappedHandler.handler );
\r
3200 XBrowserEvent.add = function( _ticket ){
\r
3201 var t = tmp.find( _ticket );
\r
3205 tmp.list.push( new tmp.ticketClass( _ticket ) );
\r
3210 XBrowserEvent.add( _ticket );
\r
3212 remove: function( _ticket ){
\r
3213 if( doc.removeEventListener ){
\r
3214 XBrowserEvent.remove = function( _ticket ){
\r
3215 _ticket.element.removeEventListener( _ticket.eventType, _ticket.wrappedHandler.handler, false );
\r
3216 _ticket.wrappedHandler.destroy();
\r
3219 if( doc.detachEvent ){
\r
3220 XBrowserEvent.remove = function( _ticket ){
\r
3221 _ticket.element.detachEvent( 'on' + _ticket.eventType, _ticket.wrappedHandler.handler );
\r
3222 _ticket.wrappedHandler.destroy();
\r
3225 XBrowserEvent.remove = function( _ticket ){
\r
3226 var t = tmp.find( _ticket );
\r
3228 t.remove( _ticket );
\r
3233 XBrowserEvent.remove( _ticket );
\r
3239 * EventTicketClass
\r
3241 var EventTicketClass = function( _element, _eventType, _handler ){
\r
3242 this.element = _element;
\r
3243 this.eventType = _eventType;
\r
3244 this.handler = _handler;
\r
3245 this.wrappedHandler = null; // for ie
\r
3247 XBrowserEvent.add( this );
\r
3249 _element = _eventType = _handler = null;
\r
3251 EventTicketClass.prototype = {
\r
3252 match: function( _element, _eventType, _handler ){
\r
3253 if( _handler && _handler !== this.handler ) return false;
\r
3254 if( _eventType && _eventType !== this.eventType ) return false;
\r
3255 if( _element && _element !== this.element ) return false;
\r
3259 destroy: function( _element, _eventType, _handler ){
\r
3260 if( this.match( _element, _eventType, _handler ) === false ) return false;
\r
3262 XBrowserEvent.remove( this );
\r
3264 delete this.element;
\r
3265 delete this.eventType;
\r
3266 delete this.handler;
\r
3267 delete this.wrappedHandler;
\r
3273 var ReadyEvent = ( function(){
\r
3277 function webkitDetect(){
\r
3278 var state = document.readyState;
\r
3279 if( state === 'loaded' || state === 'complete' ){
\r
3280 SystemTimer.remove( SUPER_USER_KEY, webkitDetect );
\r
3285 function ieDetect(){
\r
3286 if( this.readyState === 'complete' ){ // this.readyState === 'loaded' ||
\r
3287 this.onreadystatechange = new Function();
\r
3288 this.onreadystatechange = null;
\r
3289 AsyncCall.remove( SUPER_USER_KEY, ieScroll );
\r
3293 function ieScroll(){
\r
3295 document.documentElement.doScroll( 'left' );
\r
3297 AsyncCall.add( SUPER_USER_KEY, ieScroll );
\r
3300 // no errors, fire
\r
3301 document.onreadystatechange = new Function();
\r
3302 document.onreadystatechange = null;
\r
3306 function onReady(){
\r
3307 ticketReady && ticketReady.destroy();
\r
3308 ticketLoad && ticketLoad.destroy();
\r
3309 ticketReady = ticketLoad = null;
\r
3311 if( Page.registered() === true ){
\r
3318 // Apple WebKit (Safari, OmniWeb, ...)
\r
3319 if( doc.readyState && !!UA.WEBKIT ){
\r
3320 SystemTimer.add( SUPER_USER_KEY, webkitDetect, 50 );
\r
3322 if( document.readyState && UA.isIE && UA.ieVersion < 9 ){
\r
3324 document.onreadystatechange = ieDetect; */
\r
3326 ticketReady = new EventTicketClass( document, 'DOMContentLoaded', onReady );
\r
3327 ticketLoad = new EventTicketClass( window, 'load', onReady );
\r
3334 /* =====================================================
\r
3339 var ResizeEvent = ( function(){
\r
3340 var _globalLock = 0;
\r
3342 var root = window;
\r
3345 function getInnerSize(){
\r
3347 w : root.innerWidth || root.clientWidth,
\r
3348 h : root.innerHeight || root.clientHeight
\r
3351 function unlock(){
\r
3355 if( document.uniqueID ){
\r
3356 _resize = function(){
\r
3357 root = (doc.compatMode || "") !== "CSS1Compat" ? doc.body : doc.documentElement;
\r
3361 if( !_globalLock++ ){
\r
3362 var size = getInnerSize();
\r
3363 if( w !== size.w || h !== size.h ){// resized
\r
3367 Application.onWindowResize( w, h );
\r
3369 window.setTimeout( unlock, 0 );
\r
3372 window.setTimeout( loop, 100 );
\r
3377 _resize = function(){
\r
3378 new EventTicketClass( window, 'resize', onResize );
\r
3380 function onResize(){
\r
3381 if( !_globalLock++ ) {
\r
3382 var size = getInnerSize();
\r
3383 if( w !== size.w || h !== size.h ){// resized
\r
3387 Application.onWindowResize( w, h );
\r
3389 window.setTimeout( unlock, 0 );
\r
3395 AsyncCall.add( SUPER_USER_KEY, _resize );
\r
3398 getSize: getInnerSize,
\r
3399 onSystemShutdown: function(){
\r
3406 /* =====================================================
\r
3410 var MouseEvent = ( function(){
\r
3411 var CLICK_OFFSET = 2 * 2;
\r
3413 var EVENT_LIST_MAP = [],
\r
3418 * mousedown, mouseup, の移動距離を調べて clickハンドラ を呼ぶ
\r
3420 var ClickEventTicketClass = function( element, clickhandler ){
\r
3421 var startX, startY,
\r
3422 mousedownTicket = new EventTicketClass( element, 'mousedown', mousedownHandler ),
\r
3423 mouseupTicket, mouseoutTicket;
\r
3425 function mousedownHandler( e ){
\r
3426 startX = e.clientX;
\r
3427 startY = e.clientY;
\r
3429 mouseupTicket = new EventTicketClass( element, 'mouseup', mouseupHandler );
\r
3430 mouseoutTicket = new EventTicketClass( element, 'mouseout', mouseoutHandler );
\r
3433 function mouseupHandler( e ){
\r
3434 var offsetX = e.clientX - startX,
\r
3435 offsetY = e.clientY - startY;
\r
3436 mouseoutHandler();
\r
3437 if( offsetX * offsetX + offsetY * offsetY < CLICK_OFFSET ){
\r
3438 if( Function.prototype.call ){
\r
3439 return clickhandler.call( element, e );
\r
3441 element._currentHandler = clickhandler;
\r
3442 var ret = element._currentHandler( e );
\r
3443 delete element._currentHandler;
\r
3447 function mouseoutHandler( e ){
\r
3448 mouseupTicket && mouseupTicket.destroy();
\r
3449 mouseoutTicket && mouseoutTicket.destroy();
\r
3450 mouseupTicket = mouseoutTicket = null;
\r
3453 this.element = element;
\r
3454 this.handler = clickhandler;
\r
3455 this.destroy = function( _element, _eventType, _handler ){
\r
3456 if( this.match( _element, _eventType, _handler ) === false ) return false;
\r
3458 mouseoutHandler();
\r
3459 mousedownTicket.destroy();
\r
3460 element = clickhandler = mousedownTicket = null;
\r
3462 delete this.element;
\r
3463 delete this.eventType;
\r
3464 delete this.handler;
\r
3469 ClickEventTicketClass.prototype = {
\r
3470 eventType: 'click',
\r
3471 match : EventTicketClass.prototype.match
\r
3476 var WheelEventTicketClass = ( function(){
\r
3478 return function( element, wheelhandler ){
\r
3479 this.wheelTicket = new EventTicketClass( element, 'DOMMouseScroll', onWheel );
\r
3480 this.element = element;
\r
3481 this.handler = wheelhandler;
\r
3482 this.destroy = function( _element, _eventType, _handler ){
\r
3483 if( this.match( _element, _eventType, _handler ) === false ) return false;
\r
3484 element = wheelhandler = null;
\r
3486 this.wheelTicket && this.wheelTicket.destroy();
\r
3488 delete this.wheelTicket;
\r
3489 delete this.element;
\r
3490 delete this.handler;
\r
3495 function onWheel( e ){
\r
3496 e.wheelDelta = e.detail * -40;
\r
3497 return wheelhandler.call( element, e );
\r
3501 if( true || UA.isIE ){
\r
3502 return function( element, wheelhandler ){
\r
3503 this.wheelTicket = new EventTicketClass( element, 'mousewheel', wheelhandler );
\r
3504 this.element = element;
\r
3505 this.handler = wheelhandler;
\r
3506 element = wheelhandler = null;
\r
3509 TMP.wheelList = [];
\r
3510 //TMP.wheelLegacy = undefined;
\r
3511 TMP.onWheel = function( e ){
\r
3512 e = e || window.event;
\r
3513 var cancel = true,
\r
3514 f = TMP.wheelLegacy;
\r
3515 if( f ) cancel = f.call( this, e );
\r
3517 for( i = TMP.wheelList.length; i; ){
\r
3518 if( TMP.wheelList[ --i ].call( this, e ) === false ) cancel = false;
\r
3522 return function( element, wheelhandler ){
\r
3523 this.wheelTicket = null;
\r
3524 this.element = element;
\r
3525 this.handler = wheelhandler;
\r
3526 this.destroy = function( _element, _eventType, _handler ){
\r
3527 if( this.match( _element, _eventType, _handler ) === false ) return false;
\r
3529 TMP.wheelList.splice( Util.getIndex( TMP.wheelList, this.handler ) );
\r
3530 if( TMP.wheelList.length === 0 ) this.element.onmousewheel = '';
\r
3532 delete this.element;
\r
3533 delete this.handler;
\r
3538 if( TMP.wheelList.length === 0 ){
\r
3539 //TMP.wheelLegacy = Type.isFunction( window.onmousewheel ) === true ? window.onmousewheel : undefined;
\r
3540 element.onmousewheel = TMP.onWheel;
\r
3542 TMP.wheelList.push( wheelhandler );
\r
3543 element = wheelhandler = null;
\r
3547 WheelEventTicketClass.prototype = {
\r
3548 eventType : 'mousewheel',
\r
3549 match : EventTicketClass.prototype.match,
\r
3550 destroy : function( _element, _eventType, _handler ){
\r
3551 if( this.match( _element, _eventType, _handler ) === false ) return false;
\r
3553 this.wheelTicket && this.wheelTicket.destroy();
\r
3555 delete this.wheelTicket;
\r
3556 delete this.element;
\r
3557 delete this.handler;
\r
3565 add: function( _apiuser, _element, _eventType, _handler ){
\r
3566 if( isApiUser( _apiuser ) === true &&
\r
3567 ( Type.isHTMLElement( _element ) === true || _element === window || _element === doc ) &&
\r
3568 Type.isString( _eventType ) === true &&
\r
3569 Type.isFunction( _handler ) === true
\r
3571 var _uid = _apiuser.getUID(),
\r
3572 _events = EVENT_LIST_MAP[ _uid ];
\r
3573 if( Type.isArray( _events ) === false ){
\r
3574 _events = EVENT_LIST_MAP[ _uid ] = [];
\r
3577 for( var i=0, l=_events.length; i<l; ++i ){
\r
3578 if( _events[ i ].match( _element, _eventType, _handler ) === true ) return;
\r
3581 if( _eventType === 'click' ){
\r
3582 _events.push( new ClickEventTicketClass( _element, _handler ) );
\r
3584 if( _eventType === 'mousewheel' ){
\r
3585 _events.push( new WheelEventTicketClass( _element, _handler ) );
\r
3587 _events.push( new EventTicketClass( _element, _eventType, _handler ) );
\r
3591 remove: function( _apiuser, _element, _eventType, _handler ){
\r
3592 if( isApiUser( _apiuser ) === true ){
\r
3593 var _uid = _apiuser.getUID(),
\r
3594 _events = EVENT_LIST_MAP[ _uid ],
\r
3597 if( Type.isArray( _events ) === false ) return;
\r
3598 for( ;i < _events.length; ){
\r
3599 if( _events[ i ].destroy( _element, _eventType, _handler ) === true ){
\r
3600 _events.splice( i, 1 );
\r
3605 if( _events.length === 0 ){
\r
3606 _events = EVENT_LIST_MAP[ _uid ] = null;
\r
3610 onCurrentApplicationChange: function(){
\r
3613 onApplicationShutdown: function(){
\r
3616 onSystemShutdown: function(){
\r
3622 /* ----------------------------------------
\r
3625 * - EDITABLE_TEXT_CONTROL
\r
3627 * .SHIFT_DOWN_EVENT: 'shiftDown',
\r
3628 * .SHIFT_UP_EVENT: 'shiftUp',
\r
3629 * .CTRL_DOWN_EVENT: 'ctrlDown',
\r
3630 * .CTRL_UP_EVENT: 'ctrlUp',
\r
3631 * .SPACE_DOWN_EVENT: 'spaceDown',
\r
3632 * .SPACE_UP_EVENT: 'spaceUp',
\r
3633 * .init: function,
\r
3634 * .addKeyDownEvent: function,
\r
3635 * .keyEventDispatcher: function,
\r
3637 * ショートカットキーの監視とテキスト入力(input, textarea)、チェックボックスを管理する。
\r
3638 * キー入力はdocumentで受けて、テキスト編集中(input, textarea)はそちらにキーイベント流す。
\r
3641 var KeyEvent = ( function(){
\r
3642 var EVENT_LIST_MAP = [],
\r
3645 application = null,
\r
3646 currentList = null;
\r
3650 var focusTicket = null,
\r
3651 keydownTicket = null,
\r
3652 keyupTicket = null,
\r
3654 keypressTicket = null;
\r
3656 function unlock( lock, key ){
\r
3657 lock.splice( Util.getIndex( lock, key ), 1 );
\r
3660 function onKeyChange( e ){
\r
3661 var cancel = false,
\r
3663 key = e.keyCode, // || e.which,
\r
3664 shift = Type.isBoolean( e.shiftKey ) === true ? e.shiftKey : ( e.modifiers & Event.SHIFT_MASK ),
\r
3665 ctrl = Type.isBoolean( e.ctrlKey ) === true ? e.ctrlKey : ( e.modifiers & Event.CONTROL_MASK ),
\r
3666 lock = type === 'keyup' ? LOCK_UP : LOCK_DOWN;
\r
3668 // block chattering
\r
3669 if( Util.getIndex( lock, key ) !== -1 ) return;
\r
3671 AsyncCall.add( SUPER_USER_KEY, unlock, [ lock, key ] );
\r
3673 if( key === 16 || shift === true ){
\r
3674 KeyEvent.shiftEnabled = type !== 'keyup';
\r
3676 if( key === 17 || ctrl === true ){
\r
3677 KeyEvent.ctrlEnabled = type !== 'keyup';
\r
3679 for( var i=currentList.length, t; t = currentList[ --i ]; ){
\r
3680 if( Type.isFunction( t[ type ] ) === true && t.keyCode === key && ( t.shift === undefined || t.shift === shift ) && ( t.ctrl === undefined || t.ctrl === ctrl )){
\r
3681 AsyncCall.add( t.apiuser, t[ type ], e );
\r
3685 if( cancel === true || key === 18 || key === 9 || key === 27 || e.altKey === true ){ // 13.enter 18.esc 9.tab 27.esc || ( key === 13 && overlayEnabled === false)
\r
3690 if( UA.isIE === true && UA.ieRenderingVersion < 9 ){
\r
3691 keyPress = function( e ){
\r
3692 var key = e.keyCode;
\r
3693 if( key === 13 || key === 27 ){
\r
3694 e.type = 'keydown';
\r
3695 return onKeyChange( e );
\r
3700 var KeyEventTicketClass = function( _apiuser, _type, _onKeydown, _onKeyup, _keyCode, _shift, _ctrl ){
\r
3701 this.apiuser = _apiuser;
\r
3702 this.type = _type;
\r
3703 this.keydown = _onKeydown;
\r
3704 this.keyup = _onKeyup;
\r
3705 this.keyCode = _keyCode;
\r
3706 this.shift = _shift;
\r
3707 this.ctrl = _ctrl;
\r
3708 _apiuser = _onKeydown = _onKeyup = null;
\r
3710 KeyEventTicketClass.prototype = {
\r
3711 match: function( _apiuser, _type, _handler, _keyCode, _shift, _ctrl ){
\r
3712 if( _apiuser && _apiuser !== this.apiuser ) return false;
\r
3713 if( _type && _type !== this.type ) return false;
\r
3715 if( this.type === 'keydown' ){
\r
3716 if( _handler !== this.keydown ) return false;
\r
3718 if( _handler !== this.keyup ) return false;
\r
3721 if( _keyCode && _keyCode !== this.keyCode ) return false;
\r
3722 if( _shift && _shift !== this.shift ) return false;
\r
3723 if( _ctrl && _ctrl !== this.ctrl ) return false;
\r
3726 destroy: function( _apiuser, _type, _handler, _keyCode, _shift, _ctrl ){
\r
3727 if( this.match( _apiuser, _type, _handler, _keyCode, _shift, _ctrl ) === false ) return false;
\r
3729 delete this.apiuser;
\r
3730 delete this.keydown;
\r
3731 delete this.keyup;
\r
3737 function registerEvent( _apiuser, _type, _onKeydown, _onKeyup, _keyCode, _shift, _ctrl ){
\r
3738 var _uid = _apiuser.getUID(),
\r
3739 _list = EVENT_LIST_MAP[ _uid ];
\r
3740 if( Type.isArray( _list ) === false ){
\r
3741 _list = EVENT_LIST_MAP[ _uid ] = [];
\r
3743 for( var i=0, l=_list.length; i<l; ++i ){
\r
3744 if( _list[ i ].match( _apiuser, _type, _onKeydown || _onKeyup, _keyCode, _shift, _ctrl ) === true ) return;
\r
3746 _list.push( new KeyEventTicketClass( _apiuser, _type, _onKeydown, _onKeyup, _keyCode, _shift, _ctrl ));
\r
3748 if( _apiuser === application ) KeyEvent.updateCurrentListener( _apiuser );
\r
3752 add: function( _apiuser, _type, _handler, _keyCode, _shift, _ctrl ){
\r
3753 if( _type === 'keydown' ){
\r
3754 registerEvent( _apiuser, _type, _handler, null, _keyCode, _shift, _ctrl );
\r
3756 if( _type === 'keyup' ){
\r
3757 registerEvent( _apiuser, _type, null, _handler, _keyCode, _shift, _ctrl );
\r
3759 if( _type === 'keychange' ){
\r
3760 registerEvent( _apiuser, _type, _handler, _handler, _keyCode, _shift, _ctrl );
\r
3762 if( _type === 'cursol' ){
\r
3766 remove: function( _apiuser, _type, _handler, _keyCode, _shift, _ctrl ){
\r
3767 var _list = EVENT_LIST_MAP[ _apiuser.getUID() ],
\r
3769 if( Type.isArray( _list ) === true ){
\r
3770 while( i < _list.length ){
\r
3771 if( _list[ i ].destroy( _apiuser, _type, _handler, _keyCode, _shift, _ctrl ) === true ){
\r
3772 _list.splice( i, 1 );
\r
3778 if( _apiuser === application ) KeyEvent.updateCurrentListener( _apiuser );
\r
3780 shiftEnabled: false,
\r
3781 ctrlEnabled: false,
\r
3784 * currrentApplication ( overlay Application ) or
\r
3785 * superuser ( UI )
\r
3787 updateCurrentListener: function( _apiuser ){
\r
3788 application = _apiuser;
\r
3789 var _uid = _apiuser.getUID();
\r
3790 currentList = EVENT_LIST_MAP[ _uid ] || ( EVENT_LIST_MAP[ _uid ] = [] );
\r
3795 for( var i=currentList.length; _ticket = currentList[ --i ]; ){
\r
3796 if( _down === false ) _down = !!_ticket.keydown;
\r
3797 if( _up === false ) _up = !!_ticket.keyup;
\r
3798 if( _down && _up ) break;
\r
3800 if( _down === true ){
\r
3801 keydownTicket = new EventTicketClass( document, 'keydown', onKeyChange );
\r
3802 keypressTicket = keyPress !== null ? new EventTicketClass( doc, 'keypress', keyPress ) : null;
\r
3804 keydownTicket && keydownTicket.destroy();
\r
3805 keypressTicket && keypressTicket.destroy();
\r
3806 keydownTicket = keypressTicket = null;
\r
3808 if( _up === true ){
\r
3809 keyupTicket = new EventTicketClass( document, 'keyup', onKeyChange );
\r
3811 keyupTicket && keyupTicket.destroy();
\r
3812 keyupTicket = null;
\r
3815 if( _down === true || _up === true ){
\r
3816 focusTicket = new EventTicketClass( document, 'mouseenter', window.focus );
\r
3818 focusTicket && focusTicket.destroy();
\r
3819 focusTicket = null;
\r
3822 onApplicationShutdown: function( _apiuser ){
\r
3823 KeyEvent.remove( _apiuser );
\r
3825 onSystemShutdown: function(){
\r
3833 * http://thudjs.tumblr.com/post/637855087/stylesheet-onload-or-lack-thereof
\r
3836 var StyleSheet = ( function(){
\r
3837 var head = doc.getElementsByTagName( 'head' )[ 0 ];
\r
3839 var TICKET_LIST = [];
\r
3840 var STATE_LIST = 'loaded,complete,uninitialized'.split( ',' );
\r
3842 var cssRules, sheet;
\r
3844 var FetchCssTicketClass = function( _apiuser, _url, _elm, _onload, _onerror ){
\r
3845 this.apiusers = [ _apiuser ];
\r
3848 this.onload = [ _onload ];
\r
3849 this.onerror = [ _onerror ];
\r
3852 FetchCssTicketClass.prototype = {
\r
3853 match: function( _apiuser, _url ){
\r
3854 if( _apiuser && Util.getIndex( this.apiusers, _apiuser ) === -1 ) return false;
\r
3855 if( _url && _url !== this.url ) return false;
\r
3858 destroy: function( _apiuser, _url ){
\r
3859 if( this.match( _apiuser, _url ) === false ) return false;
\r
3861 var i = Util.getIndex( this.apiusers, _apiuser );
\r
3863 this.apiusers.splice( i, 1 );
\r
3864 this.onload.splice( i, 1 );
\r
3865 this.onerror.splice( i, 1 );
\r
3867 if( this.apiusers.length !== 0 ) return false;
\r
3869 head.removeChild( this.elm );
\r
3870 this.elm.onreadystatechange = new Function();
\r
3871 this.elm.onload = null;
\r
3873 delete this.apiusers;
\r
3876 delete this.onload;
\r
3877 delete this.onerror;
\r
3882 loaded: function(){
\r
3883 for( var i = this.onload.length, f; i; ){
\r
3884 f = this.onload[ --i ];
\r
3885 Type.isFunction( f ) === true && AsyncCall.add( this.apiusers[ i ], f, this.url );
\r
3886 this.onload[ i ] = this.onerror[ i ] = null;
\r
3889 error: function(){
\r
3890 for( var i = this.onerror.length, f; i; ){
\r
3891 f = this.onerror[ --i ];
\r
3892 Type.isFunction( f ) === true && AsyncCall.add( this.apiusers[ i ], f, this.url );
\r
3893 this.onload[ i ] = this.onerror[ i ] = null;
\r
3896 check: function(){
\r
3897 var el = this.elm;
\r
3899 return el[ sheet ] && el[ sheet ][ cssRules ].length > 0;
\r
3907 function getTicket( elm ){
\r
3908 for( var i = TICKET_LIST.length, t; i; ){
\r
3909 t = TICKET_LIST[ --i ];
\r
3910 if( t.elm === elm ) return t;
\r
3914 function detect(){
\r
3915 var t = getTicket( this ), rs = this.readyState, c;
\r
3916 if( t && t.done === false && ( !rs || Util.getIndex( STATE_LIST, rs ) !== -1 ) ){
\r
3919 this.onreadystatechange = new Function();
\r
3920 this.onload = null;
\r
3924 function checkTimer(){
\r
3925 var l = TICKET_LIST.length,
\r
3927 for( var i = 0; i < l; ++i ){
\r
3928 t = TICKET_LIST[ i ];
\r
3930 if( t.check() === true ){
\r
3934 if( t.time > 99 ){
\r
3940 l === n && SystemTimer.remove( SUPER_USER_KEY, checkTimer );
\r
3944 load: function( _apiuser, _url, opt_onload, opt_onerror ){
\r
3945 _url = Util.getAbsolutePath( _url );
\r
3947 for( var i=TICKET_LIST.length; i; ){
\r
3948 t = TICKET_LIST[ --i ];
\r
3949 if( t.match( null, _url ) === true ){
\r
3950 if( t.match( _apiuser, _url ) === false ){
\r
3951 t.apiusers.push( _apiuser );
\r
3952 t.onload.push( opt_onload );
\r
3953 t.onerror.push( opt_onerror );
\r
3955 SystemTimer.add( SUPER_USER_KEY, checkTimer, 333 );
\r
3959 var elm = doc.createElement( 'link' );
\r
3960 head.appendChild( elm );
\r
3961 elm.rel = 'stylesheet';
\r
3962 elm.type = 'text\/css';
\r
3963 elm.onreadystatechange = elm.onload = detect;
\r
3966 if( !sheet ){ // only assign these once
\r
3967 cssRules = 'cssRules';
\r
3969 if ( !( sheet in elm ) ) { // MSIE uses non-standard property names
\r
3970 cssRules = 'rules';
\r
3971 sheet = 'styleSheet';
\r
3975 TICKET_LIST.push( new FetchCssTicketClass( _apiuser, _url, elm, opt_onload, opt_onerror ) );
\r
3977 SystemTimer.add( SUPER_USER_KEY, checkTimer, 333 );
\r
3979 unload: function( _apiuser, _url ){
\r
3980 _url = _url ? Util.getAbsolutePath( _url ) : null;
\r
3981 for( var i = 0; i < TICKET_LIST.length; ){
\r
3982 t = TICKET_LIST[ i ];
\r
3983 if( t.destroy( _apiuser, _url ) === true ){
\r
3984 TICKET_LIST.splice( i, 1 );
\r
3989 if( TICKET_LIST.length === 0 ){
\r
3990 SystemTimer.remove( SUPER_USER_KEY, checkTimer );
\r
4006 var Image = ( function(){
\r
4007 var TASK_LIST = [];
\r
4009 * FetchClass original is
\r
4012 * URL: http://d.hatena.ne.jp/uupaa/20080413/1208067631
\r
4013 * AUTHOR: uupaa.js@gmail.com
\r
4016 function detect(){
\r
4017 for( var i=0, t; i < TASK_LIST.length; ){
\r
4018 t = TASK_LIST[ i ];
\r
4019 if( t.complete() === true ){
\r
4020 TASK_LIST.splice( i, 1 );
\r
4025 TASK_LIST.length === 0 && SystemTimer.remove( SUPER_USER_KEY, detect );
\r
4027 function getTask( img ){
\r
4028 for( var i = TASK_LIST.length; i; ){
\r
4029 if( TASK_LIST[ --i ].img === img ) return TASK_LIST[ i ];
\r
4032 function onError(){
\r
4033 var task = getTask( this );
\r
4034 if( task.finish === true ) return;
\r
4035 task.finish = true;
\r
4036 AsyncCall.add( task.apiuser, task.asyncCallback, null, task );
\r
4038 function onLoad(){
\r
4039 // if( finish === true ) return; // これがあると firefox3.6 で駄目、、、
\r
4040 // if( timer ) return; // これがあると safari3.2 で駄目、、、
\r
4041 var task = getTask( this );
\r
4042 task.finish = true;
\r
4043 TASK_LIST.splice( Util.getIndex( TASK_LIST, task ), 1 );
\r
4044 if( window.opera && !task.img.complete ){
\r
4045 AsyncCall.add( task.apiuser, task.asyncCallback, null, task );
\r
4048 task.size = Util.getImageSize( this );
\r
4049 AsyncCall.add( task.apiuser, task.asyncCallback, null, task );
\r
4053 var FetchClass = function( apiuser, abspath, onLoadCallback, onErrorCallback, timeout ){
\r
4054 this.apiuser = apiuser;
\r
4055 this.abspath = abspath;
\r
4056 this.onLoadCallback = onLoadCallback;
\r
4057 this.onErrorCallback = onErrorCallback;
\r
4058 this.timeout = timeout;
\r
4061 FetchClass.prototype = {
\r
4067 var img = this.img = document.createElement( 'img' ); //var img = new Image(); ではieでimgのsizeが取れない、、、removeChildも失敗し、imgSizeGetterにimgが残る
\r
4068 img.onabort = img.onerror = onError;
\r
4069 img.onload = onLoad;
\r
4070 img.src = this.abspath;
\r
4072 complete: function(){
\r
4073 if( this.finish === true ) return true;
\r
4074 if( this.img.complete ){
\r
4075 this.finish = true;
\r
4076 if( this.img.width ) return true;
\r
4077 AsyncCall.add( this.apiuser, this.asyncCallback, null, this );
\r
4080 if( ( this.tick += 250 ) > this.timeout ){
\r
4081 this.finish = true;
\r
4082 AsyncCall.add( this.apiuser, this.asyncCallback, null, this );
\r
4086 asyncCallback: function(){
\r
4087 this.size ? this.onLoadCallback( this.abspath, this.size.width, this.size.height ) : this.onErrorCallback( this.abspath );
\r
4090 destroy: function(){
\r
4091 this.finish = true;
\r
4092 this.img.src = this.img.onload = this.img.onabort = this.img.onerror = '';
\r
4095 delete this.onLoadCallback;
\r
4096 delete this.onErrorCallback;
\r
4099 timer !== null && window.clearTimeout( timer );
\r
4105 load: function( URLorELM, onLoad, onError, opt_timeout ){
\r
4107 if( Type.isString( URLorELM ) === true ){
\r
4110 if( Type.isHTMLElement( URLorELM ) === true && URLorELM.tagName.toLowerCase() === 'img' ){
\r
4111 src = URLorELM.src;
\r
4116 fetch = new FetchClass(
\r
4117 Util.getAbsolutePath( src ),
\r
4119 Type.isFinite( opt_timeout ) === true ? opt_timeout : undefined
\r
4121 TASK_LIST.push( fetch );
\r
4123 SystemTimer.add( SUPER_USER_KEY, detect, 250 );
\r
4125 unload: function( ){
\r
4132 /* ----------------------------------------
\r
4136 var Overlay = ( function(){
\r
4137 var elmContainer, elmShadow, elmCloseButton,
\r
4138 application = null,
\r
4140 bodyOverflow = '',
\r
4143 function onCloseClick( e ){
\r
4147 function asyncInit( /* arguments */ ){
\r
4149 //body.appendChild( application.rootElement );
\r
4150 elmContainer.insertBefore( application.rootElement, elmCloseButton );
\r
4151 application.rootElement.style.display = 'none';
\r
4152 application.init();
\r
4154 function asyncOpen( /* arguments */ ){
\r
4156 var _arg = Util.copyArray( arguments );
\r
4157 _arg.unshift( windowW, windowH );
\r
4158 application.open.apply( application, _arg );
\r
4160 elmContainer.style.cssText = "top:" + body.scrollTop + 'px;display:none;';
\r
4161 $( elmContainer ).stop().fadeIn( onFadeInComplete );
\r
4163 function onFadeInComplete(){
\r
4164 KeyEvent.add( application, Const.KEY.EVENT.KEY_DOWN, Overlay.hide, 27 ); // 27.esc
\r
4165 MouseEvent.add( application, elmCloseButton, 'click', onCloseClick );
\r
4167 function onFadeOutComplete(){
\r
4168 Util.removeAllChildren( elmContainer );
\r
4169 body.removeChild( elmContainer );
\r
4170 elmContainer = elmShadow = elmCloseButton = null;
\r
4173 show: function( _application, _bootParams ){
\r
4174 if( visible === true && application === _application ) return;
\r
4175 if( Application.isApplicationInstance( _application ) === false ) return;
\r
4177 elmContainer = document.createElement( 'div' );
\r
4178 body.appendChild( elmContainer );
\r
4180 elmContainer.id = 'overlay-container';
\r
4182 bodyOverflow = body.style.overflow;
\r
4183 body.style.overflow = 'hidden';
\r
4185 elmShadow = document.createElement( 'div' );
\r
4186 elmContainer.appendChild( elmShadow );
\r
4187 elmShadow.id = 'overlay-shadow';
\r
4189 elmCloseButton = document.createElement( 'div' );
\r
4190 elmContainer.appendChild( elmCloseButton );
\r
4191 elmCloseButton.id = 'overlay-close-button';
\r
4192 elmCloseButton.appendChild( document.createTextNode( 'x' ) );
\r
4194 elmContainer.style.display = 'none'; // hide for fadeIn
\r
4196 _application.addAsyncCall( asyncInit );
\r
4197 _application.addAsyncCall( asyncOpen, _bootParams );
\r
4200 application = _application;
\r
4203 if( visible === false ) return;
\r
4204 if( application.close() === false ) return false;
\r
4206 body.style.overflow = bodyOverflow;
\r
4208 $( elmContainer ).stop().css( {
\r
4211 }).fadeOut( onFadeOutComplete );
\r
4214 KeyEvent.remove( application, Const.KEY.EVENT.KEY_DOWN, Overlay.hide ); // 27.esc
\r
4215 MouseEvent.remove( application, elmCloseButton );
\r
4217 application = null;
\r
4219 onWindowResize: function( _windowW, _windowH ){
\r
4220 windowW = _windowW;
\r
4221 windowH = _windowH;
\r
4223 if( application === null ) return;
\r
4225 elmContainer.style.height = _windowH + 'px';
\r
4226 elmContainer.style.top = body.scrollTop + 'px';
\r
4228 elmShadow.style.height = _windowH + 'px';
\r
4230 AsyncCall.add( application, application.resize, [ _windowW, _windowH ] );
\r
4235 /* ----------------------------------------
\r
4239 * form -> overlay -> view
\r
4243 var UI = ( function(){
\r
4245 currentUser = null,
\r
4246 currentList = null,
\r
4248 currentItem = null,
\r
4252 var CLASSNAME_COMBOBOX_OPTION = 'combobox-option',
\r
4253 CLASSNAME_COMBOBOX_OPTION_CURRENT = CLASSNAME_COMBOBOX_OPTION + ' combobox-option-current',
\r
4254 ELM_A_ORIGIN = ( function(){
\r
4255 var ret = document.createElement( 'a' );
\r
4259 ELM_INPUT_TEXT = ( function(){
\r
4260 var ret = document.createElement( 'input' );
\r
4261 ret.type = 'text';
\r
4264 ELM_COMBOBOX = ( function(){
\r
4265 var ret = document.createElement( 'a' ),
\r
4266 elmToggle = document.createElement( 'span' ),
\r
4267 elmValue = document.createElement( 'span' );
\r
4269 ret.appendChild( elmToggle );
\r
4270 ret.appendChild( elmValue );
\r
4271 elmToggle.className = 'combobox-toggle';
\r
4272 elmValue.className = 'combobox-value';
\r
4274 elmToggle.appendChild( document.createTextNode( '▼' ));
\r
4275 elmValue.appendChild( document.createTextNode( 'null' ));
\r
4279 var InputTextClass = function( apiuser, uiGroup, elmWrapper, elmValue, onUpdate, validater ){
\r
4280 var elmA = ELM_A_ORIGIN.cloneNode( true ),
\r
4285 value = elmValue.innerHTML;
\r
4286 elmValue.innerHTML = '';
\r
4287 elmValue.className += ' editable-text';
\r
4288 elmValue.appendChild( elmA );
\r
4290 this.value = function( _value ){
\r
4291 if( Type.isString( _value ) === true || Type.isNumber( _value ) === true ){
\r
4292 value = '' + _value;
\r
4293 elmA.innerHTML = '' + _value;
\r
4294 if( focus === true ){
\r
4295 ELM_INPUT_TEXT.value = '' + value;
\r
4298 focus === true && instance.blur();
\r
4301 this.focus = function( e ){
\r
4303 start( apiuser, uiGroup, instance );
\r
4304 elmA.style.display = 'none';
\r
4306 elmValue.appendChild( ELM_INPUT_TEXT );
\r
4307 ELM_INPUT_TEXT.value = value;
\r
4308 ELM_INPUT_TEXT.focus();
\r
4309 ELM_INPUT_TEXT.select();
\r
4313 this.blur = function( keep ){
\r
4314 var _newValue = ELM_INPUT_TEXT.value,
\r
4315 _validated = Type.isFunction( validater ) === true ? '' + validater( _newValue ) : _newValue;
\r
4316 _newValue = keep !== 27 ? _validated : value; // 27:ESC
\r
4318 elmValue.removeChild( ELM_INPUT_TEXT );
\r
4320 elmA.innerHTML = _newValue;
\r
4321 elmA.style.display = 'block';
\r
4323 onUpdate && _newValue !== value && AsyncCall.add( apiuser, onUpdate, [ _newValue, value ], instance );
\r
4325 value = _newValue;
\r
4327 finish( apiuser, uiGroup, instance );
\r
4329 this.enabled = function(){
\r
4332 this.visible = function( _visible ){
\r
4333 if( Type.isBoolean( _visible ) === true ){
\r
4334 elmWrapper.style.display = _visible ? '' : 'none';
\r
4335 visible = _visible;
\r
4339 this.destroy = function(){
\r
4340 if( focus === true ){
\r
4341 elmValue.removeChild( ELM_INPUT_TEXT );
\r
4343 MouseEvent.remove( apiuser, elmWrapper );
\r
4345 apiuser = uiGroup = elmWrapper = elmValue = elmA = onUpdate = validater = instance = null;
\r
4347 instance.value( value );
\r
4348 MouseEvent.add( apiuser, elmWrapper, 'click', instance.focus );
\r
4351 var ButtonClass = function( apiuser, uiGroup, elmWrapper, onUpdate ){
\r
4352 var instance = this,
\r
4356 MouseEvent.add( apiuser, elmWrapper, 'click', onClick );
\r
4358 function onClick(){
\r
4361 AsyncCall.add( apiuser, onUpdate, null, instance );
\r
4364 this.focus = function(){
\r
4366 Util.addClass( elmWrapper, 'button-has-focus' );
\r
4367 start( apiuser, uiGroup, instance );
\r
4369 this.blur = function( keyCode ){
\r
4370 keyCode === 13 && onClick();
\r
4371 Util.removeClass( elmWrapper, 'button-has-focus' );
\r
4373 finish( apiuser, uiGroup, instance );
\r
4375 this.enabled = function( _enabled ){
\r
4376 if( Type.isBoolean( _enabled ) === true && enabled !== _enabled ){
\r
4377 _enabled === true ? Util.removeClass( elmWrapper, 'button-disabled' ) : Util.addClass( elmWrapper, 'button-disabled' );
\r
4378 enabled = _enabled;
\r
4382 this.visible = function( _visible ){
\r
4383 if( Type.isBoolean( _visible ) === true ){
\r
4384 elmWrapper.style.display = _visible ? '' : 'none';
\r
4385 visible = _visible;
\r
4389 this.destroy = function(){
\r
4390 MouseEvent.remove( apiuser, elmWrapper );
\r
4391 apiuser = uiGroup = elmWrapper = onUpdate = instance = null;
\r
4395 var ComboBoxClass = function( apiuser, uiGroup, elmWrapper, onUpdate ){
\r
4396 var elmBox = Util.getElementsByClassName( elmWrapper, 'combobox' )[ 0 ],
\r
4397 elmA = ELM_COMBOBOX.cloneNode( true ),
\r
4398 elmToggle = Util.getElementsByClassName( elmA, 'combobox-toggle' )[ 0 ],
\r
4399 elmValue = Util.getElementsByClassName( elmA, 'combobox-value' )[ 0 ].firstChild,
\r
4407 elmBox.appendChild( elmA );
\r
4409 this.elm = elmBox;
\r
4410 this.focus = function( e ){
\r
4411 MouseEvent.remove( apiuser, elmWrapper, 'click', instance.focus );
\r
4413 elmA.className = 'combobox-has-focus';
\r
4414 start( apiuser, uiGroup, instance );
\r
4415 OptionControl.show( apiuser, instance, optionList );
\r
4418 this.blur = function( keyCode ){
\r
4419 OptionControl.hide( instance );
\r
4421 elmA.className = '';
\r
4422 finish( apiuser, uiGroup, instance );
\r
4423 MouseEvent.add( apiuser, elmWrapper, 'click', instance.focus );
\r
4425 this.enabled = function(){
\r
4428 this.visible = function( _visible ){
\r
4429 if( Type.isBoolean( _visible ) === true ){
\r
4430 elmWrapper.style.display = _visible ? '' : 'none';
\r
4431 visible = _visible;
\r
4435 this.value = function( _value ){
\r
4436 if( Type.isString( _value ) === true && value !== _value ){
\r
4437 for( var i=0, l = optionList.length, _option; i<l; ++i ){
\r
4438 _option = optionList[ i ];
\r
4439 if( _value === _option.value ){
\r
4442 elmValue.data = _option.displayValue;
\r
4443 if( focus === true ){
\r
4444 OptionControl.update( instance, _value );
\r
4446 Type.isFunction( onUpdate ) === true && AsyncCall.add( apiuser, onUpdate, _value, instance );
\r
4453 this.selectIndex = function(){
\r
4456 this.createOption = function( _displayValue, _value, _isSelected ){
\r
4457 var option = null,
\r
4459 _value = _value || _displayValue;
\r
4460 _isSelected = !!_isSelected;
\r
4461 for( i = optionList.length; i; ){
\r
4462 _option = optionList[ --i ];
\r
4463 if( _value === _option.value ){
\r
4468 if( _isSelected === true ){
\r
4469 index = optionList.length;
\r
4470 elmValue.data = _displayValue;
\r
4472 if( option === null ){
\r
4473 option = new OptionDataClass( _displayValue, _value, _isSelected );
\r
4474 optionList.push( option );
\r
4477 this.destroy = function(){
\r
4479 MouseEvent.remove( apiuser, elmWrapper );
\r
4480 optionList.length = 0;
\r
4481 apiuser = uiGroup = elmWrapper = onUpdate = elmBox = elmA = elmToggle = elmValue = optionList = instance = null;
\r
4483 MouseEvent.add( apiuser, elmWrapper, 'click', instance.focus );
\r
4485 var OptionDataClass = function( displayValue, value, isCurrent ){
\r
4486 this.displayValue = displayValue;
\r
4487 this.value = value || displayValue;
\r
4488 this.current = isCurrent;
\r
4489 displayValue = value = null;
\r
4492 var OptionControl = ( function(){
\r
4493 var ELM_OPTION_WRAPPER = ( function(){
\r
4494 var ret = document.createElement( 'div' );
\r
4495 ret.className = 'option-container';
\r
4498 ELM_OPTION_ORIGIN = ( function(){
\r
4499 var ret = document.createElement( 'a' );
\r
4500 ret.appendChild( document.createTextNode( 'option' ) );
\r
4505 var OptionClass = function( option ){
\r
4506 this.elm = ELM_OPTION_ORIGIN.cloneNode( true );
\r
4507 this.data = option;
\r
4510 OptionClass.prototype = {
\r
4512 ELM_OPTION_WRAPPER.appendChild( this.elm );
\r
4513 this.elm.firstChild.data = this.data.displayValue;
\r
4514 this.current( this.data.current );
\r
4515 MouseEvent.add( SUPER_USER_KEY, this.elm, 'mousedown', onOptionSelect );// onclick では 選択ボックス 隠すように body に設定した onmouseup が先に動いてしまう!
\r
4517 current: function( _current ){
\r
4518 this.elm.className = _current === true ? CLASSNAME_COMBOBOX_OPTION_CURRENT : CLASSNAME_COMBOBOX_OPTION;
\r
4519 this.data.current = _current;
\r
4520 currentOption = _current === true ? this : currentOption;
\r
4522 destroy: function(){
\r
4523 MouseEvent.remove( SUPER_USER_KEY, this.elm );
\r
4524 Util.removeAllChildren( this.elm );
\r
4525 ELM_OPTION_WRAPPER.removeChild( this.elm );
\r
4531 function onOptionSelect( e ){
\r
4532 for( var i = 0, l = OPTION_LIST.length, _option; i < l; ++i){
\r
4533 _option = OPTION_LIST[ i ];
\r
4534 if( this === _option.elm ){
\r
4535 updateCurrrentOption( _option.data.value, true );
\r
4536 currentCombobox.blur();
\r
4543 var OPTION_LIST = [],
\r
4544 currentCombobox = null,
\r
4550 function updateCurrrentOption( _value, _updateCombobox ){
\r
4552 for( var i = OPTION_LIST.length; i; ){
\r
4553 _option = OPTION_LIST[ --i ];
\r
4554 if( _value === _option.data.value ){
\r
4555 currentOption && currentOption.current( false );
\r
4556 _option.current( true );
\r
4557 currentOption = _option;
\r
4559 _updateCombobox === true && currentCombobox.value( _value );
\r
4565 function bodyMouseupHandler(){
\r
4566 currentCombobox.blur();
\r
4567 OptionControl.hide( currentCombobox );
\r
4569 function updateWrapperPosition(){
\r
4570 var position = Util.getAbsolutePosition( elm );
\r
4572 ELM_OPTION_WRAPPER.style.cssText = [
\r
4573 'width:', elm.offsetWidth - 2, 'px;',
\r
4574 'left:', position.x, 'px;',
\r
4575 'top:', position.y + elm.offsetHeight, 'px;'
\r
4578 function change( e ){
\r
4579 var l = OPTION_LIST.length,
\r
4580 i = currentIndex + ( e.keyCode === 40 ? -1 : 1 );
\r
4581 if( currentCombobox === null || l < 2 ) return;
\r
4585 updateCurrrentOption( OPTION_LIST[ i ].data.value, true );
\r
4589 show: function( _apiuser, _combobox, _optionList ){
\r
4590 if( currentItem !== _combobox || currentCombobox === _combobox ) return;
\r
4591 currentCombobox && currentCombobox.blur();
\r
4593 apiuser = _apiuser;
\r
4594 currentCombobox = _combobox;
\r
4595 elm = _combobox.elm;
\r
4597 for( var i = 0, l = _optionList.length; i<l; ++i ){
\r
4598 OPTION_LIST.unshift( new OptionClass( _optionList[ i ] ) );
\r
4600 MouseEvent.add( SUPER_USER_KEY, document, 'mouseup', bodyMouseupHandler );
\r
4601 KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, change, 38 );
\r
4602 KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, change, 40 );
\r
4603 //KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onEnter, 13 );
\r
4604 //KeyEvent.updateCurrentListener( SUPER_USER_KEY );
\r
4606 body.appendChild( ELM_OPTION_WRAPPER );
\r
4608 updateCurrrentOption( _combobox.value(), false );
\r
4609 updateWrapperPosition();
\r
4611 SystemTimer.add( SUPER_USER_KEY, updateWrapperPosition, 500 );
\r
4613 hide: function( _combobox ){
\r
4614 if( currentCombobox !== _combobox || currentCombobox === null ) return;
\r
4617 while( _option = OPTION_LIST.shift() ){
\r
4618 _option.destroy();
\r
4621 body.removeChild( ELM_OPTION_WRAPPER );
\r
4623 MouseEvent.remove( SUPER_USER_KEY, doc, 'mouseup', bodyMouseupHandler );
\r
4624 KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, change );
\r
4625 KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, change );
\r
4626 //KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onEnter );
\r
4627 //KeyEvent.updateCurrentListener( apiuser );
\r
4629 SystemTimer.remove( SUPER_USER_KEY, updateWrapperPosition, 500 );
\r
4632 currentCombobox = null;
\r
4633 currentOption = null;
\r
4634 currentIndex = 0;
\r
4636 onEnter: function(){
\r
4637 currentCombobox.value( currentOption.data.value );
\r
4638 //currentCombobox.blur();
\r
4639 //OptionControl.hide( currentCombobox );
\r
4641 update: function( _combobox, _value ){
\r
4642 if( currentCombobox !== _combobox || currentItem !== _combobox ) return;
\r
4643 if( currentOption.data.value === _value ) return;
\r
4644 updateCurrrentOption( _value, true );
\r
4646 onWindowResize: function( _w, _h ){
\r
4647 currentCombobox && AsyncCall.add( apiuser, updateWrapperPosition );
\r
4652 var UIGroupClass = function( apiuser ){
\r
4657 this.focus = function( _value ){
\r
4659 if( _value === true ){
\r
4660 if( currentItem ){
\r
4661 start( apiuser, self, currentItem );
\r
4663 if( itemList.length > 0 ){
\r
4664 start( apiuser, self, itemList[ 0 ] );
\r
4667 if( _value === false ){
\r
4668 finish( apiuser, self, currentItem );
\r
4671 if( _value && Util.getIndex( itemList, _value ) !== -1 ){
\r
4672 // currentItem = _value;
\r
4673 currentList = itemList;
\r
4675 return currentUi === self;
\r
4677 this.blur = function(){
\r
4678 if( currentList === itemList ){
\r
4679 currentList = null;
\r
4682 this.createInputText = function( _elmWrapper, _onUpdate, _validater ){
\r
4683 var _elmValue = Util.getElementsByClassName( _elmWrapper, 'editable-value' )[ 0 ];
\r
4685 var ret = new InputTextClass( apiuser, self, _elmWrapper, _elmValue, _onUpdate, _validater );
\r
4686 itemList.push( ret );
\r
4689 alert( 'error createInputText' );
\r
4691 this.createButton = function( _elm, _onClick ){
\r
4692 var ret = new ButtonClass( apiuser, self, _elm, _onClick );
\r
4693 itemList.push( ret );
\r
4696 this.createFileInput = function( _elm, _onUpdate, _validater, _elmFileInput ){
\r
4697 var ret = FileInputClass( apiuser, self, _elm, _onUpdate, _validater, _elmFileInput );
\r
4698 itemList.push( ret );
\r
4701 this.createCombobox = function( _elm, _onUpdate, _optionList ){
\r
4702 var ret = new ComboBoxClass( apiuser, self, _elm, _onUpdate, _optionList );
\r
4703 itemList.push( ret );
\r
4706 this.createCheckBox = function(){
\r
4709 this.createRadio = function(){
\r
4712 this.createSlider = function(){
\r
4715 this.destroy = function(){
\r
4717 while( _item = itemList.shift() ){
\r
4720 if( currentUi === this ){
\r
4721 currentItem = null;
\r
4723 currentUser = null;
\r
4724 currentList = null;
\r
4726 apiuser = self = null;
\r
4730 function start( _apiuser, _uigroup, _item ){
\r
4731 if( currentItem !== _item ){
\r
4732 currentUi !== _uigroup && currentUi && currentUi.blur();
\r
4734 currentItem !== null && currentItem.blur();
\r
4736 currentUser = _apiuser;
\r
4737 currentUi = _uigroup;
\r
4738 currentItem = _item;
\r
4740 _uigroup.focus( _item );
\r
4742 // if( currentUser !== _apiuser ) {
\r
4743 KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 13 );
\r
4744 KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 27 );
\r
4745 KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 9 );
\r
4746 KeyEvent.updateCurrentListener( SUPER_USER_KEY );
\r
4750 function finish( _apiuser, _uigroup, _item ){
\r
4751 if( currentItem === _item ){
\r
4754 currentUser = null;
\r
4756 currentItem = null;
\r
4757 currentList = null;
\r
4759 KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 13 );
\r
4760 KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 27 );
\r
4761 KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 9 );
\r
4762 KeyEvent.updateCurrentListener( _apiuser );
\r
4766 function onKeyDown( e ){
\r
4767 if( currentItem === null ) return true;
\r
4768 var keyCode = e.keyCode,
\r
4769 _index = Util.getIndex( currentList, currentItem );
\r
4770 if( keyCode === 13 || keyCode === 27 || keyCode === 9 || keyCode === 18 || e.altKey === true ){ // 13.return 27.esc 9.tab 18.alt
\r
4771 keyCode === 9 && tabShift( _index, e.shiftKey === true ? -1 : 1 );
\r
4772 keyCode === 13 && currentItem instanceof ComboBoxClass && OptionControl.onEnter();
\r
4773 keyCode === 13 && tabShift( _index, 1 );
\r
4774 currentItem && currentItem.blur( keyCode );
\r
4779 function tabShift( _index, _way ){
\r
4780 var l = currentList.length,
\r
4781 i = _index + _way,
\r
4783 if( l < 2 ) return;
\r
4784 while( i !== _index ){
\r
4787 i < l ? i : 0; // 0 < i < l
\r
4788 _item = currentList[ i ];
\r
4789 if( _item.enabled() === true && _item.visible() === true ){
\r
4790 AsyncCall.add( currentUser, _item.focus, null, _item );
\r
4798 createUIGroup: function( _apiuser ){
\r
4799 var _uid = _apiuser.getUID(),
\r
4800 _list = UI_LIST[ _uid ],
\r
4801 _ui = new UIGroupClass( _apiuser );
\r
4802 if( Type.isArray( _list ) === false ){
\r
4803 _list = UI_LIST[ _uid ] = [];
\r
4805 _list.push( _ui );
\r
4808 onWindowResize: function( w, h ){
\r
4811 currentItem instanceof ComboBoxClass && OptionControl.onWindowResize( w, h );
\r
4813 onCurrentApplicationChange: function( _apiuser ){
\r
4814 currentList = UI_LIST[ _apiuser.getUID() ];
\r
4816 onApplicationShutdown: function( _apiuser ){
\r
4817 KeyEvent.remove( _apiuser );
\r
4819 onSystemShutdown: function(){
\r
4826 var Finder = ( function(){
\r
4827 var HTML_FINDER_ICON = ( function(){
\r
4828 return ( UA.isIE === true && UA.ieVersion < 8 ?
\r
4830 '<div class="finder-icon fnder-icon-ie7">',
\r
4831 '<a href="#" class="finder-icon-main">',
\r
4832 '<span class="finder-icon-handle"></span>',
\r
4833 '<span class="finder-icon-thumbnail"></span>',
\r
4834 '<span class="finder-icon-cell finder-icon-ie-filename">',
\r
4835 '<span class="finder-icon-vertical-middle-outer">',
\r
4836 '<span class="finder-icon-vertical-middle-inner">',
\r
4837 '<span class="finder-icon-filename break-word">file name</span>',
\r
4841 '<span class="finder-icon-cell finder-icon-ie-summary">',
\r
4842 '<span class="finder-icon-vertical-middle-outer">',
\r
4843 '<span class="finder-icon-vertical-middle-inner">',
\r
4844 '<span class="finder-icon-summary break-word">file descriptiion</span>',
\r
4849 '<div class="finder-icon-console">',
\r
4850 '<a href="#" class="finder-icon-console-action"></a>',
\r
4851 '<a href="#" class="finder-icon-console-editor-apps"></a>',
\r
4852 '<a href="#" class="finder-icon-console-viewer-apps"></a>',
\r
4857 '<div class="finder-icon fnder-icon-modern">',
\r
4858 '<span class="finder-icon-handle"></span>',
\r
4859 '<span class="finder-icon-thumbnail"></span>',
\r
4860 '<span class="finder-icon-filename break-word">file name</span>',
\r
4861 '<span class="finder-icon-summary break-word">file descriptiion</span>',
\r
4862 '<div class="finder-icon-console">',
\r
4863 '<a href="#" class="finder-icon-console-action"></a>',
\r
4864 '<a href="#" class="finder-icon-console-editor-apps"></a>',
\r
4865 '<a href="#" class="finder-icon-console-viewer-apps"></a>',
\r
4872 var FINDER_ARRAY = [],
\r
4873 ELM_ORIGIN_FINDER_LOCATION_ITEM = Util.pullHtmlAsTemplete( '<li id="templete-finder-location-item" class="finder-location-item"><a href="#"></a></li>'),
\r
4874 ELM_ORIGIN_FINDER_ICON = Util.pullHtmlAsTemplete( HTML_FINDER_ICON ),
\r
4875 ELM_ORIGIN_CONTAINER = Util.pullHtmlAsTemplete( [
\r
4876 '<div id="templete-finder-container" class="finder-container">',
\r
4877 '<div class="finder-header">',
\r
4878 '<ul class="finder-location"></ul>',
\r
4879 '<div class="finder-sidebar-switch button">side</div>',
\r
4880 '<div class="finder-style-switch button">style</div>',
\r
4881 '<div class="finder-action-switch button">action</div>',
\r
4883 '<div class="finder-body"></div>',
\r
4886 ICON_HEIGHT = Util.getElementSize( ELM_ORIGIN_FINDER_ICON ).height,
\r
4887 ICON_CLASSNAME = 'finder-icon-thumbnail',
\r
4888 FINDER_ICON_POOL = [],
\r
4889 BREAD_OBJECT_POOL = [];
\r
4891 var FinderIconClass = function(){
\r
4893 ELM_WRAPPER = ELM_ORIGIN_FINDER_ICON.cloneNode( true),
\r
4894 ELM_THUMBNAIL = Util.getElementsByClassName( ELM_WRAPPER, ICON_CLASSNAME )[ 0 ],
\r
4895 ELM_FILENAME = Util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-filename' )[ 0 ],
\r
4896 ELM_DESCRIPTION = Util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-summary' )[ 0 ],
\r
4897 ELM_EDITOR_BUTTON = Util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-console-editor-apps' )[ 0 ],
\r
4898 ELM_VIEWER_BUTTON = Util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-console-viewer-apps' )[ 0 ],
\r
4899 ELM_ACTION_BUTTON = Util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-console-action' )[ 0 ],
\r
4901 file, w, index, style,
\r
4902 onDownCallback, onEditorCallback, onViewerCallback, onActionCallback,
\r
4903 viewerList, editorList;
\r
4905 MouseEvent.add( SUPER_USER_KEY, ELM_WRAPPER, 'click', onDownClick );
\r
4906 MouseEvent.add( SUPER_USER_KEY, ELM_EDITOR_BUTTON, 'click', onEditorClick );
\r
4907 MouseEvent.add( SUPER_USER_KEY, ELM_VIEWER_BUTTON, 'click', onViwerClick );
\r
4908 MouseEvent.add( SUPER_USER_KEY, ELM_ACTION_BUTTON, 'click', onActionClick );
\r
4909 function onDownClick(){
\r
4910 onDownCallback( index );
\r
4913 function onEditorClick(){
\r
4914 onEditorCallback( file, editorList[ 0 ] );
\r
4917 function onViwerClick(){
\r
4918 onViewerCallback( file, viewerList[ 0 ] );
\r
4921 function onActionClick(){
\r
4922 onActionCallback( file );
\r
4926 var _thumb = file.getThumbnail();
\r
4927 if( _thumb.image ){
\r
4928 ELM_THUMBNAIL.className = ICON_CLASSNAME + ' has-thumbnail';
\r
4929 ELM_THUMBNAIL.style.backgroundImage = [ 'url(', _thumb.image, ')'].join( '');
\r
4931 ELM_THUMBNAIL.className = ICON_CLASSNAME + ' ' + _thumb.className;
\r
4932 ELM_THUMBNAIL.style.backgroundImage = '';
\r
4934 ELM_FILENAME.firstChild.data = file.getName();
\r
4935 ELM_DESCRIPTION.firstChild.data = file.getSummary();
\r
4937 if( Type.isArray( viewerList ) === true && viewerList.length > 0 ){
\r
4938 ELM_VIEWER_BUTTON.style.display = '';
\r
4940 ELM_VIEWER_BUTTON.style.display = 'none';
\r
4942 if( Type.isArray( editorList ) === true && editorList.length > 0 ){
\r
4943 ELM_EDITOR_BUTTON.style.display = '';
\r
4945 ELM_EDITOR_BUTTON.style.display = 'none';
\r
4948 function resize(){
\r
4949 // ELM_WRAPPER.style.top = (index * ICON_HEIGHT) +'px';
\r
4951 function onCollect(){
\r
4952 elmContainer.removeChild( ELM_WRAPPER );
\r
4953 elmContainer = null;
\r
4954 FINDER_ICON_POOL.push( instansce );
\r
4957 this.init = function( _file, _elmContainer, _w, _index, _style, _onDownCallback, _onEditorCallback, _onViewerCallback, _onActionCallback ){
\r
4958 if( elmContainer !== _elmContainer){
\r
4959 _elmContainer.appendChild( ELM_WRAPPER );
\r
4960 elmContainer = _elmContainer;
\r
4962 if( file !== _file ){
\r
4963 file && file.destroy();
\r
4965 viewerList = file.viewerApplicationList();
\r
4966 editorList = file.editorApplicationList();
\r
4969 if( index !== _index){
\r
4973 onDownCallback = _onDownCallback;
\r
4974 onEditorCallback = _onEditorCallback;
\r
4975 onViewerCallback = _onViewerCallback;
\r
4976 onActionCallback = _onActionCallback;
\r
4978 this.elm = ELM_WRAPPER,
\r
4979 this.index = function( _index){
\r
4982 this.style = function( _style ){
\r
4985 this.onResize = function( w ){
\r
4988 this.destroy = function(){
\r
4989 //MouseEvent.remove( SUPER_USER_KEY, ELM_WRAPPER, 'click', onDownClick );
\r
4990 //MouseEvent.remove( SUPER_USER_KEY, ELM_EDITOR_BUTTON, 'click', onEditorClick );
\r
4991 //MouseEvent.remove( SUPER_USER_KEY, ELM_VIEWER_BUTTON, 'click', onViwerClick );
\r
4992 //MouseEvent.remove( SUPER_USER_KEY, ELM_ACTION_BUTTON, 'click', onActionClick );
\r
4993 elmContainer.removeChild( ELM_WRAPPER );
\r
4994 file && file.destroy();
\r
4995 file = elmContainer = onDownCallback = onEditorCallback = onViewerCallback = onActionCallback = viewerList = editorList = null;
\r
4996 FINDER_ICON_POOL.push( instansce );
\r
4999 function updateIconPosition( _style, _w, _index, _elm ){
\r
5002 var BreadcrumbClass = function(){
\r
5004 ELM_WRAPPER = ELM_ORIGIN_FINDER_LOCATION_ITEM.cloneNode( true ),
\r
5005 ELM_FILENAME = ELM_WRAPPER.getElementsByTagName( 'a' )[ 0 ],
\r
5009 MouseEvent.add( SUPER_USER_KEY, ELM_WRAPPER, 'click', onClick );
\r
5011 ELM_FILENAME.className = 'file-icon-' + file.getType();
\r
5012 ELM_FILENAME.innerHTML = file.getName();
\r
5014 function resize( index ){
\r
5015 ELM_WRAPPER.style.left = ( index * 90 ) + 'px';
\r
5017 function onClick(){
\r
5018 callback( index );
\r
5021 this.init = function( _file, _elmContainer, _index, _callback ){
\r
5023 if( elmContainer !== _elmContainer ){
\r
5024 _elmContainer.appendChild( ELM_WRAPPER );
\r
5025 elmContainer = _elmContainer;
\r
5027 if( file !== _file){
\r
5031 if( index !== _index){
\r
5035 callback = _callback;
\r
5037 this.elm = ELM_WRAPPER;
\r
5038 this.index = function( _index ){
\r
5041 this.onResize = function( w ){
\r
5044 this.destroy = function(){
\r
5045 elmContainer.removeChild( ELM_WRAPPER );
\r
5046 file = elmContainer = null;
\r
5047 BREAD_OBJECT_POOL.push( this );
\r
5051 var FinderClass = function( application, elmRoot, tree, header, footer, onSelect, viewerOption, editorOption ){
\r
5052 var ICON_ARRAY = [],
\r
5054 elmContainer = ELM_ORIGIN_CONTAINER.cloneNode( true ),
\r
5055 elmLocation = elmContainer.getElementsByTagName( 'ul' )[ 0 ],
\r
5056 nodesDiv = elmContainer.getElementsByTagName( 'div' ),
\r
5057 elmSidebarButton = nodesDiv[ 1 ],
\r
5058 elmStyleButton = nodesDiv[ 2 ],
\r
5059 elmActionButton = nodesDiv[ 3 ],
\r
5060 elmBody = nodesDiv[ nodesDiv.length -1 ],
\r
5063 headH = Util.getElementSize( nodesDiv[ 0 ] ).height,
\r
5065 currentFile = null,
\r
5067 size = Util.getElementSize( ELM_ORIGIN_FINDER_ICON ),
\r
5068 iconW = size.width,
\r
5069 iconH = size.height,
\r
5074 tree.addTreeEventListener( Const.TREE.EVENT.UPDATE, draw );
\r
5075 elmRoot.appendChild( elmContainer );
\r
5077 function draw( _w, _h ){
\r
5078 w = Type.isFinite( _w ) === true ? _w : w;
\r
5079 h = Type.isFinite( _h ) === true ? _h : h;
\r
5080 bodyH = h - headH;
\r
5081 var l = tree.hierarchy() + 1,
\r
5082 m = BREAD_ARRAY.length,
\r
5084 for( var i=0; i<l; ++i ){
\r
5085 _file = i !== l-1 ? tree.getParentFileAt( i ) : tree.getCurrentFile();
\r
5087 BREAD_ARRAY[ i ].init( _file, elmLocation, i, onHeadClick );
\r
5089 BREAD_ARRAY.push( getBreadcrumb( _file, elmLocation, i, onHeadClick ));
\r
5092 while( l < BREAD_ARRAY.length ){
\r
5093 BREAD_ARRAY.pop().destroy();
\r
5096 l = _file.getChildFileLength();
\r
5097 m = ICON_ARRAY.length;
\r
5099 for( i=0; i<l; ++i ){
\r
5101 ICON_ARRAY[ i ].init( _file.getChildFileByIndex( i ), elmBody, w, i, style, onDown, onEditor, onViwer, onAction );
\r
5103 ICON_ARRAY.push( getFinderIcon( _file.getChildFileByIndex( i ), elmBody, _w, i, style, onDown, onEditor, onViwer, onAction ));
\r
5106 if( _file.getState() === Const.FILE.STATE.LOADING ){
\r
5107 elmBody.className = 'finder-body loading';
\r
5109 elmBody.className = 'finder-body';
\r
5112 elmBody.style.height = bodyH + 'px';
\r
5114 while( l < ICON_ARRAY.length && ICON_ARRAY.length > 0 ){
\r
5115 ICON_ARRAY.pop().destroy();
\r
5119 function onHeadClick( i ){
\r
5120 var l = BREAD_ARRAY.length - 1;
\r
5122 var _file = tree.getParentFileAt( i);
\r
5123 if( _file !== null){
\r
5129 function onDown( i ){
\r
5130 if( i < ICON_ARRAY.length ){
\r
5131 var _file = tree.getCurrentFile().getChildFileByIndex( i );
\r
5132 if( _file !== null && ( _file.getChildFileLength() !== -1 || _file.getType() === Const.FILE.TYPE.FOLDER )){
\r
5136 Type.isFunction( onSelect ) === true && onSelect( _file );
\r
5141 function onEditor( _file, _app, editorOption ){
\r
5142 _app.boot( _file, editorOption );
\r
5144 function onViwer( _file, _app ){
\r
5145 _app.boot( _file, viewerOption );
\r
5147 function onAction( _file ){
\r
5150 this.MIN_WIDTH = 240;
\r
5151 this.MIN_HEIGHT = 240;
\r
5152 this.onInit = function(){
\r
5153 var position = Util.getAbsolutePosition( elmLocation );
\r
5154 headX = position.x;
\r
5155 headY = position.y;
\r
5156 bodyY = Util.getAbsolutePosition( elmBody ).y;
\r
5158 this.onPaneResize = function( _w, _h ){
\r
5163 elmBody.style.height = ( _h - headH ) + 'px';
\r
5165 for( var i = ICON_ARRAY.length; i; ){
\r
5166 ICON_ARRAY[ --i ].onResize( _w );
\r
5169 this.destroy = function(){
\r
5170 tree.removeTreeEventListener( Const.TREE.EVENT.UPDATE, draw );
\r
5172 while( BREAD_ARRAY.length > 0 ){
\r
5173 BREAD_ARRAY.shift().destroy();
\r
5175 while( ICON_ARRAY.length > 0 ){
\r
5176 ICON_ARRAY.shift().destroy();
\r
5179 FINDER_ARRAY.splice( Util.getIndex( FINDER_ARRAY, instance ), 1 );
\r
5182 FinderClass.prototype = new AbstractBasicPane();
\r
5184 function getFinderIcon( _file, _elmContainer, w, index, style, onDown, onEditor, onViwer, onAction ){
\r
5186 if( FINDER_ICON_POOL.length > 0){
\r
5187 _icon = FINDER_ICON_POOL.shift();
\r
5189 _icon = new FinderIconClass();
\r
5191 _icon.init( _file, _elmContainer, w, index, style, onDown, onEditor, onViwer, onAction );
\r
5195 function getBreadcrumb( _file, _elmContainer, index, callback ){
\r
5197 if( BREAD_OBJECT_POOL.length > 0 ){
\r
5198 _bread = BREAD_OBJECT_POOL.shift();
\r
5200 _bread = new BreadcrumbClass();
\r
5202 _bread.init( _file, _elmContainer, index, callback );
\r
5210 create: function( _application, _elmTarget, _tree, _header, _footer, _onSelect, _viewerOption, _editorOption ){
\r
5211 //if( Application.isApplicationInstance( _application ) === false ) return;
\r
5213 var _finder = new FinderClass( _application, _elmTarget, _tree, _header, _footer, _onSelect, _viewerOption, _editorOption );
\r
5215 FINDER_ARRAY.push( _finder );
\r
5218 registerFinderHead: function(){
\r
5221 registerFinderPane: function( _finderPane ){
\r
5224 isFinderInstance: function( _finder ){
\r
5225 return _finder instanceof FinderClass;
\r
5227 isFinderPaneInstance: function(){
\r
5230 isFinderHeadInstance: function(){
\r
5238 * marginBottom, marginLeft, marginRight, marginTop, margin
\r
5239 * padding, paddingBottom, paddingLeft, paddingRight, paddingTop
\r
5240 * fontSize, textIndent
\r
5242 * bottom, left, right, top (len, %)
\r
5245 * borderBottomWidth, borderLeftWidth, borderRightWidth, borderTopWidth, borderWidth,
\r
5250 * borderBottomColor, borderLeftColor, borderRightColor, borderTopColor, borderColor
\r
5254 * clip rect(0px, 40px, 40px, 0px);
\r
5255 * backgroundPosition (len, %)
\r
5257 * lineHeight (len, %, num)
\r
5258 * zIndex ( order )
\r
5261 var DHTML = ( function(){
\r
5263 var ANIMATION_TICKET_ARRAY = [],
\r
5265 round = Math.round,
\r
5266 cround = function ( v ){ return round( v * 100 ) / 100 };
\r
5268 function startAnimation( _elm, _cssObject, _onComplete, _onEnterFrame, _numFrames ){
\r
5269 var _ticket, i = ANIMATION_TICKET_ARRAY.length;
\r
5271 _ticket = ANIMATION_TICKET_ARRAY[ --i ];
\r
5272 if( _ticket.elm === _elm ){
\r
5277 var _currentValues = [],
\r
5278 _offsetValues = [],
\r
5280 _targetProperties = [],
\r
5282 var target, current,
\r
5283 inlineStyle = CSS.getInlineStyle( _elm ),
\r
5284 currentStyle = CSS.getWrappedStyle( _elm ),
\r
5285 targetStyle = CSS.getWrappedStyle( _elm, _cssObject );
\r
5286 targetStyle.pxPerEm = currentStyle.get( 'fontSize' )._toPx();
\r
5287 for( var p in _cssObject ){
\r
5288 p = Util.camelize( p );
\r
5289 target = targetStyle.get( p );
\r
5290 current = currentStyle.get( p );
\r
5292 if( target.isValid() === false || current.isValid() === false || current.equal( target ) !== false ){
\r
5298 current.convert( target );
\r
5299 // alert( current.getValue() + ' , ' + target.getValue() )
\r
5300 _currentValues.push( current.getValue() );
\r
5301 _offsetValues.push( current.getOffset( target ) );
\r
5302 _endValues.push( target.getValue() );
\r
5303 _targetProperties.push( p );
\r
5304 _units.push( target.getUnit() );
\r
5306 // IE has trouble with opacity if it does not have layout
\r
5307 // Force it by setting the zoom level
\r
5308 if( p === 'opacity' && SPECIAL.hasLayout ){
\r
5309 if( SPECIAL.hasLayout( _elm ) === false ) inlineStyle.zoom = 1;
\r
5310 inlineStyle.filter = current.getValueText();
\r
5312 inlineStyle[ p ] = current.getValueText();
\r
5319 var i, _cssTextArray = [];
\r
5320 for( i = 0; i < _numFrames; ++i ){
\r
5321 if( i < _numFrames - 1 ){
\r
5322 tickValue( _currentValues, _offsetValues, _numFrames );
\r
5323 createCssText( _currentValues, _targetProperties, targetStyle, inlineStyle, _cssTextArray );
\r
5325 createCssText( _endValues, _targetProperties, targetStyle, inlineStyle, _cssTextArray );
\r
5329 ANIMATION_TICKET_ARRAY.push( new AnimationTaskClass(
\r
5330 _elm, _cssTextArray,
\r
5331 Type.isFunction( _onComplete ) === true ? _onComplete : null,
\r
5332 Type.isFunction( _onEnterFrame ) === true ? _onEnterFrame : null,
\r
5336 currentStyle.clear();
\r
5337 targetStyle.clear();
\r
5338 SystemTimer.add( SUPER_USER_KEY, onEnterFrame, 1000 / fpms );
\r
5341 function tickValue( current, offset, numFrames ){
\r
5342 if( Type.isArray( current ) === true ){
\r
5343 var ret, i = current.length;
\r
5346 ret = tickValue( current[ i ], offset[ i ], numFrames );
\r
5347 if( Type.isNumber( ret ) === true ) current[ i ] = ret;
\r
5350 return current + offset / numFrames;
\r
5353 function createCssText( update, props, style, inline, cssTextArray ){
\r
5355 for( var i = props.length; i; ){
\r
5356 prop = style.get( props[ --i ] );
\r
5357 prop.setValue( update[ i ] );
\r
5358 inline[ Util.uncamelize( prop.name ) ] = prop.getValueText();
\r
5359 //if( prop.name === 'backgroundColor' ) alert( prop.getValueText() + '|' + update[ i ].join( ',') )
\r
5362 cssTextArray.push( CSS.toCssText( inline ) );
\r
5365 function onEnterFrame(){
\r
5368 while( i < ANIMATION_TICKET_ARRAY.length ){
\r
5369 _ticket = ANIMATION_TICKET_ARRAY[ i ];
\r
5370 l = _ticket.cssTexts.length;
\r
5371 _ticket.elm.style.cssText = _ticket.cssTexts.shift();
\r
5373 _ticket.onComplete && _ticket.onComplete();
\r
5374 delete _ticket.elm;
\r
5375 delete _ticket.cssTexts;
\r
5376 delete _ticket.onComplete;
\r
5377 delete _ticket.onEnterFrame;
\r
5378 delete _ticket.numFrame;
\r
5379 ANIMATION_TICKET_ARRAY.splice( i, 1 );
\r
5381 _ticket.onEnterFrame && _ticket.onEnterFrame( l / _ticket.numFrame );
\r
5385 if( ANIMATION_TICKET_ARRAY.length === 0 ){
\r
5386 SystemTimer.remove( SUPER_USER_KEY, onEnterFrame );
\r
5390 var AnimationTaskClass = function( elm, cssTexts, onEnterFrame, onComplete, numFrame ){
\r
5392 this.cssTexts = cssTexts;
\r
5393 this.onEnterFrame = onEnterFrame;
\r
5394 this.onComplete = onComplete;
\r
5395 this.numFrame = numFrame;
\r
5398 var VisualEffectClass = function( elm ){
\r
5399 var isHtmlElement;
\r
5401 function registerAnime( _cssObject, _onComplete, _onEnterFrame, _time ){
\r
5402 var _numFrames = Math.floor( _time / fpms );
\r
5403 startAnimation( elm, _cssObject, _onComplete, _onEnterFrame, _numFrames );
\r
5405 function startFadeIn(){
\r
5408 function startFadeOut(){
\r
5411 function update( _x, _y, _w, _h ){
\r
5412 var _cssText = elm.style.cssText;
\r
5416 this.anime = registerAnime;
\r
5417 this.fadeIn = startFadeIn;
\r
5418 this.fadeOut = startFadeOut;
\r
5419 this.update = update;
\r
5423 create: function( application, _elm ){
\r
5424 return new VisualEffectClass( _elm );
\r
5426 isInstanceOfVisualEffect: function( _instance){
\r
5427 return _instance instanceof VisualEffectClass;
\r
5433 /* --------------------------------------------
\r
5437 Application.onCurrentApplicationChange( SUPER_USER_KEY );
\r
5439 SERVICE_LIST.push( MouseEvent );
\r
5441 new EventTicketClass( window, 'unload', function(){
\r
5443 while( SERVICE_LIST.length > 0 ){
\r
5444 _service = SERVICE_LIST.shift();
\r
5445 Type.isFunction( _service.onSystemShutdown ) === true && _service.onSystemShutdown();
\r
5451 /* ---------------------------------------------
\r
5452 * broadcast to global
\r
5456 gOS.registerApplication = Application.register;
\r
5457 gOS.registerDriver = File.registerDriver;
\r
5459 })( window, document );
\r
5463 gOS.PageApplicationRef = null;
\r
5464 gOS.PageApplicationClass = function(){
\r
5466 this.bgColor = '#FFF';
\r
5467 this.onOpen = function(){
\r
5468 var button = document.getElementById( 'server-page-close-button' );
\r
5470 app.addEventListener( button, 'click', gOS.PageApplicationRef.shutdown );
\r
5472 var msg = document.getElementById( 'esc-msg' );
\r
5474 app.addEventListener( msg, 'click', gOS.PageApplicationRef.shutdown );
\r
5476 app.addKeyEventListener( 'keydown', gOS.PageApplicationRef.shutdown, 27 ); // 27.esc
\r