From db7c4f787f41df4c6a162eca3cd4e4a29e991dd4 Mon Sep 17 00:00:00 2001 From: itozyun Date: Sat, 2 Feb 2013 20:04:59 +0900 Subject: [PATCH 01/16] Version 0.5.44. fetch pettanR resourcies working! --- 0.5.x/javascripts/libs.js | 315 ++++---- 0.5.x/javascripts/peta-apps.js | 997 ++++++++++++++----------- 0.5.x/javascripts/peta-common.js | 86 ++- 0.5.x/javascripts/system.js | 1483 +++++++++++++++++++++++++++++++++++++- 4 files changed, 2258 insertions(+), 623 deletions(-) diff --git a/0.5.x/javascripts/libs.js b/0.5.x/javascripts/libs.js index a21377f..aee98fe 100644 --- a/0.5.x/javascripts/libs.js +++ b/0.5.x/javascripts/libs.js @@ -1,6 +1,6 @@ /* * pettanR libs.js - * version 0.5.39 + * version 0.5.44 * * * Type @@ -317,21 +317,32 @@ var getFunctionName = function( f ){ }; }, 0 ); - function clone( src ) { - var ret; + var objSrc = [], + objCopy = [], + getIndex; + function clone( src ){ + var ret, i, key; if( Type.isArray(src) === true ){ + i = getIndex( objSrc, src ); + if( i !== -1 ) return objCopy[ i ]; ret = []; + objSrc[ objSrc.length ] = src; + objCopy[ objCopy.length ] = ret; } else if( Type.isObject(src) === true ){ + i = getIndex( objSrc, src ); + if( i !== -1 ) return objCopy[ i ]; ret = {}; + objSrc[ objSrc.length ] = src; + objCopy[ objCopy.length ] = ret; } else if( Type.isNumber(src) === true || Type.isString(src) === true || Type.isBoolean( src ) === true ){ return src; } else { return null; }; - for( var key in src ){ - ret[ key ] = clone( src[ key ]); + for( key in src ){ + ret[ key ] = clone( src[ key ] ); }; return ret; }; @@ -365,6 +376,8 @@ var getFunctionName = function( f ){ return target; }, copy: function( objOrArray ){ + objSrc.length = objCopy.length = 0; + getIndex = Util.getIndex; return clone( objOrArray ); }, cleanCommentNode: function ( _targetElm ){ @@ -645,21 +658,21 @@ var getFunctionName = function( f ){ _node.parentNode && _node.parentNode.removeChild( _node); } }, - getIndex: function( _array, _element ){ + getIndex: function( array, element ){ if( Array.prototype.indexof ){ - Util.getIndex = function( _array, _element ){ - return _array.indexof( _element ); + Util.getIndex = function( array, element ){ + return array.indexof( element ); }; } else { - Util.getIndex = function( _array, _element ){ - var i = _array.length; + Util.getIndex = function( array, element ){ + var i = array.length; for( ; i; ){ - if( _array[ --i ] === _element ) return i; + if( array[ --i ] === element ) return i; }; return -1; }; }; - return Util.getIndex( _array, _element ); + return Util.getIndex( array, element ); }, copyArray: function( _array ){ var l = _array.length, @@ -797,126 +810,95 @@ var CSS = ( function( window, documwnt, undefined ){ return _special; })(); - - function cssToObject( css ){ - var ret = {}, i, nv, n, v, - parse = Util.parse, - isNumber = Type.isNumber, - camelize = Util.camelize; - if( Type.isString( css ) === true ){ - css = css.split( ';' ); - for( i = css.length; i; ){ - nv = css[ --i ].split( ':' ); // filter の場合, progid: がくる - n = nv.shift(); - if( isNumber( parse( n ) ) === true ) continue; - v = nv.join( '' ); - while( v.charAt( 0 ) === ' ' ) v = v.substr( 1 ); - ret[ camelize( n ) ] = parse( v ); - }; - } else { - for( n in css ){ - if( Type.isNumber( parse( n ) ) === false ) ret[ n ] = parse( css[ n ] ); - }; - }; - - if( SPECIAL.setFilters ){ - SPECIAL.setFilters( ret ); - } else { - ret.opacity = SPECIAL.opacity !== null ? ret[ SPECIAL.opacity ] : 1; - }; - - SPECIAL.setBackgroundPositionXY && SPECIAL.setBackgroundPositionXY( ret ); - SPECIAL.setClipTopRightBottomLeft && SPECIAL.setClipTopRightBottomLeft( ret ); - - return ret; - }; var COLOR = ( function(){ var ret = {}, v, name, list = [ - 0, 'BLACK', - parseInt( 'FF0000', 16 ), 'RED', - parseInt( '00FF00', 16 ), 'LIME', - parseInt( '0000FF', 16 ), 'BLUE', - parseInt( 'FFFF00', 16 ), 'YELLOW', - parseInt( '00FFFF', 16 ), 'AQUA or CYAN', - parseInt( 'FF00FF', 16 ), 'FUCHSIA or MAGENTA', - parseInt( 'FFFFFF', 16 ), 'WHITE', - parseInt( '008000', 16 ), 'GREEN', - parseInt( '800080', 16 ), 'PURPLE', - parseInt( '800000', 16 ), 'MAROON', - parseInt( '000080', 16 ), 'NAVY', - parseInt( '808000', 16 ), 'OLIVE', - parseInt( '008080', 16 ), 'TEAL', - parseInt( '808080', 16 ), 'GRAY', - parseInt( 'C0C0C0', 16 ), 'SILVER', - parseInt( '696969', 16 ), 'DIMGRAY', - parseInt( '708090', 16 ), 'SLATEGRAY', - parseInt( 'A9A9A9', 16 ), 'DARKGRAY', - parseInt( 'DCDCDC', 16 ), 'GAINSBORO', - parseInt( '191970', 16 ), 'MIDNIGHTBLUE', - parseInt( '6A5ACD', 16 ), 'SLATEBLUE', - parseInt( '0000CD', 16 ), 'MEDIUMBLUE', - parseInt( '4169E1', 16 ), 'ROYALBLUE', - parseInt( '1E90FF', 16 ), 'DODGERBLUE', - parseInt( '87CEEB', 16 ), 'SKYBLUE', - parseInt( '4682B4', 16 ), 'STEELBLUE', - parseInt( 'ADD8E6', 16 ), 'LIGHTBLUE', - parseInt( 'AFEEEE', 16 ), 'PALETURQUOISE', - parseInt( '40E0D0', 16 ), 'TURQUOISE', - parseInt( 'E0FFFF', 16 ), 'LIGHTCYAN', - parseInt( '7FFFD4', 16 ), 'AQUAMARINE', - parseInt( '006400', 16 ), 'DARKGREEN', - parseInt( '2E8B57', 16 ), 'SEAGREEN', - parseInt( '90EE90', 16 ), 'LIGHTGREEN', - parseInt( '7FFF00', 16 ), 'CHARTREUSE', - parseInt( 'ADFF2F', 16 ), 'GREENYELLOW', - parseInt( '32CD32', 16 ), 'LIMEGREEN', - parseInt( '9ACD32', 16 ), 'YELLOWGREEN', - parseInt( '6B8E23', 16 ), 'OLIVEDRAB', - parseInt( 'BCB76B', 16 ), 'DARKKHAKI', - parseInt( 'EEE8AA', 16 ), 'PALEGOLDENROD', - parseInt( 'FFFFE0', 16 ), 'LIGHTYELLOW', - parseInt( 'FFD700', 16 ), 'GOLD', - parseInt( 'DAA520', 16 ), 'GOLDENROD', - parseInt( 'B8860B', 16 ), 'DARKGOLDENROD', - parseInt( 'BC8F8F', 16 ), 'ROSYBROWN', - parseInt( 'CD5C5C', 16 ), 'INDIANRED', - parseInt( '8B4513', 16 ), 'SADDLEBROWN', - parseInt( 'A0522D', 16 ), 'SIENNA', - parseInt( 'CD853F', 16 ), 'PERU', - parseInt( 'DEB887', 16 ), 'BURLYWOOD', - parseInt( 'F5F5DC', 16 ), 'BEIGE', - parseInt( 'F5DEB3', 16 ), 'WHEAT', - parseInt( 'F4A460', 16 ), 'SANDYBROWN', - parseInt( 'D2B48C', 16 ), 'TAN', - parseInt( 'D2691E', 16 ), 'CHOCOLATE', - parseInt( 'B22222', 16 ), 'FIREBRICK', - parseInt( 'A52A2A', 16 ), 'BROWN', - parseInt( 'FA8072', 16 ), 'SALMON', - parseInt( 'FFA500', 16 ), 'ORANGE', - parseInt( 'FF7F50', 16 ), 'CORAL', - parseInt( 'FF6347', 16 ), 'TOMATO', - parseInt( 'FF69B4', 16 ), 'HOTPINK', - parseInt( 'FFC0CB', 16 ), 'PINK', - parseInt( 'FF1493', 16 ), 'DEEPPINK', - parseInt( 'DB7093', 16 ), 'PALEVIOLETRED', - parseInt( 'EE82EE', 16 ), 'VIOLET', - parseInt( 'DDA0DD', 16 ), 'PLUM', - parseInt( 'DA70D6', 16 ), 'ORCHILD', - parseInt( '9400D3', 16 ), 'DARKVIOLET', - parseInt( '8A2BE2', 16 ), 'BLUEVIOLET', - parseInt( '9370DB', 16 ), 'MEDIUMPURPLE', - parseInt( 'D8BFD8', 16 ), 'THISTLE', - parseInt( 'E6E6FA', 16 ), 'LAVENDER', - parseInt( 'FFE4E1', 16 ), 'MISTYROSE', - parseInt( 'FFFFF0', 16 ), 'IVORY', - parseInt( 'FFFACD', 16 ), 'LEMONCHIFFON' + '0', 'BLACK', + 'FF0000', 'RED', + '00FF00', 'LIME', + '0000FF', 'BLUE', + 'FFFF00', 'YELLOW', + '00FFFF', 'AQUA', + '00FFFF', 'CYAN', + 'FF00FF', 'MAGENTA', + 'FF00FF', 'FUCHSIA', + 'FFFFFF', 'WHITE', + '008000', 'GREEN', + '800080', 'PURPLE', + '800000', 'MAROON', + '000080', 'NAVY', + '808000', 'OLIVE', + '008080', 'TEAL', + '808080', 'GRAY', + 'C0C0C0', 'SILVER', + '696969', 'DIMGRAY', + '708090', 'SLATEGRAY', + 'A9A9A9', 'DARKGRAY', + 'DCDCDC', 'GAINSBORO', + '191970', 'MIDNIGHTBLUE', + '6A5ACD', 'SLATEBLUE', + '0000CD', 'MEDIUMBLUE', + '4169E1', 'ROYALBLUE', + '1E90FF', 'DODGERBLUE', + '87CEEB', 'SKYBLUE', + '4682B4', 'STEELBLUE', + 'ADD8E6', 'LIGHTBLUE', + 'AFEEEE', 'PALETURQUOISE', + '40E0D0', 'TURQUOISE', + 'E0FFFF', 'LIGHTCYAN', + '7FFFD4', 'AQUAMARINE', + '006400', 'DARKGREEN', + '2E8B57', 'SEAGREEN', + '90EE90', 'LIGHTGREEN', + '7FFF00', 'CHARTREUSE', + 'ADFF2F', 'GREENYELLOW', + '32CD32', 'LIMEGREEN', + '9ACD32', 'YELLOWGREEN', + '6B8E23', 'OLIVEDRAB', + 'BCB76B', 'DARKKHAKI', + 'EEE8AA', 'PALEGOLDENROD', + 'FFFFE0', 'LIGHTYELLOW', + 'FFD700', 'GOLD', + 'DAA520', 'GOLDENROD', + 'B8860B', 'DARKGOLDENROD', + 'BC8F8F', 'ROSYBROWN', + 'CD5C5C', 'INDIANRED', + '8B4513', 'SADDLEBROWN', + 'A0522D', 'SIENNA', + 'CD853F', 'PERU', + 'DEB887', 'BURLYWOOD', + 'F5F5DC', 'BEIGE', + 'F5DEB3', 'WHEAT', + 'F4A460', 'SANDYBROWN', + 'D2B48C', 'TAN', + 'D2691E', 'CHOCOLATE', + 'B22222', 'FIREBRICK', + 'A52A2A', 'BROWN', + 'FA8072', 'SALMON', + 'FFA500', 'ORANGE', + 'FF7F50', 'CORAL', + 'FF6347', 'TOMATO', + 'FF69B4', 'HOTPINK', + 'FFC0CB', 'PINK', + 'FF1493', 'DEEPPINK', + 'DB7093', 'PALEVIOLETRED', + 'EE82EE', 'VIOLET', + 'DDA0DD', 'PLUM', + 'DA70D6', 'ORCHILD', + '9400D3', 'DARKVIOLET', + '8A2BE2', 'BLUEVIOLET', + '9370DB', 'MEDIUMPURPLE', + 'D8BFD8', 'THISTLE', + 'E6E6FA', 'LAVENDER', + 'FFE4E1', 'MISTYROSE', + 'FFFFF0', 'IVORY', + 'FFFACD', 'LEMONCHIFFON' ]; - for( i=list.length; i; ){ + for( i = list.length; i; ){ v = list[ --i ]; name = list[ --i ]; - ret[ name ] = v; + ret[ name ] = parseInt( v, 16 ); }; return ret; })(); @@ -1054,8 +1036,8 @@ var CSS = ( function( window, documwnt, undefined ){ // top, bottom, left, right, topbottom, leftright, all }; FrexiblePropertyClass.prototype = PropertyGroupClass.prototype = { - name: '', - equal: function( prop ){ + name : '', + equal : function( prop ){ var ps = this.props, i = ps.length; for( ; i; ){ --i; @@ -1063,27 +1045,27 @@ var CSS = ( function( window, documwnt, undefined ){ }; return true; }, - convert: function( prop ){ + convert : function( prop ){ var ps = this.props, i = ps.length; for( ; i; ){ --i; ps[ i ].convert( prop[ i ] ); }; }, - setValue: function( ary ){ + setValue : function( ary ){ var ps = this.props, i = 0, l = ps.length; for( ; i this.r || 0 > this.g || 0 > this.b ) return false; @@ -1471,12 +1453,43 @@ var CSS = ( function( window, documwnt, undefined ){ obj[ _p ] = obj[ _p ] || obj[ p ]; delete obj[ p ]; }; + return obj; + }; + function cssToObject( css ){ + var ret = {}, i, nv, n, v, + parse = Util.parse, + isNumber = Type.isNumber, + camelize = Util.camelize; + if( Type.isString( css ) === true ){ + css = css.split( ';' ); + for( i = css.length; i; ){ + nv = css[ --i ].split( ':' ); // filter の場合, progid: がくる + n = nv.shift(); + if( isNumber( parse( n ) ) === true ) continue; + v = nv.join( '' ); + while( v.charAt( 0 ) === ' ' ) v = v.substr( 1 ); + ret[ camelize( n ) ] = parse( v ); + }; + } else { + for( n in css ){ + if( Type.isNumber( parse( n ) ) === false ) ret[ n ] = parse( css[ n ] ); + }; + }; + + if( SPECIAL.setFilters ){ + SPECIAL.setFilters( ret ); + } else { + ret.opacity = SPECIAL.opacity !== null ? ret[ SPECIAL.opacity ] : 1; + }; + + SPECIAL.setBackgroundPositionXY && SPECIAL.setBackgroundPositionXY( ret ); + SPECIAL.setClipTopRightBottomLeft && SPECIAL.setClipTopRightBottomLeft( ret ); + + return ret; }; - return { getWrappedStyle: function( elm, opt_css ){ - opt_css && camelizeHash( opt_css ); - return new WrappedStyleClass( elm, opt_css || CSS.getComputedStyle( elm ) ); + return new WrappedStyleClass( elm, opt_css ? camelizeHash( opt_css ) : CSS.getComputedStyle( elm ) ); }, getInlineStyle: function( _elm ){ return cssToObject( _elm.style.cssText ); diff --git a/0.5.x/javascripts/peta-apps.js b/0.5.x/javascripts/peta-apps.js index 81aaa51..0b1a931 100644 --- a/0.5.x/javascripts/peta-apps.js +++ b/0.5.x/javascripts/peta-apps.js @@ -1,6 +1,6 @@ /* * pettanR peta.apps.js - * version 0.5.39 + * version 0.5.44 * * author: * itozyun @@ -16,352 +16,469 @@ MyArtistID = 'current_artist' in window ? current_artist.id : ( pettanr.CONST.SERVER_SUPPORT === false ? 1 : -1 ), Driver = null, FileAPI = gOS.registerDriver( function(){ - var self = Driver = this; + var self = Driver = this, + unregisteredFileDataJsonList = []; - function onLoadJson( _file, _json ){ - var _access = FileAPI.getFileDataAccess( _file ), - _data = _access !== null ? _access.DATA : null, - i, l; - if( _data === null ){ - onErrorJson( _file ); + function onLoadJson( file, json ){ + var access = FileAPI.getFileDataAccess( file ), + data = access !== null ? access.DATA : null, + i, l, args; + if( data === null ){ + onErrorJson( file ); return; }; - _data.state = Const.FILE.STATE.OK; - - if( Type.isArray( _json ) === true ){ - for( i = 0, l = _json.length; i < l; ++i ){ - buildFileData( _json[ i ], _data ); + data.state = Const.FILE.STATE.OK; + if( Type.isArray( json ) === true ){ + for( i = 0, l = json.length; i < l; ++i ){ + registerFileData( json[ i ], data ); }; } else - if( Type.isNumber( _json.id ) === true ){ - buildFileData( _json, _data ); + if( Type.isNumber( json.id ) === true ){ + registerFileData( json, data ); + }; + while( 0 < unregisteredFileDataJsonList.length ){ + args = unregisteredFileDataJsonList.shift(); + registerFileData( args[ 0 ], args[ 1 ] ); + //alert( unregisteredFileDataJsonList.length ) }; - _file.dispatchEvent( FileAPI.createFileEvent( Const.FILE.EVENT.GET_SEQENTIAL_FILES, _file, 'children', null ) ); + file.dispatchEvent( FileAPI.createFileEvent( Const.FILE.EVENT.GET_SEQENTIAL_FILES, file, 'children', null ) ); }; - function onErrorJson( _file ){ - var _data = FileAPI.getFileData( _file); - if( _data !== null){ - _data.state = Const.FILE.STATE.ERROR; + function onErrorJson( file ){ + var data = FileAPI.getFileData( file ); + if( data !== null){ + data.state = Const.FILE.STATE.ERROR; }; - _file.dispatchEvent( FileAPI.createFileEvent( Const.FILE.EVENT.GET_SEQENTIAL_FILES, _file, 'children', null ) ); + file.dispatchEvent( FileAPI.createFileEvent( Const.FILE.EVENT.GET_SEQENTIAL_FILES, file, 'children', null ) ); }; - function buildFileData( _data, _parent ){ - var _array, i, l; - // Panel - if( _parent === FILE_DATA_PANELS_ROOT || _parent === FILE_DATA_MY_PANELS_ROOT ){ - _data.type = FILE_TYPE.PANEL; - _array = PANEL_ARRAY; - } else - // Comic - if( _parent === FILE_DATA_COMICS_ROOT || _parent === FILE_DATA_MY_COMICS_ROOT ){ - _data.type = FILE_TYPE.COMIC; - _array = COMIC_ARRAY; - } else - if( _parent.type === FILE_TYPE.COMIC ){ - _array = PANEL_ARRAY; - } else - // Lisence - if( _parent === FILE_DATA_LISENCE_ROOT ){ - _data.type = FILE_TYPE.LICENSE; - _array = ORIGINAL_LICENSE_ARRAY; - } else - // Author - if( _parent === FILE_DATA_AUTHOR_ROOT ){ - _data.type = FILE_TYPE.AUTHOR; - _array = AUTHOR_ARRAY; - } else - // Artist - if( _parent === FILE_DATA_ARTIST_ROOT ){ - _data.type = FILE_TYPE.ARTIST; - _array = ARTIST_ARRAY; - } else - // Picture - if( _parent === FILE_DATA_PICTURE_ROOT || _parent === FILE_DATA_MY_PICTURES_ROOT ){ - _data.type = FILE_TYPE.PICTURE; - _array = RESOURCE_PICTURE_ARRAY; - // original_license を含まなければ、license object を削除して ビットデータ で保持 - // original_license なら ファイルを作る buildFileData( _license, FILE_DATA_LISENCE_ROOT) - var _license = _data.license, - _rule, - _Math_pow = Math.pow, - _bits = 0; - if( typeof _license === 'object' ){ - for( i=0, l=BASIC_LICENSES.length; i 0 ){ - var _id = _data.id - 1, - __data = _array[ _id ], - _reserved = Const.FILE.DATA_PROPERTY_RESERVED.join( ', ' ); - if( __data ){ - for( var key in _data ){ - if( _reserved.indexOf( key ) === -1 ){ - __data[ key ] = _data[ key ]; - }; + // Resource Picture + case FILE_DATA_RESOURCE_PICTURES_ROOT : + case FILE_DATA_MY_RESOURCE_PICTURES_ROOT : + case RESOURCE_PICTURE_ARRAY : + json.type = FILE_TYPE.RESOURCE_PICTURE; + data = createFileData( json, RESOURCE_PICTURE_ARRAY, 'ext' ); + if( data.artist ){ + addChildData( data.artist, data ); + data.artist.id === MyArtistID && addChildData( FILE_DATA_MY_RESOURCE_PICTURES_ROOT, data ); }; - _data = __data; // このタイミングで参照が切れるので注意!! - } else { - _array[ _id ] = _data; - }; - } else { - // alert( 'error' + _parent.name + ' ' + _data.id ); - }; - - // Author - // Artist - if( _parent === FILE_DATA_AUTHOR_ROOT || _parent === FILE_DATA_ARTIST_ROOT ){ - addChildData( _parent, _data ); - } else - // Comic + Panels - if( _parent === FILE_DATA_COMICS_ROOT || _parent === FILE_DATA_MY_COMICS_ROOT ){ - var _stories = _data.stories, - _panel; - if( Type.isArray( _stories ) === true ){ - for( i=0, l=_stories.length; i LIMIT_FILESIZE ? [ THUMB_PATH, data.id, '.', data.ext ].join( '') : null, + LOW_SRC = originalPicture.filesize && originalPicture.filesize > LIMIT_FILESIZE ? [ THUMB_PATH, data.id, '.', originalPicture.ext ].join( '') : null, reversibleImage = null, timer = null, onEnterFlag = false, instance = this; elmContainer.appendChild( elmIconWrap ); elmIconWrap.style.left = ( index * itemW ) + 'px'; - elmIconTitle.appendChild( document.createTextNode( data.filesize + 'bytes' ) ); + elmIconTitle.appendChild( document.createTextNode( originalPicture.filesize + 'bytes' ) ); function onImageLoad( url, _imgW, _imgH ){ - data.width = _imgW = _imgW || data.width || 64; - data.height = _imgH = _imgH || data.height || 64; + data.width = _imgW = _imgW || originalPicture.width || 64; + data.height = _imgH = _imgH || originalPicture.height || 64; elmIconTitle.firstChild.data = _imgW + 'x' + _imgH; var zoom = 128 /( _imgW > _imgH ? _imgW : _imgH ), MATH_FLOOR = Math.floor, @@ -777,56 +936,56 @@ var PremiumSatge = gOS.registerApplication( function(){ self.removeTimer( onEnterShowImage ); self.addTimer( onEnterShowImage, 500 ); - } + }; return false; - } + }; function drawIcons(){ while( ICON_ARRAY.length > 0 ){ ICON_ARRAY.shift().destroy(); - } + }; var _index = rootFile.search( { - id: artistID, - type: FILE_TYPE.ARTIST + id : artistID, + type : FILE_TYPE.ARTIST })[ 0 ], _artistFile = rootFile.getChildFileAt( _index ), - _file; + file; if( _artistFile !== null ){ - for(var i=0, l=_artistFile.getChildFileLength(); i 0 ){ ICON_ARRAY.shift().destroy(); - } + }; onUpdate !== null && onUpdateData !== null && onUpdate.call( onUpdateContext, onUpdateData ); onUpdate = onUpdateData = onUpdateContext = null; PremiumSatge.shutdown(); - } + }; this.MIN_WIDTH = 320; this.MIN_HEIGHT = 320; this.onInit = function(){ - self.rootElement.id = 'image-group-wrapper'; + self.rootElement.id = 'image-group-wrapper'; - self.rootElement.innerHTML = [ - '
', - '
NO DATA...
', - '
close
' - ].join( '' ); - - self.fetchCSS( pettanr.CONST.URL_PETA_APPS_CSS ); - - tree = FileAPI.createTree( FILE_DATA_ARTIST_ROOT ); - rootFile = tree.getRootFile(); + self.rootElement.innerHTML = [ + '
', + '
NO DATA...
', + '
close
' + ].join( '' ); + + self.fetchCSS( pettanr.CONST.URL_PETA_APPS_CSS ); + + tree = FileAPI.createTree( FILE_DATA_ARTIST_ROOT ); + rootFile = tree.getRootFile(); }; this.onOpen = function( _windowW, _windowH, _ARTISTIDorFILE, _onUpdate, opt_thisObj ){ elmContainer = document.getElementById( 'image-group-icon-container' ); @@ -855,11 +1014,13 @@ var PremiumSatge = gOS.registerApplication( function(){ tree.addTreeEventListener( Const.TREE.EVENT.UPDATE, drawIcons ); var data = FileAPI.getFileData( _ARTISTIDorFILE ); - if( data.type === FILE_TYPE.ARTIST || FILE_DATA_MY_PICTURES_ROOT === data ){ + if( !data ){ + artistID = MyArtistID || -1; + } else + if( data.type === FILE_TYPE.ARTIST || FILE_DATA_MY_ORIGINAL_PICTURES_ROOT === data ){ artistID = data.id || -1; } else if( Type.isNumber( _ARTISTIDorFILE ) === true ){ - alert( _ARTISTIDorFILE ) artistID = _ARTISTIDorFILE; }; @@ -1062,30 +1223,41 @@ var Reader = gOS.registerApplication( function(){ } function draw(){ - var fileData, title, author; + var fileData, title, author, story; if( Driver.isPettanrFileInstance( currentFile ) === true ){ - if( currentFile.getType() === FILE_TYPE.COMIC ){ - fileData = currentFile.read(); - title = fileData.title; - author = fileData.author.name; - comicData = fileData; - numPanel = currentFile.getChildFileLength(); - } else - if( currentFile.getType() === FILE_TYPE.PANEL ){ - fileData = currentFile.read(); - title = fileData.comic.title; - author = fileData.comic.author.name; - comicData = fileData; - numPanel = 1; - } + switch( currentFile.getType() ){ + case FILE_TYPE.COMIC : + fileData = currentFile.read(); + title = fileData.title; + author = fileData.author.name; + comicData = fileData; + numPanel = currentFile.getChildFileLength(); + break; + case FILE_TYPE.STORY : + story = currentFile.read(); + fileData = story.panel; + title = story.comic.title; + author = fileData.author.name; + comicData = fileData; + numPanel = 1; + break; + case FILE_TYPE.PANEL : + fileData = currentFile.read(); + title = 'No comic'; + author = fileData.author.name; + comicData = fileData; + numPanel = 1; + break; + }; } else { }; if( comicData !== null ){ elmTitle.data = title; elmAuthor.data = author; - bindWorker.json( comicData ); + // bindWorker.json( comicData ); + bindWorker.file( currentFile ); self.addAsyncCall( asyncResize ); }; } @@ -1120,7 +1292,7 @@ var Reader = gOS.registerApplication( function(){ self.fetchCSS( pettanr.CONST.URL_PETA_APPS_CSS ); }; - this.onOpen = function( _w, _h, _file ){ + this.onOpen = function( _w, _h, file ){ headerH = Util.getElementSize( document.getElementById( 'comic-reader-header' ) ).height; consoleH = Util.getElementSize( document.getElementById( 'comic-reader-console' ) ).height; elmContainer = document.getElementById( 'comic-reader-panel-container' ); @@ -1140,10 +1312,10 @@ var Reader = gOS.registerApplication( function(){ windowW = _w; windowH = _h; - if( FileAPI.isFileInstance( _file ) === true ){ - currentFile = _file; - _file.addEventListener( Const.FILE.EVENT.GET_SEQENTIAL_FILES, draw ); - _file.getSeqentialFiles(); + if( FileAPI.isFileInstance( file ) === true ){ + currentFile = file; + file.addEventListener( Const.FILE.EVENT.GET_SEQENTIAL_FILES, draw ); + file.getSeqentialFiles(); draw(); }; }; @@ -2141,11 +2313,11 @@ var Editor = gOS.registerApplication( function(){ var IMAGE_EXPLORER_WINDOW = ( function(){ var tree, finder; - function onFileSelect( _file ){ + function onFileSelect( file ){ // 他の image ファイルも許可する? - if( Driver.isPettanrFileInstance( _file ) === true ){ - if( _file.getType() === FILE_TYPE.PICTURE ){ - PANEL_ELEMENT_CONTROL.onImageSelect( FileAPI.getFileData( _file ) ); + if( Driver.isPettanrFileInstance( file ) === true ){ + if( file.getType() === FILE_TYPE.RESOURCE_PICTURE ){ + PANEL_ELEMENT_CONTROL.onImageSelect( FileAPI.getFileData( file ) ); }; }; }; @@ -2154,7 +2326,7 @@ var Editor = gOS.registerApplication( function(){ { onInit: function(){}, onFirstOpen: function( _w, _h, nodeBody ){ - tree = FileAPI.createTree( FILE_DATA_PICTURE_ROOT ); + tree = FileAPI.createTree( FILE_DATA_RESOURCE_PICTURES_ROOT ); var _root = tree.getRootFile(), _myPic = _root.getChildFileAt( 0 ), _pic = _root.getChildFileAt( 1 ); @@ -3512,8 +3684,9 @@ var Editor = gOS.registerApplication( function(){ this.keepSize = false; this.flipV = data.height < 0 ? -1 : 1; this.flipH = data.width < 0 ? -1 : 1; - this.rPicture = data.resource_picture; - this.artistID = this.rPicture.artist_id || this.rPicture.artist.id || -1; + this.rPicture = data.picture; + //this.oPicture = this.rPicture.original_picture; + //this.artistID = this.oPicture.artist.id || -1; var self = this; function animeComplete(){ @@ -3577,12 +3750,14 @@ var Editor = gOS.registerApplication( function(){ }, _updateResourcePicture : function( _rPicture ){ this.rPicture = _rPicture; - - this.actualW = _rPicture.width; - this.actualH = _rPicture.height; + this.oPicture = this.rPicture.original_picture; + this.artistID = this.oPicture.artist.id || -1; + + this.actualW = this.oPicture.width; + this.actualH = this.oPicture.height; var _reversibleImage = pettanr.image.createReversibleImage( - [ pettanr.CONST.RESOURCE_PICTURE_PATH, _rPicture.id, '.', _rPicture.ext ].join(''), + [ pettanr.CONST.RESOURCE_PICTURE_PATH, this.rPicture.id, '.', this.rPicture.ext ].join( '' ), this.flipH * this.w, this.flipV * this.h ); if( this.reversibleImage !== null ){ @@ -3896,17 +4071,17 @@ var Editor = gOS.registerApplication( function(){ var _panelElement; if( isPanelPictureData !== true ){ _panelElement = new ImageElementClass( { - resource_picture:data, - x: Math.floor( panelW / 2 - data.width / 2 ), - y: Math.floor( panelH / 2 - data.height / 2 ), - z: -1, - t: PANEL_ELEMENT_ARRAY.length + 1, - width: 1, - height: 1 + picture : data, + x : Math.floor( panelW / 2 - data.width / 2 ), + y : Math.floor( panelH / 2 - data.height / 2 ), + z : -1, + t : PANEL_ELEMENT_ARRAY.length + 1, + width : 1, + height : 1 }); _panelElement.init(); PANEL_ELEMENT_CONTROL.add( _panelElement ); - _panelElement.animate( undefined, undefined, Math.abs( data.width ), Math.abs( data.height ) ); + _panelElement.animate( undefined, undefined, Math.abs( data.picture.original_picture.width ), Math.abs( data.picture.original_picture.height ) ); } else { _panelElement = new ImageElementClass( data ); _panelElement.init(); @@ -4119,7 +4294,7 @@ var Editor = gOS.registerApplication( function(){ delete app.onInit; }; - this.onOpen = function( _w, _h, _file ){ + this.onOpen = function( _w, _h, file ){ // 表示奥の物から順に init() していく PANEL_ELEMENT_CONTROL.init(); PANEL_CONTROL.init(); @@ -4144,16 +4319,16 @@ var Editor = gOS.registerApplication( function(){ borderSize, fileData, panelElements, panelElm; - if( FileAPI.isFileInstance( _file ) === true ){ - if( Driver.isPettanrFileInstance( _file ) === true ){ - if( _file.getType() === FILE_TYPE.COMIC ){ - fileData = _file.read(); + if( FileAPI.isFileInstance( file ) === true ){ + if( Driver.isPettanrFileInstance( file ) === true ){ + if( file.getType() === FILE_TYPE.COMIC ){ + fileData = file.read(); panelW = fileData.width; panelH = fileData.height; comicID = fileData.id || -1; } else - if( _file.getType() === FILE_TYPE.PANEL ){ - fileData = _file.read(); + if( file.getType() === FILE_TYPE.PANEL ){ + fileData = file.read(); panelW = fileData.width; panelH = fileData.height; borderSize = fileData.border; @@ -4188,7 +4363,7 @@ var Editor = gOS.registerApplication( function(){ if( Type.isArray( panelElements ) === true ){ for( var i=0; i 0 ? def.pool.shift() : instance = new klass(); f = true; - if( def.Super && !instance.Super ){ - instance.Super = def.Super; - }; + if( def.Super && !instance.Super ) instance.Super = def.Super; if( def.isPrivate === true ){ userDef = getClassDef( dataUser ); userDef.dataList.push( instance ); userDef.userList.push( dataUser ); } else { def.live && def.live.push( instance ); + args = c( arguments ); }; - def[ CONSTRUCTOR ] && def[ CONSTRUCTOR ].apply( instance, dataUser === null ? c( arguments ) : args ); + def[ CONSTRUCTOR ] && def[ CONSTRUCTOR ].apply( instance, args ); return instance; }; @@ -441,8 +441,8 @@ var Class = ( function(){ PRIVATE_DEF_LIST.push( classDef ); } else { if( classDef.privateClass ){ - klass.newPrivateData = newPrivateData; - klass.getPrivateData = getPrivateData; + klass.newPrivateData = newPrivateData; + klass.getPrivateData = getPrivateData; }; CLASS_LIST.push( klass ); DEF_LIST.push( classDef ); @@ -453,7 +453,7 @@ var Class = ( function(){ }, getClass : function( instance ){ - + return getClass( instance ); }, getClassDef : function(){ @@ -1069,7 +1069,7 @@ var File = ( function(){ if( typeof driver.getName === 'function'){ return driver.getName( this ); } - return BASE_DRIVER.getName( this); + return BASE_DRIVER.getName( this ); }, getThumbnail: function(){ var driver = FILE_CONTROLER.getDriver( this ); @@ -1112,9 +1112,9 @@ var File = ( function(){ // simpleDeepCopy var driver = FILE_CONTROLER.getDriver( this ), data; - if( typeof driver.read === 'function'){ + if( Type.isFunction( driver.read ) === true ){ data = driver.read( this ); - } + }; return BASE_DRIVER.read( data || this ); }, write: function( _newData, _onUpdateFunction ){ @@ -1272,36 +1272,46 @@ var File = ( function(){ // debug用 全てのメニューを許可 return Const.FILE.UPDATE_POLICY.DSRWC; }; - this.read = function( _FILEorDATA ){ + this.read = function( FILEorDATA ){ var data, - protects = Const.FILE.DATA_PROPERTY_RESERVED; - if( _FILEorDATA instanceof FileClass ){ - data = FILE_CONTROLER.getFileData( _FILEorDATA ) + protects = Const.FILE.DATA_PROPERTY_RESERVED, + objSrc = [], + objCopy = [], + getIndex = Util.getIndex; + if( FILEorDATA instanceof FileClass ){ + data = FILE_CONTROLER.getFileData( FILEorDATA ) } else { - data = _FILEorDATA; - } - + data = FILEorDATA; + }; + function clone( src ) { - var ret; - if( Type.isArray(src) === true ){ + var ret, i, key; + if( Type.isArray( src ) === true ){ + i = getIndex( objSrc, src ); + if( i !== -1 ) return objCopy[ i ]; ret = []; + objSrc[ objSrc.length ] = src; + objCopy[ objCopy.length ] = ret; } else - if( Type.isObject(src) === true ){ + if( Type.isObject( src ) === true ){ + i = getIndex( objSrc, src ); + if( i !== -1 ) return objCopy[ i ]; ret = {}; + objSrc[ objSrc.length ] = src; + objCopy[ objCopy.length ] = ret; } else - if( Type.isNumber(src) === true || Type.isString(src) === true || Type.isBoolean( src ) === true ){ + if( Type.isNumber( src ) === true || Type.isString( src ) === true || Type.isBoolean( src ) === true ){ return src; } else { - return null; - } - for( var key in src ){ - if( Util.getIndex( protects, key ) === -1 ){ + return src; + }; + for( key in src ){ + if( getIndex( protects, key ) === -1 ){ ret[ key ] = clone( src[ key ]); - } - } + }; + }; return ret; - }; - + }; return clone( data ); }; this.write = function( _file, _newData, _onUpdateFunction ){ @@ -6322,4 +6332,1411 @@ var DHTML = ( function(){ gOS.registerApplication = Application.register; gOS.registerDriver = File.registerDriver; +var BoxModel + +var DOM = ( function( window, document ){ + var DIV_LIST = [], + SPAN_LIST = [], + TEXT_LIST = []; + + var elmTextSize; + + function correctNodes( node ){ + var child; + if( node && node.parentNode ){ + while( node.lastChild ) correctNodes( node.lastChild ); + node.parentNode.removeChild( node ); + if( node.nodeType === 1 ){ + switch( node.tagName ){ + case 'DIV': + DIV_LIST.push( node ); + break; + case 'SPAN': + SPAN_LIST.push( node ); + break; + + }; + node.removeAttribute( 'className' ); + node.removeAttribute( 'style' ); + node.removeAttribute( 'id' ); + } else + if( node.nodeType === 3 ){ + node.data = ''; + TEXT_LIST.push( node ); + }; + }; + }; + + return { + createDiv : function(){ + return 0 < DIV_LIST.length ? DIV_LIST.shift() : document.createElement( 'div' ); + }, + createSpan : function(){ + + }, + createText : function(){ + + }, + getTextSize : function( elm, content ){ + var span = DOM.createSpan(), + text = DOM.createText(), + w, h; + elm.appendChild( span ); + span.style.cssText = 'visibility:hidden;position:absolute;'; + span.appendChild( text ); + text.data = content; + w = span.offsetWidth; + h = span.offsetHeight; + DOM.correctNodes( span ); + return [ w, h ]; + }, + correctNodes : function( node ){ + var child; + if( node && node.parentNode ){ + while( node.lastChild ) DOM.correctNodes( node.lastChild ); + node.parentNode.removeChild( node ); + if( node.nodeType === 1 ){ + switch( node.tagName ){ + case 'DIV': + DIV_LIST.push( node ); + break; + case 'SPAN': + SPAN_LIST.push( node ); + break; + + }; + node.removeAttribute( 'className' ); + node.removeAttribute( 'style' ); + node.removeAttribute( 'id' ); + } else + if( node.nodeType === 3 ){ + node.data = ''; + TEXT_LIST.push( node ); + }; + }; + } + } +})( window, document ); + +var XBrowserStyle = ( function(){ + var EMPTY = '', + CORON = ':', + SEMICORON = ';', + SPACE = ' ', + UNITS = 'px,cm,mm,in,pt,pc,em,%'.split( ',' ), + CLIP_SEPARATOR = UA.isIE === true && UA.ieVersion < 8 ? ' ' : ','; + + var SPECIAL = ( function(){ + var special = {}; + if( UA.isIE === true && UA.ieVersion < 9 ){ + if( UA.ACTIVEX === true ){ + // special.opacity = 'ActiveXOpacity'; + special.setFilters = function( style ){ + var filters = ( style.filter || '' ).split( ') ' ), + data = {}, + i = filters.length, + filter, names, props, prop, j, l, key, v; + for( ; i; ){ + filter = filters[ --i ].split( ' ' ).join( '' ).split( '(' ); + if( filter.length !== 2 ) continue; + names = filter[ 0 ].split( '.' ); // progid:DXImageTransform.Microsoft.Shadow(color=#666666,direction=120,strength=9) + props = filter[ 1 ].split( ',' ); // + filter = {}; + for( j = 0, l = props.length; j < l; ++j ){ + prop = props[ j ].split( '=' ); + key = prop[ 0 ].toLowerCase(); + v = prop[ 1 ]; + filter[ key ] = v; //v.charAt( 0 ) === '#' ? v : parseInt( v ); + }; + data[ names[ names.length - 1 ] ] = filter; + }; + + style.filter = data; + style.opacity = data.alpha && data.alpha.opacity ? data.alpha.opacity / 100 : 1; + }; + special.hasLayout = function( elm ){ + return elm.currentStyle.hasLayout; + }; + } else { + special.opacity = null; + }; + } else { + var style = document.documentElement.style; + special.opacity = style.opacity !== undefined ? 'opacity' : + style.MozOpacity !== undefined ? 'MozOpacity' : + style.KhtmlOpacity !== undefined ? 'KhtmlOpacity' : + style[ '-khtml-opacity' ] !== undefined ? 'KhtmlOpacity' : null; + + // if( style.backgroundPositionX === undefined ){ + special.setBackgroundPositionXY = function( style ){ + var bgp = ( style.backgroundPosition || '' ).split( ' ' ); + style.backgroundPositionX = bgp[ 0 ] || 0; + style.backgroundPositionY = bgp[ 1 ] || 0; + }; + // }; + if( style.clipTop === undefined && style[ 'clip-top' ] === undefined ){ + special.setClipTopRightBottomLeft = function( style ){ + var clip = style.clip; + if( !cliop || clip.indexOf( 'rect(' ) === -1 ){ + style.clipTop = 0; + style.clipRight = 0; + style.clipBottom = 0; + style.clipLeft = 0; + return; + }; + clip = clip.split( '(' )[ 1 ].split( ')' )[ 0 ].split( clip.indexOf( ',' ) !== -1 ? ',' : ' ' ); + ret.clipTop = clip[ 0 ]; + ret.clipRight = clip[ 1 ]; + ret.clipBottom = clip[ 2 ]; + ret.clipLeft = clip[ 3 ]; + }; + }; + }; + return special; + })(); + + function cssToObject( css ){ + var ret = {}, i, nv, n, v, + parse = Util.parse, + isNumber = Type.isNumber, + camelize = Util.camelize; + if( Type.isString( css ) === true ){ + css = css.split( SEMICORON ); + for( i = css.length; i; ){ + nv = css[ --i ].split( CORON ); // filter の場合, progid: がくる + n = nv.shift(); + if( isNumber( parse( n ) ) === true ) continue; + v = nv.join( EMPTY ); + while( v.charAt( 0 ) === ' ' ) v = v.substr( 1 ); + ret[ camelize( n ) ] = parse( v ); + }; + } else { + for( n in css ){ + if( Type.isNumber( parse( n ) ) === false ) ret[ n ] = parse( css[ n ] ); + }; + }; + + if( SPECIAL.setFilters ){ + SPECIAL.setFilters( ret ); + } else { + ret.opacity = SPECIAL.opacity !== null ? ret[ SPECIAL.opacity ] : 1; + }; + + SPECIAL.setBackgroundPositionXY && SPECIAL.setBackgroundPositionXY( ret ); + SPECIAL.setClipTopRightBottomLeft && SPECIAL.setClipTopRightBottomLeft( ret ); + + return ret; + }; + + var COLOR = ( function(){ + var ret = {}, v, name, + list = [ + '0', 'BLACK', + 'FF0000', 'RED', + '00FF00', 'LIME', + '0000FF', 'BLUE', + 'FFFF00', 'YELLOW', + '00FFFF', 'AQUA', + '00FFFF', 'CYAN', + 'FF00FF', 'MAGENTA', + 'FF00FF', 'FUCHSIA', + 'FFFFFF', 'WHITE', + '008000', 'GREEN', + '800080', 'PURPLE', + '800000', 'MAROON', + '000080', 'NAVY', + '808000', 'OLIVE', + '008080', 'TEAL', + '808080', 'GRAY', + 'C0C0C0', 'SILVER', + '696969', 'DIMGRAY', + '708090', 'SLATEGRAY', + 'A9A9A9', 'DARKGRAY', + 'DCDCDC', 'GAINSBORO', + '191970', 'MIDNIGHTBLUE', + '6A5ACD', 'SLATEBLUE', + '0000CD', 'MEDIUMBLUE', + '4169E1', 'ROYALBLUE', + '1E90FF', 'DODGERBLUE', + '87CEEB', 'SKYBLUE', + '4682B4', 'STEELBLUE', + 'ADD8E6', 'LIGHTBLUE', + 'AFEEEE', 'PALETURQUOISE', + '40E0D0', 'TURQUOISE', + 'E0FFFF', 'LIGHTCYAN', + '7FFFD4', 'AQUAMARINE', + '006400', 'DARKGREEN', + '2E8B57', 'SEAGREEN', + '90EE90', 'LIGHTGREEN', + '7FFF00', 'CHARTREUSE', + 'ADFF2F', 'GREENYELLOW', + '32CD32', 'LIMEGREEN', + '9ACD32', 'YELLOWGREEN', + '6B8E23', 'OLIVEDRAB', + 'BCB76B', 'DARKKHAKI', + 'EEE8AA', 'PALEGOLDENROD', + 'FFFFE0', 'LIGHTYELLOW', + 'FFD700', 'GOLD', + 'DAA520', 'GOLDENROD', + 'B8860B', 'DARKGOLDENROD', + 'BC8F8F', 'ROSYBROWN', + 'CD5C5C', 'INDIANRED', + '8B4513', 'SADDLEBROWN', + 'A0522D', 'SIENNA', + 'CD853F', 'PERU', + 'DEB887', 'BURLYWOOD', + 'F5F5DC', 'BEIGE', + 'F5DEB3', 'WHEAT', + 'F4A460', 'SANDYBROWN', + 'D2B48C', 'TAN', + 'D2691E', 'CHOCOLATE', + 'B22222', 'FIREBRICK', + 'A52A2A', 'BROWN', + 'FA8072', 'SALMON', + 'FFA500', 'ORANGE', + 'FF7F50', 'CORAL', + 'FF6347', 'TOMATO', + 'FF69B4', 'HOTPINK', + 'FFC0CB', 'PINK', + 'FF1493', 'DEEPPINK', + 'DB7093', 'PALEVIOLETRED', + 'EE82EE', 'VIOLET', + 'DDA0DD', 'PLUM', + 'DA70D6', 'ORCHILD', + '9400D3', 'DARKVIOLET', + '8A2BE2', 'BLUEVIOLET', + '9370DB', 'MEDIUMPURPLE', + 'D8BFD8', 'THISTLE', + 'E6E6FA', 'LAVENDER', + 'FFE4E1', 'MISTYROSE', + 'FFFFF0', 'IVORY', + 'FFFACD', 'LEMONCHIFFON' + ]; + for( i = list.length; i; ){ + v = list[ --i ]; + name = list[ --i ]; + ret[ name ] = parseInt( v, 16 ); + }; + return ret; + })(); + + var PARAMS = ( function(){ + var ret = {}; + register( ret.percent = {}, + 'marginBottom,marginLeft,marginRight,marginTop,paddingBottom,paddingLeft,paddingRight,paddingTop,fontSize,textIndent' + ); + register( ret.offset = {}, + 'height,width,bottom,left,right,top' + ); + register( ret.size = {}, + 'borderBottomWidth,borderLeftWidth,borderRightWidth,borderTopWidth,letterSpacing' + ); + register( ret.color = {}, + 'backgroundColor,borderBottomColor,borderLeftColor,borderRightColor,borderTopColor,color' + ); + register( ret.region = {}, + 'margin,padding,borderWidth,borderColor' + ); + register( ret.special = {}, + 'clip,backgroundPosition,opacity,lineHeight,zIndex' + ); + register( ret.unit = {}, 'px,cm,mm,in,pt,pc,em,%' ); + + register( ret.margin = {}, 'marginBottom,marginLeft,marginRight,marginTop,paddingBottom' ); + register( ret.padding = {}, 'paddingBottom,paddingLeft,paddingRight,paddingTop' ); + register( ret.borderWidth = {}, 'borderBottomWidth,borderLeftWidth,borderRightWidth,borderTopWidth' ); + register( ret.borderColor = {}, 'borderBottomColor,borderLeftColor,borderRightColor,borderTopColor' ); + + function register( obj, params ){ + params = params.split( ',' ); + for( var i=params.length; i; ) obj[ params[ --i ] ] = true; + }; + return ret; + })(); + + /* + * + */ + var Property = Class.create( + 'Property', + Class.POOL_OBJECT, + { + Constructor : function( name, value, unit, pxPerEm ){ + this.name = name; + this.value = value; + this.unit = unit; + this.pxPerEm = pxPerEm; // XXpx = 1em; + }, + name : '', + value : 0, + pxPerEm : 12, // 1em === ??px + unit : '', + equal : function( prop ){ + if( this.unit === prop.unit ){ + return this.value === prop.value; + }; + return Math.abs( this.toPx() - prop.toPx() ) < 1; + }, + convert: function( prop ){ + var u = prop.unit, v; + if( this.unit === u ) return; + this.value = v = this.toPx(); + this.unit = u; + if( u !== px ){ + this.value = u === 'em' ? v / this.pxPerEm : Util.pxTo( v, u ); + }; + }, + setValue: function( v ){ + this.value = v; + }, + getValue: function(){ + return this.value; + }, + getOffset: function( prop ){ + return prop.value - this.value; + }, + getUnit: function(){ + return this.unit; + }, + getValueText: function(){ + return this.value === 0 ? '0' : this.value + this.unit; + }, + toPx: function(){ + var v = this.value, u = this.unit; + if( u === px ) return v; + if( u === 'em' ) return v * this.pxPerEm; + if( u === '' && this.name === 'lineHeight' ) return v * this.pxPerEm; + return Util.toPx( v, u ); + }, + isValid: function( t ){ + t = t || this; + var n = t.name, + v = t.value, + u = t.unit, + z = u !== '' ? true : v === 0; + if( PARAMS.percent[ n ] === true ) return z; + if( PARAMS.offset[ n ] === true ) return z; + if( PARAMS.size[ n ] === true ) return z && u !== '%'; + if( PARAMS.special[ n ] === true ){ + if( n === 'lineHeight' ) return true; + if( n === 'opacity' ) return 0 <= v && v <= 1 && u === ''; + if( n === 'zIndex' ) return u === ''; + }; + return false; + } + } + ); + + /** + * backgroundPosition, clip + */ + var PropertyGroup = Class.create( + 'PropertyGroup', + Class.POOL_OBJECT, + { + Constructor : function( name ){ + this.name = name; + this.props = []; + for( var i = 1, l = arguments.length; i 1 ) return false; + }; + return true; + }, + convert : function( prop ){ + var u = prop.pct, x; + if( this.pct === u ) return; + x = u === true ? 100 / 255 : 2.55; + this.r *= x; + this.g *= x; + this.b *= x; + this.pct = u; + }, + setValue : function( rgb ){ + this.r = rgb[ 0 ]; + this.g = rgb[ 1 ]; + this.b = rgb[ 2 ]; + }, + getValue : function(){ + return [ this.r, this.g, this.b ]; + }, + getOffset : function( prop ){ + return [ prop.r - this.r, prop.g - this.g, prop.b - this.b ]; + }, + getUnit : function(){ + return this.pct === true ? '%' : ''; + }, + getValueText : function(){ + if( this.pct === true ){ + return [ 'rgb(', this.r, '%,', this.g, '%,', this.b, '%)' ].join( '' ); + }; + var round = Math.round; + //return [ 'rgb(', round( this.r ), ',', round( this.g ), ',', round( this.b ), ')' ].join( '' ); + + var rgb = '00000' + ( ( round( this.r ) << 16 ) + ( round( this.g ) << 8 ) + round( this.b ) ).toString( 16 ); + return '#' + rgb.substr( rgb.length - 6 ); + }, + _toPct : function(){ + if( this.pct === true ) return [ this.r, this.g, this.b ]; + return [ this.r / 2.55, this.g / 2.55, this.b / 2.55 ]; + }, + isValid : function( t ){ + var isFinite = window.isFinite; + if( !isFinite( this.r ) || !isFinite( this.g ) || !isFinite( this.b ) ) return false; + if( 0 > this.r || 0 > this.g || 0 > this.b ) return false; + if( this.pct === true ) return this.r <= 100 && this.g <= 100 && this.b <= 100; + return this.r <= 255 && this.g <= 255 && this.b <= 255; + } + } + ); + + var isString = Type.isString, + isNumber = Type.isNumber; + var REG_UINIT = /.*\d(\w{1,2})?/, + $1 = '$1', + px = 'px', + REG_XXXXXX = /^#[\da-fA-F]{6}?/, + REG_XXX = /^#[\da-fA-F]{3}?/; + + var WrappedStyle = Class.create( + 'WrappedStyle', + Class.POOL_OBJECT, + { + Constructor : function( style ){ + this.style = style; + var fontsize = this.get( 'fontSize' ); + this.pxPerEm = fontsize.toPx(); + fonstsize.kill(); + }, + get: function( p ){ + if( PARAMS.special[ p ] === true || PARAMS.region[ p ] === true ){ + if( p === 'clip' ) return this.getClip(); + if( p === 'margin' ) return this.getMarginPaddingBorder( p, '' ); + if( p === 'padding' ) return this.getMarginPaddingBorder( p, '' ); + if( p === 'borderWidth' ) return this.getMarginPaddingBorder( 'border', 'Width' ); + if( p === 'borderColor' ) return this.getBorderColor( 'borderColor' ); + if( p === 'backgroundPosition' ) return this.getBackgroundPosition( p ); + // opacity, zindex, lineHeight + return new Property( p, this.getValue( x ), this.getUnit( x ), this.pxPerEm ); + }; + var x = this.style[ p ], e, v, u; + if( PARAMS.offset[ p ] === true ){ + return new Property( p, this.getValue( x ), this.getUnit( x, p ), this.pxPerEm ); + /* + e = this.elm; + if( p === 'width' ) v = e.offsetWidth; + if( p === 'height' ) v = e.offsetHeight; + if( p === 'top' ) v = e.offsetTop; + if( p === 'bottom' ) v = e.offsetBottom; + if( p === 'left' ) v = e.offsetLeft; + if( p === 'right' ) v = e.offsetRight; + u = this.getUnit( x, p ); + // alert( p + this.pxTo( v, u ) + u ) + return new Property( p, this.pxTo( v, u ), u, this.pxPerEm ); */ + }; + if( p === 'fontSize' ){ // xx-small 等 + v = Util.absoluteFontSizeToPx( x ); + if( v !== 0 ){ + return new Property( p, v, px, this.pxPerEm ); + }; + }; + if( PARAMS.percent[ p ] === true ){ + // alert( p + ' , ' + x + ' , ' + this.getUnit( x, p ) ) + return new Property( p, this.getValue( x ), this.getUnit( x, p ), this.pxPerEm ); + }; + if( PARAMS.size[ p ] === true ){ + return new Property( p, this.getValue( x ), this.getUnit( x, p ), this.pxPerEm ); + }; + if( PARAMS.color[ p ] === true ){ + return this.getColor( x, p ); + }; + }, + pxTo: function( px, unit ){ + if( unit === 'em' ) return px / this.pxPerEm; + return Util.pxTo( px, unit ); + }, + getValue: function( x ){ + return isString( x ) === true ? parseInt( x ) : + isNumber( x ) === true ? x : 0; + }, + getUnit: function( x, p ){ + var u; + if( isString( x ) === true ){ + u = x.replace( REG_UINIT, $1 ); + if( p === 'lineHeight' ) return u; + if( PARAMS.unit[ u ] !== true ) return px; + return u; + }; + return px; + }, + getColor: function( x, p ){ + var rgb = COLOR[ x.toUpperCase() ], + pct = false, + r = 0, + g = 0, + b = 0; + if( isNumber( rgb ) === true ){ + r = ( rgb & 0xff0000 ) >> 16; + g = ( rgb & 0xff00 ) >> 8; + b = ( rgb & 0xff ); + } else + if( x.match( REG_XXXXXX ) ){ + r = parseInt( x.charAt( 1 ) + x.charAt( 2 ), 16 ); + g = parseInt( x.charAt( 3 ) + x.charAt( 4 ), 16 ); + b = parseInt( x.charAt( 5 ) + x.charAt( 6 ), 16 ); + //alert( x + ' g: ' + g ) + } else + if( x.match( REG_XXX ) ){ + r = parseInt( x.charAt( 1 ) + x.charAt( 1 ), 16 ); + g = parseInt( x.charAt( 2 ) + x.charAt( 2 ), 16 ); + b = parseInt( x.charAt( 3 ) + x.charAt( 3 ), 16 ); + } else + if( x.indexOf( 'rgb(' ) === 0 ){ + rgb = x.substr( 4 ).split( ',' ); + r = parseFloat( rgb[ 0 ] ); + g = parseFloat( rgb[ 1 ] ); + b = parseFloat( rgb[ 2 ] ); + if( x.indexOf( '%' ) !== -1 ) pct = true; + } else { + r = 255; + g = 255; + b = 255; + }; + return new ColorProperty( p, r, g, b, pct ); + }, + getClip: function( name ){ + // rect(...) クリップします。, は上端からの、 , は左端からのオフセットで指定します。Internet Explorer 4~7 では、カンマの代わりにスペースで区切る必要があります。 + // position:absolute または position:fixed を適用した要素に対してのみ有効です。 + var top = this.get( name + 'Top' ), + right = this.get( name + 'Right' ), + bottom = this.get( name + 'Bottom' ), + left = this.get( name + 'Left' ), + ret = new PropertyGroup( name, top, right, bottom, left ); + if( ret.isValid() === true ) return ret; + ret.kill(); + all = this.style[ name ].split( '(' )[ 1 ].split( ')' )[ 0 ].split( CLIP_SEPARATOR ); + return new PropertyGroup( name, + new Property( name + 'Top', all[ 0 ], px, this.pxPerEm ), + new Property( name + 'Right', all[ 1 ], px, this.pxPerEm ), + new Property( name + 'Bottom', all[ 2 ], px, this.pxPerEm ), + new Property( name + 'Left', all[ 3 ], px, this.pxPerEm ) + ); + }, + getBackgroundPosition: function( name ){ + var x = this.get( name + 'X' ), + y = this.get( name + 'Y' ), + ret = new PropertyGroup( name, x, y ), + xy; + if( ret.isValid() === true ) return ret; + ret.kill(); + xy = this.style[ name ].split( ' ' ); + return new PropertyGroup( name, + new Property( name + 'X', this.getValue( xy[ 0 ] ), this.getUnit( xy[ 0 ] ), this.pxPerEm ), + new Property( name + 'Y', this.getValue( xy[ 1 ] ), this.getUnit( xy[ 1 ] ), this.pxPerEm ) + ); + }, + getMarginPaddingBorder: function( name, width ){ + var props = [ name + 'Top' + width, + name + 'Right' + width, + name + 'Bottom' + width, + name + 'Left' + width ], + top = this.get( props[ 0 ] ), + right = this.get( props[ 1 ] ), + bottom = this.get( props[ 2 ] ), + left = this.get( props[ 3 ] ), + ret = new FrexibleProperty( name, top, right, bottom, left ), + klass, pxPerEm, getValue, getUnit, + all, _0, _1, _2, _3, v, u; + if( ret.isValid() === true ) return ret; + ret.kill(); + klass = Property; + pxPerEm = this.pxPerEm; + getValue = this.getValue; + getUnit = this.getUnit; + all = this.style[ name + width ].split( ' ' ); + _0 = all[ 0 ]; + _1 = all[ 1 ]; + _2 = all[ 2 ]; + _3 = all[ 3 ]; + v = getValue( _0 ); + u = getUnit( _0 ); + switch( all.length ){ + case 1 : + top = new klass( props[ 0 ], v, u, pxPerEm ); + right = new klass( props[ 1 ], v, u, pxPerEm ); + bottom = new klass( props[ 2 ], v, u, pxPerEm ); + left = new klass( props[ 3 ], v, u, pxPerEm ); + break; + case 2 : + top = new klass( props[ 0 ], v, u, pxPerEm ); + bottom = new klass( props[ 2 ], v, u, pxPerEm ); + v = getValue( _1 ); + u = getUnit( _1 ); + right = new klass( props[ 1 ], v, u, pxPerEm ); + left = new klass( props[ 3 ], v, u, pxPerEm ); + break; + case 3 : + top = new klass( props[ 0 ], v, u, pxPerEm ); + v = getValue( _1 ); + u = getUnit( _1 ); + right = new klass( props[ 1 ], v, u, pxPerEm ); + left = new klass( props[ 3 ], v, u, pxPerEm ); + bottom = new klass( props[ 2 ], getValue( _2 ), getUnit( _2 ), pxPerEm ); + break; + case 4 : + top = new klass( props[ 0 ], v, u, pxPerEm ); + right = new klass( props[ 1 ], getValue( _1 ), getUnit( _1 ), pxPerEm ); + bottom = new klass( props[ 2 ], getValue( _2 ), getUnit( _2 ), pxPerEm ); + left = new klass( props[ 3 ], getValue( _3 ), getUnit( _3 ), pxPerEm ); + break; + }; + return new FrexibleProperty( name, top, right, bottom, left ); + }, + getBorderColor: function( name ){ + var props = 'borderTopColor,borderRightColor,borderBottomColor,borderLeftColor'.split( ',' ), + top = this.get( props[ 0 ] ), + right = this.get( props[ 1 ] ), + bottom = this.get( props[ 2 ] ), + left = this.get( props[ 3 ] ), + ret = new FrexibleProperty( name, top, right, bottom, left ), + all, _0, _1, getColor; + if( ret.isValid() === true ) return ret; + ret.kill(); + getColor = this.getColor; + all = this.style[ name ].split( ' ' ); + _0 = all[ 0 ]; + _1 = all[ 1 ]; + switch( all.length ){ + case 1 : + top = getColor( _0, props[ 0 ] ); + right = getColor( _0, props[ 1 ] ); + bottom = getColor( _0, props[ 2 ] ); + left = getColor( _0, props[ 3 ] ); + break; + case 2 : + top = getColor( _0, props[ 0 ] ); + right = getColor( _1, props[ 1 ] ); + bottom = getColor( _0, props[ 2 ] ); + left = getColor( _1, props[ 3 ] ); + break; + case 3 : + top = getColor( _0, props[ 0 ] ); + right = getColor( _1, props[ 1 ] ); + bottom = getColor( all[ 2 ], props[ 2 ] ); + left = getColor( _1, props[ 3 ] ); + break; + case 4 : + top = getColor( _0, props[ 0 ] ); + right = getColor( _1, props[ 1 ] ); + bottom = getColor( all[ 2 ], props[ 2 ] ); + left = getColor( all[ 3 ], props[ 3 ] ); + break; + }; + return new FrexibleProperty( name, top, right, bottom, left ); + } + } + ); + function camelizeHash( obj ){ + var p, _p, came = Util.camelize; + for( p in obj ){ + _p = came( p ); + if( _p === p ) continue; + obj[ _p ] = obj[ _p ] || obj[ p ]; + delete obj[ p ]; + }; + }; + return { + create: function( css ){ + return new WrappedStyle( camelizeHash( p ) ); + } + }; +})(); + +var XDocument = ( function( window, document ){ + + var getIndex = Util.getIndex; + + var DEF_ATTRS = []; + + var AbstractLayoutManager = Class.create( + 'AbstractLayoutManager', + Class.ABSTRACT, { + reflow : function(){} + } + ); + + var BasicLayoutManager = AbstractLayoutManager.inherits( + 'BasicLayoutManager', + { + Constructor : function(){ + + } + } + ); + + var AbstractStylePrivate = Class.create( + Class.ABSTRACT | Class.PRIVATE_DATA, + { + register : function( node ){ + var list = this.nodeList; + if( !list ){ + this.nodeList = [ node ]; + return; + }; + if( getIndex( list, node ) === -1 ) list[ list.length ] = node; + }, + unRegister : function( node ){ + var list = this.nodeList, + i = getIndex( list, node ); + if( i !== -1 && list.splice( i, 1 ) && list.length === 0 ) delete this.nodeList; + }, + clone : function(){ + var styleClass = Class.getClass( this.User ), + dataClass = Class.getClass( this ); + }, + attr : function( prop, v ){ + var update = prop[ 0 ], + propID = prop[ 1 ], + type = prop[ 2 ], + list = prop[ 3 ], + length = !!( type & DEF_ATTRS.LENGTH ), + percent = !!( type & DEF_ATTRS.PERCENT ), + color = !!( type & DEF_ATTRS.COLOR ), + uDecimal = !!( type & DEF_ATTRS.U_DECIMAL ), + numerical = !!( type & DEF_ATTRS.NUMERICAL ), + flag = !!( type & DEF_ATTRS.BOOLEAN ), + quartet = !!( type & DEF_ATTRS.QUARTET ), + url = !!( type & DEF_ATTRS.URL ), + fontName = !!( type & DEF_ATTRS.FONT_NAME ), + list = !!( type & DEF_ATTRS.LIST ), + combi = !!( type & DEF_ATTRS.COMBI ), + data = this.data, + _v = -1, + _type, i, l, nodes; + + if( v !== undefined ){ + if( Type.isNumber( v ) === true ){ + if( numerical === false ){ + if( uDecimal === false || v < 0 || 1 < v ) throw new Error( '' ); + }; + } else + if( Type.isBoolean( v ) === true ){ + if( flag === false ) throw new Error( '' ); + } else + if( Type.isString( v ) === true ){ + if( url === false && fontName === false ){ + if( v.indexOf( ' ' ) !== -1 ){ + v = v.split( ' ' ); + } else { + if( length === false && percent === false && color === false ) throw new Error( '' ); + }; + }; + }; + if( Type.isArray( v ) === true ){ + if( v.length <= 4 && quartet === true ){ + _type = type ^ DEF_ATTRS.QUARTET; + } else + if( v.length === 2 && combi === true ){ + _type = type ^ DEF_ATTRS.COMBI; + } else { + throw new Error( '' ); + }; + switch( v.length ){ + case 1 : + this.attr( [ propID , _type, list ], v[ 0 ] ); + this.attr( [ ++propID, _type, list ], v[ 0 ] ); + this.attr( [ ++propID, _type, list ], v[ 0 ] ); + this.attr( [ ++propID, _type, list ], v[ 0 ] ); + break; + case 2 : + this.attr( [ propID , _type, list ], v[ 0 ] ); + this.attr( [ ++propID, _type, list ], v[ 1 ] ); + this.attr( [ ++propID, _type, list ], v[ 0 ] ); + this.attr( [ ++propID, _type, list ], v[ 1 ] ); + break; + case 3 : + this.attr( [ propID , _type, list ], v[ 0 ] ); + this.attr( [ ++propID, _type, list ], v[ 1 ] ); + this.attr( [ ++propID, _type, list ], v[ 2 ] ); + this.attr( [ ++propID, _type, list ], v[ 1 ] ); + break; + case 4 : + this.attr( [ propID , _type, list ], v[ 0 ] ); + this.attr( [ ++propID, _type, list ], v[ 1 ] ); + this.attr( [ ++propID, _type, list ], v[ 2 ] ); + this.attr( [ ++propID, _type, list ], v[ 3 ] ); + break; + default : + }; + return this.User; + }; + if( this.invalidateLayout < update ) this.invalidate = update; + + if( list ) _v = Util.getIndex( list, v ); + data[ propID ] = _v !== -1 ? _v : v; + return this.User; + }; + if( this.invalidate === DEF_ATTRS.REFLOW ){ + nodes = this.nodeList; + if( nodes ){ + for( i = 0, l = nodes.length; i < l; ++i ){ + nodes[ i ].reflow(); + }; + }; + }; + v = data[ propID ]; + if( quartet === true ) return [ v, data[ ++propID ], data[ ++propID ], data[ ++propID ] ]; + if( combi === true ) return [ v, data[ ++propID ] ]; + if( list && Type.isNumber( v ) === true ) return list[ v ]; + return v; + } + } + ); + + var PaintPrivate = AbstractStylePrivate.inherits( + 'PaintPrivate', + Class.PRIVATE_DATA | Class.POOL_OBJECT, + { + Constructor : function(){ + this.data = []; + this.invalidate = 0; + }, + cssText : function(){ + + }, + cssObject : function(){ + + }, + paint : function( node ){ + + } + } + ); + + var PaintStyle = Class.create( + 'PaintStyle', + Class.POOL_OBJECT, + PaintPrivate, + { + Constructor : function(){ + PaintStyle.newPrivateData( this ); + }, + borderWidth : function( v ){ + return PaintStyle.getPrivateData( this ).attr( PaintPrivate.borderWidth, v ); + }, + borderColor : function(){ + return PaintStyle.getPrivateData( this ).attr( PaintPrivate.borderColor, v ); + }, + borderStyle : function(){ + return PaintStyle.getPrivateData( this ).attr( PaintPrivate.borderStyle, v ); + }, + cornerRadius : function(){ + return PaintStyle.getPrivateData( this ).attr( PaintPrivate.cornerRadius, v ); + }, + bgColor : function(){ + return PaintStyle.getPrivateData( this ).attr( PaintPrivate.bgColor, v ); + }, + bgAlpha : function(){ + return PaintStyle.getPrivateData( this ).attr( PaintPrivate.bgAlpha, v ); + }, + bgImgUrl : function(){ + return PaintStyle.getPrivateData( this ).attr( PaintPrivate.bgImgUrl, v ); + }, + bgImgRepeatX : function(){ + return PaintStyle.getPrivateData( this ).attr( PaintPrivate.bgImgRepeatX, v ); + }, + bgImgRepeatY : function(){ + return PaintStyle.getPrivateData( this ).attr( PaintPrivate.bgImgRepeatY, v ); + }, + bgImgPositionX : function(){ + return PaintStyle.getPrivateData( this ).attr( PaintPrivate.bgImgPositionX, v ); + }, + bgImgPositionY : function(){ + return PaintStyle.getPrivateData( this ).attr( PaintPrivate.bgImgPositionY, v ); + }, + shadowColor : function(){ + return PaintStyle.getPrivateData( this ).attr( PaintPrivate.shadowColor, v ); + }, + shadowAlpha : function(){ + return PaintStyle.getPrivateData( this ).attr( PaintPrivate.shadowAlpha, v ); + }, + shadowOffsetX : function(){ + return PaintStyle.getPrivateData( this ).attr( PaintPrivate.shadowOffsetX, v ); + }, + shadowOffsetY : function(){ + return PaintStyle.getPrivateData( this ).attr( PaintPrivate.shadowOffsetY, v ); + }, + shadowBlur : function(){ + return PaintStyle.getPrivateData( this ).attr( PaintPrivate.shadowBlur, v ); + }, + shadowSpread : function(){ + return PaintStyle.getPrivateData( this ).attr( PaintPrivate.shadowSpread, v ); + }, + shadowInset : function(){ + return PaintStyle.getPrivateData( this ).attr( PaintPrivate.shadowInset, v ); + } + } + ); + + var TypoPrivate = AbstractStylePrivate.inherits( + 'TypoPrivate', + Class.PRIVATE_DATA | Class.POOL_OBJECT, + { + Constructor : function(){ + this.data = []; + this.invalidate = 0; + }, + cssText : function(){ + + }, + cssObject : function(){ + + } + } + ); + + var TypoStyle = Class.create( + 'TypoStyle', + Class.POOL_OBJECT, + TypoPrivate, + { + Constructor : function( v ){ + TypoStyle.newPrivateData( this ); + }, + color : function( v ){ + return TypoStyle.getPrivateData( this ).attr( TypoPrivate.color, v ); + }, + fontFamily : function( v ){ + return TypoStyle.getPrivateData( this ).attr( TypoPrivate.fontFamily, v ); + }, + fontSize : function( v ){ + return TypoStyle.getPrivateData( this ).attr( TypoPrivate.fontSize, v ); + }, + bold : function( v ){ + return TypoStyle.getPrivateData( this ).attr( TypoPrivate.bold, v ); + }, + italic : function( v ){ + return TypoStyle.getPrivateData( this ).attr( TypoPrivate.italic, v ); + }, + lineHeight : function( v ){ + return TypoStyle.getPrivateData( this ).attr( TypoPrivate.lineHeight, v ); + }, + letterSpacing : function( v ){ + return TypoStyle.getPrivateData( this ).attr( TypoPrivate.letterSpacing, v ); + }, + wordSpacing : function( v ){ + return TypoStyle.getPrivateData( this ).attr( TypoPrivate.wordSpacing, v ); + }, + align : function( v ){ + return TypoStyle.getPrivateData( this ).attr( TypoPrivate.align, v ); + }, + decoration : function( v ){ + return TypoStyle.getPrivateData( this ).attr( TypoPrivate.decoration, v ); + }, + transform : function( v ){ + return TypoStyle.getPrivateData( this ).attr( TypoPrivate.transform, v ); + }, + shadowColor : function( v ){ + return TypoStyle.getPrivateData( this ).attr( TypoPrivate.shadowColor, v ); + }, + shadowOffsetX : function( v ){ + return TypoStyle.getPrivateData( this ).attr( TypoPrivate.shadowOffsetX, v ); + }, + shadowOffsetY : function( v ){ + return TypoStyle.getPrivateData( this ).attr( TypoPrivate.shadowOffsetY, v ); + }, + shadowBlur : function( v ){ + return TypoStyle.getPrivateData( this ).attr( TypoPrivate.shadowBlur, v ); + } + } + ); + + var LayoutPrivate = AbstractStylePrivate.inherits( + 'LayoutPrivate', + Class.PRIVATE_DATA | Class.POOL_OBJECT, + { + Constructor : function(){ + this.data = []; + this.invalidate = 0; + }, + cssText : function(){ + + }, + cssObject : function(){ + + } + } + ); + + DEF_ATTRS.LENGTH = 1; + DEF_ATTRS.PERCENT = 2; + DEF_ATTRS.COLOR = 4; + DEF_ATTRS.U_DECIMAL = 8; + DEF_ATTRS.NUMERICAL = 16; + DEF_ATTRS.BOOLEAN = 32; + DEF_ATTRS.QUARTET = 64; + DEF_ATTRS.URL = 128; + DEF_ATTRS.FONT_NAME = 256; + DEF_ATTRS.LIST = 512; + DEF_ATTRS.AUTO = 1024; + DEF_ATTRS.COMBI = 2048; + DEF_ATTRS.BORDER_STYLE = 'none,hidden,dotted,dashed,solid,double,groove,ridge,inset,outset'.split(','); + DEF_ATTRS.POSITION_X = 'left,center,right'.split(','); + DEF_ATTRS.POSITION_Y = 'top,center,bottom'.split(','); + DEF_ATTRS.ALIGN = 'left,center,right,justify'.split(','); + DEF_ATTRS.TEXT_DECORATION = 'none,underline,overline,line-through,blink'.split(','); + DEF_ATTRS.TEXT_TRANSFORM = 'none,capitalize,lowercase,uppercase'.split(','); + DEF_ATTRS.WIDTH_HEIGHT = 'auto'.split(','); + DEF_ATTRS.PAINT = 1; // 再描画のみ必要 + DEF_ATTRS.REFLOW = 2; // レイアウトの再計算が必要 + + PaintPrivate.borderWidth = [ DEF_ATTRS.REFLOW, 0, DEF_ATTRS.QUARTET | DEF_ATTRS.LENGTH ]; // em [ top, right, bottom, left ] + PaintPrivate.borderColor = [ DEF_ATTRS.PAINT, 4, DEF_ATTRS.QUARTET | DEF_ATTRS.DEF_COLOR ]; // color [ top, right, bottom, left ] + PaintPrivate.borderStyle = [ DEF_ATTRS.REFLOW, 8, DEF_ATTRS.QUARTET | DEF_ATTRS.LIST, DEF_ATTRS.BORDER_STYLE ]; // string [ top, right, bottom, left ] + PaintPrivate.cornerRadius = [ DEF_ATTRS.PAINT, 12, DEF_ATTRS.QUARTET | DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; // em, px [ top, right, bottom, left ] + PaintPrivate.bgColor = [ DEF_ATTRS.PAINT, 16, DEF_ATTRS.COLOR ]; // color + PaintPrivate.bgAlpha = [ DEF_ATTRS.PAINT, 17, DEF_ATTRS.U_DECIMAL ]; // 0 - 1 + PaintPrivate.bgImgUrl = [ DEF_ATTRS.PAINT, 18, DEF_ATTRS.URL ]; // url + PaintPrivate.bgImgRepeatX = [ DEF_ATTRS.PAINT, 19, DEF_ATTRS.BOOLEAN ]; // true / false + PaintPrivate.bgImgRepeatY = [ DEF_ATTRS.PAINT, 20, DEF_ATTRS.BOOLEAN ]; // true / false + PaintPrivate.bgImgPositionX = [ DEF_ATTRS.PAINT, 21, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT | DEF_ATTRS.LIST, DEF_ATTRS.POSITION_X ]; // em %, px, string + PaintPrivate.bgImgPositionY = [ DEF_ATTRS.PAINT, 22, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT | DEF_ATTRS.LIST, DEF_ATTRS.POSITION_Y ]; // em %, px, string + PaintPrivate.shadowColor = [ DEF_ATTRS.PAINT, 23, DEF_ATTRS.COLOR ]; // color + PaintPrivate.shadowAlpha = [ DEF_ATTRS.PAINT, 24, DEF_ATTRS.U_DECIMAL ]; // 0 - 1 + PaintPrivate.shadowOffsetX = [ DEF_ATTRS.PAINT, 25, DEF_ATTRS.LENGTH ]; // em + PaintPrivate.shadowOffsetY = [ DEF_ATTRS.PAINT, 26, DEF_ATTRS.LENGTH ]; // em + PaintPrivate.shadowBlur = [ DEF_ATTRS.PAINT, 27, DEF_ATTRS.LENGTH ]; // em + PaintPrivate.shadowSpread = [ DEF_ATTRS.PAINT, 28, DEF_ATTRS.LENGTH ]; // em + PaintPrivate.shadowInset = [ DEF_ATTRS.PAINT, 29, DEF_ATTRS.BOOLEAN ]; // true / false + + TypoPrivate.color = [ DEF_ATTRS.PAINT, 0, DEF_ATTRS.COLOR ]; // color + TypoPrivate.fontFamily = [ DEF_ATTRS.REFLOW, 1, DEF_ATTRS.FONT_NAME ]; // string + TypoPrivate.fontSize = [ DEF_ATTRS.REFLOW, 2, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; // em, % + TypoPrivate.bold = [ DEF_ATTRS.REFLOW, 3, DEF_ATTRS.BOOLEAN ]; // true / false + TypoPrivate.italic = [ DEF_ATTRS.REFLOW, 4, DEF_ATTRS.BOOLEAN ]; // true / false + TypoPrivate.lineHeight = [ DEF_ATTRS.REFLOW, 5, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT | DEF_ATTRS.NUMERICAL ]; // em, %, + TypoPrivate.letterSpacing = [ DEF_ATTRS.REFLOW, 6, DEF_ATTRS.LENGTH ]; // em + TypoPrivate.wordSpacing = [ DEF_ATTRS.REFLOW, 7, DEF_ATTRS.LENGTH ]; + TypoPrivate.align = [ DEF_ATTRS.REFLOW, 8, DEF_ATTRS.LIST, DEF_ATTRS.ALIGN ]; + TypoPrivate.decoration = [ DEF_ATTRS.PAINT, 9, DEF_ATTRS.LIST, DEF_ATTRS.TEXT_DECORATION ]; + TypoPrivate.transform = [ DEF_ATTRS.REFLOW, 10, DEF_ATTRS.LIST, DEF_ATTRS.TEXT_TRANSFORM ]; + TypoPrivate.shadowColor = [ DEF_ATTRS.PAINT, 11, DEF_ATTRS.COLOR ]; + TypoPrivate.shadowOffsetX = [ DEF_ATTRS.PAINT, 12, DEF_ATTRS.LENGTH ]; + TypoPrivate.shadowOffsetY = [ DEF_ATTRS.PAINT, 13, DEF_ATTRS.LENGTH ]; + TypoPrivate.shadowBlur = [ DEF_ATTRS.PAINT, 14, DEF_ATTRS.LENGTH ]; + + LayoutPrivate.width = [ DEF_ATTRS.REFLOW, 0, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT, DEF_ATTRS.WIDTH_HEIGHT ]; + LayoutPrivate.minWidth = [ DEF_ATTRS.REFLOW, 1, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; + LayoutPrivate.maxWidth = [ DEF_ATTRS.REFLOW, 2, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; + LayoutPrivate.height = [ DEF_ATTRS.REFLOW, 3, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT, DEF_ATTRS.WIDTH_HEIGHT ]; + LayoutPrivate.minHeight = [ DEF_ATTRS.REFLOW, 4, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; + LayoutPrivate.maxHeight = [ DEF_ATTRS.REFLOW, 5, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; + LayoutPrivate.padding = [ DEF_ATTRS.REFLOW, 6, DEF_ATTRS.QUARTET | DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; + LayoutPrivate.margin = [ DEF_ATTRS.REFLOW, 10, DEF_ATTRS.QUARTET | DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; + + + var NodePrivate = Class.create( + 'NodePrivate', + Class.PRIVATE_DATA | Class.POOL_OBJECT, + { + elmWrap : null, + textNode : null, + contentWidth : 0, + contentHeight : 0, + Constructor : function( __root, __parent ){ + this.__root = __root; + if( __parent ) this.__parent = __parent; + }, + paint : function( v ){ + if( v instanceof PaintStyle ){ + this.__paint && this.__paint.unRegister( this ); + this._paint = v; + this.__paint = PaintStyle.getPrivateData( v ); + this.__paint.register( this ); + return this.User; + } else + if( v === null ){ + this.__paint && this.__paint.unRegister( this ); + delete this._paint; + delete this.__paint; + return this.User; + }; + return this._paint; + }, + typo : function( v ){ + if( v instanceof TypoStyle ){ + this.__typo && this.__typo.unRegister( this ); + this._typo = v; + this.__typo = TypoStyle.getPrivateData( v ); + this.__typo.register( this ); + return this.User; + } else + if( v === null ){ + this.__typo && this.__typo.unRegister( this ); + delete this._typo; + delete this.__typo; + return this.User; + }; + return this._typo; + }, + /** + * 1. 要素の追加・削除 + * 2. auto 指定時は要素の高さ取得. + * 3. 親の許す子の最大サイズと自信のスタイル指定から、自身の位置とサイズを計算 + * 4. 描画更新リストに追加 + */ + reflow : function(){ + var content = this._textContent, + layout = this.__layout, + targetW = this.__parent.childWidth, + targetH = this.__parent.childHeight, + size, data, w, h; + + if( content || ( this.__paint && this.__paint.hasStyle === true ) || ( this.__typo && this.__typo.hasStyle === true ) ){ + if( !this.elmWrap ) this.elmWrap = DOM.createDiv(); + this.__parent.addDiv( this ); + if( conetnt ){ + if( !this.textNode ){ + this.textNode = DOM.cerateText(); + this.elmWrap.appendChild( this.textNode ); + }; + if( layout && ( layout.autoWidth === true || layout.autoHeight === true ) ){ + size = DOM.getTextSize( this.elmWrap, content ); + this.contentWidth = size[ 0 ]; + this.conetntHeight = size[ 1 ]; + }; + this.textNode.data = content; + } else + if( this.textNode ){ + DOM.correct( this.textNode ); + delete this.textNode; + delete this.contentWidth; + delete this.conetntHeight; + }; + this.currentWidth = this.elmWrap.offsetWidth; + this.currentHeight = this.elmWrap.offsetHeight; + } else + if( this.elmWrap ){ + DOM.correct( this.elmWrap ); + delete this.elmWrap; + delete this.textNode; + delete this.contentWidth; + delete this.conetntHeight; + delete this.currentWidth; + delete this.currentHeight + }; + + // this.__parent.layoutManager.reflow(); + }, + addDiv : function( nodeData ){ + + } + } + ); + var Node = Class.create( + 'Node', + Class.POOL_OBJECT, + NodePrivate, + { + Constructor : function( root, parent ){ + Node.newPrivateData( this, LayoutBox.getPrivateData( root ), parent ? LayoutBox.getPrivateData( parent ) : undefined, this ); + }, + paint : function( v ){ + return Node.getPrivateData( this ).paint( v ); + }, + typo : function( v ){ + return Node.getPrivateData( this ).typo( v ); + }, + remove : function(){ + Node.getPrivateData( this ).remove(); + }, + nodeIndex : function( v ){ + return Node.getPrivateData( this ).nodeIndex( v ); + }, + displayIndex : function(){ + + }, + disabled : function( v ){ + return Node.getPrivateData( this ).disabled( v ); + }, + cursor : function( v ){ + return Node.getPrivateData( this ).cursor( v ); + }, + getAbsolutePositionX : function(){ + return Node.getPrivateData( this ).getAbsolutePositionX(); + }, + getAbsolutePositionY : function(){ + return Node.getPrivateData( this ).getAbsolutePositionY(); + }, + addEventListener : function( type, handler, opt_thisObject ){ + Node.getPrivateData( this ).addEventListener( type, handler, opt_thisObject ); + }, + removeEventListener : function( type, handler ){ + Node.getPrivateData( this ).removeEventListener( type, handler ); + }, + scrollTo : function( x, y ){ + Node.getPrivateData( this ).scrollTo( x, y ); + }, + scrollX : function( v ){ + return Node.getPrivateData( this ).scrollX( v ); + }, + scrollY : function( v ){ + return Node.getPrivateData( this ).scrollY( v ); + } + } + ); + + var LayoutBoxPrivate = NodePrivate.inherits( + 'LayoutBoxPrivate', + Class.POOL_OBJECT, + { + Constructor : function( layoutManager, root, parent ){ + this.layoutManager = layoutManager; + this._root = _root; + if( _parent ) this._parent = _parent; + }, + reflow : function(){ + this.manager.reflow( this ); + }, + repaint : function(){ + this.manager.repaint( this ); + } + } + ); + + var LayoutBox = Node.inherits( + 'LayoutBox', + Class.POOL_OBJECT, + LayoutBoxPrivate, + { + Constructor : function( layoutManager, root, parent ){ + LayoutBox.newPrivateData( this, layoutManager, LayoutBox.getPrivateData( root ), parent ? LayoutBox.getPrivateData( parent ) : undefined ); + }, + layoutManager : function( v ){ + + }, + createLayoutBox : function(){ + + }, + createContentBox : function(){ + + } + } + ); + +})( window, document ); + })( window, document ); -- 2.11.0 From 33a6607c9e5410fbcdd10622d1e2664e5323435c Mon Sep 17 00:00:00 2001 From: itozyun Date: Mon, 4 Feb 2013 09:10:25 +0900 Subject: [PATCH 02/16] Version 0.5.45. --- 0.5.x/javascripts/peta-common.js | 23 +- 0.5.x/javascripts/system.js | 748 +++++++++++++++++++++++++-------------- 2 files changed, 490 insertions(+), 281 deletions(-) diff --git a/0.5.x/javascripts/peta-common.js b/0.5.x/javascripts/peta-common.js index 21b701b..ca18abd 100644 --- a/0.5.x/javascripts/peta-common.js +++ b/0.5.x/javascripts/peta-common.js @@ -1,6 +1,6 @@ /* * pettanR peta.common.js - * version 0.5.44 + * version 0.5.45 * * author: * itozyun @@ -96,7 +96,7 @@ pettanr.CONST = ( function(){ NS_PETTANR_COMIC : 'pettanr-comic', THUMBNAIL_PATH : SERVER_SUPPORT === false ? RELATIVE + 'resource_pictures\/thumbnail\/' : PETTANR_ROOT_PATH + 'resource_pictures\/', RESOURCE_PICTURE_PATH : SERVER_SUPPORT === false ? RELATIVE + 'resource_pictures\/' : PETTANR_ROOT_PATH + 'resource_pictures\/full\/', - PANEL_PICTURE_PATH : SERVER_SUPPORT === false ? RELATIVE + 'resource_pictures\/' : PETTANR_ROOT_PATH + 'pictures\/', + PICTURE_PATH : SERVER_SUPPORT === false ? RELATIVE + 'pictures\/' : PETTANR_ROOT_PATH + 'pictures\/', SYSTEM_PICTURE_PATH : ( SERVER_SUPPORT === false ? RELATIVE : PETTANR_ROOT_PATH ) + 'system_pictures\/', CREATE_COMIC_JS : SERVER_SUPPORT === false ? 'js\/create_new_comic.js' : PETTANR_ROOT_PATH + 'comics\/new.js', CREATE_PANEL_JS : SERVER_SUPPORT === false ? 'js\/create_new_panel.js' : PETTANR_ROOT_PATH + 'panels\/new.js', @@ -629,7 +629,7 @@ pettanr.image = ( function(){ pettanr.bind = ( function(){ var BIND_WORKER_ARRAY = [], NAMESPACE_CLASSNAME = pettanr.CONST.NS_PETTANR_COMIC + '-', - PICTURE_PATH = pettanr.CONST.PANEL_PICTURE_PATH, + PICTURE_PATH = pettanr.CONST.PICTURE_PATH, ELM_DETECT_WIDTH = ( function(){ var ret = document.createElement( 'div' ); ret.style.cssText = 'width: auto;height: 0;padding: 0;margin: 0;display: block;visibility: hidden;float: none;position: static;'; @@ -738,7 +738,7 @@ pettanr.bind = ( function(){ }, cssText = [], elements = json.elements, - rPic, + realPic, p, i, l; this.elmTarget.appendChild( elmPanel ); @@ -754,19 +754,18 @@ pettanr.bind = ( function(){ if( !elements ) return; for( i = 0, l = elements.length; i < l; ++i ){ - data = elements[ i ]; - rPic = data.picture; - if( rPic ){ - this.buildImage( elmPanel, data, rPic ); + data = elements[ i ]; + realPic = data.picture; + if( realPic ){ + this.buildImage( elmPanel, data, realPic ); } else { this.buildBalloon( elmPanel, data ); }; }; }, - buildImage : function( elmPanel, data, rPic ){ - var oPic = rPic.original_picture, - rImg = pettanr.image.createReversibleImage( - [ PICTURE_PATH, oPic.id, '.', oPic.ext ].join( '' ), + buildImage : function( elmPanel, data, realPic ){ + var rImg = pettanr.image.createReversibleImage( + [ PICTURE_PATH, realPic.id, '.', realPic.ext ].join( '' ), data.width, data.height ), elmImg = rImg.elm; diff --git a/0.5.x/javascripts/system.js b/0.5.x/javascripts/system.js index 54cc8a0..2e84906 100644 --- a/0.5.x/javascripts/system.js +++ b/0.5.x/javascripts/system.js @@ -1,6 +1,6 @@ /* * pettanR system.js - * version 0.5.44 + * version 0.5.45 * * gadgetOS * author: @@ -1112,30 +1112,30 @@ var File = ( function(){ // simpleDeepCopy var driver = FILE_CONTROLER.getDriver( this ), data; - if( Type.isFunction( driver.read ) === true ){ + if( Type.isFunction( driver.read ) === true ){ data = driver.read( this ); }; return BASE_DRIVER.read( data || this ); }, write: function( _newData, _onUpdateFunction ){ var driver = FILE_CONTROLER.getDriver( this ); - if( typeof driver.write === 'function'){ + if( typeof driver.write === 'function' ){ return driver.write( this, _newData, _onUpdateFunction ); - } + }; return BASE_DRIVER.write( this, _newData, _onUpdateFunction ); }, viewerApplicationList: function(){ var driver = FILE_CONTROLER.getDriver( this ); - if( typeof driver.viewerApplicationList === 'function'){ + if( typeof driver.viewerApplicationList === 'function' ){ return driver.viewerApplicationList( this ); - } + }; return BASE_DRIVER.viewerApplicationList( this ); }, editorApplicationList: function(){ var driver = FILE_CONTROLER.getDriver( this ); - if( typeof driver.editorApplicationList === 'function'){ + if( typeof driver.editorApplicationList === 'function' ){ return driver.editorApplicationList( this ); - } + }; return BASE_DRIVER.viwerApps( this ); }, create: function(){ @@ -7167,41 +7167,289 @@ var XBrowserStyle = ( function(){ var XDocument = ( function( window, document ){ - var getIndex = Util.getIndex; + var getIndex = Util.getIndex; + var ROOT_LIST = []; + var DEF_ATTRS = {}; + var AUTO = undefined; + var FULL = DEF_ATTRS; // something unigue value; + var FLOOR = Math.floor; - var DEF_ATTRS = []; + DEF_ATTRS.LENGTH = 1; + DEF_ATTRS.PERCENT = 2; + DEF_ATTRS.COLOR = 4; + DEF_ATTRS.U_DECIMAL = 8; + DEF_ATTRS.NUMERICAL = 16; + DEF_ATTRS.BOOLEAN = 32; + DEF_ATTRS.QUARTET = 64; + DEF_ATTRS.URL = 128; + DEF_ATTRS.FONT_NAME = 256; + DEF_ATTRS.LIST = 512; + DEF_ATTRS.AUTO = 1024; + DEF_ATTRS.COMBI = 2048; + DEF_ATTRS.BORDER_STYLE = 'none,hidden,dotted,dashed,solid,double,groove,ridge,inset,outset'.split(','); + DEF_ATTRS.POSITION_X = 'left,center,right'.split(','); + DEF_ATTRS.POSITION_Y = 'top,center,bottom'.split(','); + DEF_ATTRS.ALIGN = 'left,center,right,justify'.split(','); + DEF_ATTRS.TEXT_DECORATION = 'none,underline,overline,line-through,blink'.split(','); + DEF_ATTRS.TEXT_TRANSFORM = 'none,capitalize,lowercase,uppercase'.split(','); + DEF_ATTRS.WIDTH_HEIGHT = 'auto'.split(','); + DEF_ATTRS.BOX_SIZING = 'content-box,padding-box,border-box,margin-box'.split(','); + DEF_ATTRS.PAINT = 1; // 再描画のみ必要 + DEF_ATTRS.REFLOW = 2; // レイアウトの再計算が必要 - var AbstractLayoutManager = Class.create( - 'AbstractLayoutManager', - Class.ABSTRACT, { - reflow : function(){} - } - ); + DEF_ATTRS.borderWidth = [ DEF_ATTRS.REFLOW, 0, DEF_ATTRS.QUARTET | DEF_ATTRS.LENGTH ]; // em [ top, right, bottom, left ] + DEF_ATTRS.borderColor = [ DEF_ATTRS.PAINT, 4, DEF_ATTRS.QUARTET | DEF_ATTRS.DEF_COLOR ]; // color [ top, right, bottom, left ] + DEF_ATTRS.borderStyle = [ DEF_ATTRS.REFLOW, 8, DEF_ATTRS.QUARTET | DEF_ATTRS.LIST, DEF_ATTRS.BORDER_STYLE ]; // string [ top, right, bottom, left ] + DEF_ATTRS.cornerRadius = [ DEF_ATTRS.PAINT, 12, DEF_ATTRS.QUARTET | DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; // em, px [ top, right, bottom, left ] + DEF_ATTRS.bgColor = [ DEF_ATTRS.PAINT, 16, DEF_ATTRS.COLOR ]; // color + DEF_ATTRS.bgAlpha = [ DEF_ATTRS.PAINT, 17, DEF_ATTRS.U_DECIMAL ]; // 0 - 1 + DEF_ATTRS.bgImgUrl = [ DEF_ATTRS.PAINT, 18, DEF_ATTRS.URL ]; // url + DEF_ATTRS.bgImgRepeatX = [ DEF_ATTRS.PAINT, 19, DEF_ATTRS.BOOLEAN ]; // true / false + DEF_ATTRS.bgImgRepeatY = [ DEF_ATTRS.PAINT, 20, DEF_ATTRS.BOOLEAN ]; // true / false + DEF_ATTRS.bgImgPositionX = [ DEF_ATTRS.PAINT, 21, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT | DEF_ATTRS.LIST, DEF_ATTRS.POSITION_X ]; // em %, px, string + DEF_ATTRS.bgImgPositionY = [ DEF_ATTRS.PAINT, 22, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT | DEF_ATTRS.LIST, DEF_ATTRS.POSITION_Y ]; // em %, px, string + DEF_ATTRS.shadowColor = [ DEF_ATTRS.PAINT, 23, DEF_ATTRS.COLOR ]; // color + DEF_ATTRS.shadowAlpha = [ DEF_ATTRS.PAINT, 24, DEF_ATTRS.U_DECIMAL ]; // 0 - 1 + DEF_ATTRS.shadowOffsetX = [ DEF_ATTRS.PAINT, 25, DEF_ATTRS.LENGTH ]; // em + DEF_ATTRS.shadowOffsetY = [ DEF_ATTRS.PAINT, 26, DEF_ATTRS.LENGTH ]; // em + DEF_ATTRS.shadowBlur = [ DEF_ATTRS.PAINT, 27, DEF_ATTRS.LENGTH ]; // em + DEF_ATTRS.shadowSpread = [ DEF_ATTRS.PAINT, 28, DEF_ATTRS.LENGTH ]; // em + DEF_ATTRS.shadowInset = [ DEF_ATTRS.PAINT, 29, DEF_ATTRS.BOOLEAN ]; // true / false + + DEF_ATTRS.color = [ DEF_ATTRS.PAINT, 30, DEF_ATTRS.COLOR ]; // color + DEF_ATTRS.fontFamily = [ DEF_ATTRS.REFLOW, 31, DEF_ATTRS.FONT_NAME ]; // string + DEF_ATTRS.fontSize = [ DEF_ATTRS.REFLOW, 32, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; // em, % + DEF_ATTRS.bold = [ DEF_ATTRS.REFLOW, 33, DEF_ATTRS.BOOLEAN ]; // true / false + DEF_ATTRS.italic = [ DEF_ATTRS.REFLOW, 34, DEF_ATTRS.BOOLEAN ]; // true / false + DEF_ATTRS.lineHeight = [ DEF_ATTRS.REFLOW, 35, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT | DEF_ATTRS.NUMERICAL ]; // em, %, + DEF_ATTRS.letterSpacing = [ DEF_ATTRS.REFLOW, 36, DEF_ATTRS.LENGTH ]; // em + DEF_ATTRS.wordSpacing = [ DEF_ATTRS.REFLOW, 37, DEF_ATTRS.LENGTH ]; + DEF_ATTRS.align = [ DEF_ATTRS.REFLOW, 38, DEF_ATTRS.LIST, DEF_ATTRS.ALIGN ]; + DEF_ATTRS.decoration = [ DEF_ATTRS.PAINT, 39, DEF_ATTRS.LIST, DEF_ATTRS.TEXT_DECORATION ]; + DEF_ATTRS.transform = [ DEF_ATTRS.REFLOW, 40, DEF_ATTRS.LIST, DEF_ATTRS.TEXT_TRANSFORM ]; + DEF_ATTRS.shadowColor = [ DEF_ATTRS.PAINT, 41, DEF_ATTRS.COLOR ]; + DEF_ATTRS.shadowOffsetX = [ DEF_ATTRS.PAINT, 42, DEF_ATTRS.LENGTH ]; + DEF_ATTRS.shadowOffsetY = [ DEF_ATTRS.PAINT, 43, DEF_ATTRS.LENGTH ]; + DEF_ATTRS.shadowBlur = [ DEF_ATTRS.PAINT, 44, DEF_ATTRS.LENGTH ]; + + DEF_ATTRS.width = [ DEF_ATTRS.REFLOW, 45, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT, DEF_ATTRS.WIDTH_HEIGHT ]; + DEF_ATTRS.minWidth = [ DEF_ATTRS.REFLOW, 46, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; + DEF_ATTRS.maxWidth = [ DEF_ATTRS.REFLOW, 47, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; + DEF_ATTRS.height = [ DEF_ATTRS.REFLOW, 48, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT, DEF_ATTRS.WIDTH_HEIGHT ]; + DEF_ATTRS.minHeight = [ DEF_ATTRS.REFLOW, 49, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; + DEF_ATTRS.maxHeight = [ DEF_ATTRS.REFLOW, 50, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; + DEF_ATTRS.padding = [ DEF_ATTRS.REFLOW, 51, DEF_ATTRS.QUARTET | DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; + DEF_ATTRS.margin = [ DEF_ATTRS.REFLOW, 55, DEF_ATTRS.QUARTET | DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; + DEF_ATTRS.sizing = [ DEF_ATTRS.REFLOW, 59, DEF_ATTRS.LIST, DEF_ATTRS.BOX_SIZING ]; + DEF_ATTRS.pageBox = [ DEF_ATTRS.REFLOW, 60, DEF_ATTRS.BOOLEAN ]; // true / false + DEF_ATTRS.x = DEF_ATTRS.left = [ DEF_ATTRS.REFLOW, 61, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; + DEF_ATTRS.y = DEF_ATTRS.top = [ DEF_ATTRS.REFLOW, 62, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; + DEF_ATTRS.bottom = [ DEF_ATTRS.REFLOW, 63, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; + DEF_ATTRS.right = [ DEF_ATTRS.REFLOW, 64, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; - var BasicLayoutManager = AbstractLayoutManager.inherits( + /** + * 再計算と再描画 + * redraw 再描画はパラメータ変更後に setTimeout で + * reflow 再計算は値が get された場合 invalidate が サイズだったら + * または再描画前に invalidate がサイズなフラグが足っていたら + */ + + var BasicLayoutManager = Class.create( 'BasicLayoutManager', + Class.POOL_OBJECT, { Constructor : function(){ + }, + redraw : function( nodeData ){ + var root = nodeData.__root; + root.dirty === DEF_ATTRS.REFLOW && this.reflow( root ); + + // draw + }, + reflow : function( nodeData ){ + var parent = nodeData.__parent, + allowW = parent.contentWidth, + allowH = parent.contentHeight, + autoW = parent.autoWidth, + autoH = parent.autoHeight, + offsetX = parent.offsetX, + offsetY = parent.offsetY, + children = nodeData.children, + style = nodeData.__style, + x, y, w, minW, maxW, h, minH, maxH, + contentW, contentH, boxW, boxH, + autoSize, sizing, page, + paddingT, paddingR, paddingB, paddingL, + borderT, borderR, borderB, borderL, + marginT, marginR, marginB, marginL, + childW = 0, + childH = 0, + styles, child, calc, i; + + if( style ){ + styles = style.data; + calc = BasicLayoutManager.calcValue; + sizing = styles[ 53 ]; + page = styles[ 54 ]; + x = calc( styles[ 55 ], allowW ); + y = calc( styles[ 56 ], page === true ? allowH : allowW ); + w = styles[ 45 ]; + minW = styles[ 46 ]; + maxW = styles[ 47 ]; + contentW = BasicLayoutManager.finalValue( w, minW, maxW, allowW ); + h = styles[ 48 ]; + minW = styles[ 49 ]; + maxW = styles[ 50 ]; + contentH = BasicLayoutManager.finalValue( h, minW, maxW, allowH ); + autoSize = w === AUTO || h === AUTO; + paddingT = calc( styles[ 51 ], page === true ? allowH : allowW );// paddingTRBL の % 指定は 最大幅に対して TB でも幅に対して + paddingR = calc( styles[ 52 ], allowW ); + paddingT = calc( styles[ 53 ], page === true ? allowH : allowW ); + paddingL = calc( styles[ 54 ], allowW, autoW ); + borderT = styles[ 0 ]; + borderR = styles[ 1 ]; + borderB = styles[ 2 ]; + borderL = styles[ 3 ]; + marginT = calc( styles[ 55 ], page === true ? allowH : allowW );// marginTRBL の % 指定は 最大幅に対して TB でも幅に対して + marginR = calc( styles[ 56 ], allowW ); + marginB = calc( styles[ 57 ], page === true ? allowH : allowW ); + marginL = calc( styles[ 58 ], allowW ); + boxW = contentW; + boxH = contentH; + switch( sizing ){ + case 3 : // margin-box + contentW -= ( marginR + marginL ); + contentH -= ( marginT + marginR ); + + case 2 : // border-box + contentW -= ( borderR + borderL ); + contentH -= ( borderT + borderR ); + case 1 : // padding-box + contentW -= ( paddingR + paddingL ); + contentH -= ( paddingT + paddingR ); + // case 0 : // content-box + }; + } else { + boxW = contentW = w = allowW; + boxH = contentH = h = allowH; + minW = minH = 0; + maxW = maxH = Infinity; + autoSize = false; + }; + + if( nodeData.contentWidth !== contentW || nodeData.contentHeight === contentH ){ + if( autoSize === false ){ + nodeData.updateLayout(); + nodeData.contentWidth = contentW; + nodeData.contentHeight = contentH; + nodeData.boxWidth = boxW; + nodeData.boxHeight = boxH; + }; + if( node instanceof LayoutBoxPrivate ){ + nodeData.Super.reflow.call( nodeData ); + } else { + node.reflow(); + }; + }; + + if( children ){ + for( i = children.length; i; ){ + child = children[ --i ]; + if( child instanceof LayoutBoxPrivate ){ + child.layoutManager.reflow( child ); + } else { + child.reflow(); + }; + if( autoSize === false ) continue; + if( childW < child.rectRight ) childW = child.rectRight; + if( childH < child.rectBottom ) childH = child.rectBottom; + }; + if( autoSize === true ){ + if( w === AUTO && childW < contentW ) contentW = childW; + if( h === AUTO && childH < contentH ) contentH = childH; + if( contentW < minW ) contentW = minW; + if( maxW < contentW ){ + nodeData.scrollWidth = contentW; + contentW = maxW; + }; + if( contentH < minH ) contentH = minH; + if( maxH < contentH ){ + nodeData.scrollHeight = contentH; + contentH = maxH; + }; + nodeData.contentWidth = boxW = contentW; + nodeData.contentHeight = boxH = contentH; + switch( sizing ){ + case 3 : // margin-box + boxW += ( marginR + marginL ); + boxH += ( marginT + marginR ); + case 2 : // border-box + boxW += ( borderR + borderL ); + boxH += ( borderT + borderR ); + case 1 : // padding-box + boxW += ( paddingR + paddingL ); + boxH += ( paddingT + paddingR ); + // case 0 : // content-box + }; + nodeData.boxWidth = boxW; + nodeData.boxHeight = boxH; + }; + }; + delete nodeData.dirty; } } ); + BasicLayoutManager.finalValue = function( styleValue, styleMin, styleMax, srcValue ){ + var calc = BasicLayoutManager.calcValue, + v = calc( styleValue, srcValue ), + min = calc( styleMin, srcValue ), + max = calc( styleMax, srcValue ); + if( v < min ) return min; + if( max < v ) return max; + return v; + }; + BasicLayoutManager.calcValue = function( styleValue, srcValue ){ + if( styleValue === 0 ) return 0; + // 100% + if( styleValue === FULL || styleValue === AUTO ) return srcValue; + if( 1 <= styleValue ) return styleValue; // legth + if( -1 < styleValue ) return FLOOR( srcValue * styleValue ); // % + return styleValue; // - length + }; - var AbstractStylePrivate = Class.create( - Class.ABSTRACT | Class.PRIVATE_DATA, + var NodeStylePrivate = Class.create( + Class.PRIVATE_DATA | Class.POOL_OBJECT, { + colorCssText : null, + layoutCssText : null, + Constructor : function(){ + this.data = []; + this.dirty = 0; + }, register : function( node ){ - var list = this.nodeList; - if( !list ){ + var root = node.__root, + roots = this.rootList, + nodes = this.nodeList; + if( !roots ){ + this.rootList = [ root ]; + } else + if( getIndex( roots, root ) === -1 ) roots[ roots.length ] = root; + + if( !nodes ){ this.nodeList = [ node ]; return; }; - if( getIndex( list, node ) === -1 ) list[ list.length ] = node; + if( getIndex( nodes, node ) === -1 ) nodes[ nodes.length ] = node; }, unRegister : function( node ){ - var list = this.nodeList, - i = getIndex( list, node ); - if( i !== -1 && list.splice( i, 1 ) && list.length === 0 ) delete this.nodeList; + var nodes = this.nodeList, + i = getIndex( nodes, node ), + root = node._root, + roots = this.rootList, + j = getIndex( roots, root ); + if( i !== -1 && nodes.splice( i, 1 ) && nodes.length === 0 ) delete this.nodeList; + if( j !== -1 && roots.splice( j, 1 ) && roots.length === 0 ) delete this.rootList; }, clone : function(){ var styleClass = Class.getClass( this.User ), @@ -7221,12 +7469,14 @@ var XDocument = ( function( window, document ){ quartet = !!( type & DEF_ATTRS.QUARTET ), url = !!( type & DEF_ATTRS.URL ), fontName = !!( type & DEF_ATTRS.FONT_NAME ), - list = !!( type & DEF_ATTRS.LIST ), + //list = !!( type & DEF_ATTRS.LIST ), combi = !!( type & DEF_ATTRS.COMBI ), data = this.data, _v = -1, - _type, i, l, nodes; - + i, l, nodes, root; + /* + * Setter + */ if( v !== undefined ){ if( Type.isNumber( v ) === true ){ if( numerical === false ){ @@ -7247,53 +7497,68 @@ var XDocument = ( function( window, document ){ }; if( Type.isArray( v ) === true ){ if( v.length <= 4 && quartet === true ){ - _type = type ^ DEF_ATTRS.QUARTET; + type ^= DEF_ATTRS.QUARTET; } else if( v.length === 2 && combi === true ){ - _type = type ^ DEF_ATTRS.COMBI; + type ^= DEF_ATTRS.COMBI; } else { throw new Error( '' ); }; switch( v.length ){ case 1 : - this.attr( [ propID , _type, list ], v[ 0 ] ); - this.attr( [ ++propID, _type, list ], v[ 0 ] ); - this.attr( [ ++propID, _type, list ], v[ 0 ] ); - this.attr( [ ++propID, _type, list ], v[ 0 ] ); + this.attr( [ propID , type, list ], v[ 0 ] ); + this.attr( [ ++propID, type, list ], v[ 0 ] ); + this.attr( [ ++propID, type, list ], v[ 0 ] ); + this.attr( [ ++propID, type, list ], v[ 0 ] ); break; case 2 : - this.attr( [ propID , _type, list ], v[ 0 ] ); - this.attr( [ ++propID, _type, list ], v[ 1 ] ); - this.attr( [ ++propID, _type, list ], v[ 0 ] ); - this.attr( [ ++propID, _type, list ], v[ 1 ] ); + this.attr( [ propID , type, list ], v[ 0 ] ); + this.attr( [ ++propID, type, list ], v[ 1 ] ); + this.attr( [ ++propID, type, list ], v[ 0 ] ); + this.attr( [ ++propID, type, list ], v[ 1 ] ); break; case 3 : - this.attr( [ propID , _type, list ], v[ 0 ] ); - this.attr( [ ++propID, _type, list ], v[ 1 ] ); - this.attr( [ ++propID, _type, list ], v[ 2 ] ); - this.attr( [ ++propID, _type, list ], v[ 1 ] ); + this.attr( [ propID , type, list ], v[ 0 ] ); + this.attr( [ ++propID, type, list ], v[ 1 ] ); + this.attr( [ ++propID, type, list ], v[ 2 ] ); + this.attr( [ ++propID, type, list ], v[ 1 ] ); break; case 4 : - this.attr( [ propID , _type, list ], v[ 0 ] ); - this.attr( [ ++propID, _type, list ], v[ 1 ] ); - this.attr( [ ++propID, _type, list ], v[ 2 ] ); - this.attr( [ ++propID, _type, list ], v[ 3 ] ); + this.attr( [ propID , type, list ], v[ 0 ] ); + this.attr( [ ++propID, type, list ], v[ 1 ] ); + this.attr( [ ++propID, type, list ], v[ 2 ] ); + this.attr( [ ++propID, type, list ], v[ 3 ] ); break; default : }; return this.User; }; - if( this.invalidateLayout < update ) this.invalidate = update; + if( update === DEF_ATTRS.REFLOW ){ + delete this.layoutCssText; + } else { + delete this.colorCssText; + }; + if( this.dirty < update ){ + this.dirty = update; + roots = this.rootList; + for( i = 0, l = roots.length; i < l; ++i ){ + root = roots[ i ]; + if( root.dirty < update ) root.dirty = update; + }; + }; if( list ) _v = Util.getIndex( list, v ); data[ propID ] = _v !== -1 ? _v : v; return this.User; }; - if( this.invalidate === DEF_ATTRS.REFLOW ){ - nodes = this.nodeList; - if( nodes ){ - for( i = 0, l = nodes.length; i < l; ++i ){ - nodes[ i ].reflow(); + /* + * Getter + */ + if( this.dirty === DEF_ATTRS.REFLOW ){ + roots = this.rootList; + if( roots ){ + for( i = 0, l = roots.length; i < l; ++i ){ + roots[ i ].reflow(); }; }; }; @@ -7302,251 +7567,133 @@ var XDocument = ( function( window, document ){ if( combi === true ) return [ v, data[ ++propID ] ]; if( list && Type.isNumber( v ) === true ) return list[ v ]; return v; - } - } - ); - - var PaintPrivate = AbstractStylePrivate.inherits( - 'PaintPrivate', - Class.PRIVATE_DATA | Class.POOL_OBJECT, - { - Constructor : function(){ - this.data = []; - this.invalidate = 0; }, cssText : function(){ - + if( this.colorCssText === null ) this.colorCssText = this.createColorCssText(); + if( this.layoutCssText === null ) this.layoutCssText = this.createLayoutCssText(); + return this.colorCssText + ';' + this.layoutCssText; }, - cssObject : function(){ + createColorCssText : function(){ }, - paint : function( node ){ + createLayoutCssText : function(){ } } ); - var PaintStyle = Class.create( - 'PaintStyle', + var NodeStyle = Class.create( + 'NodeStyle', Class.POOL_OBJECT, - PaintPrivate, + NodeStylePrivate, { Constructor : function(){ - PaintStyle.newPrivateData( this ); + NodeStyle.newPrivateData( this ); }, borderWidth : function( v ){ - return PaintStyle.getPrivateData( this ).attr( PaintPrivate.borderWidth, v ); + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.borderWidth, v ); }, borderColor : function(){ - return PaintStyle.getPrivateData( this ).attr( PaintPrivate.borderColor, v ); + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.borderColor, v ); }, borderStyle : function(){ - return PaintStyle.getPrivateData( this ).attr( PaintPrivate.borderStyle, v ); + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.borderStyle, v ); }, cornerRadius : function(){ - return PaintStyle.getPrivateData( this ).attr( PaintPrivate.cornerRadius, v ); + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.cornerRadius, v ); }, bgColor : function(){ - return PaintStyle.getPrivateData( this ).attr( PaintPrivate.bgColor, v ); + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.bgColor, v ); }, bgAlpha : function(){ - return PaintStyle.getPrivateData( this ).attr( PaintPrivate.bgAlpha, v ); + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.bgAlpha, v ); }, bgImgUrl : function(){ - return PaintStyle.getPrivateData( this ).attr( PaintPrivate.bgImgUrl, v ); + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.bgImgUrl, v ); }, bgImgRepeatX : function(){ - return PaintStyle.getPrivateData( this ).attr( PaintPrivate.bgImgRepeatX, v ); + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.bgImgRepeatX, v ); }, bgImgRepeatY : function(){ - return PaintStyle.getPrivateData( this ).attr( PaintPrivate.bgImgRepeatY, v ); + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.bgImgRepeatY, v ); }, bgImgPositionX : function(){ - return PaintStyle.getPrivateData( this ).attr( PaintPrivate.bgImgPositionX, v ); + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.bgImgPositionX, v ); }, bgImgPositionY : function(){ - return PaintStyle.getPrivateData( this ).attr( PaintPrivate.bgImgPositionY, v ); + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.bgImgPositionY, v ); }, shadowColor : function(){ - return PaintStyle.getPrivateData( this ).attr( PaintPrivate.shadowColor, v ); + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.shadowColor, v ); }, shadowAlpha : function(){ - return PaintStyle.getPrivateData( this ).attr( PaintPrivate.shadowAlpha, v ); + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.shadowAlpha, v ); }, shadowOffsetX : function(){ - return PaintStyle.getPrivateData( this ).attr( PaintPrivate.shadowOffsetX, v ); + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.shadowOffsetX, v ); }, shadowOffsetY : function(){ - return PaintStyle.getPrivateData( this ).attr( PaintPrivate.shadowOffsetY, v ); + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.shadowOffsetY, v ); }, shadowBlur : function(){ - return PaintStyle.getPrivateData( this ).attr( PaintPrivate.shadowBlur, v ); + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.shadowBlur, v ); }, shadowSpread : function(){ - return PaintStyle.getPrivateData( this ).attr( PaintPrivate.shadowSpread, v ); + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.shadowSpread, v ); }, shadowInset : function(){ - return PaintStyle.getPrivateData( this ).attr( PaintPrivate.shadowInset, v ); - } - } - ); - - var TypoPrivate = AbstractStylePrivate.inherits( - 'TypoPrivate', - Class.PRIVATE_DATA | Class.POOL_OBJECT, - { - Constructor : function(){ - this.data = []; - this.invalidate = 0; - }, - cssText : function(){ - - }, - cssObject : function(){ - - } - } - ); - - var TypoStyle = Class.create( - 'TypoStyle', - Class.POOL_OBJECT, - TypoPrivate, - { - Constructor : function( v ){ - TypoStyle.newPrivateData( this ); + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.shadowInset, v ); }, color : function( v ){ - return TypoStyle.getPrivateData( this ).attr( TypoPrivate.color, v ); + return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.color, v ); }, fontFamily : function( v ){ - return TypoStyle.getPrivateData( this ).attr( TypoPrivate.fontFamily, v ); + return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.fontFamily, v ); }, fontSize : function( v ){ - return TypoStyle.getPrivateData( this ).attr( TypoPrivate.fontSize, v ); + return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.fontSize, v ); }, bold : function( v ){ - return TypoStyle.getPrivateData( this ).attr( TypoPrivate.bold, v ); + return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.bold, v ); }, italic : function( v ){ - return TypoStyle.getPrivateData( this ).attr( TypoPrivate.italic, v ); + return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.italic, v ); }, lineHeight : function( v ){ - return TypoStyle.getPrivateData( this ).attr( TypoPrivate.lineHeight, v ); + return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.lineHeight, v ); }, letterSpacing : function( v ){ - return TypoStyle.getPrivateData( this ).attr( TypoPrivate.letterSpacing, v ); + return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.letterSpacing, v ); }, wordSpacing : function( v ){ - return TypoStyle.getPrivateData( this ).attr( TypoPrivate.wordSpacing, v ); + return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.wordSpacing, v ); }, align : function( v ){ - return TypoStyle.getPrivateData( this ).attr( TypoPrivate.align, v ); + return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.align, v ); }, decoration : function( v ){ - return TypoStyle.getPrivateData( this ).attr( TypoPrivate.decoration, v ); + return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.decoration, v ); }, transform : function( v ){ - return TypoStyle.getPrivateData( this ).attr( TypoPrivate.transform, v ); + return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.transform, v ); }, shadowColor : function( v ){ - return TypoStyle.getPrivateData( this ).attr( TypoPrivate.shadowColor, v ); + return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.shadowColor, v ); }, shadowOffsetX : function( v ){ - return TypoStyle.getPrivateData( this ).attr( TypoPrivate.shadowOffsetX, v ); + return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.shadowOffsetX, v ); }, shadowOffsetY : function( v ){ - return TypoStyle.getPrivateData( this ).attr( TypoPrivate.shadowOffsetY, v ); + return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.shadowOffsetY, v ); }, shadowBlur : function( v ){ - return TypoStyle.getPrivateData( this ).attr( TypoPrivate.shadowBlur, v ); - } - } - ); - - var LayoutPrivate = AbstractStylePrivate.inherits( - 'LayoutPrivate', - Class.PRIVATE_DATA | Class.POOL_OBJECT, - { - Constructor : function(){ - this.data = []; - this.invalidate = 0; + return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.shadowBlur, v ); }, cssText : function(){ - - }, - cssObject : function(){ - + return TypoStyle.getPrivateData( this ).cssText(); } } ); - - DEF_ATTRS.LENGTH = 1; - DEF_ATTRS.PERCENT = 2; - DEF_ATTRS.COLOR = 4; - DEF_ATTRS.U_DECIMAL = 8; - DEF_ATTRS.NUMERICAL = 16; - DEF_ATTRS.BOOLEAN = 32; - DEF_ATTRS.QUARTET = 64; - DEF_ATTRS.URL = 128; - DEF_ATTRS.FONT_NAME = 256; - DEF_ATTRS.LIST = 512; - DEF_ATTRS.AUTO = 1024; - DEF_ATTRS.COMBI = 2048; - DEF_ATTRS.BORDER_STYLE = 'none,hidden,dotted,dashed,solid,double,groove,ridge,inset,outset'.split(','); - DEF_ATTRS.POSITION_X = 'left,center,right'.split(','); - DEF_ATTRS.POSITION_Y = 'top,center,bottom'.split(','); - DEF_ATTRS.ALIGN = 'left,center,right,justify'.split(','); - DEF_ATTRS.TEXT_DECORATION = 'none,underline,overline,line-through,blink'.split(','); - DEF_ATTRS.TEXT_TRANSFORM = 'none,capitalize,lowercase,uppercase'.split(','); - DEF_ATTRS.WIDTH_HEIGHT = 'auto'.split(','); - DEF_ATTRS.PAINT = 1; // 再描画のみ必要 - DEF_ATTRS.REFLOW = 2; // レイアウトの再計算が必要 - - PaintPrivate.borderWidth = [ DEF_ATTRS.REFLOW, 0, DEF_ATTRS.QUARTET | DEF_ATTRS.LENGTH ]; // em [ top, right, bottom, left ] - PaintPrivate.borderColor = [ DEF_ATTRS.PAINT, 4, DEF_ATTRS.QUARTET | DEF_ATTRS.DEF_COLOR ]; // color [ top, right, bottom, left ] - PaintPrivate.borderStyle = [ DEF_ATTRS.REFLOW, 8, DEF_ATTRS.QUARTET | DEF_ATTRS.LIST, DEF_ATTRS.BORDER_STYLE ]; // string [ top, right, bottom, left ] - PaintPrivate.cornerRadius = [ DEF_ATTRS.PAINT, 12, DEF_ATTRS.QUARTET | DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; // em, px [ top, right, bottom, left ] - PaintPrivate.bgColor = [ DEF_ATTRS.PAINT, 16, DEF_ATTRS.COLOR ]; // color - PaintPrivate.bgAlpha = [ DEF_ATTRS.PAINT, 17, DEF_ATTRS.U_DECIMAL ]; // 0 - 1 - PaintPrivate.bgImgUrl = [ DEF_ATTRS.PAINT, 18, DEF_ATTRS.URL ]; // url - PaintPrivate.bgImgRepeatX = [ DEF_ATTRS.PAINT, 19, DEF_ATTRS.BOOLEAN ]; // true / false - PaintPrivate.bgImgRepeatY = [ DEF_ATTRS.PAINT, 20, DEF_ATTRS.BOOLEAN ]; // true / false - PaintPrivate.bgImgPositionX = [ DEF_ATTRS.PAINT, 21, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT | DEF_ATTRS.LIST, DEF_ATTRS.POSITION_X ]; // em %, px, string - PaintPrivate.bgImgPositionY = [ DEF_ATTRS.PAINT, 22, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT | DEF_ATTRS.LIST, DEF_ATTRS.POSITION_Y ]; // em %, px, string - PaintPrivate.shadowColor = [ DEF_ATTRS.PAINT, 23, DEF_ATTRS.COLOR ]; // color - PaintPrivate.shadowAlpha = [ DEF_ATTRS.PAINT, 24, DEF_ATTRS.U_DECIMAL ]; // 0 - 1 - PaintPrivate.shadowOffsetX = [ DEF_ATTRS.PAINT, 25, DEF_ATTRS.LENGTH ]; // em - PaintPrivate.shadowOffsetY = [ DEF_ATTRS.PAINT, 26, DEF_ATTRS.LENGTH ]; // em - PaintPrivate.shadowBlur = [ DEF_ATTRS.PAINT, 27, DEF_ATTRS.LENGTH ]; // em - PaintPrivate.shadowSpread = [ DEF_ATTRS.PAINT, 28, DEF_ATTRS.LENGTH ]; // em - PaintPrivate.shadowInset = [ DEF_ATTRS.PAINT, 29, DEF_ATTRS.BOOLEAN ]; // true / false - - TypoPrivate.color = [ DEF_ATTRS.PAINT, 0, DEF_ATTRS.COLOR ]; // color - TypoPrivate.fontFamily = [ DEF_ATTRS.REFLOW, 1, DEF_ATTRS.FONT_NAME ]; // string - TypoPrivate.fontSize = [ DEF_ATTRS.REFLOW, 2, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; // em, % - TypoPrivate.bold = [ DEF_ATTRS.REFLOW, 3, DEF_ATTRS.BOOLEAN ]; // true / false - TypoPrivate.italic = [ DEF_ATTRS.REFLOW, 4, DEF_ATTRS.BOOLEAN ]; // true / false - TypoPrivate.lineHeight = [ DEF_ATTRS.REFLOW, 5, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT | DEF_ATTRS.NUMERICAL ]; // em, %, - TypoPrivate.letterSpacing = [ DEF_ATTRS.REFLOW, 6, DEF_ATTRS.LENGTH ]; // em - TypoPrivate.wordSpacing = [ DEF_ATTRS.REFLOW, 7, DEF_ATTRS.LENGTH ]; - TypoPrivate.align = [ DEF_ATTRS.REFLOW, 8, DEF_ATTRS.LIST, DEF_ATTRS.ALIGN ]; - TypoPrivate.decoration = [ DEF_ATTRS.PAINT, 9, DEF_ATTRS.LIST, DEF_ATTRS.TEXT_DECORATION ]; - TypoPrivate.transform = [ DEF_ATTRS.REFLOW, 10, DEF_ATTRS.LIST, DEF_ATTRS.TEXT_TRANSFORM ]; - TypoPrivate.shadowColor = [ DEF_ATTRS.PAINT, 11, DEF_ATTRS.COLOR ]; - TypoPrivate.shadowOffsetX = [ DEF_ATTRS.PAINT, 12, DEF_ATTRS.LENGTH ]; - TypoPrivate.shadowOffsetY = [ DEF_ATTRS.PAINT, 13, DEF_ATTRS.LENGTH ]; - TypoPrivate.shadowBlur = [ DEF_ATTRS.PAINT, 14, DEF_ATTRS.LENGTH ]; - - LayoutPrivate.width = [ DEF_ATTRS.REFLOW, 0, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT, DEF_ATTRS.WIDTH_HEIGHT ]; - LayoutPrivate.minWidth = [ DEF_ATTRS.REFLOW, 1, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; - LayoutPrivate.maxWidth = [ DEF_ATTRS.REFLOW, 2, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; - LayoutPrivate.height = [ DEF_ATTRS.REFLOW, 3, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT, DEF_ATTRS.WIDTH_HEIGHT ]; - LayoutPrivate.minHeight = [ DEF_ATTRS.REFLOW, 4, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; - LayoutPrivate.maxHeight = [ DEF_ATTRS.REFLOW, 5, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; - LayoutPrivate.padding = [ DEF_ATTRS.REFLOW, 6, DEF_ATTRS.QUARTET | DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; - LayoutPrivate.margin = [ DEF_ATTRS.REFLOW, 10, DEF_ATTRS.QUARTET | DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; - var NodePrivate = Class.create( 'NodePrivate', @@ -7554,43 +7701,38 @@ var XDocument = ( function( window, document ){ { elmWrap : null, textNode : null, + autoWidth : false, + autoHeight : false, + autoSize : false, + boxX : 0, + boxY : 0, + boxWidth : 0, + boxHeight : 0, + boxRight : 0, + boxBottom : 0, + contentX : 0, + contentY : 0, contentWidth : 0, contentHeight : 0, Constructor : function( __root, __parent ){ this.__root = __root; if( __parent ) this.__parent = __parent; }, - paint : function( v ){ - if( v instanceof PaintStyle ){ - this.__paint && this.__paint.unRegister( this ); - this._paint = v; - this.__paint = PaintStyle.getPrivateData( v ); - this.__paint.register( this ); + style : function( v ){ + if( v instanceof NodeStyle ){ + this.__style && this.__style.unRegister( this ); + this._style = v; + this.__style = StylePrivate.getPrivateData( v ); + this.__style.register( this ); return this.User; } else if( v === null ){ - this.__paint && this.__paint.unRegister( this ); - delete this._paint; - delete this.__paint; + this.__style && this.__style.unRegister( this ); + delete this._style; + delete this.__style; return this.User; }; - return this._paint; - }, - typo : function( v ){ - if( v instanceof TypoStyle ){ - this.__typo && this.__typo.unRegister( this ); - this._typo = v; - this.__typo = TypoStyle.getPrivateData( v ); - this.__typo.register( this ); - return this.User; - } else - if( v === null ){ - this.__typo && this.__typo.unRegister( this ); - delete this._typo; - delete this.__typo; - return this.User; - }; - return this._typo; + return this._style; }, /** * 1. 要素の追加・削除 @@ -7600,20 +7742,24 @@ var XDocument = ( function( window, document ){ */ reflow : function(){ var content = this._textContent, - layout = this.__layout, - targetW = this.__parent.childWidth, - targetH = this.__parent.childHeight, + style = this.__style, + parent = this.__parent, size, data, w, h; - if( content || ( this.__paint && this.__paint.hasStyle === true ) || ( this.__typo && this.__typo.hasStyle === true ) ){ - if( !this.elmWrap ) this.elmWrap = DOM.createDiv(); - this.__parent.addDiv( this ); - if( conetnt ){ + if( content || ( style && style.hasStyle === true ) ){ + if( !this.elmWrap ){ + this.elmWrap = DOM.createDiv(); + parent.addDisplayElement( this ); + }; + if( style && style.hasStyle === true ){ + this.elmWrap.style.cssText = style.cssText(); + }; + if( content ){ if( !this.textNode ){ this.textNode = DOM.cerateText(); this.elmWrap.appendChild( this.textNode ); }; - if( layout && ( layout.autoWidth === true || layout.autoHeight === true ) ){ + if( style && ( style.autoWidth === true || style.autoHeight === true ) ){ size = DOM.getTextSize( this.elmWrap, content ); this.contentWidth = size[ 0 ]; this.conetntHeight = size[ 1 ]; @@ -7626,24 +7772,94 @@ var XDocument = ( function( window, document ){ delete this.contentWidth; delete this.conetntHeight; }; - this.currentWidth = this.elmWrap.offsetWidth; - this.currentHeight = this.elmWrap.offsetHeight; + this.boxWidth = this.elmWrap.offsetWidth; + this.boxHeight = this.elmWrap.offsetHeight; } else if( this.elmWrap ){ - DOM.correct( this.elmWrap ); - delete this.elmWrap; - delete this.textNode; - delete this.contentWidth; - delete this.conetntHeight; - delete this.currentWidth; - delete this.currentHeight + parent.removeDisplayElement( this ); + }; + }, + preSizing : function( boxX, boxY, boxW, boxH, contentX, contentY, contentW, contentH ){ + var parent = nodeData.__parent, + allowW = parent.contentWidth, + allowH = parent.contentHeight, + style = nodeData.__style, + x, y, w, minW, maxW, h, minH, maxH, + contentW, contentH, + page, + paddingT, paddingR, paddingB, paddingL, + borderT, borderR, borderB, borderL, + marginT, marginR, marginB, marginL, + styles, calc; + + if( style ){ + styles = style.data; + calc = BasicLayoutManager.calcValue; + page = styles[ 54 ] === true ? allowH : allowW ; + w = styles[ 45 ]; + minW = styles[ 46 ]; + maxW = styles[ 47 ]; + contentW = BasicLayoutManager.finalValue( w, minW, maxW, allowW ); + h = styles[ 48 ]; + minW = styles[ 49 ]; + maxW = styles[ 50 ]; + contentH = BasicLayoutManager.finalValue( h, minW, maxW, allowH ); + paddingT = calc( styles[ 51 ], page );// paddingTRBL の % 指定は 最大幅に対して TB でも幅に対して + paddingR = calc( styles[ 52 ], allowW ); + paddingB = calc( styles[ 53 ], page ); + paddingL = calc( styles[ 54 ], allowW ); + borderT = styles[ 0 ]; + borderR = styles[ 1 ]; + borderB = styles[ 2 ]; + borderL = styles[ 3 ]; + marginT = calc( styles[ 55 ], page );// marginTRBL の % 指定は 最大幅に対して TB でも幅に対して + marginR = calc( styles[ 56 ], allowW ); + marginB = calc( styles[ 57 ], page ); + marginL = calc( styles[ 58 ], allowW ); + this.boxWidth = contentW; + this.boxHeight = contentH; + switch( styles[ 53 ] ){ + case 3 : // margin-box + contentW -= ( marginR + marginL ); + contentH -= ( marginT + marginR ); + + case 2 : // border-box + contentW -= ( borderR + borderL ); + contentH -= ( borderT + borderR ); + case 1 : // padding-box + contentW -= ( paddingR + paddingL ); + contentH -= ( paddingT + paddingR ); + // case 0 : // content-box + }; + this.contentX = marginL + borderL + paddingL; + this.contentY = marginT + borderT + paddingT; + this.contentWidth = contentW; + this.contentHeight = contentH; + this.autoHeight = h === AUTO; + this.autoWidth = w === AUTO; + this.autoSize = this.autoWidth || this.autoHeight; + } else { + this.boxWidth = this.contentWidth = allowW; + this.boxHeight = this.contentHeight = allowH; + delete this.contentX; + delete this.contentY; + delete this.autoSize; + delete this.autoWidth; + delete this.autoHeight; }; - - // this.__parent.layoutManager.reflow(); }, - addDiv : function( nodeData ){ + addDisplayElement : function( nodeData ){ - } + }, + removeDisplayElement : function( nodeData ){ + DOM.correct( nodeData.elmWrap ); + delete nodeData.elmWrap; + delete nodeData.textNode; + delete nodeData.contentWidth; + delete nodeData.conetntHeight; + delete nodeData.currentWidth; + delete nodeData.currentHeight; + } } ); var Node = Class.create( @@ -7654,12 +7870,9 @@ var XDocument = ( function( window, document ){ Constructor : function( root, parent ){ Node.newPrivateData( this, LayoutBox.getPrivateData( root ), parent ? LayoutBox.getPrivateData( parent ) : undefined, this ); }, - paint : function( v ){ + style : function( v ){ return Node.getPrivateData( this ).paint( v ); }, - typo : function( v ){ - return Node.getPrivateData( this ).typo( v ); - }, remove : function(){ Node.getPrivateData( this ).remove(); }, @@ -7701,7 +7914,7 @@ var XDocument = ( function( window, document ){ var LayoutBoxPrivate = NodePrivate.inherits( 'LayoutBoxPrivate', - Class.POOL_OBJECT, + Class.POOL_OBJECT | Class.SUPER_ACCESS, { Constructor : function( layoutManager, root, parent ){ this.layoutManager = layoutManager; @@ -7709,10 +7922,7 @@ var XDocument = ( function( window, document ){ if( _parent ) this._parent = _parent; }, reflow : function(){ - this.manager.reflow( this ); - }, - repaint : function(){ - this.manager.repaint( this ); + this.layoutManager.reflow( this ); } } ); -- 2.11.0 From c684a38e0f7b7202c4d26afe429a98bbfa85a77f Mon Sep 17 00:00:00 2001 From: itozyun Date: Wed, 6 Feb 2013 23:44:15 +0900 Subject: [PATCH 03/16] version 0.5.47, fix scope leek. --- 0.5.x/javascripts/libs.js | 14 ++++++----- 0.5.x/javascripts/peta-apps.js | 52 ++++++++++++++++++++-------------------- 0.5.x/javascripts/peta-common.js | 9 +++---- 0.5.x/javascripts/system.js | 35 ++++++++++++++------------- 4 files changed, 58 insertions(+), 52 deletions(-) diff --git a/0.5.x/javascripts/libs.js b/0.5.x/javascripts/libs.js index aee98fe..507033b 100644 --- a/0.5.x/javascripts/libs.js +++ b/0.5.x/javascripts/libs.js @@ -1,6 +1,6 @@ /* * pettanR libs.js - * version 0.5.44 + * version 0.5.47 * * * Type @@ -593,7 +593,8 @@ var getFunctionName = function( f ){ getElementsByClassName: function( _elm, _className, opt_tagName ){ var _all = !opt_tagName || opt_tagName === '*', _livenodes = _all === true ? ( _elm.all || _elm.getElementsByTagName( '*' )) : _elm.getElementsByTagName( opt_tagName ), - _nodes = Util.copyArray( _livenodes ); + _nodes = Util.copyArray( _livenodes), + _node; for( var j = 0; j < _nodes.length; ){ _node = _nodes[ j ]; if( _node.nodeType !== 1 || Util.hasClassName( _node, _className ) === false ){ @@ -812,7 +813,7 @@ var CSS = ( function( window, documwnt, undefined ){ })(); var COLOR = ( function(){ - var ret = {}, v, name, + var ret = {}, v, name, i, list = [ '0', 'BLACK', 'FF0000', 'RED', @@ -1314,7 +1315,8 @@ var CSS = ( function( window, documwnt, undefined ){ right = this.get( name + 'Right' ), bottom = this.get( name + 'Bottom' ), left = this.get( name + 'Left' ), - ret = new PropertyGroupClass( name, top, right, bottom, left ); + ret = new PropertyGroupClass( name, top, right, bottom, left), + all; if( ret.isValid() === true ) return ret; ret.clear(); all = this.style[ name ].split( '(' )[ 1 ].split( ')' )[ 0 ].split( CLIP_SEPARATOR ); @@ -1346,7 +1348,7 @@ var CSS = ( function( window, documwnt, undefined ){ bottom = this.get( name + 'Bottom' + widthOrColor ), left = this.get( name + 'Left' + widthOrColor ), ret = new FrexiblePropertyClass( name, top, right, bottom, left ), - all, x, v, u, i; + all, x, v, u, i, l; if( ret.isValid() === true ) return ret; ret.clear(); @@ -1627,7 +1629,7 @@ var Position = { minus = Position.isMinusBodyBorder, body = document.body, element = forElement, - parent; + parent, border; do { valueT += element.offsetTop || 0; valueL += element.offsetLeft || 0; diff --git a/0.5.x/javascripts/peta-apps.js b/0.5.x/javascripts/peta-apps.js index 0b1a931..1d822e6 100644 --- a/0.5.x/javascripts/peta-apps.js +++ b/0.5.x/javascripts/peta-apps.js @@ -1,6 +1,6 @@ /* * pettanR peta.apps.js - * version 0.5.44 + * version 0.5.47 * * author: * itozyun @@ -447,6 +447,7 @@ this.viewerApplicationList = function( file ){ var data = FileAPI.getFileData( file ), type = data !== null ? data.type : null; + if( data === FILE_DATA_MY_ORIGINAL_PICTURES_ROOT ) return [ PremiumSatge ]; switch( type ){ case FILE_TYPE.COMIC : case FILE_TYPE.PANEL : @@ -458,10 +459,7 @@ break; case FILE_TYPE.ARTIST : return [ PremiumSatge ]; - default : - if( data === FILE_DATA_MY_ORIGINAL_PICTURES_ROOT ){ - return [ PremiumSatge ]; - }; + default : }; return []; }; @@ -853,9 +851,9 @@ var PremiumSatge = gOS.registerApplication( function(){ var ImageGroupIconClass = function( index, data ){ var elmIconWrap = elmIconOrigin.cloneNode( true ), elmIconTitle = Util.getElementsByClassName( elmIconWrap, 'image-group-item-title' )[ 0 ], - originalPicture = data.original_picture, + originalPicture = data.original_picture || data, SRC = [ BASE_PATH, data.id, '.', data.ext ].join( ''), - LOW_SRC = originalPicture.filesize && originalPicture.filesize > LIMIT_FILESIZE ? [ THUMB_PATH, data.id, '.', originalPicture.ext ].join( '') : null, + LOW_SRC = originalPicture.filesize && originalPicture.filesize > LIMIT_FILESIZE ? [ THUMB_PATH, data.id, '.', data.ext ].join( '' ) : null, reversibleImage = null, timer = null, onEnterFlag = false, @@ -1390,7 +1388,7 @@ var Editor = gOS.registerApplication( function(){ var ELM_ITEM_CLASSNAME = 'menubar-item', currentMenu = null, elmBar, elmBox, - nodeBar, nodeBox, + nodeBar, nodeBox, layerBox, barH, menuW; /** ----------------------------------------- * PrivateOptionDataClass @@ -1583,7 +1581,7 @@ var Editor = gOS.registerApplication( function(){ }; MenuClass.prototype = { show: function(){ - data = MenuPrivateDataClass.get( this ); + var data = MenuPrivateDataClass.get( this ); if( data.visible === true ) return; data.elm.className = ELM_ITEM_CLASSNAME + '-focus'; @@ -1988,7 +1986,7 @@ var Editor = gOS.registerApplication( function(){ }, firstOpen : function(){ var win = this.window, - elmHead = this.elmHead = Util.getElementsByClassName( this.elm, 'window-header' )[ 0 ]; + elmHead = this.elmHead = Util.getElementsByClassName( this.elm, 'window-header' )[ 0 ], elmBody = this.elmBody = Util.getElementsByClassName( this.elm, 'window-body' )[ 0 ], elmClose = Util.getElementsByClassName( this.elm, 'window-close-button' )[ 0 ], elmFoot = Util.getElementsByClassName( this.elm, 'window-footer' )[ 0 ], @@ -2949,7 +2947,8 @@ var Editor = gOS.registerApplication( function(){ { x: 1, w: -1, y: 0, h: 1}, //bottom-left { x: 0, w: 1, y: 0, h: 1} //bottom-right ], - startX, startY, startW, startH, startFilpV, startFilpH, startAspect, + startX, startY, startW, startH, + flipV, flipH, startFilpV, startFilpH, startAspect, baseX, baseY, baseW, baseH, currentX, currentY, currentW, currentH, offsetX, offsetY, @@ -3453,9 +3452,10 @@ var Editor = gOS.registerApplication( function(){ pushoutH = 0, pushout = false, currentType = -1, + currentElement = null, visible = false, node = null, - ui, inputX, inputY, inputZ, inputA, inputW, inputH, inputAspectRatio, + ui, inputX, inputY, inputZ, inputA, inputW, inputH, inputPercentW, inputPercentH, inputAspectRatio, buttonBack, buttonForward, buttonDel, buttonEdit, butonChange; function layerBack(){ @@ -3488,7 +3488,7 @@ var Editor = gOS.registerApplication( function(){ }; function change(){ if( currentElement === null ) return; - PremiumSatge.boot( currentElement.artistID, currentElement.resourcePicture, currentElement ); + PremiumSatge.boot( currentElement.artistID, currentElement.realPicture, currentElement ); }; return { @@ -3685,8 +3685,6 @@ var Editor = gOS.registerApplication( function(){ this.flipV = data.height < 0 ? -1 : 1; this.flipH = data.width < 0 ? -1 : 1; this.rPicture = data.picture; - //this.oPicture = this.rPicture.original_picture; - //this.artistID = this.oPicture.artist.id || -1; var self = this; function animeComplete(){ @@ -3712,7 +3710,7 @@ var Editor = gOS.registerApplication( function(){ this.flipV = updateV === true ? -this.flipV : this.flipV; this.reversibleImage.resize( this.flipH * this.w, this.flipV * this.h ); }, - resourcePicture : function( _rPicture ){ + realPicture : function( _rPicture ){ if( _rPicture && _rPicture !== this.rPicture ){ HISTORY_CONTROL.saveState( this._updateResourcePicture, this.rPicture, _rPicture, this ); this._updateResourcePicture( _rPicture ); @@ -3757,7 +3755,7 @@ var Editor = gOS.registerApplication( function(){ this.actualH = this.oPicture.height; var _reversibleImage = pettanr.image.createReversibleImage( - [ pettanr.CONST.RESOURCE_PICTURE_PATH, this.rPicture.id, '.', this.rPicture.ext ].join( '' ), + [ pettanr.CONST.PICTURE_PATH, this.rPicture.id, '.', this.rPicture.ext ].join( '' ), this.flipH * this.w, this.flipV * this.h ); if( this.reversibleImage !== null ){ @@ -4071,7 +4069,7 @@ var Editor = gOS.registerApplication( function(){ var _panelElement; if( isPanelPictureData !== true ){ _panelElement = new ImageElementClass( { - picture : data, + picture : data.picture, x : Math.floor( panelW / 2 - data.width / 2 ), y : Math.floor( panelH / 2 - data.height / 2 ), z : -1, @@ -5041,7 +5039,7 @@ var Model = ( function(){ function getPanelElementByTiming(){ var i, l = panelElementArray.length; while( timing < l * 2 ){ - for( i=0; i Date: Mon, 18 Feb 2013 09:47:10 +0900 Subject: [PATCH 04/16] version 0.5, building XDocument. --- 0.5.x/javascripts/system.js | 756 +++++++++++++++++++++++++++++++++----------- 1 file changed, 566 insertions(+), 190 deletions(-) diff --git a/0.5.x/javascripts/system.js b/0.5.x/javascripts/system.js index cfddd58..26ae050 100644 --- a/0.5.x/javascripts/system.js +++ b/0.5.x/javascripts/system.js @@ -6392,6 +6392,19 @@ var DOM = ( function( window, document ){ DOM.correctNodes( span ); return [ w, h ]; }, + getTextHeight : function( elm, w, content ){ + var div = DOM.createSpan(), + text = DOM.createText(), + w, h; + elm.appendChild( div ); + div.style.cssText = 'visibility:hidden;position:absolute;width:' + w + 'px;'; + div.appendChild( text ); + text.data = content; + w = div.offsetWidth; + h = div.offsetHeight; + DOM.correctNodes( div ); + return h; + }, correctNodes : function( node ){ var child; if( node && node.parentNode ){ @@ -7173,7 +7186,7 @@ var XDocument = ( function( window, document ){ var getIndex = Util.getIndex; var ROOT_LIST = []; var DEF_ATTRS = {}; - var AUTO = undefined; + var AUTO = Number.POSITIVE_INFINITY; var FULL = DEF_ATTRS; // something unigue value; var FLOOR = Math.floor; @@ -7199,10 +7212,12 @@ var XDocument = ( function( window, document ){ DEF_ATTRS.BOX_SIZING = 'content-box,padding-box,border-box,margin-box'.split(','); DEF_ATTRS.PAINT = 1; // 再描画のみ必要 DEF_ATTRS.REFLOW = 2; // レイアウトの再計算が必要 + DEF_ATTRS.FONT = 3; // フォントサイズが変更された + DEF_ATTRS.CONTENT_UPDATE = 4; // コンテンツが変更された DEF_ATTRS.borderWidth = [ DEF_ATTRS.REFLOW, 0, DEF_ATTRS.QUARTET | DEF_ATTRS.LENGTH ]; // em [ top, right, bottom, left ] DEF_ATTRS.borderColor = [ DEF_ATTRS.PAINT, 4, DEF_ATTRS.QUARTET | DEF_ATTRS.DEF_COLOR ]; // color [ top, right, bottom, left ] - DEF_ATTRS.borderStyle = [ DEF_ATTRS.REFLOW, 8, DEF_ATTRS.QUARTET | DEF_ATTRS.LIST, DEF_ATTRS.BORDER_STYLE ]; // string [ top, right, bottom, left ] + DEF_ATTRS.borderStyle = [ DEF_ATTRS.PAINT, 8, DEF_ATTRS.QUARTET | DEF_ATTRS.LIST, DEF_ATTRS.BORDER_STYLE ]; // string [ top, right, bottom, left ] DEF_ATTRS.cornerRadius = [ DEF_ATTRS.PAINT, 12, DEF_ATTRS.QUARTET | DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; // em, px [ top, right, bottom, left ] DEF_ATTRS.bgColor = [ DEF_ATTRS.PAINT, 16, DEF_ATTRS.COLOR ]; // color DEF_ATTRS.bgAlpha = [ DEF_ATTRS.PAINT, 17, DEF_ATTRS.U_DECIMAL ]; // 0 - 1 @@ -7220,19 +7235,19 @@ var XDocument = ( function( window, document ){ DEF_ATTRS.shadowInset = [ DEF_ATTRS.PAINT, 29, DEF_ATTRS.BOOLEAN ]; // true / false DEF_ATTRS.color = [ DEF_ATTRS.PAINT, 30, DEF_ATTRS.COLOR ]; // color - DEF_ATTRS.fontFamily = [ DEF_ATTRS.REFLOW, 31, DEF_ATTRS.FONT_NAME ]; // string - DEF_ATTRS.fontSize = [ DEF_ATTRS.REFLOW, 32, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; // em, % - DEF_ATTRS.bold = [ DEF_ATTRS.REFLOW, 33, DEF_ATTRS.BOOLEAN ]; // true / false - DEF_ATTRS.italic = [ DEF_ATTRS.REFLOW, 34, DEF_ATTRS.BOOLEAN ]; // true / false - DEF_ATTRS.lineHeight = [ DEF_ATTRS.REFLOW, 35, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT | DEF_ATTRS.NUMERICAL ]; // em, %, - DEF_ATTRS.letterSpacing = [ DEF_ATTRS.REFLOW, 36, DEF_ATTRS.LENGTH ]; // em - DEF_ATTRS.wordSpacing = [ DEF_ATTRS.REFLOW, 37, DEF_ATTRS.LENGTH ]; - DEF_ATTRS.align = [ DEF_ATTRS.REFLOW, 38, DEF_ATTRS.LIST, DEF_ATTRS.ALIGN ]; + DEF_ATTRS.fontFamily = [ DEF_ATTRS.FONT, 31, DEF_ATTRS.FONT_NAME ]; // string + DEF_ATTRS.fontSize = [ DEF_ATTRS.FONT, 32, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; // em, % + DEF_ATTRS.bold = [ DEF_ATTRS.FONT, 33, DEF_ATTRS.BOOLEAN ]; // true / false + DEF_ATTRS.italic = [ DEF_ATTRS.FONT, 34, DEF_ATTRS.BOOLEAN ]; // true / false + DEF_ATTRS.lineHeight = [ DEF_ATTRS.FONT, 35, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT | DEF_ATTRS.NUMERICAL ]; // em, %, + DEF_ATTRS.letterSpacing = [ DEF_ATTRS.FONT, 36, DEF_ATTRS.LENGTH ]; // em + DEF_ATTRS.wordSpacing = [ DEF_ATTRS.FONT, 37, DEF_ATTRS.LENGTH ]; + DEF_ATTRS.align = [ DEF_ATTRS.FONT, 38, DEF_ATTRS.LIST, DEF_ATTRS.ALIGN ]; DEF_ATTRS.decoration = [ DEF_ATTRS.PAINT, 39, DEF_ATTRS.LIST, DEF_ATTRS.TEXT_DECORATION ]; - DEF_ATTRS.transform = [ DEF_ATTRS.REFLOW, 40, DEF_ATTRS.LIST, DEF_ATTRS.TEXT_TRANSFORM ]; - DEF_ATTRS.shadowColor = [ DEF_ATTRS.PAINT, 41, DEF_ATTRS.COLOR ]; - DEF_ATTRS.shadowOffsetX = [ DEF_ATTRS.PAINT, 42, DEF_ATTRS.LENGTH ]; - DEF_ATTRS.shadowOffsetY = [ DEF_ATTRS.PAINT, 43, DEF_ATTRS.LENGTH ]; + DEF_ATTRS.transform = [ DEF_ATTRS.FONT, 40, DEF_ATTRS.LIST, DEF_ATTRS.TEXT_TRANSFORM ]; + DEF_ATTRS.textShadowColor = [ DEF_ATTRS.PAINT, 41, DEF_ATTRS.COLOR ]; + DEF_ATTRS.textShadowOffsetX = [ DEF_ATTRS.PAINT, 42, DEF_ATTRS.LENGTH ]; + DEF_ATTRS.textShadowOffsetY = [ DEF_ATTRS.PAINT, 43, DEF_ATTRS.LENGTH ]; DEF_ATTRS.shadowBlur = [ DEF_ATTRS.PAINT, 44, DEF_ATTRS.LENGTH ]; DEF_ATTRS.width = [ DEF_ATTRS.REFLOW, 45, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT, DEF_ATTRS.WIDTH_HEIGHT ]; @@ -7250,6 +7265,18 @@ var XDocument = ( function( window, document ){ DEF_ATTRS.bottom = [ DEF_ATTRS.REFLOW, 63, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; DEF_ATTRS.right = [ DEF_ATTRS.REFLOW, 64, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; + var ATTRS = ( function(){ + var ret = {}, + obj = DEF_ATTRS, + p; + for( p in obj ){ + if( Type.isArray( obj[ p ] ) === true ){ + ret[ p ] = obj[ p ][ 1 ]; + }; + }; + return ret; + })(); + /** * 再計算と再描画 * redraw 再描画はパラメータ変更後に setTimeout で @@ -7289,57 +7316,8 @@ var XDocument = ( function( window, document ){ childW = 0, childH = 0, styles, child, calc, i; - - if( style ){ - styles = style.data; - calc = BasicLayoutManager.calcValue; - sizing = styles[ 53 ]; - page = styles[ 54 ]; - x = calc( styles[ 55 ], allowW ); - y = calc( styles[ 56 ], page === true ? allowH : allowW ); - w = styles[ 45 ]; - minW = styles[ 46 ]; - maxW = styles[ 47 ]; - contentW = BasicLayoutManager.finalValue( w, minW, maxW, allowW ); - h = styles[ 48 ]; - minW = styles[ 49 ]; - maxW = styles[ 50 ]; - contentH = BasicLayoutManager.finalValue( h, minW, maxW, allowH ); - autoSize = w === AUTO || h === AUTO; - paddingT = calc( styles[ 51 ], page === true ? allowH : allowW );// paddingTRBL の % 指定は 最大幅に対して TB でも幅に対して - paddingR = calc( styles[ 52 ], allowW ); - paddingT = calc( styles[ 53 ], page === true ? allowH : allowW ); - paddingL = calc( styles[ 54 ], allowW, autoW ); - borderT = styles[ 0 ]; - borderR = styles[ 1 ]; - borderB = styles[ 2 ]; - borderL = styles[ 3 ]; - marginT = calc( styles[ 55 ], page === true ? allowH : allowW );// marginTRBL の % 指定は 最大幅に対して TB でも幅に対して - marginR = calc( styles[ 56 ], allowW ); - marginB = calc( styles[ 57 ], page === true ? allowH : allowW ); - marginL = calc( styles[ 58 ], allowW ); - boxW = contentW; - boxH = contentH; - switch( sizing ){ - case 3 : // margin-box - contentW -= ( marginR + marginL ); - contentH -= ( marginT + marginR ); - - case 2 : // border-box - contentW -= ( borderR + borderL ); - contentH -= ( borderT + borderR ); - case 1 : // padding-box - contentW -= ( paddingR + paddingL ); - contentH -= ( paddingT + paddingR ); - // case 0 : // content-box - }; - } else { - boxW = contentW = w = allowW; - boxH = contentH = h = allowH; - minW = minH = 0; - maxW = maxH = Infinity; - autoSize = false; - }; + + nodeData.preSizing( allowW, allowH ); if( nodeData.contentWidth !== contentW || nodeData.contentHeight === contentH ){ if( autoSize === false ){ @@ -7413,17 +7391,39 @@ var XDocument = ( function( window, document ){ return v; }; BasicLayoutManager.calcValue = function( styleValue, srcValue ){ - if( styleValue === 0 ) return 0; - // 100% - if( styleValue === FULL || styleValue === AUTO ) return srcValue; - if( 1 <= styleValue ) return styleValue; // legth - if( -1 < styleValue ) return FLOOR( srcValue * styleValue ); // % + switch( styleValue ){ + case 0 : + return 0; + case AUTO : + return AUTO; + case FULL : + return srcValue; // 100% + default : + if( 1 <= styleValue ) return styleValue; // legth + if( -1 < styleValue ) return FLOOR( srcValue * styleValue ); // % + }; return styleValue; // - length }; + BasicLayoutManager.advancedCalcValue = function( styleValue, srcValue ){ + switch( styleValue ){ + case 0 : + return 0; + case AUTO : + return srcValue; + case FULL : + throw new Error( 'calcValueFromSelf FULL' ); + // return ; // 100% + default : + if( 1 <= styleValue ) return styleValue; + if( -1 < styleValue ) return FLOOR( ( srcValue / ( 1 - styleValue ) ) * styleValue ); // % + }; + return styleValue; // - length + } var NodeStylePrivate = Class.create( Class.PRIVATE_DATA | Class.POOL_OBJECT, { + fontCssText : null, colorCssText : null, layoutCssText : null, Constructor : function(){ @@ -7458,7 +7458,10 @@ var XDocument = ( function( window, document ){ var styleClass = Class.getClass( this.User ), dataClass = Class.getClass( this ); }, - attr : function( prop, v ){ + /* + * opt_unit は getter のみ + */ + attr : function( prop, v, opt_unit ){ var update = prop[ 0 ], propID = prop[ 1 ], type = prop[ 2 ], @@ -7536,11 +7539,17 @@ var XDocument = ( function( window, document ){ }; return this.User; }; - if( update === DEF_ATTRS.REFLOW ){ - delete this.layoutCssText; - } else { - delete this.colorCssText; + switch( update ){ + case DEF_ATTRS.REFLOW : + delete this.layoutCssText; + break; + case DEF_ATTRS.PAINT : + delete this.colorCssText; + break; + case DEF_ATTRS.FONT : + delete this.fontCssText; }; + if( this.dirty < update ){ this.dirty = update; roots = this.rootList; @@ -7552,6 +7561,25 @@ var XDocument = ( function( window, document ){ if( list ) _v = Util.getIndex( list, v ); data[ propID ] = _v !== -1 ? _v : v; + + switch( prop ){ + case DEF_ATTRS.left : + case DEF_ATTRS.right : + this.ltrtWidth = data[ DEF_ATTRS.left[ 0 ] ] === undefined && data[ DEF_ATTRS.right[ 0 ] ] === undefined; + break; + case DEF_ATTRS.top : + case DEF_ATTRS.bottom : + this.tpbtHeight = data[ DEF_ATTRS.top[ 0 ] ] === undefined && data[ DEF_ATTRS.bottom[ 0 ] ] === undefined; + break; + case DEF_ATTRS.width : + this.autoWidth = v === AUTO; + this.prctWidth = v === FULL || v < 1; + break; + case DEF_ATTRS.height : + this.autoHeight = v === AUTO; + this.prctHeight = v === FULL || v < 1; + break; + }; return this.User; }; /* @@ -7572,11 +7600,90 @@ var XDocument = ( function( window, document ){ return v; }, cssText : function(){ - if( this.colorCssText === null ) this.colorCssText = this.createColorCssText(); + if( this.fontCssText === null ) this.fontCssText = this.createFontCssText(); if( this.layoutCssText === null ) this.layoutCssText = this.createLayoutCssText(); - return this.colorCssText + ';' + this.layoutCssText; + if( this.colorCssText === null ) this.colorCssText = this.createColorCssText(); + return [ this.fontCssText, this.colorCssText, this.layoutCssText ].join( ';' ); + }, + createFontCssText : function(){ + var data = this.data, + css = [], + v; + if( v = data[ ATTRS.fontFamily ] ) css[ 0 ] = 'font-family:' + v; + if( v = data[ ATTRS.fontSize ] ) css[ css.length - 1 ] = 'font-size:' + v; + if( v = data[ ATTRS.bold ] ) css[ css.length - 1 ] = 'font-weight:bold'; + if( v = data[ ATTRS.bold ] ) css[ css.length - 1 ] = 'font-style:italic'; + if( v = data[ ATTRS.lineHeight ] ) css[ css.length - 1 ] = 'line-height:' + v; + if( v = data[ ATTRS.letterSpacing ] ) css[ css.length - 1 ] = 'letter-spacing:' + v; + if( v = data[ ATTRS.wordSpacing ] ) css[ css.length - 1 ] = 'word-spacing:' + v; + if( v = data[ ATTRS.align ] ) css[ css.length - 1 ] = 'text-align:' + DEF_ATTRS.ALIGN[ v ]; + if( v = data[ ATTRS.transform ] ) css[ css.length - 1 ] = 'text-transform:' + DEF_ATTRS.TEXT_TRANSFORM[ v ]; + return css.join( ',' ); }, createColorCssText : function(){ + var data = this.data, + css = [], + v, x, y, c, b; + if( v = data[ ATTRS.borderColor ] ) css[ 0 ] = 'border-color:' + v; + if( v = data[ ATTRS.borderStyle + 0 ] ) css[ css.length - 1 ] = 'border-top-style:' + DEF_ATTRS.BORDER_STYLE[ v ]; + if( v = data[ ATTRS.borderStyle + 1 ] ) css[ css.length - 1 ] = 'border-right-style:' + DEF_ATTRS.BORDER_STYLE[ v ]; + if( v = data[ ATTRS.borderStyle + 2 ] ) css[ css.length - 1 ] = 'border-bottom-style:' + DEF_ATTRS.BORDER_STYLE[ v ]; + if( v = data[ ATTRS.borderStyle + 3 ] ) css[ css.length - 1 ] = 'border-left-style:' + DEF_ATTRS.BORDER_STYLE[ v ]; + if( v = data[ ATTRS.cornerRadius + 0 ] ) css[ css.length - 1 ] = 'corner-radius-top:' + v; + if( v = data[ ATTRS.cornerRadius + 1 ] ) css[ css.length - 1 ] = 'corner-radius-right:' + v; + if( v = data[ ATTRS.cornerRadius + 2 ] ) css[ css.length - 1 ] = 'border-radius-bottom:' + v; + if( v = data[ ATTRS.cornerRadius + 3 ] ) css[ css.length - 1 ] = 'border-radius-left:' + v; + if( v = data[ ATTRS.bgColor ] ) css[ css.length - 1 ] = 'background-color:' + v; + // ATTRS.bgAlpha + if( v = data[ ATTRS.bgImgUrl ] ) css[ css.length - 1 ] = 'background-image:url(' + v + ')'; + x = data[ ATTRS.bgImgRepeatX ]; + y = data[ ATTRS.bgImgRepeatY ]; + if( x && y ){ + css[ css.length - 1 ] = 'background-repeat:repeat'; + } else + if( x ){ + css[ css.length - 1 ] = 'background-repeat:repeat-x'; + } else + if( y ){ + css[ css.length - 1 ] = 'background-repeat:repeat-y'; + }; + x = data[ ATTRS.bgImgPositionX ]; + y = data[ ATTRS.bgImgPositionY ]; + if( x && y ){ + css[ css.length - 1 ] = 'background-position:' + x + ' ' + y; + } else + if( x ){ + css[ css.length - 1 ] = 'background-position:' + x + ' 0'; + } else + if( y ){ + css[ css.length - 1 ] = 'background-position:0 ' + y; + }; + if( v = data[ ATTRS.color ] ) css[ css.length - 1 ] = 'color:' + v; + if( v = data[ ATTRS.decoration ] ) css[ css.length - 1 ] = 'text-decoration:' + DEF_ATTRS.TEXT_DECORATION[ v ]; + x = data[ ATTRS.textShadowOffsetX ]; + y = data[ ATTRS.textShadowOffsetY ]; + b = data[ ATTRS.textShadowBlur ]; + c = data[ ATTRS.textShadowColor ]; + if( c || x || y || b ){ + css[ css.length - 1 ] = 'text-shadow:' + x + ' ' + y + ' ' + b + ' ' + c; + }; + /* + ATTRS.shadowColor = [ DEF_ATTRS.PAINT, 23, DEF_ATTRS.COLOR ]; // color + ATTRS.shadowAlpha = [ DEF_ATTRS.PAINT, 24, DEF_ATTRS.U_DECIMAL ]; // 0 - 1 + ATTRS.shadowOffsetX = [ DEF_ATTRS.PAINT, 25, DEF_ATTRS.LENGTH ]; // em + ATTRS.shadowOffsetY = [ DEF_ATTRS.PAINT, 26, DEF_ATTRS.LENGTH ]; // em + ATTRS.shadowBlur = [ DEF_ATTRS.PAINT, 27, DEF_ATTRS.LENGTH ]; // em + ATTRS.shadowSpread = [ DEF_ATTRS.PAINT, 28, DEF_ATTRS.LENGTH ]; // em + ATTRS.shadowInset = [ DEF_ATTRS.PAINT, 29, DEF_ATTRS.BOOLEAN ]; // true / false + */ + }, + createBoxShadowCssText : function(){ + + }, + createBGAlphaCssText : function(){ + + }, + createTextShadowCssText : function(){ }, createLayoutCssText : function(){ @@ -7680,14 +7787,14 @@ var XDocument = ( function( window, document ){ transform : function( v ){ return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.transform, v ); }, - shadowColor : function( v ){ - return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.shadowColor, v ); + textShadowColor : function( v ){ + return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.textShadowColor, v ); }, - shadowOffsetX : function( v ){ - return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.shadowOffsetX, v ); + textShadowOffsetX : function( v ){ + return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.textShadowOffsetX, v ); }, - shadowOffsetY : function( v ){ - return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.shadowOffsetY, v ); + textShadowOffsetY : function( v ){ + return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.textShadowOffsetY, v ); }, shadowBlur : function( v ){ return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.shadowBlur, v ); @@ -7702,21 +7809,36 @@ var XDocument = ( function( window, document ){ 'NodePrivate', Class.PRIVATE_DATA | Class.POOL_OBJECT, { - elmWrap : null, - textNode : null, - autoWidth : false, - autoHeight : false, - autoSize : false, - boxX : 0, - boxY : 0, - boxWidth : 0, - boxHeight : 0, - boxRight : 0, - boxBottom : 0, - contentX : 0, - contentY : 0, - contentWidth : 0, - contentHeight : 0, + elmWrap : null, + textNode : null, + boxX : 0, + boxY : 0, + boxWidth : 0, + boxHeight : 0, + contentL : 0, + contentT : 0, + contentR : 0, + contentB : 0, + borderL : 0, + borderT : 0, + borderR : 0, + borderB : 0, + paddingL : 0, + paddingT : 0, + paddingR : 0, + paddingB : 0, + marginL : 0, + marginT : 0, + marginR : 0, + marginB : 0, + boxSizingOffsetLR : 0, + boxSizingOffsetTB : 0, + contentWidth : 0, + minContentWidth : 0, + maxContentWidth : AUTO, + contentHeight : 0, + minContentHeight : 0, + maxContentHeight : AUTO, Constructor : function( __root, __parent ){ this.__root = __root; if( __parent ) this.__parent = __parent; @@ -7737,124 +7859,375 @@ var XDocument = ( function( window, document ){ }; return this._style; }, + content : function( v ){ + if( Type.isString( v ) === true ){ + if( !this.textNode || ( this.textNode && this.textNode.data !== v ) ){ + this._content = v; + this.updateContent = true; + }; + return this.User; + } else + if( v === null ){ + if( this._content !== v && this.textNode ){ + this._content = v; + this.updateContent = true; + }; + return this.User; + }; + if( this._content ) return this._content; + if( this._content === null ) return null; + if( this.textNode ) return this.textNode.data; + return null; + }, /** - * 1. 要素の追加・削除 - * 2. auto 指定時は要素の高さ取得. - * 3. 親の許す子の最大サイズと自信のスタイル指定から、自身の位置とサイズを計算 - * 4. 描画更新リストに追加 + * 要素の追加・削除 + * 1. ペイントがある // 予約のみ + * 2. コンテンツがある // 予約のみ * + * 3. コンテンツを削除 // 予約のみ + * 4. 要素を削除 // 予約のみ + * + * コンテンツの再計算 + * 0. 要素追加して css セット + * 1. コンテンツの変更 + * 2. font 指定の変更 + * 3. contentWidth の変更 (コンテンツの高さの再計算) 前回の contentWidth の保持 + * + * contentSize, scrollSize の決定 */ - reflow : function(){ - var content = this._textContent, + musure : function( dirty ){ + var content = this._content, + root = this.__root, style = this.__style, - parent = this.__parent, - size, data, w, h; - - if( content || ( style && style.hasPaint === true ) ){ + w = this.contentWidth, + h = this.contentHeight; + switch( this.updateContent === true ? DEF_ATTRS.CONTENT_UPDATE : dirty ){ + case DEF_ATTRS.CONTENT_UPDATE : // コンテンツが変更された + this.paint( 0 ); + this.lastContentWidth = -1; + case DEF_ATTRS.FONT : // フォントサイズが変更された + case DEF_ATTRS.REFLOW : // レイアウトの再計算が必要 + /* http://web-designs.seesaa.net/article/188400668.html + * min-width の値が max-width の値より大きい場合は、max-width の値は min-width の値に設定される。 + * + * テキストノードがあり + * 1. contentWidth === AUTO + * style を更新して contentWidth の決定 + * min or max に引っかかったら style 更新 + * contentHeight === AUTO の場合 + * textHeight の決定 + * contentHeight !== AUTO の場合 scrollHeight のみ更新 + * 2. contentHeight === AUTO かつ + * コンテンツの高さの再取得が必要( contentWidth が最終計測時の contentWidth と一致 かつ フォント・コンテンツに変更無し の場合再取得不要) + * style を更新して contentHeight の決定 + * 必要でない + * 3. content のサイズがすでに決定している + * コンテンツの高さの再取得が必要 + * 必要でない + */ + if( this.textNode ){ + if( w === AUTO ){ + this.commitStyle(); + w = this.contentWidth = this.textNode.offsetWidth; + this.scrollWidth = w + this.contentL + this.contentR; + if( this.maxContentWidth < w - this.boxSizingOffsetLR ) this.contentWidth = this.maxContentWidth + this.boxSizingOffsetLR; + if( w - this.boxSizingOffsetLR < this.minContentWidth ) this.contentWidth = this.minContentWidth + this.boxSizingOffsetLR; + this.lastContentWidth = this.contentWidth; + + w !== this.contentWidth && this.commitStyle(); + + if( h === AUTO ){ + h = this.conetntHeight = this.textNode.offsetHeight; + this.scrollHeight = h + this.contentT + this.contentB; + if( this.maxContentHeight < h - this.boxSizingOffsetTB ) this.contentHeight = this.maxContentHeight + this.boxSizingOffsetTB; + if( h - this.boxSizingOffsetTB < this.minContentHeight ) this.contentHeight = this.minContentHeight + this.boxSizingOffsetTB; + } else { + this.scrollHeight = this.textNode.offsetHeight + this.contentT + this.contentB; + }; + } else + if( h === AUTO ){ + if( w !== this.lastContentWidth || dirty !== DEF_ATTRS.REFLOW ){ + this.commitStyle(); + this.lastContentWidth = w; + h = this.conetntHeight = this.textNode.offsetHeight; + this.scrollWidth = w + this.contentL + this.contentR; + this.scrollHeight = h + this.contentT + this.contentB; + if( this.maxContentHeight < h - this.boxSizingOffsetTB ) this.contentHeight = this.maxContentHeight + this.boxSizingOffsetTB; + if( h - this.boxSizingOffsetTB < this.minContentHeight ) this.contentHeight = this.minContentHeight + this.boxSizingOffsetTB; + } else { + this.scrollWidth = w + this.contentL + this.contentR; + this.scrollHeight = h + this.contentT + this.contentB; + root.paintReserve( this ); + }; + } else { + if( dirty !== DEF_ATTRS.REFLOW ){ + this.commitStyle(); + this.scrollWidth = this.textNode.offsetWidth + this.contentL + this.contentR; + this.scrollHeight = this.textNode.offsetHeight + this.contentT + this.contentB; + } else { + root.paintReserve( this ); + this.scrollWidth = w + this.contentL + this.contentR; + this.scrollHeight = h + this.contentT + this.contentB; + }; + }; + } else { + if( w === AUTO ) this.contentWidth = w = 0 < this.minContentWidth ? this.minContentWidth : 0; + if( h === AUTO ) this.contentHeight = h = 0 < this.minContentHeight ? this.minContentHeight : 0; + this.scrollWidth = w + this.contentL + this.contentR; + this.scrollHeight = h + this.contentT + this.contentB; + root.paintReserve( this ); + }; + break; + case DEF_ATTRS.PAINT : // 再描画のみ必要 + root.paintReserve( this ); + break; + }; + }, + paint : function( dirty ){ + var content = this._content, + style = this.__style; + if( this.updateContent === true || ( style && style.hasPaint === true ) ){ if( !this.elmWrap ){ this.elmWrap = DOM.createDiv(); - parent.addDisplayElement( this ); + this.__parent.addDisplayElement( this ); }; - if( style && style.hasStyle === true ){ - this.elmWrap.style.cssText = style.cssText(); - }; - if( content ){ - if( !this.textNode ){ - this.textNode = DOM.cerateText(); - this.elmWrap.appendChild( this.textNode ); - }; - if( style && ( style.autoWidth === true || style.autoHeight === true ) ){ - size = DOM.getTextSize( this.elmWrap, content ); - this.contentWidth = size[ 0 ]; - this.conetntHeight = size[ 1 ]; - }; - this.textNode.data = content; - } else - if( this.textNode ){ - DOM.correct( this.textNode ); - delete this.textNode; - delete this.contentWidth; - delete this.conetntHeight; + dirty !== 0 && this.commitStyle(); + if( this.updateContent === true ){ + if( content !== null ){ + if( !this.textNode ){ + this.textNode = DOM.cerateText(); + this.elmWrap.appendChild( this.textNode ); + }; + this.textNode.data = content; + } else + if( this.textNode ){ + DOM.correct( this.textNode ); + delete this.textNode; + delete this.contentWidth; + delete this.conetntHeight; + delete this.scrollWidth; + delete this.scrollHeight; + }; }; - this.boxWidth = this.elmWrap.offsetWidth; - this.boxHeight = this.elmWrap.offsetHeight; } else + if( this.elmWrap && content === null && ( !style || style.hasPaint === false ) ){ + this.__parent.removeDisplayElement( this ); + DOM.correct( this.elmWrap ); + delete this.contentWidth; + delete this.conetntHeight; + }; + }, + commitStyle : function(){ + var css; if( this.elmWrap ){ - parent.removeDisplayElement( this ); + css = this.__style ? this.__style.cssText( this ) : ''; + if( this.contentWidth !== AUTO ) css += 'width:' + this.contentWidth + 'px'; + if( this.contentHeight !== AUTO ) css += 'height:' + this.contentHeight + 'px'; + this.elmWrap.style.cssText = css; }; }, - preSizing : function(){ - var parent = nodeData.__parent, - allowW = parent.contentWidth, - allowH = parent.contentHeight, - style = nodeData.__style, - x, y, w, minW, maxW, h, minH, maxH, - contentW, contentH, - page, + /* + * 親の サイズを元に自身のサイズを計算していく + */ + preMesure : function( allowW, allowH ){ + var style = this.__style, + styles, calc, box, min, max, + contentW, contentH, allowSize, boxMinus, paddingT, paddingR, paddingB, paddingL, borderT, borderR, borderB, borderL, - marginT, marginR, marginB, marginL, - styles, calc; + marginT, marginR, marginB, marginL; if( style ){ styles = style.data; calc = BasicLayoutManager.calcValue; - page = styles[ 54 ] === true ? allowH : allowW ; - w = styles[ 45 ]; - minW = styles[ 46 ]; - maxW = styles[ 47 ]; - contentW = BasicLayoutManager.finalValue( w, minW, maxW, allowW ); - h = styles[ 48 ]; - minW = styles[ 49 ]; - maxW = styles[ 50 ]; - contentH = BasicLayoutManager.finalValue( h, minW, maxW, allowH ); - paddingT = calc( styles[ 51 ], page );// paddingTRBL の % 指定は 最大幅に対して TB でも幅に対して - paddingR = calc( styles[ 52 ], allowW ); - paddingB = calc( styles[ 53 ], page ); - paddingL = calc( styles[ 54 ], allowW ); - borderT = styles[ 0 ]; - borderR = styles[ 1 ]; - borderB = styles[ 2 ]; - borderL = styles[ 3 ]; - marginT = calc( styles[ 55 ], page );// marginTRBL の % 指定は 最大幅に対して TB でも幅に対して - marginR = calc( styles[ 56 ], allowW ); - marginB = calc( styles[ 57 ], page ); - marginL = calc( styles[ 58 ], allowW ); - this.boxWidth = contentW; - this.boxHeight = contentH; - switch( styles[ 53 ] ){ - case 3 : // margin-box - contentW -= ( marginR + marginL ); - contentH -= ( marginT + marginR ); - - case 2 : // border-box - contentW -= ( borderR + borderL ); - contentH -= ( borderT + borderR ); - case 1 : // padding-box - contentW -= ( paddingR + paddingL ); - contentH -= ( paddingT + paddingR ); - // case 0 : // content-box + box = styles[ ATTRS.sizing ]; + + // Width + // 自身が ltrtWidth の場合 親が AUTO ではない + // 自身が ltrtWidth でない場合自身が AUTO はなくかつ親 が AUTO の場合自身は % でない + if( style.ltrtWidth ? allowW !== AUTO : !style.autoWidth && ( allowW !== AUTO || !style.prctWidth ) ){ + if( style.ltrtWidth ){ + contentW = allowW - calc( styles[ ATTRS.left ], allowW ) - calc( styles[ ATTRS.right ], allowW ); + } else { + contentW = BasicLayoutManager.finalValue( styles[ ATTRS.width ], styles[ ATTRS.minWidth ], styles[ ATTRS.maxWidth ], allowW ); + }; + paddingR = calc( styles[ ATTRS.padding + 1 ], allowW ); + paddingL = calc( styles[ ATTRS.padding + 3 ], allowW ); + borderR = styles[ ATTRS.border + 1 ]; + borderL = styles[ ATTRS.margin + 3 ]; + marginR = calc( styles[ ATTRS.margin + 1 ], allowW ); + marginL = calc( styles[ ATTRS.margin + 3 ], allowW ); + this.boxWidth = contentW; + boxMinus = 0; + switch( box ){ + case 3 : // margin-box + boxMinus = - marginR - marginL; + case 2 : // border-box + boxMinus -= borderR + borderL; + case 1 : // padding-box + boxMinus -= paddingR + paddingL; + // case 0 : // content-box + }; + this.contentL = marginL + borderL + paddingL; + this.contentR = marginR + borderR + paddingR; + this.contentWidth = contentW + boxMinus; + this.boxSizingOffsetLR = boxMinus; + } else { + this.boxWidth = this.contentWidth = AUTO; + min = styles[ ATTRS.minWidth ]; + max = styles[ ATTRS.maxWidth ]; + this.minContentWidth = 1 <= min ? min : 0; + this.maxContentWidth = 1 <= max ? max : AUTO; + delete this.boxSizingOffsetLR; + }; + + // Height + if( style.tpbtHeight ? allowH !== AUTO : !style.autoHeight && ( allowH !== AUTO || !style.prctHeight ) ){ + if( style.tpbtHeight ){ + contentH = allowH - calc( styles[ ATTRS.top ], allowH ) - calc( styles[ ATTRS.bottom ], allowH ); + } else { + contentH = BasicLayoutManager.finalValue( styles[ ATTRS.height ], styles[ ATTRS.minHeight ], styles[ ATTRS.maxHeight ], allowH ); + }; + allowSize = styles[ ATTRS.pageBox ] === true ? allowH : allowW; + paddingT = calc( styles[ ATTRS.padding + 0 ], allowSize );// paddingTRBL の % 指定は 最大幅に対して TB でも幅に対して + paddingB = calc( styles[ ATTRS.padding + 2 ], allowSize ); + borderT = styles[ ATTRS.border + 0 ]; + borderB = styles[ ATTRS.border + 2 ]; + marginT = calc( styles[ ATTRS.margin + 0 ], allowSize );// marginTRBL の % 指定は 最大幅に対して TB でも幅に対して + marginB = calc( styles[ ATTRS.margin + 2 ], allowSize ); + this.boxHeight = contentH; + boxMinus = 0; + switch( box ){ + case 3 : // margin-box + boxMinus = - marginT - marginR; + case 2 : // border-box + boxMinus -= borderT + borderR; + case 1 : // padding-box + boxMinus -= paddingT + paddingR; + // case 0 : // content-box + }; + this.contentT = marginT + borderT + paddingT; + this.conetntB = marginB + borderB + paddingB; + this.contentHeight = contentH + boxMinus; + this.boxSizingOffsetTB = boxMinus; + } else { + this.boxHeight = this.contentHeight = AUTO; + min = styles[ ATTRS.minHeight ]; + max = styles[ ATTRS.maxHeight ]; + this.minContentHeight = 1 <= min ? min : 0; + this.maxContentHeight = 1 <= max ? max : AUTO; + delete this.boxSizingOffsetTB; }; - this.contentX = marginL + borderL + paddingL; - this.contentY = marginT + borderT + paddingT; - this.contentWidth = contentW; - this.contentHeight = contentH; - this.autoHeight = h === AUTO; - this.autoWidth = w === AUTO; - this.autoSize = this.autoWidth || this.autoHeight; } else { this.boxWidth = this.contentWidth = allowW; this.boxHeight = this.contentHeight = allowH; - delete this.contentX; - delete this.contentY; - delete this.autoSize; - delete this.autoWidth; - delete this.autoHeight; + delete this.minContentHeight; + delete this.maxContentHeight; + delete this.contentL; + delete this.contentT; + delete this.contentR; + delete this.contentB; + }; + }, + /** + * 自身のコンテンツサイズを元に AUTO な width, height を確定していく + */ + postMesure : function(){ + var style = this.__style, + styles, calc, box, + contentW, contentH, w, h + contentSize, contentPlus; + if( style ){ + styles = style.data; + calc = BasicLayoutManager.advancedCalcValue; + contentW = this.contentWidth; + box = styles[ ATTRS.sizing ]; + + // Width + if( this.boxWidth === AUTO ){ + paddingR = calc( styles[ ATTRS.padding + 1 ], contentW ); + paddingL = calc( styles[ ATTRS.padding + 3 ], contentW ); + borderR = styles[ ATTRS.border + 1 ]; + borderL = styles[ ATTRS.border + 3 ]; + marginR = calc( styles[ ATTRS.margin + 1 ], contentW ); + marginL = calc( styles[ ATTRS.margin + 3 ], contentW ); + contentPlus = 0; + switch( box ){ + case 3 : // margin-box + contentPlus = ( marginR + marginL ); + case 2 : // border-box + contentPlus += ( borderR + borderL ); + case 1 : // padding-box + contentPlus += ( paddingR + paddingL ); + // case 0 : // content-box + }; + this.contentWidth = contentW; + contentW += contentPlus; + if( !style.ltrtWidth ){ + min = styles[ ATTRS.minWidth ]; + max = styles[ ATTRS.maxWidth ]; + if( contentW < min && 1 <= min && contentPlus < min ){ + this.contentWidth = min - contentPlus; + } else + if( max < contentW && 1 <= max && contentPlus < max ){ + this.contentWidth = max - contentPlus; + }; + }; + this.contentL = marginL + borderL + paddingL; + this.contentR = marginR + borderR + paddingR; + this.boxWidth = this.contentWidth + this.contentL + this.contentR; + }; + // Height + if( this.boxHeight === AUTO ){ + contentH = this.contentHeight; + contentSize = styles[ ATTRS.pageBox ] === true ? contentH : contentW; + paddingT = calc( styles[ ATTRS.padding + 0 ], contentSize );// paddingTRBL の % 指定は 最大幅に対して TB でも幅に対して + paddingB = calc( styles[ ATTRS.padding + 2 ], contentSize ); + borderT = styles[ ATTRS.border + 0 ]; + borderB = styles[ ATTRS.border + 2 ]; + marginT = calc( styles[ ATTRS.margin + 0 ], contentSize );// marginTRBL の % 指定は 最大幅に対して TB でも幅に対して + marginB = calc( styles[ ATTRS.margin + 2 ], contentSize ); + contentPlus = 0; + switch( box ){ + case 3 : // margin-box + contentPlus = ( marginT + marginB ); + case 2 : // border-box + contentPlus += ( borderT + borderB ); + case 1 : // padding-box + contentPlus += ( paddingT + paddingB ); + // case 0 : // content-box + }; + this.contentHeight = contentH; + contentH += contentPlus; + if( !style.tpbtHeight ){ + min = styles[ ATTRS.minHeight ]; + max = styles[ ATTRS.maxHeight ]; + if( contentH < min && 1 <= min && contentPlus < min ){ + this.contentHeight = min - contentPlus; + } else + if( max < contentH && 1 <= max && contentPlus < max ){ + this.contentHeight = max - contentPlus; + }; + }; + this.contentT = marginT + borderT + paddingT; + this.contentB = marginB + borderB + paddingB; + this.boxHeight = this.contentHeight + this.contentT + this.contentB; + }; + } else { + this.boxWidth = this.contentWidth; + this.boxHeight = this.contentHeight; + delete this.minContentHeight; + delete this.maxContentHeight; + delete this.contentL; + delete this.contentT; + delete this.contentR; + delete this.contentB; }; }, addDisplayElement : function( nodeData ){ - + // 描画更新リストに追加 }, removeDisplayElement : function( nodeData ){ + // 描画更新リストに追加 DOM.correct( nodeData.elmWrap ); delete nodeData.elmWrap; delete nodeData.textNode; @@ -7873,6 +8246,9 @@ var XDocument = ( function( window, document ){ Constructor : function( root, parent ){ Node.newPrivateData( this, LayoutBox.getPrivateData( root ), parent ? LayoutBox.getPrivateData( parent ) : undefined, this ); }, + content : function( v ){ + return Node.getPrivateData( this ).content( v ); + }, style : function( v ){ return Node.getPrivateData( this ).paint( v ); }, -- 2.11.0 From 1cb589585bcfaa4a59a6a3769a253cf8ffe4cfc0 Mon Sep 17 00:00:00 2001 From: itozyun Date: Wed, 20 Feb 2013 09:03:33 +0900 Subject: [PATCH 05/16] building XDocument.. --- 0.5.x/javascripts/system.js | 137 +++++++++++++++++++++----------------------- 1 file changed, 64 insertions(+), 73 deletions(-) diff --git a/0.5.x/javascripts/system.js b/0.5.x/javascripts/system.js index 26ae050..ffb7e8a 100644 --- a/0.5.x/javascripts/system.js +++ b/0.5.x/javascripts/system.js @@ -7297,86 +7297,50 @@ var XDocument = ( function( window, document ){ // draw }, - reflow : function( nodeData ){ - var parent = nodeData.__parent, - allowW = parent.contentWidth, - allowH = parent.contentHeight, - autoW = parent.autoWidth, - autoH = parent.autoHeight, - offsetX = parent.offsetX, - offsetY = parent.offsetY, - children = nodeData.children, - style = nodeData.__style, - x, y, w, minW, maxW, h, minH, maxH, - contentW, contentH, boxW, boxH, - autoSize, sizing, page, - paddingT, paddingR, paddingB, paddingL, - borderT, borderR, borderB, borderL, - marginT, marginR, marginB, marginL, - childW = 0, - childH = 0, - styles, child, calc, i; + reflow : function( nodeData, allowW, allowH ){ + var children = nodeData.children, + contentW, contentH, autoW, autoH, auto, calc, + childW, childH, child, i, style, data, + t, r, b, l; - nodeData.preSizing( allowW, allowH ); - - if( nodeData.contentWidth !== contentW || nodeData.contentHeight === contentH ){ - if( autoSize === false ){ - nodeData.updateLayout(); - nodeData.contentWidth = contentW; - nodeData.contentHeight = contentH; - nodeData.boxWidth = boxW; - nodeData.boxHeight = boxH; - }; - if( node instanceof LayoutBoxPrivate ){ - nodeData.Super.reflow.call( nodeData ); - } else { - node.reflow(); - }; - }; - + nodeData.preMesure( allowW, allowH ); if( children ){ + contentW = nodeData.contentWidth; + contentH = nodeData.contentHeight; + childW = 0; + childH = 0; + autoW = contentW === AUTO; + autoH = contentH === AUTO; + auto = autoW && autoH; + calc = BasicLayoutManager.calcValue; for( i = children.length; i; ){ child = children[ --i ]; + style = child.__syule; + if( style ){ + data = style.data; + t = calc( data[ ATTRS.top ], contentH ); + r = calc( data[ ATTRS.right ], contentW ); + b = calc( data[ ATTRS.bottom ], contentH ); + l = calc( data[ ATTRS.left ], contentW ); + } else { + t = r = b = l = 0; + }; if( child instanceof LayoutBoxPrivate ){ - child.layoutManager.reflow( child ); + child.layoutManager.reflow( child, contentW - r - l, contentH - t - b ); } else { - child.reflow(); + child.preMesure( contentW - r - l, contentH - t - b ); + child.mesure(); + child.postMesure(); }; - if( autoSize === false ) continue; - if( childW < child.rectRight ) childW = child.rectRight; - if( childH < child.rectBottom ) childH = child.rectBottom; + if( !auto ) continue; + if( autoW && childW < child.contentWidth + r + l ) childW = child.contentWidth + r + l; + if( autoH && childH < child.contentHeight + t + b ) childH = child.contentHeight + t + b; }; - if( autoSize === true ){ - if( w === AUTO && childW < contentW ) contentW = childW; - if( h === AUTO && childH < contentH ) contentH = childH; - if( contentW < minW ) contentW = minW; - if( maxW < contentW ){ - nodeData.scrollWidth = contentW; - contentW = maxW; - }; - if( contentH < minH ) contentH = minH; - if( maxH < contentH ){ - nodeData.scrollHeight = contentH; - contentH = maxH; - }; - nodeData.contentWidth = boxW = contentW; - nodeData.contentHeight = boxH = contentH; - switch( sizing ){ - case 3 : // margin-box - boxW += ( marginR + marginL ); - boxH += ( marginT + marginR ); - case 2 : // border-box - boxW += ( borderR + borderL ); - boxH += ( borderT + borderR ); - case 1 : // padding-box - boxW += ( paddingR + paddingL ); - boxH += ( paddingT + paddingR ); - // case 0 : // content-box - }; - nodeData.boxWidth = boxW; - nodeData.boxHeight = boxH; - }; + if( autoW ) nodeData.contentWidth = childW; + if( autoH ) nodeData.contentHeight = childH; }; + auto && nodeData.postMesure(); + delete nodeData.dirty; } } @@ -7589,7 +7553,7 @@ var XDocument = ( function( window, document ){ roots = this.rootList; if( roots ){ for( i = 0, l = roots.length; i < l; ++i ){ - roots[ i ].reflow(); + roots[ i ].layoutManager.reflow(); }; }; }; @@ -8298,10 +8262,26 @@ var XDocument = ( function( window, document ){ Constructor : function( layoutManager, root, parent ){ this.layoutManager = layoutManager; this._root = _root; + this.paintList = []; if( _parent ) this._parent = _parent; }, - reflow : function(){ + mesure : function(){ this.layoutManager.reflow( this ); + }, + paintReserve : function( nodeData ){ + var list = this.paintList; + if( Util.getIndex( list, nodeData ) === -1 ) list[ list.length - 1 ] = nodeData; + }, + paintRelease : function( nodeData ){ + var list = this.paintList, + i = Util.getIndex( list, nodeData ); + i === -1 && list.splice( i, 1 ); + }, + paint : function(){ + var list = this.paintList, i = list.length; + for( ; i; ){ + list[ --i ].paint(); + }; } } ); @@ -8326,6 +8306,17 @@ var XDocument = ( function( window, document ){ } ); + var RootNode = Node.inherits( + 'RootNode', + Class.POOL_OBJECT, + LayoutBoxPrivate, + { + Constructor : function(){ + RootNode.newPrivateData( this, BasicLayoutManager ); + } + } + ); + })( window, document ); })( window, document ); -- 2.11.0 From 4496896ea44ef7d7480094b8aa162754bdfb4d86 Mon Sep 17 00:00:00 2001 From: itozyun Date: Tue, 26 Feb 2013 07:15:26 +0900 Subject: [PATCH 06/16] add xdoc.js --- 0.5.x/javascripts/system.js | 14659 ++++++++++++++++++------------------------ 1 file changed, 6337 insertions(+), 8322 deletions(-) diff --git a/0.5.x/javascripts/system.js b/0.5.x/javascripts/system.js index ffb7e8a..7ab89d8 100644 --- a/0.5.x/javascripts/system.js +++ b/0.5.x/javascripts/system.js @@ -1,8322 +1,6337 @@ -/* - * pettanR system.js - * version 0.5.47 - * - * gadgetOS - * author: - * itozyun - * licence: - * 3-clause BSD - */ - -( function( window, document, undefined ){ - - var body = document.getElementsByTagName( 'body' )[ 0 ]; //( document.compatMode || '' ) !== 'CSS1Compat' ? document.body : document.documentElement;// - var SERVICE_LIST = []; - var SUPER_USER_KEY = { getUID: function(){ return 0; }}; - var API_USER_LIST = [ SUPER_USER_KEY ]; - var numApiUser = 1; - - function EMPTY_FUNCTION(){}; - - function isApiUser( _user ){ - return _user === SUPER_USER_KEY || - File.isDriver( _user ) === true || - Application.isApplicationInstance( _user ) === true; - }; - - var Const = { - FILE: { - TYPE: { - UNKNOWN: 0, - FOLDER: 1, - IMAGE: 2, - TEXT: 3, - HTML: 4, - CSV: 5, - JSON: 6, - XML: 7 - }, - STATE: { - UNKNOWN: 0, - OK: 1, - LOADING: 2, - ERROR: 3, - BROKEN: 4 - }, - UPDATE_POLICY: { - _____: parseInt( '00000', 2 ), - ____C: parseInt( '00001', 2 ), // hasCreateMenu - ___W_: parseInt( '00010', 2 ), // isWritable - ___WC: parseInt( '00011', 2 ), // isWritable - __R__: parseInt( '00100', 2 ), // isRenamable - __R_C: parseInt( '00101', 2 ), // hasCreateMenu - __RW_: parseInt( '00110', 2 ), // isWritable - __RWC: parseInt( '00111', 2 ), // isWritable - _S___: parseInt( '01000', 2 ), // childrenIsSortable - _S__C: parseInt( '01001', 2 ), - _S_W_: parseInt( '01010', 2 ), - _S_WC: parseInt( '01011', 2 ), - _SR__: parseInt( '01100', 2 ), - _SR_C: parseInt( '01101', 2 ), - _SRW_: parseInt( '01110', 2 ), - _SRWC: parseInt( '01111', 2 ), - D____: parseInt( '10000', 2 ), - D___C: parseInt( '10001', 2 ), // hasCreateMenu - D__W_: parseInt( '10010', 2 ), // isWritable - D__WC: parseInt( '10011', 2 ), // isWritable - D_R__: parseInt( '10100', 2 ), // isRenamable - D_R_C: parseInt( '10101', 2 ), // hasCreateMenu - D_RW_: parseInt( '10110', 2 ), // isWritable - D_RWC: parseInt( '10111', 2 ), // isWritable - DS___: parseInt( '11000', 2 ), // childrenIsSortable - DS__C: parseInt( '11001', 2 ), - DS_W_: parseInt( '11010', 2 ), - DS_WC: parseInt( '11011', 2 ), - DSR__: parseInt( '11100', 2 ), - DSR_C: parseInt( '11101', 2 ), - DSRW_: parseInt( '11110', 2 ), - DSRWC: parseInt( '11111', 2 ), - CREATE: 1, - WRAITE: 2, - RENAME: 4, - SORT: 8, - DELETE: 16 - }, - EVENT: { - UPDATE_ATTRIVUTE: 'onFileUpdate', - GET_SEQENTIAL_FILES:'gotSeqentilFiles' - }, - DATA_PROPERTY_RESERVED: [ - 'children', 'driver', 'state', 'type' - ] - }, - TREE: { - EVENT: { - UPDATE: 'onTreeUpdate' - } - }, - KEY: { - EVENT: { - KEY_DOWN: 'keydown', - KEY_UP: 'keyup', - KEY_CHANGE: 'keychange', - CURSOL: 'cursol' - } - }, - APP: { - TYPE: { - GENERAL : 0, - OVERLAY : 1, - PAGE : 2 - } - } - }; - -/** - * Class を定義し システムの管理下に置く. - * 全てのクラスと pool が有効の場合インスタンスへの参照が保持される. - * 1. Class.create( def, opt_final, opt_pool, opt_abstract ) でクラスを登録. - * 2. コンストラクタ となるメソッドは、Constructor : function( arg ){ ... }, に書く. - * 3. 通常通り new で インスタンス生成 - * 4. kill() でオブジェクトをクリーンして削除、pool が有効の場合は pool される. - * 5. pool が有効の場合、new で pool されたインスタンスが返される. - * 6. - * - */ -var Class = ( function(){ - var CLASS_LIST = [], - DEF_LIST = [], - PRIVATE_CLASS_LIST = [], - PRIVATE_DEF_LIST = [], - CONSTRUCTOR = 'Constructor', - GET_INDEX = Util.getIndex, - killPrivateFlag = false, - dataUser = null, - traits = null, - f = true, - copyArray = Util.copyArray; - - function getClass( instance ){ - var cList = CLASS_LIST, - i = cList.length, - klass; - for( ; i; ){ - klass = cList[ --i ]; - if( instance instanceof klass ) return klass; - }; - cList = PRIVATE_CLASS_LIST; - i = cList.length; - for( ; i; ){ - klass = cList[ --i ]; - if( instance instanceof klass ) return klass; - }; - - if( GET_INDEX( cList, instance ) !== -1 ) return instance; - if( GET_INDEX( CLASS_LIST, instance ) !== -1 ) return instance; - }; - - function getClassDef( KlassOrInstance ){ - var getIndex = GET_INDEX, - i = getIndex( CLASS_LIST, KlassOrInstance ); - if( i === -1 ) i = getIndex( CLASS_LIST, getClass( KlassOrInstance ) ); - if( i !== -1 ) return DEF_LIST[ i ]; - - i = getIndex( PRIVATE_CLASS_LIST, KlassOrInstance ); - if( i === -1 ) i = getIndex( PRIVATE_CLASS_LIST, getClass( KlassOrInstance ) ); - if( i !== -1 ) return PRIVATE_DEF_LIST[ i ]; - - if( GET_INDEX( DEF_LIST, KlassOrInstance ) !== -1 ) return KlassOrInstance; - if( GET_INDEX( PRIVATE_DEF_LIST, KlassOrInstance ) !== -1 ) return KlassOrInstance; - }; - - /* over のプロパティを target にコピーする.ただし target の プロパティが優先, force で解除 */ - function override( target, over, force ){ - for( var p in over ){ - if( force === true || typeof target[ p ] === 'undefined' ){ - target[ p ] = over[ p ]; - }; - }; - return target; - }; - - /* サブクラスを作るメソッド - * var subClass = superClass.inherits( ... ) - * http://d.hatena.ne.jp/m-hiyama/20051018/1129605002 - */ - function inherits( /* displayName, classSetting, opt_PrivateClass, props */ ){ - var args = copyArray( arguments ), - params = [], - Super = this, - superDef = getClassDef( Super ), - displayName = args[ 0 ], - classSetting, - opt_super, - klass; - if( superDef.Final === true ) throw new Error( 'Class is final!' ); - - if( Type.isString( displayName ) === true ){ - args.shift(); - } else { - displayName = 'SubClass of ' + superDef.displayName; - }; - params.push( displayName ); - - classSetting = args[ 0 ]; - if( Type.isNumber( classSetting ) === true ){ - if( superDef.isPrivate === true ) classSetting = classSetting | Class.PRIVATE_DATA; - opt_super = !!( classSetting & Class.SUPER_ACCESS ); - params.push( classSetting ); - args.shift(); - }; - if( getClass( args[ 0 ] ) ){ - params.push( args.shift() ); - } else - if( superDef.privateClass ){ - params.push( superDef.privateClass ); - }; - params.push( args[ 0 ] ); /* props */ - f = false; - traits = new Super(); - f = true; - klass = Class.create.apply( Class, params ); - traits = null; - if( opt_super === true ) getClassDef( klass ).Super = Super.prototype; - return klass; - }; - - /* Class.create で作られたクラスのインスタンスが共通で備えるメソッド */ - var CommonProps = { - kill : function(){ - var instance = this, - klass = getClass( instance ), - def = getClassDef( klass ), - data, p, i; - if( def.isPrivate === true && killPrivateFlag === false ){ - throw new Error( 'PrivateInstance.kill() work in PrivateUser.kill().' ); - }; - Type.isFunction( instance.onKill ) === true && instance.onKill(); - for( p in instance ){ - if( instance.hasOwnProperty && !instance.hasOwnProperty( p ) ) continue; - delete instance[ p ]; - }; - if( def.pool ){ - def.live && def.live.splice( GET_INDEX( def.live, instance ), 1 ); - def.pool.push( instance ); - }; - if( def.privateClass ){ - i = GET_INDEX( def.userList, instance ); - if( i !== -1 ){ - data = klass.getPrivateData( instance ); - killPrivateFlag = true; - data.kill(); - killPrivateFlag = false; - def.dataList.splice( i, 1 ); - def.userList.splice( i, 1 ); - }; - }; - // myCallback の削除 - // myCallback を受け取った API への通知 - }, - getMyCallback : function( callback ){ - var def = getClassDef( this ), - iList = def.callbackInstanceList, - rList = def.callbackRegisterList, - i, cList, myCallback; - if( !iList ){ - iList = def.callbackInstanceList = []; - rList = def.callbackRegisterList = []; - }; - i = GET_INDEX( iList, this ); - if( i === -1 ){ - cList = []; - iList.push( this ); - rList.push( cList ); - } else { - cList = rList[ i ]; - for( i = cList.length; i; ){ - if( cList[ --i ].callback === callback ) return cList[ i ]; - }; - }; - myCallback = new Callback( this, callback ); - cList.push( myCallback ); - return myCallback; - }, - releaseMyCallback : function( callback ){ - var def = getClassDef( this ), - iList = def.callbackInstanceList, - rList = def.callbackRegisterList, - i, _i, cList; - if( !iList ) return; - i = GET_INDEX( iList, this ); - if( i === -1 ) return; - cList = rList[ i ]; - _i = GET_INDEX( cList, callback ); - if( _i === -1 ) return; - cList.splice( _i, 1 ); - callback.kill(); - if( cList.length !== 0 ) return; - iList.splice( i, 1 ); - rList.splice( i, 1 ); - if( iList.length !== 0 ) return; - delete def.callbackInstanceList; - delete def.callbackRegisterList; - } - }; - - /* privateDataclass をもつクラスに追加されるメソッド */ - function newPrivateData( /* instance, args */ ){ - var args = copyArray( arguments ), - user = args.shift(), - def = getClassDef( user ), - privateClass = def.privateClass, - privateDef = getClassDef( privateClass ), - i = -1, - data; - if( def.userList ){ - i = GET_INDEX( def.userList, user ); - } else { - def.userList = []; - def.dataList = []; - }; - if( i !== -1 ){ - throw new Error( 'PrivateData already exist!' ); - }; - dataUser = user; - data = new privateClass( args ); - data.User = user; - dataUser = null; - return data; - }; - function getPrivateData( instance ){ - var def = getClassDef( instance ), - i = GET_INDEX( def.userList, instance ); - if( i !== -1 ) return def.dataList[ i ]; - }; - - /* - * new の実体.コンストラクタの機能は instance.Constructor に書く. - * これにより pool された オブジェクト(破棄されたインスタンス) を再利用できる - */ - /* Constructor Real for GeneralClass */ - function C( args ){ - var klass = this, - def = getClassDef( klass ), - instance, - userDef; - if( def.Abstract === true ){ - throw new Error( 'AbstractClass!' ); - }; - if( def.isPrivate === true && dataUser === null ){ - throw new Error( 'use myClass.newPrivateData( instance, ...args )!' ); - }; - f = false; - instance = def.pool && def.pool.length > 0 ? def.pool.shift() : instance = new klass(); - f = true; - if( def.Super && !instance.Super ) instance.Super = def.Super; - if( def.isPrivate === true ){ - userDef = getClassDef( dataUser ); - userDef.dataList.push( instance ); - userDef.userList.push( dataUser ); - } else { - def.live && def.live.push( instance ); - args = copyArray( arguments ); - }; - def[ CONSTRUCTOR ] && def[ CONSTRUCTOR ].apply( instance, args ); - return instance; - }; - - return { - POOL_OBJECT : 1, - ABSTRACT : 2, - FINAL : 4, - SUPER_ACCESS : 8, - PRIVATE_DATA : 16, - create : function( /* displayName, classSetting, opt_PrivateClass, props */ ){ - var args = copyArray( arguments ), - displayName = args[ 0 ], - classSetting, - opt_pool, opt_abstract, opt_final, opt_private, - privateDef, - props, - klass, - classDef = {}; - if( Type.isString( displayName ) === true ){ - classDef.displayName = displayName; - args.shift(); - }; - classSetting = args[ 0 ]; - if( Type.isNumber( classSetting ) === true ){ - opt_pool = !!( classSetting & Class.POOL_OBJECT ); - opt_abstract = !!( classSetting & Class.ABSTRACT ); - opt_final = !!( classSetting & Class.FINAL ); - opt_private = !!( classSetting & Class.PRIVATE_DATA ); - if( opt_final === true && opt_abstract === true ){ - throw new Error( 'final & Abstract!' ); - }; - args.shift(); - }; - - if( GET_INDEX( PRIVATE_CLASS_LIST, args[ 0 ] ) !== -1 ){ - privateDef = getClassDef( args[ 0 ] ); - if( privateDef.isPrivate !== true ){ - throw new Error( 'PrivateClass not found! please, Class.create( Class.PRIVATE, {...} ).' ); - } else - if( privateDef.Abstract === true ){ - throw new Error( 'PrivateClass is Abstract!' ); - }; - classDef.privateClass = args.shift(); - }; - props = args[ 0 ]; - if( props === null || Type.isObject( props ) === false ){ - throw new Error( 'No Class Def!' ); - }; - - if( Type.isFunction( props[ CONSTRUCTOR ] ) === true ){ - classDef[ CONSTRUCTOR ] = props[ CONSTRUCTOR ]; - }; - - klass = function(){ var a = arguments; if( f ) return C.apply( a.callee, a )}; - klass.prototype = override( override( traits || {}, props, true ), CommonProps, false ); - - if( opt_abstract === true ){ - classDef.Abstract = true; - } else - if( opt_pool === true ){ - classDef.pool = []; - if( opt_private === false )classDef.live = []; - }; - if( opt_final === true ){ - classDef.Final = true; - } else { - klass.inherits = inherits; - }; - if( opt_private === true ){ - if( classDef.privateClass ){ - throw new Error( 'Private Data Class has no PrivateClass!' ); - }; - classDef.isPrivate = true; - PRIVATE_CLASS_LIST.push( klass ); - PRIVATE_DEF_LIST.push( classDef ); - } else { - if( classDef.privateClass ){ - klass.newPrivateData = newPrivateData; - klass.getPrivateData = getPrivateData; - }; - CLASS_LIST.push( klass ); - DEF_LIST.push( classDef ); - }; - return klass; - }, - onShutdown : function(){ - - }, - getClass : function( instance ){ - return getClass( instance ); - }, - getClassDef : function(){ - - } - }; -})(); - -/** - * Callback 時に thisObject や args を指定したい場合に使用. - */ -var Callback = Class.create( - Class.POOL_OBJECT | Class.FINAL, { - Constructor : function( thisObject, callback, opt_args ){ - if( Type.isFunction( callback ) === false ){ - throw new Error( 'Not function!' ); - }; - this.callback = callback; - if( thisObject ) this.thisObject = thisObject; - if( Type.isArray( opt_args ) === true ){ - this.args = opt_args; - } else - if( opt_args !== undefined ){ - this.arg = opt_args; - }; - }, - fire : function( /* args */ ){ - var thisObject = this.thisObject || window, - args = Util.copyArray( arguments ); - if( 0 < args.length ){ - if( this.args !== undefined ){ - args.push.apply( args, this.args ); - } else - if( this.arg !== undefined ){ - args.push( this.arg ); - }; - this.callback.apply( thisObject, args ); - } else { - if( this.args !== undefined ){ - this.callback.apply( thisObject, this.args ); - } else - if( this.arg !== undefined ){ - this.callback.call( thisObject, this.arg ); - } else { - this.callback.call( thisObject ); - }; - }; - }, - registerUser : function( user ){ - if( !this.userList ){ - this.userList = [ user ]; - } else { - Util.getIndex( this.userList, user ) === -1 && this.userList.push( user ); - }; - }, - onKill : function(){ - var instance = this.thisObject; - this.userList && Class.getClass( instance ) && instance.releaseMyCalllback( this ); - } -}); - - -/* -------------------------------------------------------------- - * System Timer - * - */ - -var SystemTimer = ( function(){ - var setTimeout = window.setTimeout; - var clearTimeout = window.clearTimeout; - var INTERVAL_TIME = 16; - var TICKET_LIST = []; - var timerId = undefined; - var next = 0; - - function loop(){ - var i = 0, - list = TICKET_LIST; - for( i = 0; i < list.length; ){ - if( list[ i ].fire( next ) !== false ) ++i; - }; - timerId = undefined; - update(); - }; - function update(){ - var list = TICKET_LIST, - l = list.length, - n = 99999999, - c; - if( l === 0 ){ - timerId !== undefined && clearTimeout( timerId ); - timerId = undefined; - return; - }; - for( ; l; ){ - c = list[ --l ].count; - if( n > c ) n = c; - }; - if( next > n || timerId === undefined ){ - timerId !== undefined && clearTimeout( timerId ); - timerId = setTimeout( loop, INTERVAL_TIME * n ); - next = n; - }; - }; - - var TimerTicket = Class.create( - Class.POOL_OBJECT, { - Constructor : function( apiuser, callback, time, once, opt_thisObject ){ - this.apiuser = apiuser; - this.callback = callback; - this.time = time; - this.count = time; - if( once ) this.once = once; - this.thisObj = opt_thisObject || apiuser; - }, - fire : function( c ){ - this.count -= c; - if( 0 < this.count ) return; - this.callback.call( this.thisObj ); - if( this.once === true ){ - this.destroy(); - TICKET_LIST.splice( Util.getIndex( TICKET_LIST, this ), 1 ); - return false; - } else { - this.count = this.time; - }; - }, - destroy : function( apiuser, callback ){ - if( apiuser && apiuser !== this.apiuser ) return false; - if( callback && callback !== this.callback ) return false; - - this.kill(); - return true; - } - } - ); - - return { - add: function( _apiuser, _handler, _time, _once, opt_thisObject ){ - if( Type.isNumber( _time ) === false || _time < INTERVAL_TIME ) _time = INTERVAL_TIME; - - var _ticket = new TimerTicket( _apiuser, _handler, Math.ceil( _time / INTERVAL_TIME ), _once, opt_thisObject ); - TICKET_LIST.push( _ticket ); - - update(); - }, - remove: function( _apiuser, _handler ){ - var _ticket, - i = 0; - while( _ticket = TICKET_LIST[ i ] ){ - if( _ticket.destroy( _apiuser, _handler ) === true ){ - TICKET_LIST.splice( i, 1 ); - } else { - ++i; - }; - }; - update(); - } - }; -})(); - -/* -------------------------------------------------------------- - * Async Callback - * - */ -var AsyncCall = ( function(){ - var CALLBACK_LIST = []; - - var CallbackTicket = Class.create( - Class.POOL_OBJECT, { - Constructor : function( apiuser, callback, args, thisObject ){ - this.apiuser = apiuser; - this.callback = callback; - this.args = args; - this.thisObj = thisObject || apiuser; - }, - fire : function(){ - var f = this.callback, - a = this.args, - t = this.thisObj; - this.destroy(); - if( Type.isArray( a ) === true ){ - f.apply( t, a ); - } else { - f.call( t, a ); - }; - }, - destroy : function( apiuser, callback ){ - if( apiuser && apiuser !== this.apiuser ) return false; - if( callback && callback !== this.callback ) return false; - - this.kill(); - return true; - } - }); - - function dispatch(){ - var _ticket = CALLBACK_LIST.shift(); - if( _ticket ){ - _ticket.fire(); - CALLBACK_LIST.length !== 0 && SystemTimer.add( SUPER_USER_KEY, dispatch, 1, true ); - }; - }; - - return { - add: function( _apiuser, _callback, _argments, _thisObject ){ - CALLBACK_LIST.length === 0 && SystemTimer.add( SUPER_USER_KEY, dispatch, 1, true ); - CALLBACK_LIST.push( new CallbackTicket( _apiuser, _callback, _argments, _thisObject ) ); - }, - remove: function( _apiuser, _callback ){ - var _ticket, - i = 0; - while( _ticket = CALLBACK_LIST[ i ] ){ - if( _ticket.destroy( _apiuser, _callback ) === true ){ - CALLBACK_LIST.splice( i, 1 ); - } else { - ++i; - }; - }; - } - }; -})(); - -/* ----------------------------------------------------------- - * 画像一覧は - * お気に入り画像一覧 > tag:ペン次郎 > ペン次郎:笑う - * 最近アップロードされた画像 > images - * 最近使われた画像 > images - * キャラクター画像庫 > アニマル系 > tag:ペン次郎 > ペン次郎:笑う - * 風景画像庫 > - * 効果画像庫 > - * アイテム画像庫 > - * - * 画像一覧を読み込むタイミング - */ -var File = ( function(){ - var DRIVER_LIST = []; - - var FILE_TYPE_IS_FOLDER = Const.FILE.TYPE.FOLDER, - numFileType = Const.FILE.TYPE.XML, - FILEDATA_RESITER = [], // store all of fileData( json object ) - FILEDATA_ACCESS = [], // file operations for Kernel only ! hide from Out of File - FILE_OBJECT_POOL = [], - EVENT_LISTENER_REGISTER = [], - TREE_ARRAY = [], - TREE_ACCESS_ARRAY = []; - - var REQUEST_CONTROLER = ( function(){ - var REQUEST_TICKET_RESISTER = [], - currentTicket = null, - currentData = null, - DATA_TYPE_ARRAY = 'json,xml,html,text'.split( ',' ), - DATA_IS_JSON = 0, - DATA_IS_XML = 1, - DATA_IS_HTML = 2, - DATA_IS_TEXT = 3, - numError = 0; - - var RequestTicket = Class.create( - Class.POOL_OBJECT, { - Constructor : function( apiuser, type, data, url, onLoad, onError ){ - this.apiuser = apiuser; - this.type = type; - this.data = data; - this.url = url; - this.onLoad = onLoad; - this.onError = onError; - this.state = 0; - }, - load : function( data ){ - AsyncCall.add( this.apiuser, this.onLoad, [ this.data, data ] ); - }, - error : function(){ - AsyncCall.add( this.apiuser, this.onError, this.data ); - } - }); - - function request(){ - if( currentTicket !== null || REQUEST_TICKET_RESISTER.length === 0 ) return; - currentTicket = REQUEST_TICKET_RESISTER.shift(); - $.ajax({ - url: currentTicket.url, - dataType: DATA_TYPE_ARRAY[ currentTicket.type ], - success: onSuccess, - error: onError - }); - }; - function onSuccess( _data ){ - currentTicket.load( _data ); - currentTicket.kill(); - currentTicket = null; - request(); - }; - function onError(){ - ++numError; - currentTicket.error(); - currentTicket.kill(); // retry - currentTicket = null; - request(); - }; - - return { - getNumTask: function(){ - return REQUEST_TICKET_RESISTER.length; - }, - getNumError: function(){ - return numError; - }, - getJson: function( _apiuser, _data, _url, _onLoad, _onError ){ - REQUEST_TICKET_RESISTER.push( new RequestTicket( _apiuser, DATA_IS_JSON, _data, _url, _onLoad, _onError )); - currentTicket === null && request(); - } - }; - })(); - - var FILE_CONTROLER = { - createTree: function( _apiuser, _rootFileData ){ - var _tree = new TreeClass( _apiuser, _rootFileData ); - TREE_ARRAY.push( _tree ); - return _tree; - }, - getFileUID: function( FILEDATAorFILE ){ - if( FILEDATAorFILE instanceof FileClass ){ - return FILEDATAorFILE.getUID(); - }; - - var uid = Util.getIndex( FILEDATA_RESITER, FILEDATAorFILE ); - if( uid === -1 ){ - uid = FILEDATA_RESITER.length; - FILEDATA_RESITER.push( FILEDATAorFILE ); - }; - return uid; - }, - getFileDataAccess: function( UIDorFILEorFILEDATA ){ - var _uid, _data = FILE_CONTROLER.getFileData( UIDorFILEorFILEDATA ), _access; - - if( _data === null || typeof _data !== 'object' ) return null; - for( var i=0, l = FILEDATA_ACCESS.length; i= _bit; - }, - move: function( _prentUID, _targetfile, _newFolder, _newIndex, _opt_callback ){ - var _parentData = FILE_CONTROLER.getFileDataAccess( _prentUID ), - _parentType = _parentData.TYPE, - _targetData = FILE_CONTROLER.getFileDataAccess( _targetfile ), - _targetType = _targetData.TYPE; - }, - replace: function( _uid, _file, _newIndex ){ - - }, - addEventListener: function( FILEorNULL, _eventType, _callback, opt_thisObject ){ - var _uid = FILEorNULL instanceof FileClass ? FILEorNULL.getUID() : FILEorNULL; - EVENT_LISTENER_REGISTER.push( new FileEventTicket( _uid, _eventType, _callback, opt_thisObject )); - }, - removeEventListener: function( FILEorNULL, eventType, callback ){ - var uid = FILEorNULL instanceof FileClass ? FILEorNULL.getUID() : FILEorNULL, - list = EVENT_LISTENER_REGISTER, - i = 0, - ticket; - for( ; i < list.length; ){ - ticket = list[ i ]; - if( ticket.fileUID === uid && ticket.eventType === eventType && ticket.callBack === callback ){ - list.splice( i, 1 ); - ticket.kill(); - } else { - ++i; - }; - }; - }, - getTreeAccess: function(){ - - }, - fileEventRellay: function( _uid, _event ){ - var _fileAccess = FILE_CONTROLER.getFileDataAccess( _uid ); - if( _fileAccess === null ) return; - var _treeUID = _fileAccess.TREE.getUID(), - _treeAccess = TREE_ACCESS_ARRAY[ _treeUID ], - _data = _fileAccess.DATA, - _tree; - if( !_treeAccess ) return; - _treeAccess.dispatchFileEvent( _event ); - for( var i=0, l = TREE_ARRAY.length; i= l ) return null; - return PARENT_FILE_RESITER[ l -1 -_index ]; - }; - this.down = function( _index ){ - if( typeof _index !== 'number' || _index < 0 || _index >= currentFile.getChildFileLength()) return; - PARENT_FILE_RESITER.unshift( currentFile ); - currentFile = currentFile.getChildFileAt( _index ); - currentFile.getSeqentialFiles(); - return currentFile; - }; - this.up = function( _index ){ - var l = PARENT_FILE_RESITER.length; - if( l === 0 ) return null; - - if( currentFile ){ - var _currentFile = currentFile; - currentFile = null; - _currentFile.destroy(); - }; - if( typeof _index === 'number' ){ - if( _index >= l ) return null; - currentFile = this.getParentFileAt( _index ); - PARENT_FILE_RESITER.splice( 0, l -_index); - } else { - currentFile = PARENT_FILE_RESITER.shift(); - }; - currentFile.getSeqentialFiles(); - return currentFile; - }; - this.addTreeEventListener = function( _eventType, _callback, opt_thisObject ){ - FILE_CONTROLER.addEventListener( null, _eventType, _callback, opt_thisObject ); - }; - this.removeTreeEventListener = function( _eventType, _callback ){ - FILE_CONTROLER.removeEventListener( null, _eventType, _callback ); - }; - this.destroy = function( _apiuser ){ - if( _apiuser && apiuser !== _apiuser ) return false; - // removeEvent - var _currentFile = currentFile; - currentFile = rootFile = rootFileData = null; - // currentFile, rootFile を null にしないと .File.destroy() ができない. - _currentFile.destroy(); - while( PARENT_FILE_RESITER.length > 0 ){ - _currentFile = PARENT_FILE_RESITER.shift(); - _currentFile.destroy(); - }; - - AsyncCall.remove( apiuser ); - instance = apiuser = null; - return true; - }; - }; - - var FileEventTicket = Class.create( - Class.POOL_OBJECT, { - Constructor : function( uid, eventType, callback, opt_thisObject ){ - this.fileUID = uid; - this.eventType = eventType; - this.callBack = callback; - this.thisObject = opt_thisObject; - } - }); - - var FileEventClass = function( eventType, file, key, value ){ - this.eventType = eventType; - this.targetFile = file; - this.updatedAttribute = key; - this.updatedValue = value; - }; - -/* - * file の data は object で保持している。 - * File の外からファイルをみるときは、FileClassを通して操作する。 - * fileの変更、それに付随して追加されたイベントは、TreeClassで管理される。 - * treeがdestryされると、fileのイベントリスナーも全て削除される。 - * 他の tree も data の共通する currentFile に対してのみは、file の変更イベントを受け取って流す. - * - */ - - var FileClass = function( tree, parentData, data ){ - var uid = FILE_CONTROLER.getFileUID( data ); - - FILEDATA_ACCESS.push( { - TREE: tree, - parentData: parentData, - DATA: data - } ); - - tree = parentData = data = null; - - this.getUID = function(){ - return uid; - }; - }; - - FileClass.prototype = { - isChildFile: function( _FILEorFILEDATA ){ - return this.getChildFileIndex( _FILEorFILEDATA) !== -1; - }, - getSeqentialFiles: function(){ - var _driver = FILE_CONTROLER.getDriver( this ); - if( _driver !== null && typeof _driver.getSeqentialFiles === 'function' ){ - _driver.getSeqentialFiles( this ); - } - }, - addEventListener: function( _eventType, _callback ){ - FILE_CONTROLER.addEventListener( this, _eventType, _callback ); - }, - removeEventListener: function( _eventType, _callback ){ - FILE_CONTROLER.removeEventListener( this, _eventType, _callback ); - }, - dispatchEvent: function( e ){ - e instanceof FileEventClass && FILE_CONTROLER.fileEventRellay( this.getUID(), e ); - }, - getChildFileLength: function(){ - var children = FILE_CONTROLER.getChildren( this ); - return Type.isArray( children ) === true ? children.length : -1; - }, - getChildFileIndex: function( _FILEorFILEDATA ){ - var children = FILE_CONTROLER.getChildren( this ); - if( Type.isArray( children ) === false ) return -1; - var l = children.length, - _fileData = FILE_CONTROLER.getFileData( _FILEorFILEDATA ); - if( _fileData === null ) return -1; - for( var i=0; i= _children.length ) return null; - var _file = new FileClass( _access.TREE, _access.DATA, _children[ _index ]); - // _file.init(); - return _file; - }, - getName: function(){ - var driver = FILE_CONTROLER.getDriver( this ); - if( typeof driver.getName === 'function'){ - return driver.getName( this ); - } - return BASE_DRIVER.getName( this ); - }, - getThumbnail: function(){ - var driver = FILE_CONTROLER.getDriver( this ); - if( typeof driver.getThumbnail === 'function'){ - return driver.getThumbnail( this ); - } - return BASE_DRIVER.getThumbnail( this ); - }, - getType: function(){ - var _data = FILE_CONTROLER.getFileData( this ); - return typeof _data.type === 'number' ? _data.type : Const.FILE.TYPE.UNKNOWN; - }, - getState: function(){ - var _data = FILE_CONTROLER.getFileData( this ); - return typeof _data.state === 'number' ? _data.state : Const.FILE.STATE.OK; - }, - getSummary: function(){ - var driver = FILE_CONTROLER.getDriver( this ); - if( typeof driver.getSummary === 'function'){ - return driver.getSummary( this ); - } - return BASE_DRIVER.getSummary( this ); - }, - isWritable: function(){ - return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.WRITE ); - }, - isSortable: function(){ - return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.SORT ); - }, - isCreatable: function(){ - return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.CREATE ); - }, - isRenamable: function(){ - return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.RENAME ); - }, - isDeletable: function(){ - return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.DELETE ); - }, - read: function(){ - // simpleDeepCopy - var driver = FILE_CONTROLER.getDriver( this ), - data; - if( Type.isFunction( driver.read ) === true ){ - data = driver.read( this ); - }; - return BASE_DRIVER.read( data || this ); - }, - write: function( _newData, _onUpdateFunction ){ - var driver = FILE_CONTROLER.getDriver( this ); - if( typeof driver.write === 'function' ){ - return driver.write( this, _newData, _onUpdateFunction ); - }; - return BASE_DRIVER.write( this, _newData, _onUpdateFunction ); - }, - viewerApplicationList: function(){ - var driver = FILE_CONTROLER.getDriver( this ); - if( typeof driver.viewerApplicationList === 'function' ){ - return driver.viewerApplicationList( this ); - }; - return BASE_DRIVER.viewerApplicationList( this ); - }, - editorApplicationList: function(){ - var driver = FILE_CONTROLER.getDriver( this ); - if( typeof driver.editorApplicationList === 'function' ){ - return driver.editorApplicationList( this ); - }; - return BASE_DRIVER.viwerApps( this ); - }, - create: function(){ - - }, - sort: function(){ - - }, - onCopy: function(){ - - }, - onDelete: function(){ - - }, - move: function( _newFolder, _newIndex, opt_callback ){ - var _access = FILE_CONTROLER.getFileDataAccess( this ); - _access.TREE.move( _access.parentData, this.getUID(), _newFolder, _newIndex, opt_callback ); - }, - replace: function( _newIndex, opt_callback ){ - var _access = FILE_CONTROLER.getFileDataAccess( this ); - _access.TREE.replace( _access.parentData, this.getUID(), _newIndex, opt_callback); - }, - /** - * サーチ - * 探しているファイルの属性と値を指定.一致する child の index を配列で返す. - */ - search: function( obj, rule ){ - var _children = FILE_CONTROLER.getChildren( this ), - _child, - ret = [], k, c; - for( var i=0, l=_children.length; i this.w || this.application.MIN_HEIGHT > this.h ){ - if( Type.isHTMLElement( this.rootElement ) === true ){ - // 小さすぎる!、と表示 - }; - }; - if( this.bootParams.length > 2 ){ - this.application.onOpen.apply( this.application, this.bootParams ); - } else { - this.application.onOpen( this.w, this.h ); - }; - this.phase = 4; - }, - fetchResourceComplete : function(){ - --this.fetchResource; - } -}; -ApplicationPrivateData.list = []; -ApplicationPrivateData.get = function( app ){ - var list = ApplicationPrivateData.list, - i = list.length; - for( ; i; ){ - if( app instanceof list[ --i ].appClass ) return list[ i ]; - }; - return null; -}; - -var AbstractApplication = function( appClass, displayName, isOverlay ){ - ( new ApplicationPrivateData() ).init( appClass, displayName, isOverlay ); -}; -AbstractApplication.prototype = { - getUID : function(){ - var data = ApplicationPrivateData.get( this ); - return Util.getIndex( API_USER_LIST, data.appClass ); - }, - init : function(){ - var data = ApplicationPrivateData.get( this ); - // this.rootElement = data.rootElement; - // data.application = this; - data.phase = 1; - data.appClass === Page.appClass && Page.show(); - this.onInit(); - data.phase = 2; - }, - open : function( w, h /*, _option */ ){ - var data = ApplicationPrivateData.get( this ); - data.phase = 3; - data.bootParams = Util.copyArray( arguments ); - data.w = w; - data.h = h; - if( data.rootElement.innerHTML && data.rootElement.innerHTML.length > 0 ){ - SystemTimer.add( this, data.detect, 16, false, data ); - } else { - data.onOpen(); - }; - }, - resize : function( w, h ){ - var data = ApplicationPrivateData.get( this ); - if( data.phase !== 4 ) return; - if( this.MIN_WIDTH > w || this.MIN_HEIGHT > h ){ - if( Type.isHTMLElement( this.rootElement ) === true ){ - // 小さすぎる!、と表示 - }; - return; - }; - this.onPaneResize( w, h ); - }, - close : function(){ - var data = ApplicationPrivateData.get( this ); - data.phase = 5; - if( this.onClose() === false ){ - return false; - }; - if( data.uiList ){ - while( data.uiList.length > 0 ) data.uiList.shift().destroy(); - }; - if( data.finderList ){ - while( data.finderList.length > 0 ) data.finderList.shift().destroy(); - }; - - data.eventRoot && PointingDeviceEventTree.destroyTree( data.eventRoot ); - MouseEvent.remove( this ); - KeyEvent.remove( this ); - SystemTimer.remove( this ); - AsyncCall.remove( this ); - StyleSheet.unload( this ); - - var elm = this.rootElement; - Util.removeAllChildren( elm ); - elm.parentNode.removeChild( elm ); - - Application.shutdown( this, data.isOverlay ); - - data.appClass === Page.appClass && Page.hide(); - - data.phase = 6; - - var list = ApplicationPrivateData.list; - list.splice( Util.getIndex( list, data ), 1 ); - }, - createUIGroup : function( node ){ - var data = ApplicationPrivateData.get( this ), - ui = UI.createUIGroup( this, node ); - if( data.uiList === null ) data.uiList = []; - data.uiList.push( ui ); - return ui; - }, - createUIForm : function( nodeOrElm, opt_elmForm ){ - var data = ApplicationPrivateData.get( this ), - form = UIForm.createForm( this, nodeOrElm, opt_elmForm ); - if( data.formList === null ) data.formList = []; - data.formList.push( form ); - return form; - }, - createFinder : function( _elmTarget, _tree, _onSelect, _viewerOption, _editorOption ){ - var data = ApplicationPrivateData.get( this ), - finder = Finder.create( this, _elmTarget, _tree, _onSelect, _viewerOption, _editorOption ); - if( data.finderList === null ) data.finderList = []; - data.finderList.push( finder ); - return finder; - }, - createDHTML : function( _elm ){ - return DHTML.create( this, _elm ); - }, - addEventListener : function( element, eventType, handler, opt_thisObject ){ - MouseEvent.add( this, element, eventType, handler, opt_thisObject ); - }, - removeEventListener : function( element, eventType, handler ){ - MouseEvent.remove( this, element, eventType, handler ); - }, - getPointingDeviceEventTreeRoot : function(){ - var data = ApplicationPrivateData.get( this ); - if( data.phase === 1 ){ - data.eventRoot = PointingDeviceEventTree.create( this ); - data.styleCursor = PointingDeviceEventTree._getNodePrivateData( data.eventRoot ).elmMouseCatch.style; - }; - return data.eventRoot; - }, - updateCoursor : function( _cursor ){ - var data = ApplicationPrivateData.get( this ); - if( data.cursor !== _cursor ){ - data.styleCursor.cursor = data.cursor = _cursor; - }; - }, - fetchCSS : function( url, opt_onload, opt_onerror ){ - var data = ApplicationPrivateData.get( this ); - if( data.phase === 1 ){ - ++data.fetchResource; - StyleSheet.load( this, url, data.fetchResourceComplete, data.fetchResourceComplete, data ); - }; - }, - onInit : function(){}, - onOpen : function(){}, - onClose : function(){ return true; }, - onPaneResize : function( w, h ){}, - addKeyEventListener : function( _eventType, _handler, _keyCode, _shift, _ctrl ){ - KeyEvent.add( this, _eventType, _handler, _keyCode, _shift, _ctrl ); - }, - removeKeyEventListener : function( _eventType, _handler, _keyCode, _shift, _ctrl ){ - KeyEvent.remove( this, _eventType, _handler, _keyCode, _shift, _ctrl ); - }, - shiftEnabled : function(){ - return KeyEvent.shiftEnabled; - }, - ctrlEnabled : function(){ - return KeyEvent.ctrlEnabled; - }, - addTimer : function( handler, time, once ){ - SystemTimer.add( this, handler, time, !!once ); - }, - removeTimer : function( handler ){ - SystemTimer.remove( this, handler ); - }, - addAsyncCall : function( _callback, _argments, _thisObject ){ - AsyncCall.add( this, _callback, _argments, _thisObject ); - }, - removeAsyncCall : function( _callback ){ - AsyncCall.remove( this, _callback ); - }, - fetchHTMLElement : function( id ){ - var elm = document.getElementById( id ); - if( elm ){ - elm.removeAttribute( 'id' ); - elm.parentNode.removeChild( elm ); - return elm; - }; - } -}; - -var PointingDeviceEventTree = ( function(){ - var ROOT_LIST = [], - currentRootData = null, - targetNodeData = null, - forceNodeData = null, - hoverList = []; - - function eventRellay( e ){ - var data = forceNodeData, // || targetNodeData, - x = e.clientX, - y = e.clientY, - type = e.type, - list = hoverList, - i = 0, - ret, systemOnly = false, addClass, removeClass, - parent; - if( data && data.dispatchEvent( e, type, true ) === true ) return false; - if( currentRootData === null ) return; - targetNodeData = currentRootData; - currentRootData._capcher( x, y ); - targetNodeData.apiuser.updateCoursor( targetNodeData._cursor ); - data = targetNodeData; - while( data ){ - ret = data.dispatchEvent( e, type, true, systemOnly ); - if( ret === true || ret === false ) break; // systemOnly = true; - data = data.parentData; - }; - - addClass = Util.addClass; - removeClass = Util.removeClass; - for( ; i < list.length; ){ - parent = data = list[ i ]; - while( parent.parentData && parent === parent.parentData.hitChild ){ - parent = parent.parentData; - }; - if( parent !== currentRootData ){ - data.hover === true && removeClass( data.elm, data.hoverClass ); - delete data.isHover; - data.events && data.events.mouseout && data.fire( e, 'mouseout', false ); - delete data.hitSelf; - list.splice( i, 1 ); - continue; - }; - if( data.hover === true && data.isHover === false ){ - addClass( data.elm, data.hoverClass ); - data.isHover = true; - }; - if( data.hitSelf === false ){ - data.events && data.events.mouseover && data.fire( e, 'mouseover', true ); - data.hitSelf = true; - }; - ++i; - }; - return false; - }; - - var NodeClass = function( apiuser, rootData, /*parentLayer,*/ parentData, rangeOrElm, through, clip, hover, cursor, scroll, dragdrop ){ - ( new NodePrivateData() ).init( apiuser, rootData, /*parentLayer,*/ parentData, this, rangeOrElm, through, clip, hover, cursor, scroll, dragdrop ); - }; - NodeClass.prototype = { - createNode : function( rangeOrElmData, through, clip, hover, cursor, scroll, dragdrop ){ - var data = NodePrivateData.get( this ), - elm; - if( Type.isHTMLElement( rangeOrElmData ) === true ){ - elm = rangeOrElmData; - } else - if( Type.isString( rangeOrElmData ) === true ){ - elm = document.getElementById( rangeOrElmData ); - if( !elm ){ - elm = Util.pullHtmlAsTemplete( rangeOrElmData ); - }; - if( !elm || Type.isHTMLElement( elm ) === false || elm.nodeType !== 1 ){ - throw new Error( "invalid HTMLElement." ); - }; - } else - if( Type.isObject( rangeOrElmData ) === false || Type.isFinite( rangeOrElmData.x ) === false || Type.isFinite( rangeOrElmData.y ) === false ){ - throw new Error( "No range" ); - }; - - if( elm && data.elm === null ){ - throw new Error( "MetaLayer don't containe HTMLElement-Layer." ); - }; - if( data.elm && data.elm.style.hasLayout === false ){ - throw new Error( "[ie] OffsetParent is hasLayout === false." ); - }; - - var newNode = new NodeClass( data.apiuser, data.rootData, data, elm || rangeOrElmData, through, clip, hover, cursor, scroll, dragdrop ), - newData = NodePrivateData.get( newNode ); - - if( data.childData === null ) data.childData = []; - data.childData.push( newData ); - return newNode; - }, - createNodeAt : function(){ - }, - remove : function(){ - NodePrivateData.get( this ).remove(); - }, - nodeIndex : function( v ){ - return NodePrivateData.get( this ).nodeIndex( v ); - }, - numNode : function(){ - return NodePrivateData.get( this ).numNode(); - }, - disabled : function( v ){ - return NodePrivateData.get( this ).disabled( v ); - }, - childrenDisabled : function( v ){ - return NodePrivateData.get( this ).disabled( v ); - }, - mesure : function(){ - NodePrivateData.get( this ).mesure(); - }, - mesureChildren : function(){ - NodePrivateData.get( this ).mesureChildren(); - }, - update : function( x, y, w, h ){ - NodePrivateData.get( this ).update( x, y, w, h ); - }, - setPosition : function( x, y ){ - NodePrivateData.get( this ).setPosition( x, y ); - }, - setSize : function( w, h ){ - NodePrivateData.get( this ).setSize( w, h ); - }, - cursor : function( v ){ - return NodePrivateData.get( this ).cursor( v ); - }, - x : function( x ){ - return NodePrivateData.get( this ).positionX( x ); - }, - y : function( y ){ - return NodePrivateData.get( this ).positionY( y ); - }, - width : function( w ){ - return NodePrivateData.get( this ).width( w ); - }, - height : function( h ){ - return NodePrivateData.get( this ).height( h ); - }, - getAbsolutePositionX : function(){ - return NodePrivateData.get( this ).getAbsolutePositionX(); - }, - getAbsolutePositionY : function(){ - return NodePrivateData.get( this ).getAbsolutePositionY(); - }, - addEventListener : function( type, handler, opt_thisObject ){ - NodePrivateData.get( this ).addEventListener( type, handler, opt_thisObject ); - }, - removeEventListener : function( type, handler ){ - NodePrivateData.get( this ).removeEventListener( type, handler ); - }, - scrollTo : function( x, y ){ - NodePrivateData.get( this ).scrollTo( x, y ); - }, - scrollX : function( v ){ - return NodePrivateData.get( this ).scrollX( v ); - }, - scrollY : function( v ){ - return NodePrivateData.get( this ).scrollY( v ); - }, - invalidateScrollbar : function(){ - ScrollBarManager.update( NodePrivateData.get( this ) ); - } - }; - - /** - * clip : true の場合、子ノードの変更によってヒットエリアを変化させない.elm には overflow:hidden としておくのが通常. - */ - var NodePrivateData = function(){}; - NodePrivateData.prototype = { - elmMouseCatch : null, // rootData only - eventCounter : null, // rootData only - cursorStyle : null, // rootData only - node : null, - apiuser : null, - rootData : null, - elm : null, // resizeTarget - elmScroll : null, - elmScroller : null, - elmScrollbar : null, - x : 0, - y : 0, - w : 0, - h : 0, - t : 0, // top - l : 0, // left - b : 0, // bottom - r : 0, // right - absoluteX : 0, - absoluteY : 0, - _scrollX : 0, - _scrollY : 0, - scrollingX : 0, - scrollingY : 0, - _cursor : '', - // parentLayer : null, - parentData : null, - childData : null, - events : null, - hitChild : null, - hitSelf : false, - _disabled : false, - _childDisabled: false, - layoutManager : null, - through : false, - clip : false, - hover : false, - hoverClass : null, - isHover : false, - scroll : false, - dragdrop : false, - tooltip : null, - init: function( apiuser, rootData, /*parentLayer,*/ parentData, node, rangeOrElm, through, clip, hover, cursor, scroll, dragdrop ){ - this.apiuser = apiuser; - this.rootData = rootData || this; - // this.parentLayer = parentLayer; - this.parentData = parentData; - this.node = node; - this.through = through; - this.clip = !!clip; - if( cursor ) this._cursor = cursor; - - if( Type.isHTMLElement( rangeOrElm ) === true ){ - this.elm = rangeOrElm; - this.hover = !!hover; - this.hoverClass = hover; - this.scroll = clip && scroll; - this.mesure(); - this.scroll === true && ScrollBarManager.register( this ); - } else { - this.update( rangeOrElm.x, rangeOrElm.y, rangeOrElm.w, rangeOrElm.h ); - }; - - NodePrivateData.dataList.push( this ); - }, - mesure : function(){ - var x, y, w, h, parent, _this, _parent; - if( this.elm ){ - w = this.elm.offsetWidth; - h = this.elm.offsetHeight; - _this = Position.cumulativeOffset( this.elm ); - _parent = this.parentData ? Position.cumulativeOffset( this.parentData.elm ) : [ 0, 0 ]; - x = _this[ 0 ] - _parent[ 0 ]; - y = _this[ 1 ] - _parent[ 1 ]; - if( this.x !== x || this.y !== y || this.w !== w || this.h !== h ){ - this.x = x; - this.y = y; - this.w = w; - this.h = h; - parent = this.parentData; - parent && this._updateAbsoluteXY( parent.absoluteX, parent.absoluteY, parent.scrollingX, parent.scrollingY ); - this._updateRectangle(); - }; - } else { - this._updateRectangle(); - }; - }, - mesureChildren : function(){ - var nodes, i; - if( nodes = this.childData ){ - for( i = nodes.length; i; ){ - nodes[ --i ].mesure(); - }; - }; - }, - update : function( x, y, w, h ){ - var updateXY = false, - _this, _parent, - parent; - - if( this.elm ){ - // width - if( Type.isFinite( w ) === true ){ - this.elm.style.width = w + 'px'; - } else - if( Type.isString( w ) === true ){ - this.elm.style.width = w; - w = this.elm.offsetWidth; - }; - //update = this.w !== w; - - // height - if( Type.isFinite( h ) === true ){ - this.elm.style.height = h + 'px'; - } else - if( Type.isString( h ) === true ){ - this.elm.style.height = w; - h = this.elm.offsetHeight; - }; - //update = update || this.h !== h; - - // x - if( Type.isFinite( x ) === true ){ - this.elm.style.left = x + 'px'; - } else - if( Type.isString( x ) === true ){ - this.elm.style.left = x; - updateXY = true; - } else { - updateXY = true; - }; - - // y - if( Type.isFinite( y ) === true ){ - this.elm.style.top = y + 'px'; - } else - if( Type.isString( y ) === true ){ - this.elm.style.top = y; - updateXY = true; - } else { - updateXY = true; - }; - if( updateXY === true ){ - _this = Position.cumulativeOffset( this.elm ); - _parent = this.parentData ? Position.cumulativeOffset( this.parentData.elm ) : [ 0, 0 ]; - x = _this[ 0 ] - _parent[ 0 ]; - y = _this[ 1 ] - _parent[ 1 ]; - }; - //update = update || this.x !== x; - //update = update || this.y !== y; - - //update === true && this._updateRectangle(); - // return; - }; - x = Type.isFinite( x ) === true ? x : this.x; - y = Type.isFinite( y ) === true ? y : this.y; - w = Type.isFinite( w ) === true ? w : this.w; - h = Type.isFinite( h ) === true ? h : this.h; - if( this.x !== x || this.y !== y ){ - this.x = x; - this.y = y; - //console.log( 'xy ' + ( this.elm ? this.elm.id : '' ) + ' x:' + x + ' y:' + y + ' w:' + w + ' h:' + h + ' absX:' + this.parentData.absoluteX ) - parent = this.parentData; - parent && this._updateAbsoluteXY( parent.absoluteX, parent.absoluteY, parent.scrollingX, parent.scrollingY ); - this.w === w && this.h === h && this._updateRectangle(); - }; - if( this.w !== w || this.h !== h ){ - this.w = w; - this.h = h; - //console.log( 'wh ' + ( this.elm ? this.elm.id : '' ) + ' x:' + x + ' y:' + y + ' w:' + w + ' h:' + h ) - this._updateRectangle(); - }; - - ScrollBarManager.update( this ); - }, - _updateAbsoluteXY : function( x, y, sX, sY ){ - var nodes, i; - this.absoluteX = x = this.x + x; - this.absoluteY = y = this.y + y; - if( nodes = this.childData ){ - for( i = nodes.length; i; ){ - nodes[ --i ]._updateAbsoluteXY( x, y, this.scrollingX, this.scrollingY ); - }; - }; - }, - _updateRectangle : function(){ - var w = this.w, - h = this.h, - x = this.x, - y = this.y, - l = x, - t = y, - r = x + w, - b = y + h, - nodes = this.childData, - i, node; - // self; - // childnodes - if( this.clip === false && nodes ){ - for( i = nodes.length; i; ){ - node = nodes[ --i ]; - if( node.l + x < l ) l = x + node.l; - if( node.t + y < t ) t = y + node.t; - if( r < node.r + x ) r = x + node.r; - if( b < node.b + y ) b = y + node.b; - }; - }; - // update - if( b !== this.b || r !== this.r || t !== this.t || l !== this.l ){ - this.l = l; - this.t = t; - this.r = r; - this.b = b; - // this.w = r - x; - // this.h = b - y; - this.parentData && this.parentData.clip === false && this.parentData._updateRectangle(); - return true; - }; - }, - setPosition : function( x, y ){ - this.update( x, y ); - }, - setSize : function( w, h ){ - this.update( undefined, undefined, w, h ); - }, - positionX : function( x ){ - x !== undefined && this.update( x ); - return this.x; - }, - positionY : function( y ){ - y !== undefined && this.update( undefined, y ); - return this.y; - }, - width : function( w ){ - w !== undefined && this.update( undefined, undefined, w ); - return this.w; - }, - height : function( h ){ - h !== undefined && this.update( undefined, undefined, undefined, h ); - return this.h; - }, - getAbsolutePositionX : function(){ - return this.absoluteX; - }, - getAbsolutePositionY : function(){ - return this.absoluteY; - }, - cursor : function( v ){ - if( Type.isString( v ) === true ){ - this._cursor = v; - this === targetNodeData && this.apiuser.updateCoursor( v ); - }; - return this._cursor; - }, - addEventListener : function( eventType, handler, opt_thisObject ){ - var node = this.node, - counter = this.rootData.eventCounter, - list, i; - if( this.events === null ) this.events = {}; - list = this.events[ eventType ]; - if( !list ){ - list = this.events[ eventType ] = []; - } else { - for( i = list.length; i; ){ - if( list[ --i ].match( eventType, handler ) === true ){ - return; - }; - }; - }; - list.push( new EventTicketClass( this.node, eventType, handler, opt_thisObject ) ); - if( eventType !== 'mouseout' && eventType !== 'mouseover' ){ - if( counter[ eventType ] ){ - ++counter[ eventType ]; - } else { - //console.log( eventType ); - counter[ eventType ] = 1; - MouseEvent.add( this.apiuser, this.rootData.elmMouseCatch, eventType, eventRellay ); - }; - }; - }, - removeEventListener : function( eventType, handler ){ - var events = this.events, - counter = this.rootData.eventCounter, - type, list, i = 0; - if( events === null ) return; - console.log( ' *** remove ' + eventType ); - for( type in events ){ - list = events[ type ]; - if( eventType && eventType !== type ) continue; - for( ; i < list.length; ){ - if( list[ i ].destroy( type, handler ) === true ){ - console.log( ' *** removed! ' + type ); - list.splice( i, 1 ); - } else { - ++i; - }; - }; - if( list.length === 0 ){ - // delete this[ type ]; - delete events[ type ]; - }; - if( counter[ type ] ){ - --counter[ type ]; - if( counter[ type ] === 0 ){ - MouseEvent.remove( this.apiuser, this.rootData.elmMouseCatch, type, eventRellay ); - delete counter[ type ]; - }; - }; - }; - }, - _capcher : function( x, y ){ - var t = this, nodes, child, _x, _y, hit, i; - if( t._disabled === true ) return false; - delete t.hitChild; - x -= t.x; - y -= t.y; - if( nodes = t.childData ){ - _x = x - t.scrollingX; - _y = y - t.scrollingY; - for( i = nodes.length; i; ){ - child = nodes[ --i ]; - if( child._disabled === false && child.l <= _x && _x < child.r && child.t <= _y && _y < child.b && child._capcher( _x, _y ) === true ){ - t.hitChild = child; - break; - }; - }; - }; - if( t.through === true ){ - t.hitChild && t.hitSelf === false && hoverList.push( t ); - return !!t.hitChild; - }; - hit = 0 <= x && x < t.w && 0 <= y && y < t.h; - ( t.hitChild || hit ) && t.hitSelf === false && hoverList.push( t ); - if( hit === true && t.hitChild === null ) targetNodeData = t; - return hit || !!t.hitChild; - }, - fire : function( e, eventType, hit ){ - var list = this.events[ eventType ], - i = list.length; - e = NodePrivateData.createEvent( e, eventType, this, hit ); - for( ; i; ) list[ --i ].fire( e ); - // console.log( eventType + ' x:' + x + ' y:' + y ); - }, - dispatchEvent : function( e, eventType, hit ){ - var ret, list, i, p, child; - if( !this.events || !( list = this.events[ eventType ] ) ) return; - - child = !!this.hitChild; - e = NodePrivateData.createEvent( e, eventType, this, hit ); - for( i = list.length; i; ){ - ret = list[ --i ].fire( e ); - if( ret === true && child === false ){ - forceNodeData = this; - return true; - }; - if( ret === false ) return false; - }; - forceNodeData = null; - }, - scrollTo : function( x, y ){ - this._scrollX = x; - this._scrollY = y; - ScrollBarManager.update( this ); - }, - scrollX : function( v ){ - if( Type.isFinite( v ) === true ){ - this._scrillX = v; - ScrollBarManager.update( this ); - }; - return this.scrollingX; // this._scrollX; - }, - scrollY : function( v ){ - if( Type.isFinite( v ) === true ){ - this._scrillY = v; - ScrollBarManager.update( this ); - }; - return this.scrollingY; // this._scrollY; - }, - nodeIndex : function( v ){ - var list, i; - if( !this.parentData ) return 0; - - list = this.parentData.childData; - i = Util.getIndex( list, this ); - if( Type.isFinite( v ) === false || i === v && v < 0 && list.length <= v ) return i; - - list.splice( i, 1 ); - list.length === v ? list.push( this ) : list.splice( v, 0, this ); - this._free(); - return v; - }, - _free : function(){ - if( this.parentData.hitChild === this ){ - this.parentData.hitChild = null; - this.isHover === true && hoverList.splice( Util.getIndex( hoverList, this ), 1 ) && Util.removeClass( this.elm, this.hoverClass ); - this.isHover = false; - if( forceNodeData === this ) forceNodeData = null; - if( targetNodeData === this ) targetNodeData = null; - }; - }, - numNode : function(){ - return this.childData ? this.childData.length : 0; - }, - disabled : function( v ){ - if( Type.isBoolean( v ) === true ){ - this._disabled = v; - if( v === false ){ - this._free(); - }; - }; - return this._disabled; - }, - childrenDisabled : function( v ){ - if( Type.isBoolean( v ) === true ){ - this._childDisabled = v; - }; - return this._childDisabled; - }, - remove : function(){ - if( this === this.rootData ) return; - var parent = this.parentData, - nodes = parent.childData; - this._destroy(); - if( parent.hitChild === this ) delete parent.hitChild; - nodes.splice( Util.getIndex( nodes, this ), 1 ); - if( nodes.length === 0 ) delete parent.childData; - parent.clip === false && parent._updateRectangle(); - }, - _destroy : function(){ - var nodes = this.childData, - list = NodePrivateData.dataList, - node; - this.removeEventListener(); - ScrollBarManager.remove( this ); - if( nodes ){ - while( node = nodes.shift() ) node._destroy(); - delete this.childData; - }; - list.splice( Util.getIndex( list, this ), 1 ); - } - }; - NodePrivateData.dataList = []; - NodePrivateData.get = function( node ){ - // if( node instanceof NodePrivateData ) return node; - // return NodePrivateData.dataList[ layer._getUID() ]; - var list = NodePrivateData.dataList; - for( var i = list.length; i; ){ - if( list[ --i ].node === node ) return list[ i ]; - }; - return null; - }; - NodePrivateData.createEvent = function( e, eventType, data, hit ){ - var _e = { - layerX : e.clientX - data.absoluteX, - layerY : e.clientY - data.absoluteY, - clientX : e.clientX, - clientY : e.clientY, - dragOffsetX : e.dragOffsetX, - dragOffsetY : e.dragOffsetY, - dragPhase : e.dragPhase, - eventType : eventType, - hit : hit, - node : data.node, - wheelDelta : e.wheelDelta, - target : forceNodeData ? forceNodeData.node : targetNodeData ? targetNodeData.node : null - }; - return _e; - }; - - var EventTicketClass = function( node, eventType, handler, opt_thisObject ){ - this.node = node; - this.type = eventType; - this.handler = handler; - this.thisObj = opt_thisObject || node; - }; - EventTicketClass.prototype = { - match : function( eventType, handler ){ - if( handler && this.handler !== handler ) return false; - if( eventType && this.type !== eventType ) return false; - return true; - }, - destroy : function( eventType, handler ){ - if( this.match( eventType, handler ) === false ) return false; - delete this.node; - delete this.type; - delete this.handler; - delete this.thisObj; - return true; - }, - fire : ( function(){ - if( Function.prototype.call ){ - return function( e ){ - return this.handler.call( this.thisObj, e ); - }; - }; - return function( e ){ - var ret; - this.thisObj._currentHandler = this.handler; - ret = this.thisObj._currentHandler( e ); - delete this.thisObj._currentHandler; - return ret; - }; - })() - }; - -/*------------------------------------- - * StayHelper - */ - var StayEventTicketClass = function( node, data, stayhandler, opt_thisObject ){ - node.addEventListener( 'mouseover', this.mouseoverHandler, this ); - this.node = node; - this.data = data; - this.handler = stayhandler; - this.thisObject = opt_thisObject; - }; - StayEventTicketClass.prototype = Util.extend( new EventTicketClass( null, 'mousestay' ), { - // type : 'mousestay', - e : null, - mouseoverHandler : function( e ){ - this.e = NodePrivateData.createEvent( e, this.type, this.data, true ); - this.node.addEventListener( 'mouseout', this.mousestayHandler, this ); - this.node.addEventListener( 'mousemove', this.mousemoveHandler, this ); - SystemTimer.add( this.data.apiuser, this.timeoutHandler, null, this ); - }, - timeoutHandler : function(){ - this.mouseoutHandler(); - return this.fire( this.e ); - }, - mousemoveHandler : function( e ){ - this.e = NodePrivateData.createEvent( e, this.type, this.data, true ); - SystemTimer.remove( this.data.apiuser, this.timeoutHandler ); - SystemTimer.add( this.data.apiuser, this.timeoutHandler, null, this ); - }, - mouseoutHandler : function( e ){ - this.node.removeEventListener( 'mouseout', this.mousestayHandler ); - this.node.removeEventListener( 'mousemove', this.mousemoveHandler ); - SystemTimer.remove( this.data.apiuser, this.timeoutHandler ); - delete this.e; - } - }); - - var ScrollBarManager = ( function(){ - var elmScroller = document.createElement( 'div' ), - elmBar = document.createElement( 'div' ), - smoothList = [], - dragPhase = 2, - dragOut = false, - currentNodeData = null, - dragStartY = 0, - currentEvent; - - function tick(){ - var list = smoothList, - i, data, y; - for( i = 0; i < list.length; ){ - data = list[ i ]; - if( data.scrollingY !== data._scrollY ){ - y = data.scrollingY += data.smoothY; - if( data.smoothY < 0 ){ - y = y < data._scrollY ? data._scrollY : y; - } else { - y = data._scrollY < y ? data._scrollY : y; - }; - data.scrollingY = y; - data.elm.scrollTop = -y; - data.events && data.events.scroll && data.fire( currentEvent, 'scroll', true ); - }; - if( data.scrollingY === data._scrollY ){ - list.splice( i, 1 ); - // data.events && data.events.scroll && data.fire( currentEvent, 'scroll', true ); - } else { - ++i; - }; - }; - list.length === 0 && SystemTimer.remove( SUPER_USER_KEY, tick ); - currentEvent.type = 'updateAfterScroll'; - AsyncCall.add( data.apiuser, eventRellay, currentEvent ); // スクロール後の更新 - }; - - function scrollReady( e ){ - var data = this; - - dragOut = false; - if( data === currentNodeData || dragPhase !== 2 ) return; // Drag中の場合は 他にスクロールを作らない - currentNodeData && scrollRelease(); - - dragPhase = 2; - data.elm.parentNode.appendChild( elmScroller ); - elmScroller.appendChild( data.elm ); - - elmScroller.style.cssText = 'position:absolute;left:0;top:0;'; - elmScroller.appendChild( elmBar ); - - data.elm.scrollTop = -data.scrollingY; - data.rootData.addEventListener( 'mousewheel', onMouseWheelScroll, data ); - data.rootData.addEventListener( 'mousedrag', onMouseDragScroll, data ); - data.addEventListener( 'mouseout', onMouseOut, data ); - currentNodeData = data; - ScrollBarManager.update( data ); - }; - function scrollRelease(){ - var data = currentNodeData; - var parent = elmScroller.parentNode; - parent.appendChild( currentNodeData.elm ); - parent.removeChild( elmScroller ); - currentNodeData.elm.scrollTop = -data.scrollingY; - - data.rootData.removeEventListener( 'mousewheel', onMouseWheelScroll, data ); - data.rootData.removeEventListener( 'mousedrag', onMouseDragScroll, data ); - data.removeEventListener( 'mouseout', onMouseOut, data ); - currentNodeData = null; - }; - function onMouseOut( e ){ - dragOut = true; - console.log( 'mouseOut ' + dragPhase ); - dragPhase === 2 && scrollRelease(); // Dragしてのアウトの場合, scroll をリリースしない - }; - function onMouseWheelScroll( e ){ - var data = this; - this._scrollY += e.wheelDelta; - ScrollBarManager.update( this ); - currentEvent = e; - return true; - }; - function onMouseDragScroll( e ){ - var data = this; - //e.dragOffsetY; - currentEvent = e; - dragPhase = e.dragPhase; - switch( dragPhase ){ - case 0: - dragStartY = this.scrollingY; - data.rootData.removeEventListener( 'mousewheel', onMouseWheelScroll, data ); - case 1: - this._scrollY = dragStartY + e.dragOffsetY; - ScrollBarManager.update( this ); - return true; - case 2: - dragOut === true ? scrollRelease() : data.rootData.addEventListener( 'mousewheel', onMouseWheelScroll, data ); - return false; - }; - }; - - return { - register : function( data ){ - data.addEventListener( 'mouseover', scrollReady, data ); - }, - update : function( data ){ - // if( data !== currentNodeData ) return; - var isCurrent = data === currentNodeData; - - var contentH = data._scrollH = data.elm.scrollHeight, - clipH = data.h, - offsetH = contentH - clipH, - scrollY = data._scrollY = 0 < data._scrollY ? 0 : ( data._scrollY < -offsetH ? -offsetH : data._scrollY ), - barH, barY; - if( isCurrent === true ){ - elmScroller.style.width = data.w + 'px'; - elmScroller.style.height = clipH + 'px'; - }; - - if( offsetH < 1 ){ - data._scrollY = scrollY = 0; - if( isCurrent === true ) elmBar.style.display = 'none'; - } else - if( isCurrent === true ){ - barH = Math.floor( clipH * ( clipH / contentH ) ); - barY = Math.floor( ( clipH - barH ) * - scrollY / offsetH ); - elmBar.style.cssText = [ - 'position:absolute;', - 'width:10px;', - 'background-color:#333;', - 'right:2px;', - 'font-size:0;line-height:0;', - 'height:', barH, 'px;', - 'top:', data.y + barY, 'px;' - ].join( '' ); - }; - data.smoothY = ( scrollY - data.scrollingY ) / 10; - if( data.scrollingY !== scrollY && Util.getIndex( smoothList, data ) === -1 ){ - smoothList.length === 0 && SystemTimer.add( SUPER_USER_KEY, tick, 16 ); - smoothList.push( data ); - }; - }, - remove : function( data ){ - var list = smoothList, - i = Util.getIndex( list, data ); - data === currentNodeData && scrollRelease(); - i !== -1 && list.splice( i, 1 ); - } - }; - })(); - - return { - create : function( apiuser ){ - var elm = document.createElement( 'div' ), - root, data; - body.appendChild( elm ); - - root = new NodeClass( apiuser, null, null, elm ); - data = NodePrivateData.get( root ); - - // elm.style.cssText = 'position:absolute;top:0;left:0;height:100%;'; - elm.className = 'mouse-operation-catcher'; - elm.unselectable = 'on'; - data.elmMouseCatch = elm; - - data.eventCounter = {}; - ROOT_LIST.push( data ); - currentRootData = data; - targetNodeData = null; - forceNodeData = null; - - MouseEvent.add( apiuser, elm, 'mousemove', eventRellay ); - return root; - }, - onCurrentApplicationChange : function( _application ){ - currentRootData = null; - targetNodeData = null; - forceNodeData = null; - for( var i = ROOT_LIST.length; i; ){ - if( ROOT_LIST[ --i ].apiuser === _application ){ - currentRootData = ROOT_LIST[ i ]; - return; - }; - }; - }, - destroyTree : function( root ){ - var data = NodePrivateData.get( root ); - MouseEvent.remove( data.apiuser, data.elmMouseCatch, 'mousemove', eventRellay ); - body.removeChild( data.elmMouseCatch ); - data._destroy(); - ROOT_LIST.splice( Util.getIndex( ROOT_LIST, data ), 1 ); - if( currentRootData === data ){ - currentRootData = null; - targetNodeData = null; - forceNodeData = null; - }; - }, - onSystemShutdown : function(){ - - }, - isNodeInstance : function( node ){ - return node instanceof NodeClass; - }, - _getNodePrivateData : function( node ){ // system only - return NodePrivateData.get( node ); - } - }; -})(); - -var Application = ( function(){ - - var LIVE_APPLICATION_LIST = []; - - var currentApplication = null, - coveredApplication = null, - winW = 0, - winH = 0; - - var ApplicationReference = function( appClass, isOverlay, displayName, id, thumbnailUrl, tailColor ){ - var self = this; - var application = null; - this.id = id; - this.displayName = displayName; - this.thumbnailUrl = thumbnailUrl; - this.tailColor = tailColor; - - function asyncBoot(){ - application = Application.boot( appClass, displayName, self.getUID(), isOverlay, Util.copyArray( arguments ) ); - }; - this.getUID = function(){ - return Util.getIndex( API_USER_LIST, appClass ); - }; - this.getDisplayName = function(){ - return this.displayName; - }; - this.boot = function( /* _option */ ){ - AsyncCall.add( this, asyncBoot, Util.copyArray( arguments ) ); - }; - this.shutdown = function(){ - if( !application ) return false; - - AsyncCall.add( application, ( isOverlay === true ? Overlay.hide : application.close ) ); - }; - }; - - function asyncBootHome(){ - currentApplication === null && Home.boot(); - }; - function asyncOpen( /* arguments */ ){ - var _arg = Util.copyArray( arguments ); - _arg.unshift( winW, winH ); - currentApplication.open.apply( currentApplication, _arg ); - }; - return { - register: function( _class, _overlay, _tail, _displayName, _id, _thumbnailUrl, _tailColor ){ - APPLICATION_LIST.push( _class ); - API_USER_LIST.push( _class ); - var _ref = new ApplicationReference( _class, _overlay, _displayName, _id, _thumbnailUrl, _tailColor ); - _tail === true && Home.add( _ref ); - return _ref; - }, - isApplicationInstance: function( app ){ - return ApplicationPrivateData.get( app ) !== null; - }, - isApplicationReference: function( _reference ){ - return _reference instanceof ApplicationReference; - }, - isCurrentAppplication: function( app ){ - return app === currentApplication; - }, - boot: function( appClass, displayName, uid, isOverlay, arg ){ - if( currentApplication ){ - if( currentApplication.getUID() === uid ) return null; - if( isOverlay === false && currentApplication.close() === false ) return null; - }; - - appClass.prototype = new AbstractApplication( appClass, displayName, isOverlay ); - - var application = new appClass(), - data = ApplicationPrivateData.get( application ); - - application.rootElement = data.rootElement; - data.application = application; - - coveredApplication = isOverlay === true ? currentApplication : null; - - Application.onCurrentApplicationChange( application ); - - if( isOverlay === false ){ - body.style.backgroundColor = application.bgColor; - - body.appendChild( data.rootElement ); - data.rootElement.style.display = 'none'; - application.init(); - - application.addAsyncCall( asyncOpen, arg ); - } else { - Overlay.show( application, arg ); - }; - - return application; - }, - shutdown: function( _application, isOverlay ){ - if( isOverlay === false ){ - currentApplication = null; - AsyncCall.add( SUPER_USER_KEY, asyncBootHome ); - } else { - Application.onCurrentApplicationChange( coveredApplication ); - coveredApplication = null; - }; - }, - onCurrentApplicationChange: function( _application ){ - if( Application.isApplicationInstance( _application ) === false ) return; - if( currentApplication === _application ) return; - currentApplication = _application; - MouseEvent.onCurrentApplicationChange( _application ); - PointingDeviceEventTree.onCurrentApplicationChange( _application ); - KeyEvent.updateCurrentListener( _application ); - // InteractiveLayer.onCurrentApplicationChange( _application ); - }, - onApplicationShutdown: function( _application ){ - LIVE_APPLICATION_LIST.splice( Util.getIndex( LIVE_APPLICATION_LIST, _application ) ); - }, - onWindowResize: function( w, h ){ - winW = w; - winH = h; - currentApplication && currentApplication.resize( w, h ); - Overlay.onWindowResize( w, h ); - UI.onWindowResize( w, h ); - }, - onSystemShutdown: function(){ - - } - } -})(); - -/* -------------------------------------------------------------- - * Home - * - */ - var Home = ( function(){ - var APP_REF_LIST = []; - var ELM_TAIL_ORIGIN = ( function(){ - var ret = document.createElement( 'div' ), - h2 = document.createElement( 'h2' ); - ret.className = 'tail-wrapper'; - ret.appendChild( h2 ); - h2.appendChild( document.createTextNode( 'appName' ) ); - return ret; - })(); - - var TailClass = function( appRef ){ - this.elm = ELM_TAIL_ORIGIN.cloneNode( true ); - this.destroy = function(){ - appRef = self = elmName = null; - }; - - var self = this, - elmName = this.elm.getElementsByTagName( 'h2' )[ 0 ].firstChild; - - this.elm.style.backgroundColor = appRef.tailColor; - elmName.data = appRef.displayName; - }; - - var ref = Application.register( function(){ - var self = this, - winW = 0, - winH = 0, - tailList = [], - elmContainer, elmHeader; - - function draw(){ - var tail, elm; - for( var i=0, l=APP_REF_LIST.length; i 0 ){ - tailList.shift().destroy(); - } - self = tailList = elmContainer = null; - }; - }, false, false, 'home', 'home', null ); - - return { - add: function( _appRef ){ - if( Application.isApplicationReference( _appRef ) === false ) return; - Util.getIndex( APP_REF_LIST, _appRef ) === -1 && APP_REF_LIST.push( _appRef ); - }, - boot: function(){ - ref.boot(); - } - } - })(); - - var Page = ( function(){ - var pageNodes = [], - appClass, ref, - ignoreTagList = [ 'script', 'noscript', 'style' ]; - - var MemoryClass = function( node ){ - this.node = node; - }; - MemoryClass.prototype = { - init: function(){ - var node = this.node, - _nodeType = node.nodeType; - if( _nodeType === 1 && Util.getIndex( ignoreTagList, node.tagName.toLowerCase() ) === -1 ){ - this.type = _nodeType; - this.display = node.style.display; - } else - if( _nodeType === 3 ){ - if( node.data.replace( /\s/g, '' ).length !== 0 ){ - this.type = _nodeType; - this.before = pageNodes.length === 0 ? null : pageNodes[ pageNodes.length - 1 ].node; - } else { - body.removeChild( node ); - return false; - } - } else { - // body.removeChild( node ); - return false; - }; - }, - show: function(){ - if( this.type === 1 ){ - if( this.display ){ - this.node.style.display = this.display; - } else { - this.node.style.display = ''; - } - } else { - if( this.before ){ - body.insertBefore( this.node, this.before ); - } else { - body.appendChild( this.node ); - }; - }; - }, - hide: function(){ - if( !this.node.parentNode ){ - return; - }; - if( this.type === 1 ){ - this.node.style.display = 'none'; - } else { - body.removeChild( this.node ); - }; - } - }; - - return { - onReady: function(){ - var _children = Util.copyArray( body.childNodes ), - _mem; - for( var i = 0, l = _children.length; i= CLICK_OFFSET && this.mouseoutHandler(); - return false; - }, - mouseupHandler : function( e ){ - this.mouseoutHandler(); - return this.fire( ClickEventTicketClass.createEvent( e ) ); - }, - mouseoutHandler : function( e ){ - this.mousemoveTicket && this.mousemoveTicket.destroy(); - this.mouseupTicket && this.mouseupTicket.destroy(); - this.mouseoutTicket && this.mouseoutTicket.destroy(); - if( this.mousemoveTicket ) delete this.mousemoveTicket; - if( this.mouseupTicket ) delete this.mouseupTicket; - if( this.mouseoutTicket ) delete this.mouseoutTicket; - return false; - }, - destroy : function( _element, _eventType, _handler ){ - if( this.match( _element, _eventType, _handler ) === false ) return false; - - this.mouseoutHandler(); - this.mousedownTicket.destroy(); - - delete this.element; - delete this.handler; - delete this.thisObject; - delete this.mousedownTicket; - return true; - } - }; - if( document.createEvent ){ - ClickEventTicketClass.createEvent = function( e ){ - var _e = document.createEvent( 'MouseEvents' ); - _e.initMouseEvent( - 'click' , false, true, e.view, - e.detail, e.screenX, e.screenY, e.clientX, e.clientY, - e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, - e.button, e.relatedTarget - ); - return _e; - }; - } else - if( document.attachEvent ){ - ClickEventTicketClass.createEvent = function( e ){ - e.type = 'click'; - return e; - }; - } else { - - }; - - /*------------------------------------- - * WheelHelper - */ - var WheelEventTicketClass = ( function(){ - if( UA.GECKO ){ - return function( element, wheelhandler, opt_thisObject ){ - this.wheelTicket = new EventTicketClass( element, 'DOMMouseScroll', this.onGeckoWheel, this ); - this.element = element; - this.handler = wheelhandler; - this.thisObject = opt_thisObject; - }; - } else - if( true || UA.isIE ){ - return function( element, wheelhandler, opt_thisObject ){ - this.wheelTicket = new EventTicketClass( element, this.eventType, wheelhandler ); - this.element = element; - this.handler = wheelhandler; - this.thisObject = opt_thisObject; - }; - } else { - TMP.wheelHandlerList = []; - TMP.wheelThisObjList = []; - //TMP.wheelLegacy = undefined; - TMP.onWheel = function( e ){ - e = e || window.event; - var cancel = true, - f = TMP.wheelLegacy, i; - if( f ) cancel = f.call( this, e ); - - for( i = TMP.wheelHandlerList.length; i; ){ - if( TMP.wheelHandlerList[ --i ].call( TMP.wheelThisObjList[ i ] || this, e ) === false ) cancel = false; - }; - return cancel; - }; - return function( element, wheelhandler, opt_thisObject ){ - this.element = element; - this.handler = wheelhandler; - this.thisObject = opt_thisObject; - - if( TMP.wheelHandlerList.length === 0 ){ - //TMP.wheelLegacy = Type.isFunction( window.onmousewheel ) === true ? window.onmousewheel : undefined; - element.onmousewheel = TMP.onWheel; - }; - TMP.wheelHandlerList.push( wheelhandler ); - TMP.wheelThisObjList.push( opt_thisObject ) - }; - }; - })(); - WheelEventTicketClass.prototype = { - eventType : 'mousewheel', - match : EventTicketClass.prototype.match, - destroy : function( _element, _eventType, _handler ){ - if( this.match( _element, _eventType, _handler ) === false ) return false; - - this.wheelTicket && this.wheelTicket.destroy(); - - delete this.wheelTicket; - delete this.element; - delete this.handler; - delete this.thisObject; - - this.onDestroy && this.onDestroy(); - return true; - } - }; - if( UA.GECKO ){ - WheelEventTicketClass.prototype.onGeckoWheel = function( e ){ - var _e = document.createEvent( 'MouseEvents' ); - _e.initMouseEvent( - 'mousewheel' , false, true, e.view, - e.detail, e.screenX, e.screenY, e.clientX, e.clientY, - e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, - e.button, e.relatedTarget - ); - _e.wheelDelta = e.detail * -40; - return this.handler.call( this.thisObject || this.element, _e ); - }; - } else - if( true || UA.isIE ){ - - } else { - WheelEventTicketClass.prototype.onDestroy = function(){ - TMP.wheelHandlerList.splice( Util.getIndex( TMP.wheelHandlerList, this.handler ), 1 ); - TMP.wheelThisObjList.splice( Util.getIndex( TMP.wheelThisObjList, this.handler ), 1 ); - if( TMP.wheelHandlerList.length === 0 ) this.element.onmousewheel = ''; - }; - }; - - /*------------------------------------- - * DragHelper - */ - var DragEventTicketClass = function( element, draghandler, opt_thisObject ){ - this.mousedownTicket = new EventTicketClass( element, 'mousedown', this.mousedownHandler, this ); - this.element = element; - this.handler = draghandler; - this.thisObject = opt_thisObject; - }; - DragEventTicketClass.prototype = { - element : null, - handler : null, - thisObject : null, - startX : 0, - startY : 0, - dragging : false, - mousedownTicket : null, - mousemoveTicket : null, - mouseupTicket : null, - mouseoutTicket : null, - eventType : 'mousedrag', - fire : EventTicketClass.prototype.fire, - match : EventTicketClass.prototype.match, - mousedownHandler: function( e ){ - this.startX = e.clientX; - this.startY = e.clientY; - - this.mousemoveTicket = new EventTicketClass( this.element, 'mousemove', this.dragMoveHandler, this ); - this.mouseupTicket = new EventTicketClass( this.element, 'mouseup', this.dragEndHandler, this ); - this.mouseoutTicket = new EventTicketClass( this.element, 'mouseout', this.dragEndHandler, this ); - - return false; - }, - dragMoveHandler : function( e ){ - var offsetX = e.clientX - this.startX, - offsetY = e.clientY - this.startY; - if( this.dragging === false ){ - if( offsetX * offsetX + offsetY * offsetY < DRAG_OFFSET ) return; - console.log( 'Drag start' ); - // dragStart - this.dragging = true; - return this.fire( DragEventTicketClass.createEvent( e, offsetX, offsetY, 0 ) ); - }; - return this.fire( DragEventTicketClass.createEvent( e, offsetX, offsetY, 1 ) ); - }, - dragEndHandler : function( e ){ - if( this.dragging === true ){ - console.log( 'Drag End ' + e.type ); - this.removeEvents(); - // dragEnd - return this.fire( DragEventTicketClass.createEvent( e, e.clientX - this.startX, e.clientY - this.startY, 2 ) ); - }; - this.removeEvents(); - return false; - }, - removeEvents : function(){ - this.dragging = false; - if( this.mousemoveTicket ){ - this.mousemoveTicket.destroy(); - delete this.mousemoveTicket; - }; - if( this.mouseupTicket ){ - this.mouseupTicket.destroy(); - delete this.mouseupTicket; - }; - if( this.mouseoutTicke ){ - this.mouseoutTicket.destroy(); - delete this.mouseoutTicket; - }; - }, - destroy : function( _element, _eventType, _handler ){ - if( this.match( _element, _eventType, _handler ) === false ) return false; - - this.removeEvents(); - this.mousedownTicket.destroy(); - - delete this.element; - delete this.handler; - delete this.thisObject; - delete this.mousedownTicket; - return true; - } - }; - if( document.createEvent ){ - DragEventTicketClass.createEvent = function( e, offsetX, offsetY, dragPhase ){ - var _e = document.createEvent( 'MouseEvents' ); - _e.initMouseEvent( - DragEventTicketClass.prototype.eventType , false, true, e.view, - e.detail, e.screenX, e.screenY, e.clientX, e.clientY, - e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, - e.button, e.relatedTarget - ); - _e.dragPhase = dragPhase; - _e.dragOffsetX = offsetX; - _e.dragOffsetY = offsetY; - return _e; - }; - } else - if( document.attachEvent ){ - DragEventTicketClass.createEvent = function( e, offsetX, offsetY, dragPhase ){ - e.type = DragEventTicketClass.prototype.eventType; - e.dragPhase = dragPhase; - e.dragOffsetX = offsetX; - e.dragOffsetY = offsetY; - return e; - }; - } else { - - }; - - return { - add: function( _apiuser, _element, _eventType, _handler, opt_thisObject ){ - if( isApiUser( _apiuser ) === true && - ( Type.isHTMLElement( _element ) === true || _element === window || _element === document ) && - Type.isString( _eventType ) === true && - Type.isFunction( _handler ) === true - ){ - var _uid = _apiuser.getUID(), - _events = EVENT_LIST_MAP[ _uid ]; - if( Type.isArray( _events ) === false ){ - _events = EVENT_LIST_MAP[ _uid ] = []; - } else { - // 2重登録の禁止 - for( var i=0, l=_events.length; i 0; - } catch( e ){ - return false; - }; - }, - done: false - }; - - function getTicket( elm ){ - for( var i = TICKET_LIST.length, t; i; ){ - t = TICKET_LIST[ --i ]; - if( t.elm === elm ) return t; - }; - }; - - function detect(){ - var t = getTicket( this ), rs = this.readyState, c; - if( t && t.done === false && ( !rs || Util.getIndex( STATE_LIST, rs ) !== -1 ) ){ - t.done = true; - t.loaded(); - this.onreadystatechange = new Function(); - this.onload = null; - }; - }; - - function checkTimer(){ - var l = TICKET_LIST.length, - n = 0, t; - for( var i = 0; i < l; ++i ){ - t = TICKET_LIST[ i ]; - ++t.time; - if( t.check() === true ){ - t.loaded(); - ++n; - } else - if( t.time > 99 ){ - t.error(); - } else { - - }; - }; - l === n && SystemTimer.remove( SUPER_USER_KEY, checkTimer ); - }; - - return { - load: function( _apiuser, _url, opt_onload, opt_onerror, opt_thisObject ){ - _url = Util.getAbsolutePath( _url ); - var t; - for( var i=TICKET_LIST.length; i; ){ - t = TICKET_LIST[ --i ]; - if( t.match( null, _url ) === true ){ - if( t.match( _apiuser, _url ) === false ){ - t.apiusers.push( _apiuser ); - t.onload.push( opt_onload ); - t.onerror.push( opt_onerror ); - t.thisObj.push( opt_thisObject ); - }; - SystemTimer.add( SUPER_USER_KEY, checkTimer, 333 ); - return; - }; - }; - var elm = document.createElement( 'link' ); - head.appendChild( elm ); - elm.rel = 'stylesheet'; - elm.type = 'text\/css'; - elm.onreadystatechange = elm.onload = detect; - elm.href = _url; - - if( !sheet ){ // only assign these once - cssRules = 'cssRules'; - sheet = 'sheet'; - if ( !( sheet in elm ) ) { // MSIE uses non-standard property names - cssRules = 'rules'; - sheet = 'styleSheet'; - }; - }; - - TICKET_LIST.push( new FetchCssTicketClass( _apiuser, _url, elm, opt_onload, opt_onerror, opt_thisObject ) ); - - SystemTimer.add( SUPER_USER_KEY, checkTimer, 333 ); - }, - unload: function( _apiuser, _url ){ - _url = _url ? Util.getAbsolutePath( _url ) : null; - var t; - for( var i = 0; i < TICKET_LIST.length; ){ - t = TICKET_LIST[ i ]; - if( t.destroy( _apiuser, _url ) === true ){ - TICKET_LIST.splice( i, 1 ); - } else { - ++i; - } - }; - if( TICKET_LIST.length === 0 ){ - SystemTimer.remove( SUPER_USER_KEY, checkTimer ); - } - } - } -})(); - -/* - * AssetLoader - * fetchCSS - * fetchJson - * fetchHtml - * fetchImage - * fetchLocalFile - * fetchLocalStorage - */ - -var Image = ( function(){ - var TASK_LIST = []; - /* - * FetchClass original is - * - * LICENSE: MIT? - * URL: http://d.hatena.ne.jp/uupaa/20080413/1208067631 - * AUTHOR: uupaa.js@gmail.com - * - */ - function detect(){ - for( var i=0, t; i < TASK_LIST.length; ){ - t = TASK_LIST[ i ]; - if( t.complete() === true ){ - TASK_LIST.splice( i, 1 ); - } else { - ++i; - }; - }; - TASK_LIST.length === 0 && SystemTimer.remove( SUPER_USER_KEY, detect ); - }; - function getTask( img ){ - for( var i = TASK_LIST.length; i; ){ - if( TASK_LIST[ --i ].img === img ) return TASK_LIST[ i ]; - }; - }; - function onError(){ - var task = getTask( this ); - if( task.finish === true ) return; - task.finish = true; - AsyncCall.add( task.apiuser, task.asyncCallback, null, task ); - }; - function onLoad(){ - // if( finish === true ) return; // これがあると firefox3.6 で駄目、、、 - // if( timer ) return; // これがあると safari3.2 で駄目、、、 - var task = getTask( this ); - task.finish = true; - TASK_LIST.splice( Util.getIndex( TASK_LIST, task ), 1 ); - if( window.opera && !task.img.complete ){ - AsyncCall.add( task.apiuser, task.asyncCallback, null, task ); - return; - }; - task.size = Util.getImageSize( this ); - AsyncCall.add( task.apiuser, task.asyncCallback, null, task ); - }; - - - var FetchClass = function( apiuser, abspath, onLoadCallback, onErrorCallback, timeout ){ - this.apiuser = apiuser; - this.abspath = abspath; - this.onLoadCallback = onLoadCallback; - this.onErrorCallback = onErrorCallback; - this.timeout = timeout; - this.tick = 0; - }; - FetchClass.prototype = { - img: null, - size: null, - tick: 0, - finish: false, - load: function(){ - var img = this.img = document.createElement( 'img' ); //var img = new Image(); ではieでimgのsizeが取れない、、、removeChildも失敗し、imgSizeGetterにimgが残る - img.onabort = img.onerror = onError; - img.onload = onLoad; - img.src = this.abspath; - }, - complete: function(){ - if( this.finish === true ) return true; - if( this.img.complete ){ - this.finish = true; - if( this.img.width ) return true; - AsyncCall.add( this.apiuser, this.asyncCallback, null, this ); - return true; - }; - if( ( this.tick += 250 ) > this.timeout ){ - this.finish = true; - AsyncCall.add( this.apiuser, this.asyncCallback, null, this ); - return true; - }; - }, - asyncCallback: function(){ - this.size ? this.onLoadCallback( this.abspath, this.size.width, this.size.height ) : this.onErrorCallback( this.abspath ); - this.destroy(); - }, - destroy: function(){ - this.finish = true; - this.img.src = this.img.onload = this.img.onabort = this.img.onerror = ''; - delete this.img; - delete this.size; - delete this.onLoadCallback; - delete this.onErrorCallback; - }, - stop: function(){ - timer !== null && window.clearTimeout( timer ); - destroy(); - } - }; - - return { - load: function( URLorELM, onLoad, onError, opt_timeout ){ - var src, fetch; - if( Type.isString( URLorELM ) === true ){ - src = URLorELM; - } else - if( Type.isHTMLElement( URLorELM ) === true && URLorELM.tagName.toLowerCase() === 'img' ){ - src = URLorELM.src; - } else { - return; - }; - - fetch = new FetchClass( - Util.getAbsolutePath( src ), - onLoad, onError, - Type.isFinite( opt_timeout ) === true ? opt_timeout : undefined - ); - TASK_LIST.push( fetch ); - - SystemTimer.add( SUPER_USER_KEY, detect, 250 ); - }, - unload: function( ){ - - } - }; -})(); - - -/* ---------------------------------------- - * - */ - -var Overlay = ( function(){ - var elmContainer, elmShadow, elmCloseButton, - bootParams, - application = null, - visible = false, - bodyOverflow = '', - windowW, windowH; - - function onCloseClick( e ){ - Overlay.hide(); - return false; - }; - function asyncInit( /* arguments */ ){ - application.init(); - //application.rootElement.style.display = 'none'; - - elmContainer.style.cssText = "top:" + body.scrollTop + 'px;display:none;'; - $( elmContainer ).stop().fadeIn( onFadeInComplete ); - }; - function asyncOpen( /* arguments */ ){ - - - - }; - function onFadeInComplete(){ - KeyEvent.add( application, Const.KEY.EVENT.KEY_DOWN, Overlay.hide, 27 ); // 27.esc - MouseEvent.add( application, elmCloseButton, 'click', onCloseClick ); - - var _arg = bootParams; //Util.copyArray( arguments ); - _arg.unshift( windowW, windowH ); - application.open.apply( application, _arg ); - }; - function onFadeOutComplete(){ - Util.removeAllChildren( elmContainer ); - body.removeChild( elmContainer ); - elmContainer = elmShadow = elmCloseButton = null; - }; - return { - show: function( _application, _bootParams ){ - if( visible === true && application === _application ) return; - if( Application.isApplicationInstance( _application ) === false ) return; - - elmContainer = document.createElement( 'div' ); - body.appendChild( elmContainer ); - - elmContainer.id = 'overlay-container'; - - bodyOverflow = body.style.overflow; - body.style.overflow = 'hidden'; - - elmShadow = document.createElement( 'div' ); - elmContainer.appendChild( elmShadow ); - elmShadow.id = 'overlay-shadow'; - - elmCloseButton = document.createElement( 'div' ); - elmContainer.appendChild( elmCloseButton ); - elmCloseButton.id = 'overlay-close-button'; - elmCloseButton.appendChild( document.createTextNode( 'x' ) ); - - elmContainer.style.display = 'none'; // hide for fadeIn - - visible = true; - application = _application; - - //asyncInit(); - elmContainer.insertBefore( application.rootElement, elmCloseButton ); - _application.addAsyncCall( asyncInit ); - // _application.addAsyncCall( asyncOpen, ); - - bootParams = _bootParams; - }, - hide: function(){ - if( visible === false ) return; - if( application.close() === false ) return false; - - body.style.overflow = bodyOverflow; - - $( elmContainer ).stop().css( { - filter: '', - opacity: '' - }).fadeOut( onFadeOutComplete ); - visible = false; - - application = null; - }, - onWindowResize: function( _windowW, _windowH ){ - windowW = _windowW; - windowH = _windowH; - - if( application === null ) return; - - elmContainer.style.height = _windowH + 'px'; - elmContainer.style.top = body.scrollTop + 'px'; - - elmShadow.style.height = _windowH + 'px'; - - AsyncCall.add( application, application.resize, [ _windowW, _windowH ] ); - } - } -})(); - -/* ---------------------------------------- - * UI - * - * keyEventRellay - * form -> overlay -> view - * - */ - -var UI = ( function(){ - var UI_LIST = [], - currentUser = null, - currentList = null, - currentUi = null, - currentItem = null, - windowW = 0, - windowH = 0; - - var CLASSNAME_COMBOBOX_OPTION = 'combobox-option', - CLASSNAME_COMBOBOX_OPTION_CURRENT = CLASSNAME_COMBOBOX_OPTION + ' combobox-option-current', - ELM_COMBOBOX = ( function(){ - var ret = document.createElement( 'a' ), - elmToggle = document.createElement( 'span' ), - elmValue = document.createElement( 'span' ); - ret.href = '#'; - ret.appendChild( elmToggle ); - ret.appendChild( elmValue ); - elmToggle.className = 'combobox-toggle'; - elmValue.className = 'combobox-value'; - - elmToggle.appendChild( document.createTextNode( '▼' )); - elmValue.appendChild( document.createTextNode( 'null' )); - return ret; - })(); - - var UIItemPrivateData = function(){}; - UIItemPrivateData.prototype = { - groupData : null, - item : null, - elm : null, - node : null, - focus : false, - visible : true, - enabled : true, - value : null, - onUpdate : null, - validator : null, - elmValue : null, - elmBox : null, - elmA : null, - elmToggle : null, - elmValue : null, - selectIndex : 0, - optionList : null, - init : function( groupData, item, elm, value, onUpdate, validator, focus, visible, enabled ){ - this.groupData = groupData; - this.item = item; - this.elm = elm; - this.value = value; - this.onUpdate = onUpdate; - this.validator = validator; - this.focus = !!focus; - this.visible = !!visible; - this.enabled = !!enabled; - UIItemPrivateData.list.push( this ); - }, - destroy : function(){ - var list = UIItemPrivateData.list; - list.splice( Util.getIndex( list, this ), 1 ); - - list = this.groupData.itemList; - var i = Util.getIndex( list, this.item ); - i !== -1 && list.splice( i, 1 ); - - this.node && this.node.remove(); - } - }; - UIItemPrivateData.list = []; - UIItemPrivateData.get = function( item ){ - var list = UIItemPrivateData.list; - for( i = list.length; i; ){ - if( list[ --i ].item === item ) return list[ i ]; - }; - return null; - }; - -/* -------------------------------- - * TextInputManager - */ - var TextInputManager = ( function(){ - var elmInput = ( function(){ - var ret = document.createElement( 'input' ); - ret.type = 'text'; - ret.id = 'ui-textinput'; - return ret; - })(); - var currentData; - - function updateWrapperPosition(){ - var p = Position.cumulativeOffset( currentData.elmValue ), - w = currentData.elmValue.offsetWidth - 2, - _w; - elmInput.style.cssText = [ - 'left:', p[ 0 ], 'px;', - 'top:', p[ 1 ], 'px;',//, - 'width:', w, 'px;'//, - //'height:', data.elmValue.offsetHeight, 'px;', - //'position:absolute;' - ].join( '' ); - - //_w = elmInput.offsetWidth; - //if( w !== _w ) elmInput.style.width = ( w - ( _w - w ) ) + 'px;'; - }; - - return { - show: function( data ){ - // this.groupData.node.addEventListener( 'mouseout' ); - currentData = data; - - body.appendChild( elmInput ); - elmInput.value = data.value; - updateWrapperPosition(); - - elmInput.focus(); - elmInput.select(); - - SystemTimer.add( SUPER_USER_KEY, updateWrapperPosition, 500 ); - }, - hide : function( data ){ - if( currentData !== data ) return; - currentData = null; - body.removeChild( elmInput ); - var ret = elmInput.value; - elmInput.value = ''; - SystemTimer.remove( SUPER_USER_KEY, updateWrapperPosition ); - return ret; - }, - update : function( data ){ - elmInput.value = data.value; - }, - onWindowResize: function( _w, _h ){ - AsyncCall.add( currentUser, updateWrapperPosition ); - } - }; - })(); - - var TextInputClass = function( groupData, elmWrapper, elmValue, onUpdate, validater ){ - var data = new UIItemPrivateData(); - data.init( groupData, this, elmWrapper, elmValue.innerHTML, onUpdate, validater, false, true, true ); - Util.addClass( elmValue, 'editable-text' ); - data.elmValue = elmValue; - this.value( data.value ); - data.node = groupData.node.createNode( elmWrapper, false, true, 'ui-inpittext-hover', 'pointer' ); - data.node.addEventListener( 'click', this.focus, this ); - //MouseEvent.add( groupData.apiuser, elmWrapper, 'click', instance.focus ); - }; - TextInputClass.prototype = { - value : function( value ){ - var data = UIItemPrivateData.get( this ); - if( Type.isString( value ) === true || Type.isNumber( value ) === true ){ - data.elmValue.innerHTML = data.value = '' + value; - data.focus === true && TextInputManager.update( data ); - }; - data.focus === true && this.blur(); - return data.value; - }, - focus : function( e ){ - var data = UIItemPrivateData.get( this ); - data.focus = true; - start( data ); - TextInputManager.show( data ); - return false; - }, - blur : function( keep ){ - var data = UIItemPrivateData.get( this ), - newValue; - if( data.focus === false ) return; - newValue = TextInputManager.hide( data ); - newValue = keep !== 27 ? ( data.validater ? '' + data.validater( newValue ) : newValue ) : data.value; // 27:ESC - - data.elmValue.innerHTML = newValue; - - data.onUpdate && newValue !== data.value && AsyncCall.add( data.groupData.apiuser, data.onUpdate, [ newValue, data.value ], this ); - - data.value = newValue; - data.focus = false; - finish( data ); - }, - enabled : function( v ){ - var data = UIItemPrivateData.get( this ); - if( Type.isBoolean( v ) === true && data.enabled !== v ){ - Util.toggleClass( data.elm, 'ui-textinput-disabled', !v ); - if( data.focus === true && v === false ) this.blur(); - data.enabled = v; - data.node.disabled( !( data.visible && v ) ); - }; - return data.enabled; - }, - visible : function( v ){ - var data = UIItemPrivateData.get( this ); - if( Type.isBoolean( v ) === true && data.visible !== v ){ - data.elm.style.display = v ? '' : 'none'; - if( data.focus === true && v === false ) this.blur(); - data.visible = v; - data.node.disabled( !( data.enabled && v ) ); - }; - return data.visible; - }, - destroy : function(){ - var data = UIItemPrivateData.get( this ); - data.focus === true && TextInputManager.hide( data ); - data.destroy(); - } - }; - -/* -------------------------------- - * TextInputManager - */ - var FileInputManager = ( function(){ - var currentData, - elmForm, - elmFileInput, - elmWrap, - evt; - - function updateWrapperPosition(){ - var p = Position.cumulativeOffset( currentData.elmValue ), - w = currentData.elmValue.offsetWidth, - _w; - elmWrap.style.cssText = [ - 'left:', p[ 0 ], 'px;', - 'top:', p[ 1 ], 'px;',//, - 'width:', w, 'px;'//, - //'height:', data.elmValue.offsetHeight, 'px;', - //'position:absolute;' - ].join( '' ); - - _w = elmWrap.offsetWidth; - if( w !== _w ) elmWrap.style.width = ( w - ( _w - w ) ) + 'px'; - }; - - function change( e ){ - var data = currentData, - file = data.elmFileInputReal.value; - file = file.split( '\\' ); - file = file[ file.length - 1 ]; - if( data.value !== file ){ - data.onUpdate && AsyncCall.add( data.groupData.apiuser, data.onUpdate, [ file, data.value ], this ); - data.elmValue.innerHTML = data.value = file; - }; - currentData.item.blur(); - }; - function asyncMouseout(){ - currentData && currentData.item.blur(); - }; - function onClick(){ - MouseEvent.remove( currentUser, elmFileInput, 'mouseout', asyncMouseout ); - MouseEvent.remove( currentUser, elmFileInput, 'click', onClick ); - }; - return { - show : function( data ){ - currentData = data; - - elmFileInput = data.elmFileInputReal; - elmWrap = elmFileInput.parentNode; - // - - updateWrapperPosition(); - elmFileInput.focus(); - //data.node.addEventListener( 'change', change, data ); - evt = new EventTicketClass( elmFileInput, 'change', change ); - MouseEvent.add( currentUser, elmFileInput, 'mouseout', asyncMouseout ); - MouseEvent.add( currentUser, elmFileInput, 'click', onClick ); - // currentData.elmFileInputReal.onchange = change; - SystemTimer.add( SUPER_USER_KEY, updateWrapperPosition, 500 ); - }, - hide : function( data ){ - if( currentData !== data ) return; - // data.node.removeEventListener( 'change', change ); - evt.destroy(); - // MouseEvent.remove( currentUser, elmFileInput, 'mouseout', asyncMouseout ); - onClick(); - //currentData.elmFileInputReal.onchange = null; - elmWrap.style.display = 'none'; - currentData = elmFileInput = null; - SystemTimer.remove( SUPER_USER_KEY, updateWrapperPosition ); - }, - onWindowResize: function( _w, _h ){ - AsyncCall.add( currentUser, updateWrapperPosition ); - } - }; - })(); - - var FileInputClass = function( groupData, elmWrapper, onUpdate, validater, elmFileInputReal, elmValue ){ - var data = new UIItemPrivateData(); - data.init( groupData, this, elmWrapper, null, onUpdate, null, false, true, true ); - data.node = groupData.node.createNode( elmWrapper, false, true, 'ui-fileinput-hover', 'pointer' ); - data.elmValue = elmValue; - data.elmFileInputReal = elmFileInputReal; - data.node.addEventListener( 'mouseover', this.focus, this ); - }; - FileInputClass.prototype = { - value : function(){ - return data.value; - }, - focus : function(){ - var data = UIItemPrivateData.get( this ); - data.focus = true; - Util.addClass( data.elm, 'fileinput-has-focus' ); - start( data ); - FileInputManager.show( data ); - }, - blur : function( keyCode ){ - var data = UIItemPrivateData.get( this ); - Util.removeClass( data.elm, 'fileinput-has-focus' ); - data.focus = false; - FileInputManager.hide( data ); - finish( data ); - }, - enabled : function( v ){ - var data = UIItemPrivateData.get( this ); - if( Type.isBoolean( v ) === true && data.enabled !== v ){ - if( data.focus === true && v === false ) this.blur(); - Util.toggleClass( data.elm, 'fileinput-disabled', !v ); - data.enabled = v; - data.node.disabled( !( data.visible && v ) ); - }; - return data.enabled; - }, - visible : function( v ){ - var data = UIItemPrivateData.get( this ); - if( Type.isBoolean( v ) === true && data.visible !== v ){ - if( data.focus === true && v === false ) this.blur(); - data.elm.style.display = v ? '' : 'none'; - data.visible = v; - data.node.disabled( !( data.enabled && v ) ); - }; - return data.visible; - }, - destroy : function(){ - var data = UIItemPrivateData.get( this ); - data.focus === true && FileInputManager.hide( data ); - data.destroy(); - } - }; - - var ButtonClass = function( groupData, elmWrapper, onUpdate ){ - var data = new UIItemPrivateData(); - data.init( groupData, this, elmWrapper, null, onUpdate, null, false, true, true ); - data.node = groupData.node.createNode( elmWrapper, false, true, 'ui-button-hover', 'pointer' ); - data.node.addEventListener( 'click', onUpdate ); - //MouseEvent.add( groupData.apiuser, elmWrapper, 'click', onUpdate ); - }; - ButtonClass.prototype = { - focus : function(){ - var data = UIItemPrivateData.get( this ); - data.focus = true; - Util.addClass( data.elm, 'button-has-focus' ); - start( data ); - }, - blur : function( keyCode ){ - var data = UIItemPrivateData.get( this ); - keyCode === 13 && data.onUpdate && data.onUpdate(); - Util.removeClass( data.elm, 'button-has-focus' ); - data.focus = false; - finish( data ); - }, - enabled : function( v ){ - var data = UIItemPrivateData.get( this ); - if( Type.isBoolean( v ) === true && data.enabled !== v ){ - Util.toggleClass( data.elm, 'button-disabled', !v ); - data.enabled = v; - data.node.disabled( !( data.visible && v ) ); - }; - return data.enabled; - }, - visible : function( v ){ - var data = UIItemPrivateData.get( this ); - if( Type.isBoolean( v ) === true && data.visible !== v ){ - data.elm.style.display = v ? '' : 'none'; - data.visible = v; - data.node.disabled( !( data.enabled && v ) ); - }; - return data.visible; - }, - destroy : function(){ - var data = UIItemPrivateData.get( this ); - // MouseEvent.remove( data.groupData.apiuser, data.elm ); - data.destroy(); - } - }; - - var ComboBoxClass = function( groupData, elmWrapper, onUpdate ){ - var elmA = ELM_COMBOBOX.cloneNode( true ), - data = new UIItemPrivateData(); - data.init( groupData, this, elmWrapper, null, onUpdate, null, false, true, true ); - - data.elmBox = Util.getElementsByClassName( elmWrapper, 'combobox' )[ 0 ]; - data.elmBox.appendChild( elmA ); - data.elmA = elmA; - data.elmToggle = Util.getElementsByClassName( elmA, 'combobox-toggle' )[ 0 ]; - data.elmValue = Util.getElementsByClassName( elmA, 'combobox-value' )[ 0 ].firstChild; - data.selectIndex = 0; - data.optionList = []; - - data.node = groupData.node.createNode( elmWrapper, false, true, 'ui-combobox-hover', 'pointer' ); - data.node.addEventListener( 'click', this.focus, this ); - }; - ComboBoxClass.prototype = { - focus : function( e ){ - var data = UIItemPrivateData.get( this ); - data.node.removeEventListener( 'click', this.focus ); - data.focus = true; - data.elmA.className = 'combobox-has-focus'; - start( data ); - OptionControl.show( data ); - return false; - }, - blur : function( keyCode ){ - var data = UIItemPrivateData.get( this ); - OptionControl.hide( this ); - data.focus = false; - data.elmA.className = ''; - finish( data ); - data.node.addEventListener( 'click', this.focus, this ); - }, - enabled : function( v ){ - var data = UIItemPrivateData.get( this ); - if( Type.isBoolean( v ) === true && data.enabled !== v ){ - Util.toggleClass( data.elm, 'ui-combobox-disabled', !v ); - if( data.focus === true && v === false ) this.blur(); - data.enabled = v; - data.node.disabled( !( data.visible && v ) ); - }; - return data.enabled; - }, - visible : function( v ){ - var data = UIItemPrivateData.get( this ); - if( Type.isBoolean( v ) === true && data.visible !== v ){ - data.elm.style.display = v ? '' : 'none'; - if( data.focus === true && v === false ) this.blur(); - data.visible = v; - data.node.disabled( !( data.enabled && v ) ); - }; - return data.visible; - }, - value : function( _value ){ - var data = UIItemPrivateData.get( this ), - i = 0, - list = data.optionList, - l = list.length, - _option; - if( Type.isString( _value ) === true && data.value !== _value ){ - for( ; i < l; ++i ){ - _option = list[ i ]; - if( _value === _option.value ){ - data.value = _value; - data.index = i; - data.elmValue.data = _option.displayValue; - if( data.focus === true ){ - OptionControl.update( this, _value ); - }; - data.onUpdate && AsyncCall.add( data.groupData.apiuser, data.onUpdate, _value, this ); - break; - }; - }; - }; - return data.value; - }, - selectIndex : function(){ - var data = UIItemPrivateData.get( this ); - return data.selectIndex; - }, - createOption : function( _displayValue, _value, _isSelected ){ - var data = UIItemPrivateData.get( this ), - option = null, - list = data.optionList, - i = list.length, - _option, i; - _value = _value || _displayValue; - _isSelected = !!_isSelected; - for( ; i; ){ - _option = list[ --i ]; - if( _value === _option.value ){ - option = _option; - break; - }; - }; - if( _isSelected === true ){ - data.selectIndex = list.length; - data.elmValue.data = _displayValue; - }; - option === null && list.push( new OptionDataClass( _displayValue, _value, _isSelected ) ); - }, - destroy : function(){ - var data = UIItemPrivateData.get( this ); - data.focus === true && OptionControl.hide( this ); - // this.blur(); - // MouseEvent.remove( data.groupData.apiuser, data.elm ); - data.optionList.length = 0; - data.destroy(); - } - }; - var OptionDataClass = function( displayValue, value, isCurrent ){ - this.displayValue = displayValue; - this.value = value || displayValue; - this.current = isCurrent; - displayValue = value = null; - }; - - var OptionControl = ( function(){ - var ELM_OPTION_WRAPPER = ( function(){ - var ret = document.createElement( 'div' ); - ret.className = 'option-container'; - return ret; - })(), - ELM_OPTION_ORIGIN = ( function(){ - var ret = document.createElement( 'a' ); - ret.appendChild( document.createTextNode( 'option' ) ); - ret.href = '#'; - return ret; - })(); - - var OptionClass = function( option ){ - this.elm = ELM_OPTION_ORIGIN.cloneNode( true ); - this.data = option; - this.init(); - }; - OptionClass.prototype = { - init: function(){ - ELM_OPTION_WRAPPER.appendChild( this.elm ); - this.elm.firstChild.data = this.data.displayValue; - this.current( this.data.current ); - MouseEvent.add( SUPER_USER_KEY, this.elm, 'mousedown', onOptionSelect );// onclick では 選択ボックス 隠すように body に設定した onmouseup が先に動いてしまう! - }, - current: function( _current ){ - this.elm.className = _current === true ? CLASSNAME_COMBOBOX_OPTION_CURRENT : CLASSNAME_COMBOBOX_OPTION; - this.data.current = _current; - currentOption = _current === true ? this : currentOption; - }, - destroy: function(){ - MouseEvent.remove( SUPER_USER_KEY, this.elm ); - Util.removeAllChildren( this.elm ); - ELM_OPTION_WRAPPER.removeChild( this.elm ); - delete this.elm; - delete this.data; - } - }; - - function onOptionSelect( e ){ - var i = 0, - l = OPTION_LIST.length, - _option; - for( ; i < l; ++i ){ - _option = OPTION_LIST[ i ]; - if( this === _option.elm ){ - updateCurrrentOption( _option.data.value, true ); - currentCombobox.blur(); - break; - }; - }; - return false; - }; - - var OPTION_LIST = [], - currentCombobox = null, - apiuser, - elm, - currentOption, - currentIndex; - - function updateCurrrentOption( _value, _updateCombobox ){ - var _option, - i = OPTION_LIST.length; - for( ; i; ){ - _option = OPTION_LIST[ --i ]; - if( _value === _option.data.value ){ - currentOption && currentOption.current( false ); - _option.current( true ); - currentOption = _option; - currentIndex = i; - _updateCombobox === true && currentCombobox.value( _value ); - break; - }; - }; - }; - function bodyMouseupHandler(){ - currentCombobox.blur(); - OptionControl.hide( currentCombobox ); - }; - function updateWrapperPosition(){ - var position = Util.getAbsolutePosition( elm ); - - ELM_OPTION_WRAPPER.style.cssText = [ - 'width:', elm.offsetWidth - 2, 'px;', - 'left:', position.x, 'px;', - 'top:', position.y + elm.offsetHeight, 'px;' - ].join( '' ); - }; - function change( e ){ - var l = OPTION_LIST.length, - i = currentIndex + ( e.keyCode === 40 ? -1 : 1 ); - if( currentCombobox === null || l < 2 ) return; - i = i < 0 ? - l - 1 : - i < l ? i : 0; - updateCurrrentOption( OPTION_LIST[ i ].data.value, true ); - return false; - }; - return { - show: function( data ){ - var combobox = data.item, - list = data.optionList, - i = 0, - l = list.length; - if( currentItem !== combobox || currentCombobox === combobox ) return; - currentCombobox && currentCombobox.blur(); - - apiuser = data.groupData.apiuser; - currentCombobox = combobox; - elm = data.elmBox; - - for( ; i < l; ++i ){ - OPTION_LIST.unshift( new OptionClass( list[ i ] ) ); - }; - MouseEvent.add( SUPER_USER_KEY, document, 'mouseup', bodyMouseupHandler ); - KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, change, 38 ); - KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, change, 40 ); - //KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onEnter, 13 ); - //KeyEvent.updateCurrentListener( SUPER_USER_KEY ); - - body.appendChild( ELM_OPTION_WRAPPER ); - - updateCurrrentOption( combobox.value(), false ); - updateWrapperPosition(); - - SystemTimer.add( SUPER_USER_KEY, updateWrapperPosition, 500 ); - }, - hide: function( _combobox ){ - if( currentCombobox !== _combobox || currentCombobox === null ) return; - - var _option; - while( _option = OPTION_LIST.shift() ){ - _option.destroy(); - }; - - body.removeChild( ELM_OPTION_WRAPPER ); - - MouseEvent.remove( SUPER_USER_KEY, document, 'mouseup', bodyMouseupHandler ); - KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, change ); - KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, change ); - //KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onEnter ); - //KeyEvent.updateCurrentListener( apiuser ); - - SystemTimer.remove( SUPER_USER_KEY, updateWrapperPosition, 500 ); - - apiuser = null; - currentCombobox = null; - currentOption = null; - currentIndex = 0; - }, - onEnter: function(){ - currentCombobox.value( currentOption.data.value ); - //currentCombobox.blur(); - //OptionControl.hide( currentCombobox ); - }, - update: function( data, _value ){ - if( currentCombobox !== data.item || currentItem !== data.item ) return; - if( currentOption.data.value === _value ) return; - updateCurrrentOption( _value, true ); - }, - onWindowResize: function( _w, _h ){ - currentCombobox && AsyncCall.add( apiuser, updateWrapperPosition ); - } - }; - })(); - - var UIGroupPrivateData = function(){}; - UIGroupPrivateData.prototype = { - apiuser : null, - node : null, - uigroup : null, - itemList : null, - visible : true, - enabled : true, - init : function( apiuser, node, uigroup ){ - this.apiuser = apiuser; - this.node = node; - this.uigroup = uigroup; - this.itemList = []; - UIGroupPrivateData.list.push( this ); - }, - destroy : function(){ - - } - }; - UIGroupPrivateData.list = []; - UIGroupPrivateData.get = function( uigroup ){ - var list = UIGroupPrivateData.list, - i = list.length; - for( ; i; ){ - if( list[ --i ].uigroup === uigroup ) return list[ i ]; - }; - return null; - }; - - var UIGroupClass = function( apiuser, node ){ - ( new UIGroupPrivateData() ).init( apiuser, node, this ); - }; - UIGroupClass.prototype = { - focus : function( _value ){ - var data = UIGroupPrivateData.get( this ); - /* - if( _value === true ){ - if( currentItem ){ - start( apiuser, self, currentItem ); - } else - if( itemList.length > 0 ){ - start( apiuser, self, itemList[ 0 ] ); - }; - } else - if( _value === false ){ - finish( apiuser, self, currentItem ); - } else - */ - if( _value && Util.getIndex( data.itemList, _value ) !== -1 ){ - // currentItem = _value; - currentList = data.itemList; - }; - return currentUi === this; - }, - blur : function(){ - var data = UIGroupPrivateData.get( this ); - if( currentList === data.itemList ){ - currentList = null; - }; - }, - createInputText : function( elmWrapper, onUpdate, validater ){ - var data = UIGroupPrivateData.get( this ), - elmValue = Util.getElementsByClassName( elmWrapper, 'editable-value' )[ 0 ], - ret; - if( elmValue ){ - ret = new TextInputClass( data, elmWrapper, elmValue, onUpdate, validater ); - data.itemList.push( ret ); - return ret; - }; - alert( 'error createInputText' ); - }, - createButton : function( elm, onClick ){ - var data = UIGroupPrivateData.get( this ), - ret = new ButtonClass( data, elm, onClick ); - data.itemList.push( ret ); - return ret; - }, - createFileInput : function( elm, onUpdate, validater, elmFileInputReal ){ - var data = UIGroupPrivateData.get( this ), - elmValue = Util.getElementsByClassName( elm, 'fileinput-value' )[ 0 ], - ret; - if( elmValue ){ - ret = new FileInputClass( data, elm, onUpdate, validater, elmFileInputReal, elmValue ); - data.itemList.push( ret ); - return ret; - }; - return ret; - }, - createCombobox : function( elm, onUpdate, optionList ){ - var data = UIGroupPrivateData.get( this ), - ret = new ComboBoxClass( data, elm, onUpdate, optionList ); - data.itemList.push( ret ); - return ret; - }, - createCheckBox : function(){ - - }, - createRadio : function(){ - - }, - createSlider : function(){ - - }, - visible : function( v ){ - var data = UIGroupPrivateData.get( this ); - if( Type.isBoolean( v ) === true && data.visible !== v ){ - for( var i = data.itemList.length; i; ){ - data.itemList[ --i ].visible( v ); - }; - data.visible = v; - data.node.disabled( !( data.enabled && v ) ); - }; - return data.visible; - }, - enabled : function( v ){ - var data = UIGroupPrivateData.get( this ); - if( Type.isBoolean( v ) === true && data.enabled !== v ){ - for( var i = data.itemList.length; i; ){ - data.itemList[ --i ].enabled( v ); - }; - data.enabled = v; - data.node.disabled( !( data.visible && v ) ); - }; - return data.enabled; - }, - destroy : function(){ - var data = UIGroupPrivateData.get( this ), - _item; - if( currentUi === this ){ - currentItem.blur(); - // finish( UIItemPrivateData.get( currentItem ) ); - }; - while( _item = data.itemList.shift() ){ - _item.destroy(); - }; - data.destroy(); - } - }; - - function start( data ){ - if( currentItem !== data.item ){ - currentUi !== data.groupData.uigroup && currentUi && currentUi.blur(); - - currentItem !== null && currentItem.blur(); - - currentUser = data.groupData.apiuser; - currentUi = data.groupData.uigroup; - currentItem = data.item; - - currentUi.focus( currentItem ); - - // if( currentUser !== _apiuser ) { - KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 13 ); - KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 27 ); - KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 9 ); - KeyEvent.updateCurrentListener( SUPER_USER_KEY ); - // }; - }; - } - function finish( data ){ - if( currentItem === data.item ){ - currentUi.blur(); - - currentUser = null; - currentUi = null; - currentItem = null; - currentList = null; - - KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 13 ); - KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 27 ); - KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 9 ); - KeyEvent.updateCurrentListener( data.groupData.apiuser ); - }; - }; - - function onKeyDown( e ){ - if( currentItem === null ) return true; - var keyCode = e.keyCode, - index = Util.getIndex( currentList, currentItem ); - if( keyCode === 13 || keyCode === 27 || keyCode === 9 || keyCode === 18 || e.altKey === true ){ // 13.return 27.esc 9.tab 18.alt - keyCode === 9 && tabShift( index, e.shiftKey === true ? -1 : 1 ); - keyCode === 13 && currentItem instanceof ComboBoxClass && OptionControl.onEnter(); - keyCode === 13 && tabShift( index, 1 ); - currentItem && currentItem.blur( keyCode ); - return false; - }; - }; - - function tabShift( index, way ){ - var l = currentList.length, - i = index + way, - item; - if( l < 2 ) return; - while( i !== index ){ - i = i < 0 ? - l - 1 : - i < l ? i : 0; // 0 < i < l - item = currentList[ i ]; - if( item.enabled() === true && item.visible() === true ){ - AsyncCall.add( currentUser, item.focus, null, item ); - return; - }; - i += way; - }; - }; - - return { - createUIGroup: function( apiuser, node ){ - var uid = apiuser.getUID(), - list = UI_LIST[ uid ], - ui = new UIGroupClass( apiuser, node ); - if( Type.isArray( list ) === false ){ - list = UI_LIST[ uid ] = []; - }; - list.push( ui ); - return ui; - }, - onWindowResize: function( w, h ){ - windowW = w; - windowH = h; - currentItem instanceof ComboBoxClass && OptionControl.onWindowResize( w, h ); - currentItem instanceof TextInputClass && TextInputManager.onWindowResize( w, h ); - currentItem instanceof FileInputClass && FileInputManager.onWindowResize( w, h ); - }, - onCurrentApplicationChange: function( _apiuser ){ - currentList = UI_LIST[ _apiuser.getUID() ]; - }, - onApplicationShutdown: function( _apiuser ){ - KeyEvent.remove( _apiuser ); - }, - onSystemShutdown: function(){ - - } - }; -})(); - -var UIForm = ( function(){ - var FORM_LIST = []; - var CLASSNAME_FORM = 'uiform-invisible'; - var CLASSNAME_FILE_WRAP = 'ui-fileinput-wrapper'; - var FormItemData = function(){}; - var windowW, windowH; - FormItemData.prototype = { - formData : null, - uiItem : null, - init : function( formData, uiItem ){ - this.formData = formData; - this.uiItem = uiItem; - }, - onUpdate : function( v ){ - // var index = Util.getIndex( this.formData.itemList, this ); - } - }; - - var FormPrivateData = function(){}; - FormPrivateData.prototype = { - apiuser : null, - node : null, - form : null, - elmForm : null, - itemList : null, - visible : true, - enabled : true, - init : function( apiuser, from, node, elm, elmForm ){ - this.apiuser = apiuser; - this.form = form; - this.ui = apiuser.createUIGroup( node ); - this.node = node; - this.elm = elm; - this.elmForm = elmForm; - this.itemList = []; - elmForm.className = CLASSNAME_FORM; - FormPrivateData.list.push( this ); - - var forms = Util.copyArray( elmForm.getElementsByTagName( '*' ) ), - l = forms.length, - i = 0, - items = 'input,select,textarea,button', - form, data, el, wrap; - for( ; i
' ); - elm.appendChild( el ); - data = new FormItemData(); - wrap = document.createElement( 'div' ); - form.parentNode.insertBefore( wrap, form ); - wrap.className = CLASSNAME_FILE_WRAP; - wrap.appendChild( form ); - data.init( this, this.ui.createFileInput( el, data.onUpdate, null, form ) ); - this.itemList.push( data ); - break; - case 'button': - break; - default: - continue; - }; - break; - case 'select': - break; - case 'button': - break; - case 'textarea': - break; - default: - continue; - }; - }; - }, - destroy : function(){ - - } - }; - FormPrivateData.list = []; - FormPrivateData.get = function( from ){ - var list = FormPrivateData.list, - i = list.length; - for( ; i; ){ - if( list[ --i ].form === form ) return list[ i ]; - }; - return null; - }; - - var FormClass = function( apiuser, node, elm, elmForm ){ - ( new FormPrivateData() ).init( apiuser, this, node, elm, elmForm ); - }; - FormClass.prototype = { - createTextInput : function(){ - - }, - createMultiLineInput : function(){ - - }, - createFileInput : function(){ - - }, - createButton : function(){ - - }, - createComboBox : function(){ - - }, - submit : function(){ - - } - }; - - return { - createForm: function( apiuser, nodeOrElm, opt_elmForm ){ - var uid = apiuser.getUID(), - list = FORM_LIST[ uid ], - node, elm, form; - if( PointingDeviceEventTree.isNodeInstance( nodeOrElm ) === true ){ - node = nodeOrElm; - elm = PointingDeviceEventTree._getNodePrivateData( nodeOrElm ).elm; - } else { - // App が eventTree を持っている? - // App が eventTree を持っていない - elm = nodeOrElm; - }; - form = new FormClass( apiuser, node, elm, opt_elmForm ); - if( Type.isArray( list ) === false ){ - list = FORM_LIST[ uid ] = []; - }; - list.push( form ); - return form; - }, - onWindowResize: function( w, h ){ - windowW = w; - windowH = h; - currentItem instanceof ComboBoxClass && OptionControl.onWindowResize( w, h ); - currentItem instanceof TextInputClass && TextInputManager.onWindowResize( w, h ); - currentItem instanceof FileInputClass && FileInputManager.onWindowResize( w, h ); - }, - onCurrentApplicationChange: function( _apiuser ){ - }, - onApplicationShutdown: function( _apiuser ){ - }, - onSystemShutdown: function(){ - - } - }; -})(); - -var Finder = ( function(){ - var FINDER_LIST = [], - ELM_ORIGIN_LOCATION_ITEM = Util.pullHtmlAsTemplete( '
' ), - HTML_FINDER_ICON = ( function(){ - return ( UA.isIE === true && UA.ieVersion < 8 ? - [ - '
', - '
', - '
', - '', - '', - '', - 'file name', - '', - '', - '', - '', - '', - '', - 'file descriptiion', - '', - '', - '', - '
', - '
' - ] : - [ - '
', - '
', - '
', - '
file name
', - '
file descriptiion
', - '
>
', - '
' - ] ).join( '' ); - })(), - ELM_ORIGIN_FINDER_ICON = Util.pullHtmlAsTemplete( HTML_FINDER_ICON ), - ICON_HEIGHT = Util.getElementSize( ELM_ORIGIN_FINDER_ICON ).height; - - // t : 時間 - // b : 開始の値(開始時の座標やスケールなど) - // c : 開始と終了の値の差分 - // d : Tween(トゥイーン)の合計時間 - - function easeOutQuad( t, b, c, d ){ - t /= d; - return -c * t*( t-2 ) + b; - }; - -/** - * FinderIconClass - */ - var FinderIconClass = function(){}; - FinderIconClass.prototype = { - finderData : null, - file : null, - elm : null, - node : null, - _index : -1, - _style : -1, - init : function( page, file, w, index, style ){ - if( !this.elm ) this.elm = ELM_ORIGIN_FINDER_ICON.cloneNode( true ); - - if( this.page !== page ){ - this.page = page; - page.elm.appendChild( this.elm ); - this.node && this.node.remove(); - this.node = page.node.createNode( this.elm, false, true, 'finder-icon-hover', '' ); - }; - if( this.file !== file ){ - this.file && this.file.destroy(); - this.file = file; - this._index = index; - this.draw( w ); - return; - }; - if( this._index !== index ){ - this._index = index; - this.resize( w ); - }; - }, - index : function( _index ){ - return this._index; - }, - style : function( _style ){ - return this._style; - }, - draw : function( w ){ - var file = this.file, - elm = this.elm, - thumb = file.getThumbnail(), - elmThumb = Util.getElementsByClassName( elm, 'file-icon' )[ 0 ].firstChild, - elmName = Util.getElementsByClassName( elm, 'finder-icon-filename' )[ 0 ], - elmDesc = Util.getElementsByClassName( elm, 'finder-icon-summary' )[ 0 ]; - if( thumb.image ){ - elmThumb.className = 'has-thumbnail'; - elmThumb.style.backgroundImage = [ 'url(', thumb.image, ')' ].join( '' ); - } else { - elmThumb.className = thumb.className; - elmThumb.style.backgroundImage = ''; - }; - - elmName.firstChild.data = file.getName(); - elmDesc.firstChild.data = file.getSummary(); - - this.resize( w ); - }, - resize : function( w ){ - this.node.update( 0, this._index * ICON_HEIGHT, w ); - }, - onEditorClick : function( e ){ - this.onEditorCallback && this.onEditorCallback( this.file, this.file.editorApplicationList()[ 0 ] ); - return false; - }, - onViwerClick : function( e ){ - this.onViewerCallback && this.onViewerCallback( this.file, this.file.viewerApplicationList()[ 0 ] ); - return false; - }, - onActionClick : function( e ){ - this.onActionCallback && this.onActionCallback( this.file ); - return false; - }, - destroy : function(){ - this.elm && this.elm.parentNode.removeChild( this.elm ); - this.file && this.file.destroy(); - this.node && this.node.remove(); - delete this.page; - delete this.file; - delete this.node; - delete this._index; - delete this._style; - FinderIconClass.pool.push( this ); - } - }; - FinderIconClass.pool = []; - FinderIconClass.get = function( page, file, w, index, style ){ - var _icon = FinderIconClass.pool.length > 0 ? FinderIconClass.pool.shift() : new FinderIconClass(); - _icon.init( page, file, w, index, style ); - return _icon; - }; - -/** - * PathClass - */ - var PathClass = function(){}; - PathClass.prototype = { - finderData : null, - elm : null, - node : null, - file : null, - _index : null, - w : 0, - init : function( finderData, file, index ){ - if( !this.elm ) this.elm = ELM_ORIGIN_LOCATION_ITEM.cloneNode( true ); - - if( this.finderData !== finderData ){ - this.finderData = finderData; - finderData.elmPath.appendChild( this.elm ); - this.node && this.node.remove(); - delete this.node; - }; - if( this.file !== file ){ - this.file = file; - this.draw(); - }; - this._index = index; - if( !this.node ) this.node = finderData.nodePath.createNode( this.elm, false, true, 'finder-path-hover', 'pointer' ); - }, - draw : function(){ - this.elm.className = 'file-icon-' + this.file.getType(); - this.elm.innerHTML = this.file.getName(); - }, - textWidth : function(){ - this.elm.style.width = 'auto'; - var ret = this.elm.offsetWidth; - this.elm.style.width = ''; - return ret + 15; - }, - update : function( x, w ){ - this.node.update( x - 15, undefined, w ); - }, - index : function( _index ){ - return this._index; - }, - destroy : function(){ - this.finderData.elmPath.removeChild( this.elm ); - this.node && this.node.remove(); - - delete this.finderData; - delete this.elm; - delete this.node; - delete this.file; - delete this._index; - PathClass.pool.push( this ); - } - }; - PathClass.pool = []; - PathClass.get = function( finderData, file, index ){ - var _bread = PathClass.pool.length > 0 ? PathClass.pool.shift() : new PathClass(); - _bread.init( finderData, file, index ); - return _bread; - }; - - - /** - * Page - */ - var PageClass = function(){}; - PageClass.prototype = { - nodeRoot : null, - elmRoot : null, - elmScroll : null, - elm : null, - node : null, - folder : null, - iconList : null, - sliding : false, - currentX : 0, - panTime : 0, - startX : 0, - offsetX : 0, - panTotalTime : 0, - isPanOut : false, - init : function( nodeRoot, elmRoot, elmScroll ){ - this.nodeRoot = nodeRoot; - this.elmRoot = elmRoot; - this.elmScroll = elmScroll; - - if( this.elm === null ){ - this.elm = document.createElement( 'div' ); - }; - elmScroll.appendChild( this.elm ); - this.elm.style.cssText = 'position:absolute;top:0;'; - // this.elm.style.display = 'none'; - this.node = this.nodeRoot.createNode( this.elm, true, false ); - if( this.iconList === null ){ - this.iconList = []; - }; - }, - panInReady : function( way ){ - this.elm.style.display = ''; - var x = this.sliding === true ? this.currentX : way * this.nodeRoot.width(); - this.startX = this.currentX = x; - this.targetX = 0; - this.offsetX = -x; - this.panTime = 0; - this.panTotalTime = 20; - this.sliding = true; - this.isPanOut = false; - // this.elm.style.left = x + 'px'; - this.node.x( x ); - }, - panOutReady : function( way ){ - var x = -way * this.nodeRoot.width(); - this.startX = this.currentX || 0; - this.targetX = x; - this.offsetX = x - this.startX; - this.panTime = 0; - this.panTotalTime = 20; - this.sliding = true; - this.isPanOut = true; - }, - pan : function(){ - var page = this, - x = page.currentX = easeOutQuad( page.panTime, page.startX, page.offsetX, page.panTotalTime ); - // page.elm.style.left = x + 'px'; - this.node.x( x ); - if( page.panTotalTime < ++page.panTime ){ - delete page.panTime; - delete page.startX; - delete page.offsetX; - delete page.panTotalTime; - delete page.sliding; - if( this.isPanOut === true ) this.elm.style.display = 'none'; - }; - }, - draw : function( folder ){ - var _w = this.nodeRoot.width(); - this.folder = folder; - var data = this, - iconList = data.iconList, - i = 0, - j = 0, - l = folder.getChildFileLength(), - m = iconList.length, - scrollY = -this.nodeRoot.scrollY(), - rootH = scrollY + this.nodeRoot.height(), - icon; - - for( ; i < l; ++i ){ - if( ( i + 1 ) * ICON_HEIGHT < scrollY || rootH < i * ICON_HEIGHT ) continue; - if( j < m ){ - iconList[ j ].init( this, folder.getChildFileAt( i ), _w, i, data.style ); - } else { - iconList.push( FinderIconClass.get( this, folder.getChildFileAt( i ), _w, i, data.style ) ); - }; - j++; - }; - data.elmRoot.className = folder.getState() === Const.FILE.STATE.LOADING ? 'finder-body loading' : 'finder-body'; - // data.elmRoot.style.height = ( data.h - data.headH ) + 'px'; - - while( j < iconList.length ) iconList.pop().destroy(); - data.elmScroll.style.height = ( l * ICON_HEIGHT ) + 'px'; - }, - onScroll : function(){ - var _w = this.nodeRoot.width(); - - var data = this, - iconList = data.iconList, - folder = this.folder, - i = 0, - j = 0, - l = folder.getChildFileLength(), - scrollY = -this.nodeRoot.scrollY(), - rootH = scrollY + this.nodeRoot.height(), - startIndex = 0 < iconList.length ? iconList[ 0 ]._index : 0, - icon; - - // console.log( ' > ' + scrollY + ' , ' + rootH ) - for( ; i < l; ++i ){ - if( ( i + 1 ) * ICON_HEIGHT < scrollY || rootH < i * ICON_HEIGHT ){ - if( iconList.length <= j ) continue; - icon = iconList[ j ]; - if( icon._index !== i ) continue; - icon.destroy(); - iconList.splice( j, 1 ); - continue; - }; - if( iconList.length <= j || iconList[ j ]._index !== i ){ - if( i < startIndex ){ - iconList.splice( j, 0, FinderIconClass.get( this, folder.getChildFileAt( i ), _w, i, data.style ) ); - } else - if( startIndex + iconList.length <= i ){ - iconList.push( FinderIconClass.get( this, folder.getChildFileAt( i ), _w, i, data.style ) ); - }; - }; - ++j; - }; - - //while( j < iconList.length ) iconList.pop().destroy(); - }, - resize : function( w ){ - var list = this.iconList, - i = list.length; - for( ; i; ) list[ --i ].resize( w ); - }, - destroy : function(){ - var icon; - while( icon = this.iconList.shift() ) icon.destroy(); - - this.elm.parentNode.removeChild( this.elm ); - } - }; - - var ApplicationButton = function(){}; - ApplicationButton.prototype = { - elm : null, - button : null, - app : null, - file : null, - fileUID : -1, - init : function( ui, elmParent, app, file ){ - if( this.elm === null ){ - this.elm = document.createElement( 'div' ); - }; - elmParent.appendChild( this.elm ); - this.elm.className = 'button'; - this.elm.innerHTML = app.getDisplayName(); - - var that = this; - this.button = ui.createButton( this.elm, function(){ - that.onClick(); - // that = null; - } ); - - this.app = app; - this.file = file; - this.fileUID = file.getUID(); - }, - onClick : function(){ - this.app.boot( this.file ); - return false; - }, - destroy : function(){ - var elm = this.elm; - elm.parentNode.removeChild( elm ); - - this.button.destroy(); - //this.kill() - //this.elm = elm; - } - }; - - var DetailPageClass = function(){}; - DetailPageClass.prototype = Util.extend( new PageClass(), { - appButtons : null, - init : function( finderData ){ - this.finderData = finderData; - this.apiuser = finderData.apiuser; - this.nodeRoot = finderData.nodeRoot; - this.elmRoot = finderData.elmRoot; - this.elmScroll = finderData.elmScroll; - - if( this.elm === null ){ - this.elm = Util.pullHtmlAsTemplete( [ - '
', - '
', - '
file name
', - '
file descriptiion
', - '
View this file
', - '
', - '
Edit this file
', - '
', - '
' - ].join( '' ) ); - }; - this.elm.style.display = 'none'; - this.elmScroll.appendChild( this.elm ); - this.node = this.nodeRoot.createNode( this.elm, true, false ); - - this.ui = this.apiuser.createUIGroup( this.node ); - this.appButtons = []; - }, - draw : function( file ){ - var elm = this.elm, - thumb = file.getThumbnail(), - elmThumb = Util.getElementsByClassName( elm, 'file-icon' )[ 0 ].firstChild, - elmName = Util.getElementsByClassName( elm, 'finder-detail-filename' )[ 0 ], - elmDesc = Util.getElementsByClassName( elm, 'finder-detail-summary' )[ 0 ], - tmpButtons = Util.copyArray( this.appButtons ), - apps, app, elmContainer, button; - if( thumb.image ){ - elmThumb.className = 'has-thumbnail'; - elmThumb.style.backgroundImage = [ 'url(', thumb.image, ')' ].join( '' ); - } else { - elmThumb.className = thumb.className; - elmThumb.style.backgroundImage = ''; - }; - - elmName.firstChild.data = file.getName(); - elmDesc.firstChild.data = file.getSummary(); - this.node.width( this.nodeRoot.width() ); - this.node.height( this.nodeRoot.height() ); - - this.appButtons.length = 0; - - apps = file.viewerApplicationList(); - elmContainer = Util.getElementsByClassName( elm, 'viewer-apps' )[ 0 ]; - for( i = 0; i < apps.length; ++i ){ - button = 0 < tmpButtons.length ? tmpButtons.shift() : new ApplicationButton(); - button.init( this.ui, elmContainer, apps[ i ], file ); - this.appButtons.push( button ); - }; - apps = file.editorApplicationList(); - elmContainer = Util.getElementsByClassName( elm, 'editor-apps' )[ 0 ]; - for( i = 0; i < apps.length; ++i ){ - button = 0 < tmpButtons.length ? tmpButtons.shift() : new ApplicationButton(); - button.init( this.ui, elmContainer, apps[ i ], file ); - this.appButtons.push( button ); - }; - - while( button = tmpButtons.shift() ) button.destroy(); - - this.resize(); - }, - pan : function(){ - var page = this, - x = page.currentX = easeOutQuad( page.panTime, page.startX, page.offsetX, page.panTotalTime ); - // page.elm.style.left = x + 'px'; - this.node.x( x ); - if( page.panTotalTime < ++page.panTime ){ - delete page.panTime; - delete page.startX; - delete page.offsetX; - delete page.panTotalTime; - delete page.sliding; - if( this.isPanOut === true ) this.elm.style.display = 'none'; - }; - }, - onScroll : function(){ - - }, - resize : function(){ - this.elmScroll.style.height = this.nodeRoot.height() + 'px'; - }, - destroy : function(){ - var button; - while( button = this.appButtons.shift() ) button.destroy(); - this.ui.destroy(); - this.node.remove(); - } - }); - -/** - * FinderPrivateData - */ - var FinderPrivateData = Class.create( - Class.PRIVATE_DATA, { - finder : null, - apiuser : null, - elmRoot : null, - nodeRoot : null, - elmScroll : null, - elmPath : null, - nodePath : null, - tree : null, - onSelect : null, - viewerOption : null, - editorOption : null, - pathList : null, - headH : 0, - iconW : 0, - iconH : 0, - style : 0, - pageIcons1 : null, - pageIcons2 : null, - panInPage : null, - panOutPage : null, - pageDetail : null, - currentFile : null, - Constructor : function( finder, apiuser, elm, tree, onSelect, viewerOption, editorOption ){ - this.finder = finder; - this.apiuser = apiuser; - if( PointingDeviceEventTree.isNodeInstance( elm ) === true ){ - this.nodeRoot = elm; - this.elmRoot = PointingDeviceEventTree._getNodePrivateData( elm ).elm; - } else { - // App が eventTree を持っている? - // App が eventTree を持っていない - this.elmRoot = elm; - }; - this.nodeRoot.addEventListener( 'click', this.onIconClick, this ); - this.nodeRoot.addEventListener( 'scroll', this.onScroll, this ); - - this.elmScroll = document.createElement( 'div' ); - this.elmRoot.appendChild( this.elmScroll ); - this.elmScroll.className = 'finder-elm-scroll'; - this.elmScroll.style.cssText = 'width:100%;overflow:hidden;'; - - this.tree = tree; - this.onSelect = onSelect; - this.viewerOption = viewerOption; - this.editorOption = editorOption; - - var size = Util.getElementSize( ELM_ORIGIN_FINDER_ICON ); - this.iconW = size.width; - this.iconH = size.height; - - tree.addTreeEventListener( Const.TREE.EVENT.UPDATE, this.draw, this ); - Util.addClass( this.elmRoot, 'finder-body' ); - - if( this.panInPage === null ){ - this.pageIcons1 = new PageClass(); - this.pageIcons2 = new PageClass(); - this.pageDetail = new DetailPageClass(); - }; - this.pageIcons1.init( this.nodeRoot, this.elmRoot, this.elmScroll ); - this.pageIcons2.init( this.nodeRoot, this.elmRoot, this.elmScroll ); - this.pageDetail.init( this ); - }, - onIconClick : function( e ){ - if( this.panInPage === this.pageDetail ) return; - - var target = e.target, - list = this.panInPage.iconList, - i, icon, - file; - if( target === this.nodeRoot ) return; - for( i = list.length; i; ){ - icon = list[ --i ]; - if( icon.node === target ){ - i = icon._index; - file = this.currentFile.getChildFileAt( i ); - if( target.width() - 30 < e.layerX ){ - this.tree.down( i ); - this.draw( this.w, this.h, 1, true ); - } else - if( file.getChildFileLength() !== -1 || file.getType() === Const.FILE.TYPE.FOLDER ){ - this.tree.down( i ); - this.draw( this.w, this.h, 1 ); - } else - if( Type.isFunction( this.onSelect ) === true ){ /* && this.onSelect( file ) === true */ - this.onSelect( file ); - } else { - this.tree.down( i ); - this.draw( this.w, this.h, 1 ); - }; - file.destroy(); - break; - }; - }; - }, - onScroll : function( e ){ - this.panInPage.onScroll( e ); - }, - onPathClick : function( e ){ - var target = e.target, - i = target.nodeIndex(); - if( target === this.nodePath || this.nodePath.numNode() - 1 === i ) return; - this.tree.up( i ); - this.draw( this.w, this.h, -1 ); - }, - draw : function( w, h, way, showDetail ){ - var data = this, page; - data.w = w = Type.isFinite( w ) === true ? w : data.w; - data.h = h = Type.isFinite( h ) === true ? h : data.h; - - var file = this.currentFile = this.tree.getCurrentFile(), - isFolder = showDetail !== true && ( file.getChildFileLength() !== -1 || file.getType() === Const.FILE.TYPE.FOLDER ); - - data.elmPath && data.drawPath( w ); - page = this.panInPage; - if( Type.isNumber( way ) === true ){ - if( page.sliding === false ){ - if( isFolder === true ){ - this.panInPage = page === this.pageIcons1 ? this.pageIcons2 : ( page === this.pageIcons2 ? this.pageIcons1 : this.panOutPage ); - } else { - this.panInPage = this.pageDetail; - }; - this.panOutPage = page; - }; - this.panInPage.panInReady( way ); - //this.panInPage.elm.className = 'panIN'; - this.panOutPage.panOutReady( way ); - //this.panOutPage.elm.className = 'panOut'; - this.nodeRoot.disabled( true ); - SystemTimer.add( this.apiuser, this.tick, 16, false, this ); - } else { - if( isFolder === true ){ - this.panInPage = page === null ? this.pageIcons1 : page; - } else { - this.panInPage = this.pageDetail; - }; - }; - this.panInPage.draw( file ); - - data.nodeRoot.invalidateScrollbar(); - }, - tick : function(){ - if( this.panInPage.sliding === false && this.panOutPage.sliding === false ){ - SystemTimer.remove( this.apiuser, this.tick ); - this.nodeRoot.disabled( false ); - this.nodeRoot.invalidateScrollbar(); - return; - }; - this.panInPage.sliding === true && this.panInPage.pan(); - this.panOutPage.sliding === true && this.panOutPage.pan(); - }, - drawPath : function( w ){ - if( !this.elmPath.parentNode ) return; - w = this.nodePath.width(); - var data = this, - tree = data.tree, - pathList = data.pathList, - i = 0, - l = tree.hierarchy() + 1, - m = pathList.length, - wList = [], - totalW = 0, - minW = FinderPrivateData.MIN_PATH_WIDTH, - file, path, pathW, offset, remove, pathX = 0, fit = false; - - for( ; i < l; ++i ){ - file = i !== l - 1 ? tree.getParentFileAt( i ) : this.currentFile; - if( i < m ){ - pathList[ i ].init( this, file, i ); - } else { - pathList.push( PathClass.get( this, file, i ) ); - }; - }; - while( l < pathList.length ) pathList.pop().destroy(); - - for( i = l; i; ){ - pathW = pathList[ --i ].textWidth(); - wList.push( pathW ); - totalW += pathW; - }; - - //if( minW * ( l + 1 ) * 1.2 < w ){ - console.log( totalW + ' , ' + w ) - while( true ){ - if( fit === true ) break; - for( i = 0; i < l; ++i ){ - offset = totalW - w; - if( offset <= 0 ){ - fit = true; - break; - }; - remove = l - i; - remove = offset < remove ? offset : remove; - pathW = wList[ i ]; - if( pathW - remove < minW ){ - totalW -= ( pathW - minW ); - wList[ i ] = minW; - } else { - wList[ i ] = pathW - remove; - totalW -= remove; - }; - }; - }; - for( i = 0; i < l; ++i ){ - path = pathList[ i ]; - pathW = wList[ i ]; - path.update( pathX, pathW ); - pathX += pathW; - }; - //} else { - - //}; - }, - createPath : function( node ){ - if( this.elmPath ) return; - - if( PointingDeviceEventTree.isNodeInstance( node ) === true ){ - this.nodePath = node; - this.elmPath = PointingDeviceEventTree._getNodePrivateData( node ).elm; - - node.addEventListener( 'click', this.onPathClick, this ); - Util.addClass( this.elmPath, 'finder-path' ); - // this.elmPath = document.createElement( 'div' ); - // this.elmPath.className = ; - this.pathList = []; - // this.headH = 0; - AsyncCall.add( this.apiuser, this.draw, null, this ); - }; - }, - onKill : function(){ - this.tree.removeTreeEventListener( Const.TREE.EVENT.UPDATE, this.draw ); - - if( this.pathList ){ - while( this.pathList.length > 0 ) this.pathList.shift().destroy(); - }; - - this.pageIcons1.destroy(); - this.pageIcons2.destroy(); - this.pageDetail.destroy(); - this.nodeRoot.remove(); - - FINDER_LIST.splice( Util.getIndex( FINDER_LIST, this.finder ), 1 ); - var data = ApplicationPrivateData.get( this.apiuser ), - list = data.finderList, - i = Util.getIndex( list, this.finder ); - i !== -1 && list.splice( i, 1 ); - } - }); - FinderPrivateData.MIN_PATH_WIDTH = 25; - -/** - * FinderClass - */ - var Finder = Class.create( - FinderPrivateData, { - Constructor : function( application, elmRoot, tree, onSelect, viewerOption, editorOption ){ - Finder.newPrivateData( this, this, application, elmRoot, tree, onSelect, viewerOption, editorOption ); - }, - MIN_WIDTH : 200, - MIN_HEIGHT : 200, - resize : function( w, h ){ - var data = Finder.getPrivateData( this ); - data.panInPage && data.panInPage.resize( w ); - }, - createPath : function( node ){ - return Finder.getPrivateData( this ).createPath( node ); - }, - destroy : function(){ - this.kill(); - } - }); - - return { - init: function(){ - - }, - create: function( application, elmTarget, tree, onSelect, viewerOption, editorOption ){ - //if( Application.isApplicationInstance( _application ) === false ) return; - - var finder = new Finder( application, elmTarget, tree, onSelect, viewerOption, editorOption ); - FINDER_LIST.push( finder ); - return finder; - }, - registerFinderHead: function(){ - - }, - registerFinderPane: function( _finderPane ){ - - }, - isFinderInstance: function( _finder ){ - return _finder instanceof Finder; - }, - isFinderPaneInstance: function(){ - - }, - isFinderHeadInstance: function(){ - } - }; -})(); - - -/* - * -- len, % - * marginBottom, marginLeft, marginRight, marginTop, margin - * padding, paddingBottom, paddingLeft, paddingRight, paddingTop - * fontSize, textIndent - * height, width - * bottom, left, right, top (len, %) - * - * -- len - * borderBottomWidth, borderLeftWidth, borderRightWidth, borderTopWidth, borderWidth, - * letterSpacing - * - * -- color - * backgroundColor - * borderBottomColor, borderLeftColor, borderRightColor, borderTopColor, borderColor - * color - * - * -- special - * clip rect(0px, 40px, 40px, 0px); - * backgroundPosition (len, %) - * opacity - * lineHeight (len, %, num) - * zIndex ( order ) - */ - -var DHTML = ( function(){ - - var TICKET_ARRAY = [], - fpms = 50, - round = Math.round, - cround = function( v ){ return round( v * 100 ) / 100 }; - - function startAnimation( _elm, _cssObject, _onComplete, _onEnterFrame, _numFrames ){ - var _ticket, i = TICKET_ARRAY.length; - for( ; i; ){ - _ticket = TICKET_ARRAY[ --i ]; - if( _ticket.elm === _elm ){ - return; - }; - }; - - var _currentValues = [], - _offsetValues = [], - _endValues = [], - _targetProperties = [], - _units = []; - var target, current, - inlineStyle = CSS.getInlineStyle( _elm ), - currentStyle = CSS.getWrappedStyle( _elm ), - targetStyle = CSS.getWrappedStyle( _elm, _cssObject ); - targetStyle.pxPerEm = currentStyle.get( 'fontSize' )._toPx(); - for( var p in _cssObject ){ - p = Util.camelize( p ); - target = targetStyle.get( p ); - current = currentStyle.get( p ); - - if( target.isValid() === false || current.isValid() === false || current.equal( target ) !== false ){ - target.clear(); - current.clear(); - continue; - }; - - current.convert( target ); - // alert( current.getValue() + ' , ' + target.getValue() ) - _currentValues.push( current.getValue() ); - _offsetValues.push( current.getOffset( target ) ); - _endValues.push( target.getValue() ); - _targetProperties.push( p ); - _units.push( target.getUnit() ); - - // IE has trouble with opacity if it does not have layout - // Force it by setting the zoom level - if( p === 'opacity' && SPECIAL.hasLayout ){ - if( SPECIAL.hasLayout( _elm ) === false ) inlineStyle.zoom = 1; - inlineStyle.filter = current.getValueText(); - } else { - inlineStyle[ p ] = current.getValueText(); - }; - - target.clear(); - current.clear(); - }; - - var i, cssTexts = []; - for( i = 0; i < _numFrames; ++i ){ - if( i < _numFrames - 1 ){ - tickValue( _currentValues, _offsetValues, _numFrames ); - cssTexts.push( createCssText( _currentValues, _targetProperties, targetStyle, inlineStyle ) ); - } else { - cssTexts.push( createCssText( _endValues, _targetProperties, targetStyle, inlineStyle ) ); - }; - }; - - TICKET_ARRAY.push( new AnimationTaskClass( - _elm, cssTexts, - Type.isFunction( _onComplete ) === true ? _onComplete : null, - Type.isFunction( _onEnterFrame ) === true ? _onEnterFrame : null, - _numFrames - ) ); - - currentStyle.clear(); - targetStyle.clear(); - SystemTimer.add( SUPER_USER_KEY, onEnterFrame, 1000 / fpms ); - }; - - function tickValue( current, offset, numFrames ){ - if( Type.isArray( current ) === true ){ - var ret, i = current.length; - for( ; i; ){ - --i; - ret = tickValue( current[ i ], offset[ i ], numFrames ); - if( Type.isNumber( ret ) === true ) current[ i ] = ret; - }; - } else { - return current + offset / numFrames; - }; - }; - function createCssText( update, props, style, inline ){ - var prop; - for( var i = props.length; i; ){ - prop = style.get( props[ --i ] ); - prop.setValue( update[ i ] ); - inline[ Util.uncamelize( prop.name ) ] = prop.getValueText(); - //if( prop.name === 'backgroundColor' ) alert( prop.getValueText() + '|' + update[ i ].join( ',') ) - prop.clear(); - }; - return CSS.toCssText( inline ); - }; - - function onEnterFrame(){ - var _ticket, l, - i = 0; - while( i < TICKET_ARRAY.length ){ - _ticket = TICKET_ARRAY[ i ]; - l = _ticket.cssTexts.length; - _ticket.elm.style.cssText = _ticket.cssTexts.shift(); - if( l === 1 ){ - _ticket.onComplete && _ticket.onComplete(); - delete _ticket.elm; - delete _ticket.cssTexts; - delete _ticket.onComplete; - delete _ticket.onEnterFrame; - delete _ticket.numFrame; - TICKET_ARRAY.splice( i, 1 ); - } else { - _ticket.onEnterFrame && _ticket.onEnterFrame( l / _ticket.numFrame ); - ++i; - }; - }; - if( TICKET_ARRAY.length === 0 ){ - SystemTimer.remove( SUPER_USER_KEY, onEnterFrame ); - }; - }; - - var AnimationTaskClass = function( elm, cssTexts, onEnterFrame, onComplete, numFrame ){ - this.elm = elm; - this.cssTexts = cssTexts; - this.onEnterFrame = onEnterFrame; - this.onComplete = onComplete; - this.numFrame = numFrame; - }; - - var VisualEffectClass = function( elm ){ - this.elm = elm; - }; - VisualEffectClass.prototype = { - anime : function( _cssObject, _onComplete, _onEnterFrame, _time ){ - var _numFrames = Math.floor( _time / fpms ); - startAnimation( this.elm, _cssObject, _onComplete, _onEnterFrame, _numFrames ); - }, - fadeIn : function(){ - - }, - fadeOut : function(){ - - }, - update : function( x, y, w, h ){ - var _cssText = this.elm.style.cssText; - } - }; - - return { - create: function( application, _elm ){ - return new VisualEffectClass( _elm ); - }, - isInstanceOfVisualEffect: function( _instance){ - return _instance instanceof VisualEffectClass; - } - } -})(); - - -/* -------------------------------------------- - * - */ - - Application.onCurrentApplicationChange( SUPER_USER_KEY ); - - SERVICE_LIST.push( MouseEvent ); - - new EventTicketClass( window, 'unload', function(){ - var _service; - while( SERVICE_LIST.length > 0 ){ - _service = SERVICE_LIST.shift(); - Type.isFunction( _service.onSystemShutdown ) === true && _service.onSystemShutdown(); - } - }); - // beforeunload - - -/* --------------------------------------------- - * broadcast to global - */ - window.gOS = {}; - - gOS.registerApplication = Application.register; - gOS.registerDriver = File.registerDriver; - -var BoxModel - -var DOM = ( function( window, document ){ - var DIV_LIST = [], - SPAN_LIST = [], - TEXT_LIST = []; - - var elmTextSize; - - function correctNodes( node ){ - var child; - if( node && node.parentNode ){ - while( node.lastChild ) correctNodes( node.lastChild ); - node.parentNode.removeChild( node ); - if( node.nodeType === 1 ){ - switch( node.tagName ){ - case 'DIV': - DIV_LIST.push( node ); - break; - case 'SPAN': - SPAN_LIST.push( node ); - break; - - }; - node.removeAttribute( 'className' ); - node.removeAttribute( 'style' ); - node.removeAttribute( 'id' ); - } else - if( node.nodeType === 3 ){ - node.data = ''; - TEXT_LIST.push( node ); - }; - }; - }; - - return { - createDiv : function(){ - return 0 < DIV_LIST.length ? DIV_LIST.shift() : document.createElement( 'div' ); - }, - createSpan : function(){ - - }, - createText : function(){ - - }, - getTextSize : function( elm, content ){ - var span = DOM.createSpan(), - text = DOM.createText(), - w, h; - elm.appendChild( span ); - span.style.cssText = 'visibility:hidden;position:absolute;'; - span.appendChild( text ); - text.data = content; - w = span.offsetWidth; - h = span.offsetHeight; - DOM.correctNodes( span ); - return [ w, h ]; - }, - getTextHeight : function( elm, w, content ){ - var div = DOM.createSpan(), - text = DOM.createText(), - w, h; - elm.appendChild( div ); - div.style.cssText = 'visibility:hidden;position:absolute;width:' + w + 'px;'; - div.appendChild( text ); - text.data = content; - w = div.offsetWidth; - h = div.offsetHeight; - DOM.correctNodes( div ); - return h; - }, - correctNodes : function( node ){ - var child; - if( node && node.parentNode ){ - while( node.lastChild ) DOM.correctNodes( node.lastChild ); - node.parentNode.removeChild( node ); - if( node.nodeType === 1 ){ - switch( node.tagName ){ - case 'DIV': - DIV_LIST.push( node ); - break; - case 'SPAN': - SPAN_LIST.push( node ); - break; - - }; - node.removeAttribute( 'className' ); - node.removeAttribute( 'style' ); - node.removeAttribute( 'id' ); - } else - if( node.nodeType === 3 ){ - node.data = ''; - TEXT_LIST.push( node ); - }; - }; - } - } -})( window, document ); - -var XBrowserStyle = ( function(){ - var EMPTY = '', - CORON = ':', - SEMICORON = ';', - SPACE = ' ', - UNITS = 'px,cm,mm,in,pt,pc,em,%'.split( ',' ), - CLIP_SEPARATOR = UA.isIE === true && UA.ieVersion < 8 ? ' ' : ','; - - var SPECIAL = ( function(){ - var special = {}; - if( UA.isIE === true && UA.ieVersion < 9 ){ - if( UA.ACTIVEX === true ){ - // special.opacity = 'ActiveXOpacity'; - special.setFilters = function( style ){ - var filters = ( style.filter || '' ).split( ') ' ), - data = {}, - i = filters.length, - filter, names, props, prop, j, l, key, v; - for( ; i; ){ - filter = filters[ --i ].split( ' ' ).join( '' ).split( '(' ); - if( filter.length !== 2 ) continue; - names = filter[ 0 ].split( '.' ); // progid:DXImageTransform.Microsoft.Shadow(color=#666666,direction=120,strength=9) - props = filter[ 1 ].split( ',' ); // - filter = {}; - for( j = 0, l = props.length; j < l; ++j ){ - prop = props[ j ].split( '=' ); - key = prop[ 0 ].toLowerCase(); - v = prop[ 1 ]; - filter[ key ] = v; //v.charAt( 0 ) === '#' ? v : parseInt( v ); - }; - data[ names[ names.length - 1 ] ] = filter; - }; - - style.filter = data; - style.opacity = data.alpha && data.alpha.opacity ? data.alpha.opacity / 100 : 1; - }; - special.hasLayout = function( elm ){ - return elm.currentStyle.hasLayout; - }; - } else { - special.opacity = null; - }; - } else { - var style = document.documentElement.style; - special.opacity = style.opacity !== undefined ? 'opacity' : - style.MozOpacity !== undefined ? 'MozOpacity' : - style.KhtmlOpacity !== undefined ? 'KhtmlOpacity' : - style[ '-khtml-opacity' ] !== undefined ? 'KhtmlOpacity' : null; - - // if( style.backgroundPositionX === undefined ){ - special.setBackgroundPositionXY = function( style ){ - var bgp = ( style.backgroundPosition || '' ).split( ' ' ); - style.backgroundPositionX = bgp[ 0 ] || 0; - style.backgroundPositionY = bgp[ 1 ] || 0; - }; - // }; - if( style.clipTop === undefined && style[ 'clip-top' ] === undefined ){ - special.setClipTopRightBottomLeft = function( style ){ - var clip = style.clip; - if( !cliop || clip.indexOf( 'rect(' ) === -1 ){ - style.clipTop = 0; - style.clipRight = 0; - style.clipBottom = 0; - style.clipLeft = 0; - return; - }; - clip = clip.split( '(' )[ 1 ].split( ')' )[ 0 ].split( clip.indexOf( ',' ) !== -1 ? ',' : ' ' ); - ret.clipTop = clip[ 0 ]; - ret.clipRight = clip[ 1 ]; - ret.clipBottom = clip[ 2 ]; - ret.clipLeft = clip[ 3 ]; - }; - }; - }; - return special; - })(); - - function cssToObject( css ){ - var ret = {}, i, nv, n, v, - parse = Util.parse, - isNumber = Type.isNumber, - camelize = Util.camelize; - if( Type.isString( css ) === true ){ - css = css.split( SEMICORON ); - for( i = css.length; i; ){ - nv = css[ --i ].split( CORON ); // filter の場合, progid: がくる - n = nv.shift(); - if( isNumber( parse( n ) ) === true ) continue; - v = nv.join( EMPTY ); - while( v.charAt( 0 ) === ' ' ) v = v.substr( 1 ); - ret[ camelize( n ) ] = parse( v ); - }; - } else { - for( n in css ){ - if( Type.isNumber( parse( n ) ) === false ) ret[ n ] = parse( css[ n ] ); - }; - }; - - if( SPECIAL.setFilters ){ - SPECIAL.setFilters( ret ); - } else { - ret.opacity = SPECIAL.opacity !== null ? ret[ SPECIAL.opacity ] : 1; - }; - - SPECIAL.setBackgroundPositionXY && SPECIAL.setBackgroundPositionXY( ret ); - SPECIAL.setClipTopRightBottomLeft && SPECIAL.setClipTopRightBottomLeft( ret ); - - return ret; - }; - - var COLOR = ( function(){ - var ret = {}, v, name, - list = [ - '0', 'BLACK', - 'FF0000', 'RED', - '00FF00', 'LIME', - '0000FF', 'BLUE', - 'FFFF00', 'YELLOW', - '00FFFF', 'AQUA', - '00FFFF', 'CYAN', - 'FF00FF', 'MAGENTA', - 'FF00FF', 'FUCHSIA', - 'FFFFFF', 'WHITE', - '008000', 'GREEN', - '800080', 'PURPLE', - '800000', 'MAROON', - '000080', 'NAVY', - '808000', 'OLIVE', - '008080', 'TEAL', - '808080', 'GRAY', - 'C0C0C0', 'SILVER', - '696969', 'DIMGRAY', - '708090', 'SLATEGRAY', - 'A9A9A9', 'DARKGRAY', - 'DCDCDC', 'GAINSBORO', - '191970', 'MIDNIGHTBLUE', - '6A5ACD', 'SLATEBLUE', - '0000CD', 'MEDIUMBLUE', - '4169E1', 'ROYALBLUE', - '1E90FF', 'DODGERBLUE', - '87CEEB', 'SKYBLUE', - '4682B4', 'STEELBLUE', - 'ADD8E6', 'LIGHTBLUE', - 'AFEEEE', 'PALETURQUOISE', - '40E0D0', 'TURQUOISE', - 'E0FFFF', 'LIGHTCYAN', - '7FFFD4', 'AQUAMARINE', - '006400', 'DARKGREEN', - '2E8B57', 'SEAGREEN', - '90EE90', 'LIGHTGREEN', - '7FFF00', 'CHARTREUSE', - 'ADFF2F', 'GREENYELLOW', - '32CD32', 'LIMEGREEN', - '9ACD32', 'YELLOWGREEN', - '6B8E23', 'OLIVEDRAB', - 'BCB76B', 'DARKKHAKI', - 'EEE8AA', 'PALEGOLDENROD', - 'FFFFE0', 'LIGHTYELLOW', - 'FFD700', 'GOLD', - 'DAA520', 'GOLDENROD', - 'B8860B', 'DARKGOLDENROD', - 'BC8F8F', 'ROSYBROWN', - 'CD5C5C', 'INDIANRED', - '8B4513', 'SADDLEBROWN', - 'A0522D', 'SIENNA', - 'CD853F', 'PERU', - 'DEB887', 'BURLYWOOD', - 'F5F5DC', 'BEIGE', - 'F5DEB3', 'WHEAT', - 'F4A460', 'SANDYBROWN', - 'D2B48C', 'TAN', - 'D2691E', 'CHOCOLATE', - 'B22222', 'FIREBRICK', - 'A52A2A', 'BROWN', - 'FA8072', 'SALMON', - 'FFA500', 'ORANGE', - 'FF7F50', 'CORAL', - 'FF6347', 'TOMATO', - 'FF69B4', 'HOTPINK', - 'FFC0CB', 'PINK', - 'FF1493', 'DEEPPINK', - 'DB7093', 'PALEVIOLETRED', - 'EE82EE', 'VIOLET', - 'DDA0DD', 'PLUM', - 'DA70D6', 'ORCHILD', - '9400D3', 'DARKVIOLET', - '8A2BE2', 'BLUEVIOLET', - '9370DB', 'MEDIUMPURPLE', - 'D8BFD8', 'THISTLE', - 'E6E6FA', 'LAVENDER', - 'FFE4E1', 'MISTYROSE', - 'FFFFF0', 'IVORY', - 'FFFACD', 'LEMONCHIFFON' - ]; - for( i = list.length; i; ){ - v = list[ --i ]; - name = list[ --i ]; - ret[ name ] = parseInt( v, 16 ); - }; - return ret; - })(); - - var PARAMS = ( function(){ - var ret = {}; - register( ret.percent = {}, - 'marginBottom,marginLeft,marginRight,marginTop,paddingBottom,paddingLeft,paddingRight,paddingTop,fontSize,textIndent' - ); - register( ret.offset = {}, - 'height,width,bottom,left,right,top' - ); - register( ret.size = {}, - 'borderBottomWidth,borderLeftWidth,borderRightWidth,borderTopWidth,letterSpacing' - ); - register( ret.color = {}, - 'backgroundColor,borderBottomColor,borderLeftColor,borderRightColor,borderTopColor,color' - ); - register( ret.region = {}, - 'margin,padding,borderWidth,borderColor' - ); - register( ret.special = {}, - 'clip,backgroundPosition,opacity,lineHeight,zIndex' - ); - register( ret.unit = {}, 'px,cm,mm,in,pt,pc,em,%' ); - - register( ret.margin = {}, 'marginBottom,marginLeft,marginRight,marginTop,paddingBottom' ); - register( ret.padding = {}, 'paddingBottom,paddingLeft,paddingRight,paddingTop' ); - register( ret.borderWidth = {}, 'borderBottomWidth,borderLeftWidth,borderRightWidth,borderTopWidth' ); - register( ret.borderColor = {}, 'borderBottomColor,borderLeftColor,borderRightColor,borderTopColor' ); - - function register( obj, params ){ - params = params.split( ',' ); - for( var i=params.length; i; ) obj[ params[ --i ] ] = true; - }; - return ret; - })(); - - /* - * - */ - var Property = Class.create( - 'Property', - Class.POOL_OBJECT, - { - Constructor : function( name, value, unit, pxPerEm ){ - this.name = name; - this.value = value; - this.unit = unit; - this.pxPerEm = pxPerEm; // XXpx = 1em; - }, - name : '', - value : 0, - pxPerEm : 12, // 1em === ??px - unit : '', - equal : function( prop ){ - if( this.unit === prop.unit ){ - return this.value === prop.value; - }; - return Math.abs( this.toPx() - prop.toPx() ) < 1; - }, - convert: function( prop ){ - var u = prop.unit, v; - if( this.unit === u ) return; - this.value = v = this.toPx(); - this.unit = u; - if( u !== px ){ - this.value = u === 'em' ? v / this.pxPerEm : Util.pxTo( v, u ); - }; - }, - setValue: function( v ){ - this.value = v; - }, - getValue: function(){ - return this.value; - }, - getOffset: function( prop ){ - return prop.value - this.value; - }, - getUnit: function(){ - return this.unit; - }, - getValueText: function(){ - return this.value === 0 ? '0' : this.value + this.unit; - }, - toPx: function(){ - var v = this.value, u = this.unit; - if( u === px ) return v; - if( u === 'em' ) return v * this.pxPerEm; - if( u === '' && this.name === 'lineHeight' ) return v * this.pxPerEm; - return Util.toPx( v, u ); - }, - isValid: function( t ){ - t = t || this; - var n = t.name, - v = t.value, - u = t.unit, - z = u !== '' ? true : v === 0; - if( PARAMS.percent[ n ] === true ) return z; - if( PARAMS.offset[ n ] === true ) return z; - if( PARAMS.size[ n ] === true ) return z && u !== '%'; - if( PARAMS.special[ n ] === true ){ - if( n === 'lineHeight' ) return true; - if( n === 'opacity' ) return 0 <= v && v <= 1 && u === ''; - if( n === 'zIndex' ) return u === ''; - }; - return false; - } - } - ); - - /** - * backgroundPosition, clip - */ - var PropertyGroup = Class.create( - 'PropertyGroup', - Class.POOL_OBJECT, - { - Constructor : function( name ){ - this.name = name; - this.props = []; - for( var i = 1, l = arguments.length; i 1 ) return false; - }; - return true; - }, - convert : function( prop ){ - var u = prop.pct, x; - if( this.pct === u ) return; - x = u === true ? 100 / 255 : 2.55; - this.r *= x; - this.g *= x; - this.b *= x; - this.pct = u; - }, - setValue : function( rgb ){ - this.r = rgb[ 0 ]; - this.g = rgb[ 1 ]; - this.b = rgb[ 2 ]; - }, - getValue : function(){ - return [ this.r, this.g, this.b ]; - }, - getOffset : function( prop ){ - return [ prop.r - this.r, prop.g - this.g, prop.b - this.b ]; - }, - getUnit : function(){ - return this.pct === true ? '%' : ''; - }, - getValueText : function(){ - if( this.pct === true ){ - return [ 'rgb(', this.r, '%,', this.g, '%,', this.b, '%)' ].join( '' ); - }; - var round = Math.round; - //return [ 'rgb(', round( this.r ), ',', round( this.g ), ',', round( this.b ), ')' ].join( '' ); - - var rgb = '00000' + ( ( round( this.r ) << 16 ) + ( round( this.g ) << 8 ) + round( this.b ) ).toString( 16 ); - return '#' + rgb.substr( rgb.length - 6 ); - }, - _toPct : function(){ - if( this.pct === true ) return [ this.r, this.g, this.b ]; - return [ this.r / 2.55, this.g / 2.55, this.b / 2.55 ]; - }, - isValid : function( t ){ - var isFinite = window.isFinite; - if( !isFinite( this.r ) || !isFinite( this.g ) || !isFinite( this.b ) ) return false; - if( 0 > this.r || 0 > this.g || 0 > this.b ) return false; - if( this.pct === true ) return this.r <= 100 && this.g <= 100 && this.b <= 100; - return this.r <= 255 && this.g <= 255 && this.b <= 255; - } - } - ); - - var isString = Type.isString, - isNumber = Type.isNumber; - var REG_UINIT = /.*\d(\w{1,2})?/, - $1 = '$1', - px = 'px', - REG_XXXXXX = /^#[\da-fA-F]{6}?/, - REG_XXX = /^#[\da-fA-F]{3}?/; - - var WrappedStyle = Class.create( - 'WrappedStyle', - Class.POOL_OBJECT, - { - Constructor : function( style ){ - this.style = style; - var fontsize = this.get( 'fontSize' ); - this.pxPerEm = fontsize.toPx(); - fonstsize.kill(); - }, - get: function( p ){ - if( PARAMS.special[ p ] === true || PARAMS.region[ p ] === true ){ - if( p === 'clip' ) return this.getClip(); - if( p === 'margin' ) return this.getMarginPaddingBorder( p, '' ); - if( p === 'padding' ) return this.getMarginPaddingBorder( p, '' ); - if( p === 'borderWidth' ) return this.getMarginPaddingBorder( 'border', 'Width' ); - if( p === 'borderColor' ) return this.getBorderColor( 'borderColor' ); - if( p === 'backgroundPosition' ) return this.getBackgroundPosition( p ); - // opacity, zindex, lineHeight - return new Property( p, this.getValue( x ), this.getUnit( x ), this.pxPerEm ); - }; - var x = this.style[ p ], e, v, u; - if( PARAMS.offset[ p ] === true ){ - return new Property( p, this.getValue( x ), this.getUnit( x, p ), this.pxPerEm ); - /* - e = this.elm; - if( p === 'width' ) v = e.offsetWidth; - if( p === 'height' ) v = e.offsetHeight; - if( p === 'top' ) v = e.offsetTop; - if( p === 'bottom' ) v = e.offsetBottom; - if( p === 'left' ) v = e.offsetLeft; - if( p === 'right' ) v = e.offsetRight; - u = this.getUnit( x, p ); - // alert( p + this.pxTo( v, u ) + u ) - return new Property( p, this.pxTo( v, u ), u, this.pxPerEm ); */ - }; - if( p === 'fontSize' ){ // xx-small 等 - v = Util.absoluteFontSizeToPx( x ); - if( v !== 0 ){ - return new Property( p, v, px, this.pxPerEm ); - }; - }; - if( PARAMS.percent[ p ] === true ){ - // alert( p + ' , ' + x + ' , ' + this.getUnit( x, p ) ) - return new Property( p, this.getValue( x ), this.getUnit( x, p ), this.pxPerEm ); - }; - if( PARAMS.size[ p ] === true ){ - return new Property( p, this.getValue( x ), this.getUnit( x, p ), this.pxPerEm ); - }; - if( PARAMS.color[ p ] === true ){ - return this.getColor( x, p ); - }; - }, - pxTo: function( px, unit ){ - if( unit === 'em' ) return px / this.pxPerEm; - return Util.pxTo( px, unit ); - }, - getValue: function( x ){ - return isString( x ) === true ? parseInt( x ) : - isNumber( x ) === true ? x : 0; - }, - getUnit: function( x, p ){ - var u; - if( isString( x ) === true ){ - u = x.replace( REG_UINIT, $1 ); - if( p === 'lineHeight' ) return u; - if( PARAMS.unit[ u ] !== true ) return px; - return u; - }; - return px; - }, - getColor: function( x, p ){ - var rgb = COLOR[ x.toUpperCase() ], - pct = false, - r = 0, - g = 0, - b = 0; - if( isNumber( rgb ) === true ){ - r = ( rgb & 0xff0000 ) >> 16; - g = ( rgb & 0xff00 ) >> 8; - b = ( rgb & 0xff ); - } else - if( x.match( REG_XXXXXX ) ){ - r = parseInt( x.charAt( 1 ) + x.charAt( 2 ), 16 ); - g = parseInt( x.charAt( 3 ) + x.charAt( 4 ), 16 ); - b = parseInt( x.charAt( 5 ) + x.charAt( 6 ), 16 ); - //alert( x + ' g: ' + g ) - } else - if( x.match( REG_XXX ) ){ - r = parseInt( x.charAt( 1 ) + x.charAt( 1 ), 16 ); - g = parseInt( x.charAt( 2 ) + x.charAt( 2 ), 16 ); - b = parseInt( x.charAt( 3 ) + x.charAt( 3 ), 16 ); - } else - if( x.indexOf( 'rgb(' ) === 0 ){ - rgb = x.substr( 4 ).split( ',' ); - r = parseFloat( rgb[ 0 ] ); - g = parseFloat( rgb[ 1 ] ); - b = parseFloat( rgb[ 2 ] ); - if( x.indexOf( '%' ) !== -1 ) pct = true; - } else { - r = 255; - g = 255; - b = 255; - }; - return new ColorProperty( p, r, g, b, pct ); - }, - getClip: function( name ){ - // rect(...) クリップします。, は上端からの、 , は左端からのオフセットで指定します。Internet Explorer 4~7 では、カンマの代わりにスペースで区切る必要があります。 - // position:absolute または position:fixed を適用した要素に対してのみ有効です。 - var top = this.get( name + 'Top' ), - right = this.get( name + 'Right' ), - bottom = this.get( name + 'Bottom' ), - left = this.get( name + 'Left' ), - ret = new PropertyGroup( name, top, right, bottom, left), - all; - if( ret.isValid() === true ) return ret; - ret.kill(); - all = this.style[ name ].split( '(' )[ 1 ].split( ')' )[ 0 ].split( CLIP_SEPARATOR ); - return new PropertyGroup( name, - new Property( name + 'Top', all[ 0 ], px, this.pxPerEm ), - new Property( name + 'Right', all[ 1 ], px, this.pxPerEm ), - new Property( name + 'Bottom', all[ 2 ], px, this.pxPerEm ), - new Property( name + 'Left', all[ 3 ], px, this.pxPerEm ) - ); - }, - getBackgroundPosition: function( name ){ - var x = this.get( name + 'X' ), - y = this.get( name + 'Y' ), - ret = new PropertyGroup( name, x, y ), - xy; - if( ret.isValid() === true ) return ret; - ret.kill(); - xy = this.style[ name ].split( ' ' ); - return new PropertyGroup( name, - new Property( name + 'X', this.getValue( xy[ 0 ] ), this.getUnit( xy[ 0 ] ), this.pxPerEm ), - new Property( name + 'Y', this.getValue( xy[ 1 ] ), this.getUnit( xy[ 1 ] ), this.pxPerEm ) - ); - }, - getMarginPaddingBorder: function( name, width ){ - var props = [ name + 'Top' + width, - name + 'Right' + width, - name + 'Bottom' + width, - name + 'Left' + width ], - top = this.get( props[ 0 ] ), - right = this.get( props[ 1 ] ), - bottom = this.get( props[ 2 ] ), - left = this.get( props[ 3 ] ), - ret = new FrexibleProperty( name, top, right, bottom, left ), - klass, pxPerEm, getValue, getUnit, - all, _0, _1, _2, _3, v, u; - if( ret.isValid() === true ) return ret; - ret.kill(); - klass = Property; - pxPerEm = this.pxPerEm; - getValue = this.getValue; - getUnit = this.getUnit; - all = this.style[ name + width ].split( ' ' ); - _0 = all[ 0 ]; - _1 = all[ 1 ]; - _2 = all[ 2 ]; - _3 = all[ 3 ]; - v = getValue( _0 ); - u = getUnit( _0 ); - switch( all.length ){ - case 1 : - top = new klass( props[ 0 ], v, u, pxPerEm ); - right = new klass( props[ 1 ], v, u, pxPerEm ); - bottom = new klass( props[ 2 ], v, u, pxPerEm ); - left = new klass( props[ 3 ], v, u, pxPerEm ); - break; - case 2 : - top = new klass( props[ 0 ], v, u, pxPerEm ); - bottom = new klass( props[ 2 ], v, u, pxPerEm ); - v = getValue( _1 ); - u = getUnit( _1 ); - right = new klass( props[ 1 ], v, u, pxPerEm ); - left = new klass( props[ 3 ], v, u, pxPerEm ); - break; - case 3 : - top = new klass( props[ 0 ], v, u, pxPerEm ); - v = getValue( _1 ); - u = getUnit( _1 ); - right = new klass( props[ 1 ], v, u, pxPerEm ); - left = new klass( props[ 3 ], v, u, pxPerEm ); - bottom = new klass( props[ 2 ], getValue( _2 ), getUnit( _2 ), pxPerEm ); - break; - case 4 : - top = new klass( props[ 0 ], v, u, pxPerEm ); - right = new klass( props[ 1 ], getValue( _1 ), getUnit( _1 ), pxPerEm ); - bottom = new klass( props[ 2 ], getValue( _2 ), getUnit( _2 ), pxPerEm ); - left = new klass( props[ 3 ], getValue( _3 ), getUnit( _3 ), pxPerEm ); - break; - }; - return new FrexibleProperty( name, top, right, bottom, left ); - }, - getBorderColor: function( name ){ - var props = 'borderTopColor,borderRightColor,borderBottomColor,borderLeftColor'.split( ',' ), - top = this.get( props[ 0 ] ), - right = this.get( props[ 1 ] ), - bottom = this.get( props[ 2 ] ), - left = this.get( props[ 3 ] ), - ret = new FrexibleProperty( name, top, right, bottom, left ), - all, _0, _1, getColor; - if( ret.isValid() === true ) return ret; - ret.kill(); - getColor = this.getColor; - all = this.style[ name ].split( ' ' ); - _0 = all[ 0 ]; - _1 = all[ 1 ]; - switch( all.length ){ - case 1 : - top = getColor( _0, props[ 0 ] ); - right = getColor( _0, props[ 1 ] ); - bottom = getColor( _0, props[ 2 ] ); - left = getColor( _0, props[ 3 ] ); - break; - case 2 : - top = getColor( _0, props[ 0 ] ); - right = getColor( _1, props[ 1 ] ); - bottom = getColor( _0, props[ 2 ] ); - left = getColor( _1, props[ 3 ] ); - break; - case 3 : - top = getColor( _0, props[ 0 ] ); - right = getColor( _1, props[ 1 ] ); - bottom = getColor( all[ 2 ], props[ 2 ] ); - left = getColor( _1, props[ 3 ] ); - break; - case 4 : - top = getColor( _0, props[ 0 ] ); - right = getColor( _1, props[ 1 ] ); - bottom = getColor( all[ 2 ], props[ 2 ] ); - left = getColor( all[ 3 ], props[ 3 ] ); - break; - }; - return new FrexibleProperty( name, top, right, bottom, left ); - } - } - ); - function camelizeHash( obj ){ - var p, _p, came = Util.camelize; - for( p in obj ){ - _p = came( p ); - if( _p === p ) continue; - obj[ _p ] = obj[ _p ] || obj[ p ]; - delete obj[ p ]; - }; - }; - return { - create: function( css ){ - return new WrappedStyle( camelizeHash( p ) ); - } - }; -})(); - -var XDocument = ( function( window, document ){ - - var getIndex = Util.getIndex; - var ROOT_LIST = []; - var DEF_ATTRS = {}; - var AUTO = Number.POSITIVE_INFINITY; - var FULL = DEF_ATTRS; // something unigue value; - var FLOOR = Math.floor; - - DEF_ATTRS.LENGTH = 1; - DEF_ATTRS.PERCENT = 2; - DEF_ATTRS.COLOR = 4; - DEF_ATTRS.U_DECIMAL = 8; - DEF_ATTRS.NUMERICAL = 16; - DEF_ATTRS.BOOLEAN = 32; - DEF_ATTRS.QUARTET = 64; - DEF_ATTRS.URL = 128; - DEF_ATTRS.FONT_NAME = 256; - DEF_ATTRS.LIST = 512; - DEF_ATTRS.AUTO = 1024; - DEF_ATTRS.COMBI = 2048; - DEF_ATTRS.BORDER_STYLE = 'none,hidden,dotted,dashed,solid,double,groove,ridge,inset,outset'.split(','); - DEF_ATTRS.POSITION_X = 'left,center,right'.split(','); - DEF_ATTRS.POSITION_Y = 'top,center,bottom'.split(','); - DEF_ATTRS.ALIGN = 'left,center,right,justify'.split(','); - DEF_ATTRS.TEXT_DECORATION = 'none,underline,overline,line-through,blink'.split(','); - DEF_ATTRS.TEXT_TRANSFORM = 'none,capitalize,lowercase,uppercase'.split(','); - DEF_ATTRS.WIDTH_HEIGHT = 'auto'.split(','); - DEF_ATTRS.BOX_SIZING = 'content-box,padding-box,border-box,margin-box'.split(','); - DEF_ATTRS.PAINT = 1; // 再描画のみ必要 - DEF_ATTRS.REFLOW = 2; // レイアウトの再計算が必要 - DEF_ATTRS.FONT = 3; // フォントサイズが変更された - DEF_ATTRS.CONTENT_UPDATE = 4; // コンテンツが変更された - - DEF_ATTRS.borderWidth = [ DEF_ATTRS.REFLOW, 0, DEF_ATTRS.QUARTET | DEF_ATTRS.LENGTH ]; // em [ top, right, bottom, left ] - DEF_ATTRS.borderColor = [ DEF_ATTRS.PAINT, 4, DEF_ATTRS.QUARTET | DEF_ATTRS.DEF_COLOR ]; // color [ top, right, bottom, left ] - DEF_ATTRS.borderStyle = [ DEF_ATTRS.PAINT, 8, DEF_ATTRS.QUARTET | DEF_ATTRS.LIST, DEF_ATTRS.BORDER_STYLE ]; // string [ top, right, bottom, left ] - DEF_ATTRS.cornerRadius = [ DEF_ATTRS.PAINT, 12, DEF_ATTRS.QUARTET | DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; // em, px [ top, right, bottom, left ] - DEF_ATTRS.bgColor = [ DEF_ATTRS.PAINT, 16, DEF_ATTRS.COLOR ]; // color - DEF_ATTRS.bgAlpha = [ DEF_ATTRS.PAINT, 17, DEF_ATTRS.U_DECIMAL ]; // 0 - 1 - DEF_ATTRS.bgImgUrl = [ DEF_ATTRS.PAINT, 18, DEF_ATTRS.URL ]; // url - DEF_ATTRS.bgImgRepeatX = [ DEF_ATTRS.PAINT, 19, DEF_ATTRS.BOOLEAN ]; // true / false - DEF_ATTRS.bgImgRepeatY = [ DEF_ATTRS.PAINT, 20, DEF_ATTRS.BOOLEAN ]; // true / false - DEF_ATTRS.bgImgPositionX = [ DEF_ATTRS.PAINT, 21, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT | DEF_ATTRS.LIST, DEF_ATTRS.POSITION_X ]; // em %, px, string - DEF_ATTRS.bgImgPositionY = [ DEF_ATTRS.PAINT, 22, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT | DEF_ATTRS.LIST, DEF_ATTRS.POSITION_Y ]; // em %, px, string - DEF_ATTRS.shadowColor = [ DEF_ATTRS.PAINT, 23, DEF_ATTRS.COLOR ]; // color - DEF_ATTRS.shadowAlpha = [ DEF_ATTRS.PAINT, 24, DEF_ATTRS.U_DECIMAL ]; // 0 - 1 - DEF_ATTRS.shadowOffsetX = [ DEF_ATTRS.PAINT, 25, DEF_ATTRS.LENGTH ]; // em - DEF_ATTRS.shadowOffsetY = [ DEF_ATTRS.PAINT, 26, DEF_ATTRS.LENGTH ]; // em - DEF_ATTRS.shadowBlur = [ DEF_ATTRS.PAINT, 27, DEF_ATTRS.LENGTH ]; // em - DEF_ATTRS.shadowSpread = [ DEF_ATTRS.PAINT, 28, DEF_ATTRS.LENGTH ]; // em - DEF_ATTRS.shadowInset = [ DEF_ATTRS.PAINT, 29, DEF_ATTRS.BOOLEAN ]; // true / false - - DEF_ATTRS.color = [ DEF_ATTRS.PAINT, 30, DEF_ATTRS.COLOR ]; // color - DEF_ATTRS.fontFamily = [ DEF_ATTRS.FONT, 31, DEF_ATTRS.FONT_NAME ]; // string - DEF_ATTRS.fontSize = [ DEF_ATTRS.FONT, 32, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; // em, % - DEF_ATTRS.bold = [ DEF_ATTRS.FONT, 33, DEF_ATTRS.BOOLEAN ]; // true / false - DEF_ATTRS.italic = [ DEF_ATTRS.FONT, 34, DEF_ATTRS.BOOLEAN ]; // true / false - DEF_ATTRS.lineHeight = [ DEF_ATTRS.FONT, 35, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT | DEF_ATTRS.NUMERICAL ]; // em, %, - DEF_ATTRS.letterSpacing = [ DEF_ATTRS.FONT, 36, DEF_ATTRS.LENGTH ]; // em - DEF_ATTRS.wordSpacing = [ DEF_ATTRS.FONT, 37, DEF_ATTRS.LENGTH ]; - DEF_ATTRS.align = [ DEF_ATTRS.FONT, 38, DEF_ATTRS.LIST, DEF_ATTRS.ALIGN ]; - DEF_ATTRS.decoration = [ DEF_ATTRS.PAINT, 39, DEF_ATTRS.LIST, DEF_ATTRS.TEXT_DECORATION ]; - DEF_ATTRS.transform = [ DEF_ATTRS.FONT, 40, DEF_ATTRS.LIST, DEF_ATTRS.TEXT_TRANSFORM ]; - DEF_ATTRS.textShadowColor = [ DEF_ATTRS.PAINT, 41, DEF_ATTRS.COLOR ]; - DEF_ATTRS.textShadowOffsetX = [ DEF_ATTRS.PAINT, 42, DEF_ATTRS.LENGTH ]; - DEF_ATTRS.textShadowOffsetY = [ DEF_ATTRS.PAINT, 43, DEF_ATTRS.LENGTH ]; - DEF_ATTRS.shadowBlur = [ DEF_ATTRS.PAINT, 44, DEF_ATTRS.LENGTH ]; - - DEF_ATTRS.width = [ DEF_ATTRS.REFLOW, 45, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT, DEF_ATTRS.WIDTH_HEIGHT ]; - DEF_ATTRS.minWidth = [ DEF_ATTRS.REFLOW, 46, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; - DEF_ATTRS.maxWidth = [ DEF_ATTRS.REFLOW, 47, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; - DEF_ATTRS.height = [ DEF_ATTRS.REFLOW, 48, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT, DEF_ATTRS.WIDTH_HEIGHT ]; - DEF_ATTRS.minHeight = [ DEF_ATTRS.REFLOW, 49, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; - DEF_ATTRS.maxHeight = [ DEF_ATTRS.REFLOW, 50, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; - DEF_ATTRS.padding = [ DEF_ATTRS.REFLOW, 51, DEF_ATTRS.QUARTET | DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; - DEF_ATTRS.margin = [ DEF_ATTRS.REFLOW, 55, DEF_ATTRS.QUARTET | DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; - DEF_ATTRS.sizing = [ DEF_ATTRS.REFLOW, 59, DEF_ATTRS.LIST, DEF_ATTRS.BOX_SIZING ]; - DEF_ATTRS.pageBox = [ DEF_ATTRS.REFLOW, 60, DEF_ATTRS.BOOLEAN ]; // true / false - DEF_ATTRS.x = DEF_ATTRS.left = [ DEF_ATTRS.REFLOW, 61, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; - DEF_ATTRS.y = DEF_ATTRS.top = [ DEF_ATTRS.REFLOW, 62, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; - DEF_ATTRS.bottom = [ DEF_ATTRS.REFLOW, 63, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; - DEF_ATTRS.right = [ DEF_ATTRS.REFLOW, 64, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; - - var ATTRS = ( function(){ - var ret = {}, - obj = DEF_ATTRS, - p; - for( p in obj ){ - if( Type.isArray( obj[ p ] ) === true ){ - ret[ p ] = obj[ p ][ 1 ]; - }; - }; - return ret; - })(); - - /** - * 再計算と再描画 - * redraw 再描画はパラメータ変更後に setTimeout で - * reflow 再計算は値が get された場合 invalidate が サイズだったら - * または再描画前に invalidate がサイズなフラグが足っていたら - */ - - var BasicLayoutManager = Class.create( - 'BasicLayoutManager', - Class.POOL_OBJECT, - { - Constructor : function(){ - - }, - redraw : function( nodeData ){ - var root = nodeData.__root; - root.dirty === DEF_ATTRS.REFLOW && this.reflow( root ); - - // draw - }, - reflow : function( nodeData, allowW, allowH ){ - var children = nodeData.children, - contentW, contentH, autoW, autoH, auto, calc, - childW, childH, child, i, style, data, - t, r, b, l; - - nodeData.preMesure( allowW, allowH ); - if( children ){ - contentW = nodeData.contentWidth; - contentH = nodeData.contentHeight; - childW = 0; - childH = 0; - autoW = contentW === AUTO; - autoH = contentH === AUTO; - auto = autoW && autoH; - calc = BasicLayoutManager.calcValue; - for( i = children.length; i; ){ - child = children[ --i ]; - style = child.__syule; - if( style ){ - data = style.data; - t = calc( data[ ATTRS.top ], contentH ); - r = calc( data[ ATTRS.right ], contentW ); - b = calc( data[ ATTRS.bottom ], contentH ); - l = calc( data[ ATTRS.left ], contentW ); - } else { - t = r = b = l = 0; - }; - if( child instanceof LayoutBoxPrivate ){ - child.layoutManager.reflow( child, contentW - r - l, contentH - t - b ); - } else { - child.preMesure( contentW - r - l, contentH - t - b ); - child.mesure(); - child.postMesure(); - }; - if( !auto ) continue; - if( autoW && childW < child.contentWidth + r + l ) childW = child.contentWidth + r + l; - if( autoH && childH < child.contentHeight + t + b ) childH = child.contentHeight + t + b; - }; - if( autoW ) nodeData.contentWidth = childW; - if( autoH ) nodeData.contentHeight = childH; - }; - auto && nodeData.postMesure(); - - delete nodeData.dirty; - } - } - ); - BasicLayoutManager.finalValue = function( styleValue, styleMin, styleMax, srcValue ){ - var calc = BasicLayoutManager.calcValue, - v = calc( styleValue, srcValue ), - min = calc( styleMin, srcValue ), - max = calc( styleMax, srcValue ); - if( v < min ) return min; - if( max < v ) return max; - return v; - }; - BasicLayoutManager.calcValue = function( styleValue, srcValue ){ - switch( styleValue ){ - case 0 : - return 0; - case AUTO : - return AUTO; - case FULL : - return srcValue; // 100% - default : - if( 1 <= styleValue ) return styleValue; // legth - if( -1 < styleValue ) return FLOOR( srcValue * styleValue ); // % - }; - return styleValue; // - length - }; - BasicLayoutManager.advancedCalcValue = function( styleValue, srcValue ){ - switch( styleValue ){ - case 0 : - return 0; - case AUTO : - return srcValue; - case FULL : - throw new Error( 'calcValueFromSelf FULL' ); - // return ; // 100% - default : - if( 1 <= styleValue ) return styleValue; - if( -1 < styleValue ) return FLOOR( ( srcValue / ( 1 - styleValue ) ) * styleValue ); // % - }; - return styleValue; // - length - } - - var NodeStylePrivate = Class.create( - Class.PRIVATE_DATA | Class.POOL_OBJECT, - { - fontCssText : null, - colorCssText : null, - layoutCssText : null, - Constructor : function(){ - this.data = []; - this.dirty = 0; - }, - register : function( node ){ - var root = node.__root, - roots = this.rootList, - nodes = this.nodeList; - if( !roots ){ - this.rootList = [ root ]; - } else - if( getIndex( roots, root ) === -1 ) roots[ roots.length ] = root; - - if( !nodes ){ - this.nodeList = [ node ]; - return; - }; - if( getIndex( nodes, node ) === -1 ) nodes[ nodes.length ] = node; - }, - unRegister : function( node ){ - var nodes = this.nodeList, - i = getIndex( nodes, node ), - root = node._root, - roots = this.rootList, - j = getIndex( roots, root ); - if( i !== -1 && nodes.splice( i, 1 ) && nodes.length === 0 ) delete this.nodeList; - if( j !== -1 && roots.splice( j, 1 ) && roots.length === 0 ) delete this.rootList; - }, - clone : function(){ - var styleClass = Class.getClass( this.User ), - dataClass = Class.getClass( this ); - }, - /* - * opt_unit は getter のみ - */ - attr : function( prop, v, opt_unit ){ - var update = prop[ 0 ], - propID = prop[ 1 ], - type = prop[ 2 ], - list = prop[ 3 ], - length = !!( type & DEF_ATTRS.LENGTH ), - percent = !!( type & DEF_ATTRS.PERCENT ), - color = !!( type & DEF_ATTRS.COLOR ), - uDecimal = !!( type & DEF_ATTRS.U_DECIMAL ), - numerical = !!( type & DEF_ATTRS.NUMERICAL ), - flag = !!( type & DEF_ATTRS.BOOLEAN ), - quartet = !!( type & DEF_ATTRS.QUARTET ), - url = !!( type & DEF_ATTRS.URL ), - fontName = !!( type & DEF_ATTRS.FONT_NAME ), - //list = !!( type & DEF_ATTRS.LIST ), - combi = !!( type & DEF_ATTRS.COMBI ), - data = this.data, - _v = -1, - i, l, nodes, root; - /* - * Setter - */ - if( v !== undefined ){ - if( Type.isNumber( v ) === true ){ - if( numerical === false ){ - if( uDecimal === false || v < 0 || 1 < v ) throw new Error( '' ); - }; - } else - if( Type.isBoolean( v ) === true ){ - if( flag === false ) throw new Error( '' ); - } else - if( Type.isString( v ) === true ){ - if( url === false && fontName === false ){ - if( v.indexOf( ' ' ) !== -1 ){ - v = v.split( ' ' ); - } else { - if( length === false && percent === false && color === false ) throw new Error( '' ); - }; - }; - }; - if( Type.isArray( v ) === true ){ - if( v.length <= 4 && quartet === true ){ - type ^= DEF_ATTRS.QUARTET; - } else - if( v.length === 2 && combi === true ){ - type ^= DEF_ATTRS.COMBI; - } else { - throw new Error( '' ); - }; - switch( v.length ){ - case 1 : - this.attr( [ propID , type, list ], v[ 0 ] ); - this.attr( [ ++propID, type, list ], v[ 0 ] ); - this.attr( [ ++propID, type, list ], v[ 0 ] ); - this.attr( [ ++propID, type, list ], v[ 0 ] ); - break; - case 2 : - this.attr( [ propID , type, list ], v[ 0 ] ); - this.attr( [ ++propID, type, list ], v[ 1 ] ); - this.attr( [ ++propID, type, list ], v[ 0 ] ); - this.attr( [ ++propID, type, list ], v[ 1 ] ); - break; - case 3 : - this.attr( [ propID , type, list ], v[ 0 ] ); - this.attr( [ ++propID, type, list ], v[ 1 ] ); - this.attr( [ ++propID, type, list ], v[ 2 ] ); - this.attr( [ ++propID, type, list ], v[ 1 ] ); - break; - case 4 : - this.attr( [ propID , type, list ], v[ 0 ] ); - this.attr( [ ++propID, type, list ], v[ 1 ] ); - this.attr( [ ++propID, type, list ], v[ 2 ] ); - this.attr( [ ++propID, type, list ], v[ 3 ] ); - break; - default : - }; - return this.User; - }; - switch( update ){ - case DEF_ATTRS.REFLOW : - delete this.layoutCssText; - break; - case DEF_ATTRS.PAINT : - delete this.colorCssText; - break; - case DEF_ATTRS.FONT : - delete this.fontCssText; - }; - - if( this.dirty < update ){ - this.dirty = update; - roots = this.rootList; - for( i = 0, l = roots.length; i < l; ++i ){ - root = roots[ i ]; - if( root.dirty < update ) root.dirty = update; - }; - }; - - if( list ) _v = Util.getIndex( list, v ); - data[ propID ] = _v !== -1 ? _v : v; - - switch( prop ){ - case DEF_ATTRS.left : - case DEF_ATTRS.right : - this.ltrtWidth = data[ DEF_ATTRS.left[ 0 ] ] === undefined && data[ DEF_ATTRS.right[ 0 ] ] === undefined; - break; - case DEF_ATTRS.top : - case DEF_ATTRS.bottom : - this.tpbtHeight = data[ DEF_ATTRS.top[ 0 ] ] === undefined && data[ DEF_ATTRS.bottom[ 0 ] ] === undefined; - break; - case DEF_ATTRS.width : - this.autoWidth = v === AUTO; - this.prctWidth = v === FULL || v < 1; - break; - case DEF_ATTRS.height : - this.autoHeight = v === AUTO; - this.prctHeight = v === FULL || v < 1; - break; - }; - return this.User; - }; - /* - * Getter - */ - if( this.dirty === DEF_ATTRS.REFLOW ){ - roots = this.rootList; - if( roots ){ - for( i = 0, l = roots.length; i < l; ++i ){ - roots[ i ].layoutManager.reflow(); - }; - }; - }; - v = data[ propID ]; - if( quartet === true ) return [ v, data[ ++propID ], data[ ++propID ], data[ ++propID ] ]; - if( combi === true ) return [ v, data[ ++propID ] ]; - if( list && Type.isNumber( v ) === true ) return list[ v ]; - return v; - }, - cssText : function(){ - if( this.fontCssText === null ) this.fontCssText = this.createFontCssText(); - if( this.layoutCssText === null ) this.layoutCssText = this.createLayoutCssText(); - if( this.colorCssText === null ) this.colorCssText = this.createColorCssText(); - return [ this.fontCssText, this.colorCssText, this.layoutCssText ].join( ';' ); - }, - createFontCssText : function(){ - var data = this.data, - css = [], - v; - if( v = data[ ATTRS.fontFamily ] ) css[ 0 ] = 'font-family:' + v; - if( v = data[ ATTRS.fontSize ] ) css[ css.length - 1 ] = 'font-size:' + v; - if( v = data[ ATTRS.bold ] ) css[ css.length - 1 ] = 'font-weight:bold'; - if( v = data[ ATTRS.bold ] ) css[ css.length - 1 ] = 'font-style:italic'; - if( v = data[ ATTRS.lineHeight ] ) css[ css.length - 1 ] = 'line-height:' + v; - if( v = data[ ATTRS.letterSpacing ] ) css[ css.length - 1 ] = 'letter-spacing:' + v; - if( v = data[ ATTRS.wordSpacing ] ) css[ css.length - 1 ] = 'word-spacing:' + v; - if( v = data[ ATTRS.align ] ) css[ css.length - 1 ] = 'text-align:' + DEF_ATTRS.ALIGN[ v ]; - if( v = data[ ATTRS.transform ] ) css[ css.length - 1 ] = 'text-transform:' + DEF_ATTRS.TEXT_TRANSFORM[ v ]; - return css.join( ',' ); - }, - createColorCssText : function(){ - var data = this.data, - css = [], - v, x, y, c, b; - if( v = data[ ATTRS.borderColor ] ) css[ 0 ] = 'border-color:' + v; - if( v = data[ ATTRS.borderStyle + 0 ] ) css[ css.length - 1 ] = 'border-top-style:' + DEF_ATTRS.BORDER_STYLE[ v ]; - if( v = data[ ATTRS.borderStyle + 1 ] ) css[ css.length - 1 ] = 'border-right-style:' + DEF_ATTRS.BORDER_STYLE[ v ]; - if( v = data[ ATTRS.borderStyle + 2 ] ) css[ css.length - 1 ] = 'border-bottom-style:' + DEF_ATTRS.BORDER_STYLE[ v ]; - if( v = data[ ATTRS.borderStyle + 3 ] ) css[ css.length - 1 ] = 'border-left-style:' + DEF_ATTRS.BORDER_STYLE[ v ]; - if( v = data[ ATTRS.cornerRadius + 0 ] ) css[ css.length - 1 ] = 'corner-radius-top:' + v; - if( v = data[ ATTRS.cornerRadius + 1 ] ) css[ css.length - 1 ] = 'corner-radius-right:' + v; - if( v = data[ ATTRS.cornerRadius + 2 ] ) css[ css.length - 1 ] = 'border-radius-bottom:' + v; - if( v = data[ ATTRS.cornerRadius + 3 ] ) css[ css.length - 1 ] = 'border-radius-left:' + v; - if( v = data[ ATTRS.bgColor ] ) css[ css.length - 1 ] = 'background-color:' + v; - // ATTRS.bgAlpha - if( v = data[ ATTRS.bgImgUrl ] ) css[ css.length - 1 ] = 'background-image:url(' + v + ')'; - x = data[ ATTRS.bgImgRepeatX ]; - y = data[ ATTRS.bgImgRepeatY ]; - if( x && y ){ - css[ css.length - 1 ] = 'background-repeat:repeat'; - } else - if( x ){ - css[ css.length - 1 ] = 'background-repeat:repeat-x'; - } else - if( y ){ - css[ css.length - 1 ] = 'background-repeat:repeat-y'; - }; - x = data[ ATTRS.bgImgPositionX ]; - y = data[ ATTRS.bgImgPositionY ]; - if( x && y ){ - css[ css.length - 1 ] = 'background-position:' + x + ' ' + y; - } else - if( x ){ - css[ css.length - 1 ] = 'background-position:' + x + ' 0'; - } else - if( y ){ - css[ css.length - 1 ] = 'background-position:0 ' + y; - }; - if( v = data[ ATTRS.color ] ) css[ css.length - 1 ] = 'color:' + v; - if( v = data[ ATTRS.decoration ] ) css[ css.length - 1 ] = 'text-decoration:' + DEF_ATTRS.TEXT_DECORATION[ v ]; - x = data[ ATTRS.textShadowOffsetX ]; - y = data[ ATTRS.textShadowOffsetY ]; - b = data[ ATTRS.textShadowBlur ]; - c = data[ ATTRS.textShadowColor ]; - if( c || x || y || b ){ - css[ css.length - 1 ] = 'text-shadow:' + x + ' ' + y + ' ' + b + ' ' + c; - }; - /* - ATTRS.shadowColor = [ DEF_ATTRS.PAINT, 23, DEF_ATTRS.COLOR ]; // color - ATTRS.shadowAlpha = [ DEF_ATTRS.PAINT, 24, DEF_ATTRS.U_DECIMAL ]; // 0 - 1 - ATTRS.shadowOffsetX = [ DEF_ATTRS.PAINT, 25, DEF_ATTRS.LENGTH ]; // em - ATTRS.shadowOffsetY = [ DEF_ATTRS.PAINT, 26, DEF_ATTRS.LENGTH ]; // em - ATTRS.shadowBlur = [ DEF_ATTRS.PAINT, 27, DEF_ATTRS.LENGTH ]; // em - ATTRS.shadowSpread = [ DEF_ATTRS.PAINT, 28, DEF_ATTRS.LENGTH ]; // em - ATTRS.shadowInset = [ DEF_ATTRS.PAINT, 29, DEF_ATTRS.BOOLEAN ]; // true / false - */ - }, - createBoxShadowCssText : function(){ - - }, - createBGAlphaCssText : function(){ - - }, - createTextShadowCssText : function(){ - - }, - createLayoutCssText : function(){ - - } - } - ); - - var NodeStyle = Class.create( - 'NodeStyle', - Class.POOL_OBJECT, - NodeStylePrivate, - { - Constructor : function(){ - NodeStyle.newPrivateData( this ); - }, - borderWidth : function( v ){ - return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.borderWidth, v ); - }, - borderColor : function(){ - return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.borderColor, v ); - }, - borderStyle : function(){ - return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.borderStyle, v ); - }, - cornerRadius : function(){ - return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.cornerRadius, v ); - }, - bgColor : function(){ - return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.bgColor, v ); - }, - bgAlpha : function(){ - return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.bgAlpha, v ); - }, - bgImgUrl : function(){ - return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.bgImgUrl, v ); - }, - bgImgRepeatX : function(){ - return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.bgImgRepeatX, v ); - }, - bgImgRepeatY : function(){ - return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.bgImgRepeatY, v ); - }, - bgImgPositionX : function(){ - return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.bgImgPositionX, v ); - }, - bgImgPositionY : function(){ - return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.bgImgPositionY, v ); - }, - shadowColor : function(){ - return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.shadowColor, v ); - }, - shadowAlpha : function(){ - return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.shadowAlpha, v ); - }, - shadowOffsetX : function(){ - return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.shadowOffsetX, v ); - }, - shadowOffsetY : function(){ - return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.shadowOffsetY, v ); - }, - shadowBlur : function(){ - return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.shadowBlur, v ); - }, - shadowSpread : function(){ - return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.shadowSpread, v ); - }, - shadowInset : function(){ - return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.shadowInset, v ); - }, - color : function( v ){ - return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.color, v ); - }, - fontFamily : function( v ){ - return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.fontFamily, v ); - }, - fontSize : function( v ){ - return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.fontSize, v ); - }, - bold : function( v ){ - return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.bold, v ); - }, - italic : function( v ){ - return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.italic, v ); - }, - lineHeight : function( v ){ - return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.lineHeight, v ); - }, - letterSpacing : function( v ){ - return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.letterSpacing, v ); - }, - wordSpacing : function( v ){ - return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.wordSpacing, v ); - }, - align : function( v ){ - return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.align, v ); - }, - decoration : function( v ){ - return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.decoration, v ); - }, - transform : function( v ){ - return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.transform, v ); - }, - textShadowColor : function( v ){ - return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.textShadowColor, v ); - }, - textShadowOffsetX : function( v ){ - return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.textShadowOffsetX, v ); - }, - textShadowOffsetY : function( v ){ - return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.textShadowOffsetY, v ); - }, - shadowBlur : function( v ){ - return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.shadowBlur, v ); - }, - cssText : function(){ - return TypoStyle.getPrivateData( this ).cssText(); - } - } - ); - - var NodePrivate = Class.create( - 'NodePrivate', - Class.PRIVATE_DATA | Class.POOL_OBJECT, - { - elmWrap : null, - textNode : null, - boxX : 0, - boxY : 0, - boxWidth : 0, - boxHeight : 0, - contentL : 0, - contentT : 0, - contentR : 0, - contentB : 0, - borderL : 0, - borderT : 0, - borderR : 0, - borderB : 0, - paddingL : 0, - paddingT : 0, - paddingR : 0, - paddingB : 0, - marginL : 0, - marginT : 0, - marginR : 0, - marginB : 0, - boxSizingOffsetLR : 0, - boxSizingOffsetTB : 0, - contentWidth : 0, - minContentWidth : 0, - maxContentWidth : AUTO, - contentHeight : 0, - minContentHeight : 0, - maxContentHeight : AUTO, - Constructor : function( __root, __parent ){ - this.__root = __root; - if( __parent ) this.__parent = __parent; - }, - style : function( v ){ - if( v instanceof NodeStyle ){ - this.__style && this.__style.unRegister( this ); - this._style = v; - this.__style = StylePrivate.getPrivateData( v ); - this.__style.register( this ); - return this.User; - } else - if( v === null ){ - this.__style && this.__style.unRegister( this ); - delete this._style; - delete this.__style; - return this.User; - }; - return this._style; - }, - content : function( v ){ - if( Type.isString( v ) === true ){ - if( !this.textNode || ( this.textNode && this.textNode.data !== v ) ){ - this._content = v; - this.updateContent = true; - }; - return this.User; - } else - if( v === null ){ - if( this._content !== v && this.textNode ){ - this._content = v; - this.updateContent = true; - }; - return this.User; - }; - if( this._content ) return this._content; - if( this._content === null ) return null; - if( this.textNode ) return this.textNode.data; - return null; - }, - /** - * 要素の追加・削除 - * 1. ペイントがある // 予約のみ - * 2. コンテンツがある // 予約のみ * - * 3. コンテンツを削除 // 予約のみ - * 4. 要素を削除 // 予約のみ - * - * コンテンツの再計算 - * 0. 要素追加して css セット - * 1. コンテンツの変更 - * 2. font 指定の変更 - * 3. contentWidth の変更 (コンテンツの高さの再計算) 前回の contentWidth の保持 - * - * contentSize, scrollSize の決定 - */ - musure : function( dirty ){ - var content = this._content, - root = this.__root, - style = this.__style, - w = this.contentWidth, - h = this.contentHeight; - switch( this.updateContent === true ? DEF_ATTRS.CONTENT_UPDATE : dirty ){ - case DEF_ATTRS.CONTENT_UPDATE : // コンテンツが変更された - this.paint( 0 ); - this.lastContentWidth = -1; - case DEF_ATTRS.FONT : // フォントサイズが変更された - case DEF_ATTRS.REFLOW : // レイアウトの再計算が必要 - /* http://web-designs.seesaa.net/article/188400668.html - * min-width の値が max-width の値より大きい場合は、max-width の値は min-width の値に設定される。 - * - * テキストノードがあり - * 1. contentWidth === AUTO - * style を更新して contentWidth の決定 - * min or max に引っかかったら style 更新 - * contentHeight === AUTO の場合 - * textHeight の決定 - * contentHeight !== AUTO の場合 scrollHeight のみ更新 - * 2. contentHeight === AUTO かつ - * コンテンツの高さの再取得が必要( contentWidth が最終計測時の contentWidth と一致 かつ フォント・コンテンツに変更無し の場合再取得不要) - * style を更新して contentHeight の決定 - * 必要でない - * 3. content のサイズがすでに決定している - * コンテンツの高さの再取得が必要 - * 必要でない - */ - if( this.textNode ){ - if( w === AUTO ){ - this.commitStyle(); - w = this.contentWidth = this.textNode.offsetWidth; - this.scrollWidth = w + this.contentL + this.contentR; - if( this.maxContentWidth < w - this.boxSizingOffsetLR ) this.contentWidth = this.maxContentWidth + this.boxSizingOffsetLR; - if( w - this.boxSizingOffsetLR < this.minContentWidth ) this.contentWidth = this.minContentWidth + this.boxSizingOffsetLR; - this.lastContentWidth = this.contentWidth; - - w !== this.contentWidth && this.commitStyle(); - - if( h === AUTO ){ - h = this.conetntHeight = this.textNode.offsetHeight; - this.scrollHeight = h + this.contentT + this.contentB; - if( this.maxContentHeight < h - this.boxSizingOffsetTB ) this.contentHeight = this.maxContentHeight + this.boxSizingOffsetTB; - if( h - this.boxSizingOffsetTB < this.minContentHeight ) this.contentHeight = this.minContentHeight + this.boxSizingOffsetTB; - } else { - this.scrollHeight = this.textNode.offsetHeight + this.contentT + this.contentB; - }; - } else - if( h === AUTO ){ - if( w !== this.lastContentWidth || dirty !== DEF_ATTRS.REFLOW ){ - this.commitStyle(); - this.lastContentWidth = w; - h = this.conetntHeight = this.textNode.offsetHeight; - this.scrollWidth = w + this.contentL + this.contentR; - this.scrollHeight = h + this.contentT + this.contentB; - if( this.maxContentHeight < h - this.boxSizingOffsetTB ) this.contentHeight = this.maxContentHeight + this.boxSizingOffsetTB; - if( h - this.boxSizingOffsetTB < this.minContentHeight ) this.contentHeight = this.minContentHeight + this.boxSizingOffsetTB; - } else { - this.scrollWidth = w + this.contentL + this.contentR; - this.scrollHeight = h + this.contentT + this.contentB; - root.paintReserve( this ); - }; - } else { - if( dirty !== DEF_ATTRS.REFLOW ){ - this.commitStyle(); - this.scrollWidth = this.textNode.offsetWidth + this.contentL + this.contentR; - this.scrollHeight = this.textNode.offsetHeight + this.contentT + this.contentB; - } else { - root.paintReserve( this ); - this.scrollWidth = w + this.contentL + this.contentR; - this.scrollHeight = h + this.contentT + this.contentB; - }; - }; - } else { - if( w === AUTO ) this.contentWidth = w = 0 < this.minContentWidth ? this.minContentWidth : 0; - if( h === AUTO ) this.contentHeight = h = 0 < this.minContentHeight ? this.minContentHeight : 0; - this.scrollWidth = w + this.contentL + this.contentR; - this.scrollHeight = h + this.contentT + this.contentB; - root.paintReserve( this ); - }; - break; - case DEF_ATTRS.PAINT : // 再描画のみ必要 - root.paintReserve( this ); - break; - }; - }, - paint : function( dirty ){ - var content = this._content, - style = this.__style; - if( this.updateContent === true || ( style && style.hasPaint === true ) ){ - if( !this.elmWrap ){ - this.elmWrap = DOM.createDiv(); - this.__parent.addDisplayElement( this ); - }; - dirty !== 0 && this.commitStyle(); - if( this.updateContent === true ){ - if( content !== null ){ - if( !this.textNode ){ - this.textNode = DOM.cerateText(); - this.elmWrap.appendChild( this.textNode ); - }; - this.textNode.data = content; - } else - if( this.textNode ){ - DOM.correct( this.textNode ); - delete this.textNode; - delete this.contentWidth; - delete this.conetntHeight; - delete this.scrollWidth; - delete this.scrollHeight; - }; - }; - } else - if( this.elmWrap && content === null && ( !style || style.hasPaint === false ) ){ - this.__parent.removeDisplayElement( this ); - DOM.correct( this.elmWrap ); - delete this.contentWidth; - delete this.conetntHeight; - }; - }, - commitStyle : function(){ - var css; - if( this.elmWrap ){ - css = this.__style ? this.__style.cssText( this ) : ''; - if( this.contentWidth !== AUTO ) css += 'width:' + this.contentWidth + 'px'; - if( this.contentHeight !== AUTO ) css += 'height:' + this.contentHeight + 'px'; - this.elmWrap.style.cssText = css; - }; - }, - /* - * 親の サイズを元に自身のサイズを計算していく - */ - preMesure : function( allowW, allowH ){ - var style = this.__style, - styles, calc, box, min, max, - contentW, contentH, allowSize, boxMinus, - paddingT, paddingR, paddingB, paddingL, - borderT, borderR, borderB, borderL, - marginT, marginR, marginB, marginL; - - if( style ){ - styles = style.data; - calc = BasicLayoutManager.calcValue; - box = styles[ ATTRS.sizing ]; - - // Width - // 自身が ltrtWidth の場合 親が AUTO ではない - // 自身が ltrtWidth でない場合自身が AUTO はなくかつ親 が AUTO の場合自身は % でない - if( style.ltrtWidth ? allowW !== AUTO : !style.autoWidth && ( allowW !== AUTO || !style.prctWidth ) ){ - if( style.ltrtWidth ){ - contentW = allowW - calc( styles[ ATTRS.left ], allowW ) - calc( styles[ ATTRS.right ], allowW ); - } else { - contentW = BasicLayoutManager.finalValue( styles[ ATTRS.width ], styles[ ATTRS.minWidth ], styles[ ATTRS.maxWidth ], allowW ); - }; - paddingR = calc( styles[ ATTRS.padding + 1 ], allowW ); - paddingL = calc( styles[ ATTRS.padding + 3 ], allowW ); - borderR = styles[ ATTRS.border + 1 ]; - borderL = styles[ ATTRS.margin + 3 ]; - marginR = calc( styles[ ATTRS.margin + 1 ], allowW ); - marginL = calc( styles[ ATTRS.margin + 3 ], allowW ); - this.boxWidth = contentW; - boxMinus = 0; - switch( box ){ - case 3 : // margin-box - boxMinus = - marginR - marginL; - case 2 : // border-box - boxMinus -= borderR + borderL; - case 1 : // padding-box - boxMinus -= paddingR + paddingL; - // case 0 : // content-box - }; - this.contentL = marginL + borderL + paddingL; - this.contentR = marginR + borderR + paddingR; - this.contentWidth = contentW + boxMinus; - this.boxSizingOffsetLR = boxMinus; - } else { - this.boxWidth = this.contentWidth = AUTO; - min = styles[ ATTRS.minWidth ]; - max = styles[ ATTRS.maxWidth ]; - this.minContentWidth = 1 <= min ? min : 0; - this.maxContentWidth = 1 <= max ? max : AUTO; - delete this.boxSizingOffsetLR; - }; - - // Height - if( style.tpbtHeight ? allowH !== AUTO : !style.autoHeight && ( allowH !== AUTO || !style.prctHeight ) ){ - if( style.tpbtHeight ){ - contentH = allowH - calc( styles[ ATTRS.top ], allowH ) - calc( styles[ ATTRS.bottom ], allowH ); - } else { - contentH = BasicLayoutManager.finalValue( styles[ ATTRS.height ], styles[ ATTRS.minHeight ], styles[ ATTRS.maxHeight ], allowH ); - }; - allowSize = styles[ ATTRS.pageBox ] === true ? allowH : allowW; - paddingT = calc( styles[ ATTRS.padding + 0 ], allowSize );// paddingTRBL の % 指定は 最大幅に対して TB でも幅に対して - paddingB = calc( styles[ ATTRS.padding + 2 ], allowSize ); - borderT = styles[ ATTRS.border + 0 ]; - borderB = styles[ ATTRS.border + 2 ]; - marginT = calc( styles[ ATTRS.margin + 0 ], allowSize );// marginTRBL の % 指定は 最大幅に対して TB でも幅に対して - marginB = calc( styles[ ATTRS.margin + 2 ], allowSize ); - this.boxHeight = contentH; - boxMinus = 0; - switch( box ){ - case 3 : // margin-box - boxMinus = - marginT - marginR; - case 2 : // border-box - boxMinus -= borderT + borderR; - case 1 : // padding-box - boxMinus -= paddingT + paddingR; - // case 0 : // content-box - }; - this.contentT = marginT + borderT + paddingT; - this.conetntB = marginB + borderB + paddingB; - this.contentHeight = contentH + boxMinus; - this.boxSizingOffsetTB = boxMinus; - } else { - this.boxHeight = this.contentHeight = AUTO; - min = styles[ ATTRS.minHeight ]; - max = styles[ ATTRS.maxHeight ]; - this.minContentHeight = 1 <= min ? min : 0; - this.maxContentHeight = 1 <= max ? max : AUTO; - delete this.boxSizingOffsetTB; - }; - } else { - this.boxWidth = this.contentWidth = allowW; - this.boxHeight = this.contentHeight = allowH; - delete this.minContentHeight; - delete this.maxContentHeight; - delete this.contentL; - delete this.contentT; - delete this.contentR; - delete this.contentB; - }; - }, - /** - * 自身のコンテンツサイズを元に AUTO な width, height を確定していく - */ - postMesure : function(){ - var style = this.__style, - styles, calc, box, - contentW, contentH, w, h - contentSize, contentPlus; - if( style ){ - styles = style.data; - calc = BasicLayoutManager.advancedCalcValue; - contentW = this.contentWidth; - box = styles[ ATTRS.sizing ]; - - // Width - if( this.boxWidth === AUTO ){ - paddingR = calc( styles[ ATTRS.padding + 1 ], contentW ); - paddingL = calc( styles[ ATTRS.padding + 3 ], contentW ); - borderR = styles[ ATTRS.border + 1 ]; - borderL = styles[ ATTRS.border + 3 ]; - marginR = calc( styles[ ATTRS.margin + 1 ], contentW ); - marginL = calc( styles[ ATTRS.margin + 3 ], contentW ); - contentPlus = 0; - switch( box ){ - case 3 : // margin-box - contentPlus = ( marginR + marginL ); - case 2 : // border-box - contentPlus += ( borderR + borderL ); - case 1 : // padding-box - contentPlus += ( paddingR + paddingL ); - // case 0 : // content-box - }; - this.contentWidth = contentW; - contentW += contentPlus; - if( !style.ltrtWidth ){ - min = styles[ ATTRS.minWidth ]; - max = styles[ ATTRS.maxWidth ]; - if( contentW < min && 1 <= min && contentPlus < min ){ - this.contentWidth = min - contentPlus; - } else - if( max < contentW && 1 <= max && contentPlus < max ){ - this.contentWidth = max - contentPlus; - }; - }; - this.contentL = marginL + borderL + paddingL; - this.contentR = marginR + borderR + paddingR; - this.boxWidth = this.contentWidth + this.contentL + this.contentR; - }; - // Height - if( this.boxHeight === AUTO ){ - contentH = this.contentHeight; - contentSize = styles[ ATTRS.pageBox ] === true ? contentH : contentW; - paddingT = calc( styles[ ATTRS.padding + 0 ], contentSize );// paddingTRBL の % 指定は 最大幅に対して TB でも幅に対して - paddingB = calc( styles[ ATTRS.padding + 2 ], contentSize ); - borderT = styles[ ATTRS.border + 0 ]; - borderB = styles[ ATTRS.border + 2 ]; - marginT = calc( styles[ ATTRS.margin + 0 ], contentSize );// marginTRBL の % 指定は 最大幅に対して TB でも幅に対して - marginB = calc( styles[ ATTRS.margin + 2 ], contentSize ); - contentPlus = 0; - switch( box ){ - case 3 : // margin-box - contentPlus = ( marginT + marginB ); - case 2 : // border-box - contentPlus += ( borderT + borderB ); - case 1 : // padding-box - contentPlus += ( paddingT + paddingB ); - // case 0 : // content-box - }; - this.contentHeight = contentH; - contentH += contentPlus; - if( !style.tpbtHeight ){ - min = styles[ ATTRS.minHeight ]; - max = styles[ ATTRS.maxHeight ]; - if( contentH < min && 1 <= min && contentPlus < min ){ - this.contentHeight = min - contentPlus; - } else - if( max < contentH && 1 <= max && contentPlus < max ){ - this.contentHeight = max - contentPlus; - }; - }; - this.contentT = marginT + borderT + paddingT; - this.contentB = marginB + borderB + paddingB; - this.boxHeight = this.contentHeight + this.contentT + this.contentB; - }; - } else { - this.boxWidth = this.contentWidth; - this.boxHeight = this.contentHeight; - delete this.minContentHeight; - delete this.maxContentHeight; - delete this.contentL; - delete this.contentT; - delete this.contentR; - delete this.contentB; - }; - }, - addDisplayElement : function( nodeData ){ - // 描画更新リストに追加 - }, - removeDisplayElement : function( nodeData ){ - // 描画更新リストに追加 - DOM.correct( nodeData.elmWrap ); - delete nodeData.elmWrap; - delete nodeData.textNode; - delete nodeData.contentWidth; - delete nodeData.conetntHeight; - delete nodeData.currentWidth; - delete nodeData.currentHeight; - } - } - ); - var Node = Class.create( - 'Node', - Class.POOL_OBJECT, - NodePrivate, - { - Constructor : function( root, parent ){ - Node.newPrivateData( this, LayoutBox.getPrivateData( root ), parent ? LayoutBox.getPrivateData( parent ) : undefined, this ); - }, - content : function( v ){ - return Node.getPrivateData( this ).content( v ); - }, - style : function( v ){ - return Node.getPrivateData( this ).paint( v ); - }, - remove : function(){ - Node.getPrivateData( this ).remove(); - }, - nodeIndex : function( v ){ - return Node.getPrivateData( this ).nodeIndex( v ); - }, - displayIndex : function(){ - - }, - disabled : function( v ){ - return Node.getPrivateData( this ).disabled( v ); - }, - cursor : function( v ){ - return Node.getPrivateData( this ).cursor( v ); - }, - getAbsolutePositionX : function(){ - return Node.getPrivateData( this ).getAbsolutePositionX(); - }, - getAbsolutePositionY : function(){ - return Node.getPrivateData( this ).getAbsolutePositionY(); - }, - addEventListener : function( type, handler, opt_thisObject ){ - Node.getPrivateData( this ).addEventListener( type, handler, opt_thisObject ); - }, - removeEventListener : function( type, handler ){ - Node.getPrivateData( this ).removeEventListener( type, handler ); - }, - scrollTo : function( x, y ){ - Node.getPrivateData( this ).scrollTo( x, y ); - }, - scrollX : function( v ){ - return Node.getPrivateData( this ).scrollX( v ); - }, - scrollY : function( v ){ - return Node.getPrivateData( this ).scrollY( v ); - } - } - ); - - var LayoutBoxPrivate = NodePrivate.inherits( - 'LayoutBoxPrivate', - Class.POOL_OBJECT | Class.SUPER_ACCESS, - { - Constructor : function( layoutManager, root, parent ){ - this.layoutManager = layoutManager; - this._root = _root; - this.paintList = []; - if( _parent ) this._parent = _parent; - }, - mesure : function(){ - this.layoutManager.reflow( this ); - }, - paintReserve : function( nodeData ){ - var list = this.paintList; - if( Util.getIndex( list, nodeData ) === -1 ) list[ list.length - 1 ] = nodeData; - }, - paintRelease : function( nodeData ){ - var list = this.paintList, - i = Util.getIndex( list, nodeData ); - i === -1 && list.splice( i, 1 ); - }, - paint : function(){ - var list = this.paintList, i = list.length; - for( ; i; ){ - list[ --i ].paint(); - }; - } - } - ); - - var LayoutBox = Node.inherits( - 'LayoutBox', - Class.POOL_OBJECT, - LayoutBoxPrivate, - { - Constructor : function( layoutManager, root, parent ){ - LayoutBox.newPrivateData( this, layoutManager, LayoutBox.getPrivateData( root ), parent ? LayoutBox.getPrivateData( parent ) : undefined ); - }, - layoutManager : function( v ){ - - }, - createLayoutBox : function(){ - - }, - createContentBox : function(){ - - } - } - ); - - var RootNode = Node.inherits( - 'RootNode', - Class.POOL_OBJECT, - LayoutBoxPrivate, - { - Constructor : function(){ - RootNode.newPrivateData( this, BasicLayoutManager ); - } - } - ); - -})( window, document ); - -})( window, document ); +/* + * pettanR system.js + * version 0.5.47 + * + * gadgetOS + * author: + * itozyun + * licence: + * 3-clause BSD + */ + +( function( window, document, undefined ){ + + var body = document.getElementsByTagName( 'body' )[ 0 ]; //( document.compatMode || '' ) !== 'CSS1Compat' ? document.body : document.documentElement;// + var SERVICE_LIST = []; + var SUPER_USER_KEY = { getUID: function(){ return 0; }}; + var API_USER_LIST = [ SUPER_USER_KEY ]; + var numApiUser = 1; + + function EMPTY_FUNCTION(){}; + + function isApiUser( _user ){ + return _user === SUPER_USER_KEY || + File.isDriver( _user ) === true || + Application.isApplicationInstance( _user ) === true; + }; + + var Const = { + FILE: { + TYPE: { + UNKNOWN: 0, + FOLDER: 1, + IMAGE: 2, + TEXT: 3, + HTML: 4, + CSV: 5, + JSON: 6, + XML: 7 + }, + STATE: { + UNKNOWN: 0, + OK: 1, + LOADING: 2, + ERROR: 3, + BROKEN: 4 + }, + UPDATE_POLICY: { + _____: parseInt( '00000', 2 ), + ____C: parseInt( '00001', 2 ), // hasCreateMenu + ___W_: parseInt( '00010', 2 ), // isWritable + ___WC: parseInt( '00011', 2 ), // isWritable + __R__: parseInt( '00100', 2 ), // isRenamable + __R_C: parseInt( '00101', 2 ), // hasCreateMenu + __RW_: parseInt( '00110', 2 ), // isWritable + __RWC: parseInt( '00111', 2 ), // isWritable + _S___: parseInt( '01000', 2 ), // childrenIsSortable + _S__C: parseInt( '01001', 2 ), + _S_W_: parseInt( '01010', 2 ), + _S_WC: parseInt( '01011', 2 ), + _SR__: parseInt( '01100', 2 ), + _SR_C: parseInt( '01101', 2 ), + _SRW_: parseInt( '01110', 2 ), + _SRWC: parseInt( '01111', 2 ), + D____: parseInt( '10000', 2 ), + D___C: parseInt( '10001', 2 ), // hasCreateMenu + D__W_: parseInt( '10010', 2 ), // isWritable + D__WC: parseInt( '10011', 2 ), // isWritable + D_R__: parseInt( '10100', 2 ), // isRenamable + D_R_C: parseInt( '10101', 2 ), // hasCreateMenu + D_RW_: parseInt( '10110', 2 ), // isWritable + D_RWC: parseInt( '10111', 2 ), // isWritable + DS___: parseInt( '11000', 2 ), // childrenIsSortable + DS__C: parseInt( '11001', 2 ), + DS_W_: parseInt( '11010', 2 ), + DS_WC: parseInt( '11011', 2 ), + DSR__: parseInt( '11100', 2 ), + DSR_C: parseInt( '11101', 2 ), + DSRW_: parseInt( '11110', 2 ), + DSRWC: parseInt( '11111', 2 ), + CREATE: 1, + WRAITE: 2, + RENAME: 4, + SORT: 8, + DELETE: 16 + }, + EVENT: { + UPDATE_ATTRIVUTE: 'onFileUpdate', + GET_SEQENTIAL_FILES:'gotSeqentilFiles' + }, + DATA_PROPERTY_RESERVED: [ + 'children', 'driver', 'state', 'type' + ] + }, + TREE: { + EVENT: { + UPDATE: 'onTreeUpdate' + } + }, + KEY: { + EVENT: { + KEY_DOWN: 'keydown', + KEY_UP: 'keyup', + KEY_CHANGE: 'keychange', + CURSOL: 'cursol' + } + }, + APP: { + TYPE: { + GENERAL : 0, + OVERLAY : 1, + PAGE : 2 + } + } + }; + +/** + * Class を定義し システムの管理下に置く. + * 全てのクラスと pool が有効の場合インスタンスへの参照が保持される. + * 1. Class.create( def, opt_final, opt_pool, opt_abstract ) でクラスを登録. + * 2. コンストラクタ となるメソッドは、Constructor : function( arg ){ ... }, に書く. + * 3. 通常通り new で インスタンス生成 + * 4. kill() でオブジェクトをクリーンして削除、pool が有効の場合は pool される. + * 5. pool が有効の場合、new で pool されたインスタンスが返される. + * 6. + * + */ +var Class = ( function(){ + var CLASS_LIST = [], + DEF_LIST = [], + PRIVATE_CLASS_LIST = [], + PRIVATE_DEF_LIST = [], + CONSTRUCTOR = 'Constructor', + GET_INDEX = Util.getIndex, + killPrivateFlag = false, + dataUser = null, + traits = null, + f = true, + copyArray = Util.copyArray; + + function getClass( instance ){ + var cList = CLASS_LIST, + i = cList.length, + klass; + for( ; i; ){ + klass = cList[ --i ]; + if( instance instanceof klass ) return klass; + }; + cList = PRIVATE_CLASS_LIST; + i = cList.length; + for( ; i; ){ + klass = cList[ --i ]; + if( instance instanceof klass ) return klass; + }; + + if( GET_INDEX( cList, instance ) !== -1 ) return instance; + if( GET_INDEX( CLASS_LIST, instance ) !== -1 ) return instance; + }; + + function getClassDef( KlassOrInstance ){ + var getIndex = GET_INDEX, + i = getIndex( CLASS_LIST, KlassOrInstance ); + if( i === -1 ) i = getIndex( CLASS_LIST, getClass( KlassOrInstance ) ); + if( i !== -1 ) return DEF_LIST[ i ]; + + i = getIndex( PRIVATE_CLASS_LIST, KlassOrInstance ); + if( i === -1 ) i = getIndex( PRIVATE_CLASS_LIST, getClass( KlassOrInstance ) ); + if( i !== -1 ) return PRIVATE_DEF_LIST[ i ]; + + if( GET_INDEX( DEF_LIST, KlassOrInstance ) !== -1 ) return KlassOrInstance; + if( GET_INDEX( PRIVATE_DEF_LIST, KlassOrInstance ) !== -1 ) return KlassOrInstance; + }; + + /* over のプロパティを target にコピーする.ただし target の プロパティが優先, force で解除 */ + function override( target, over, force ){ + for( var p in over ){ + if( force === true || typeof target[ p ] === 'undefined' ){ + target[ p ] = over[ p ]; + }; + }; + return target; + }; + + /* サブクラスを作るメソッド + * var subClass = superClass.inherits( ... ) + * http://d.hatena.ne.jp/m-hiyama/20051018/1129605002 + */ + function inherits( /* displayName, classSetting, opt_PrivateClass, props */ ){ + var args = copyArray( arguments ), + params = [], + Super = this, + superDef = getClassDef( Super ), + displayName = args[ 0 ], + classSetting, + opt_super, + klass; + if( superDef.Final === true ) throw new Error( 'Class is final!' ); + + if( Type.isString( displayName ) === true ){ + args.shift(); + } else { + displayName = 'SubClass of ' + superDef.displayName; + }; + params.push( displayName ); + + classSetting = args[ 0 ]; + if( Type.isNumber( classSetting ) === true ){ + if( superDef.isPrivate === true ) classSetting = classSetting | Class.PRIVATE_DATA; + opt_super = !!( classSetting & Class.SUPER_ACCESS ); + params.push( classSetting ); + args.shift(); + }; + if( getClass( args[ 0 ] ) ){ + params.push( args.shift() ); + } else + if( superDef.privateClass ){ + params.push( superDef.privateClass ); + }; + params.push( args[ 0 ] ); /* props */ + f = false; + traits = new Super(); + f = true; + klass = Class.create.apply( Class, params ); + traits = null; + if( opt_super === true ) getClassDef( klass ).Super = Super.prototype; + return klass; + }; + + /* Class.create で作られたクラスのインスタンスが共通で備えるメソッド */ + var CommonProps = { + kill : function(){ + var instance = this, + klass = getClass( instance ), + def = getClassDef( klass ), + data, p, i; + if( def.isPrivate === true && killPrivateFlag === false ){ + throw new Error( 'PrivateInstance.kill() work in PrivateUser.kill().' ); + }; + Type.isFunction( instance.onKill ) === true && instance.onKill(); + for( p in instance ){ + if( instance.hasOwnProperty && !instance.hasOwnProperty( p ) ) continue; + delete instance[ p ]; + }; + if( def.pool ){ + def.live && def.live.splice( GET_INDEX( def.live, instance ), 1 ); + def.pool.push( instance ); + }; + if( def.privateClass ){ + i = GET_INDEX( def.userList, instance ); + if( i !== -1 ){ + data = klass.getPrivateData( instance ); + killPrivateFlag = true; + data.kill(); + killPrivateFlag = false; + def.dataList.splice( i, 1 ); + def.userList.splice( i, 1 ); + }; + }; + // myCallback の削除 + // myCallback を受け取った API への通知 + }, + getMyCallback : function( callback ){ + var def = getClassDef( this ), + iList = def.callbackInstanceList, + rList = def.callbackRegisterList, + i, cList, myCallback; + if( !iList ){ + iList = def.callbackInstanceList = []; + rList = def.callbackRegisterList = []; + }; + i = GET_INDEX( iList, this ); + if( i === -1 ){ + cList = []; + iList.push( this ); + rList.push( cList ); + } else { + cList = rList[ i ]; + for( i = cList.length; i; ){ + if( cList[ --i ].callback === callback ) return cList[ i ]; + }; + }; + myCallback = new Callback( this, callback ); + cList.push( myCallback ); + return myCallback; + }, + releaseMyCallback : function( callback ){ + var def = getClassDef( this ), + iList = def.callbackInstanceList, + rList = def.callbackRegisterList, + i, _i, cList; + if( !iList ) return; + i = GET_INDEX( iList, this ); + if( i === -1 ) return; + cList = rList[ i ]; + _i = GET_INDEX( cList, callback ); + if( _i === -1 ) return; + cList.splice( _i, 1 ); + callback.kill(); + if( cList.length !== 0 ) return; + iList.splice( i, 1 ); + rList.splice( i, 1 ); + if( iList.length !== 0 ) return; + delete def.callbackInstanceList; + delete def.callbackRegisterList; + } + }; + + /* privateDataclass をもつクラスに追加されるメソッド */ + function newPrivateData( /* instance, args */ ){ + var args = copyArray( arguments ), + user = args.shift(), + def = getClassDef( user ), + privateClass = def.privateClass, + privateDef = getClassDef( privateClass ), + i = -1, + data; + if( def.userList ){ + i = GET_INDEX( def.userList, user ); + } else { + def.userList = []; + def.dataList = []; + }; + if( i !== -1 ){ + throw new Error( 'PrivateData already exist!' ); + }; + dataUser = user; + data = new privateClass( args ); + data.User = user; + dataUser = null; + return data; + }; + function getPrivateData( instance ){ + var def = getClassDef( instance ), + i = GET_INDEX( def.userList, instance ); + if( i !== -1 ) return def.dataList[ i ]; + }; + + /* + * new の実体.コンストラクタの機能は instance.Constructor に書く. + * これにより pool された オブジェクト(破棄されたインスタンス) を再利用できる + */ + /* Constructor Real for GeneralClass */ + function C( args ){ + var klass = this, + def = getClassDef( klass ), + instance, + userDef; + if( def.Abstract === true ){ + throw new Error( 'AbstractClass!' ); + }; + if( def.isPrivate === true && dataUser === null ){ + throw new Error( 'use myClass.newPrivateData( instance, ...args )!' ); + }; + f = false; + instance = def.pool && def.pool.length > 0 ? def.pool.shift() : instance = new klass(); + f = true; + if( def.Super && !instance.Super ) instance.Super = def.Super; + if( def.isPrivate === true ){ + userDef = getClassDef( dataUser ); + userDef.dataList.push( instance ); + userDef.userList.push( dataUser ); + } else { + def.live && def.live.push( instance ); + args = copyArray( arguments ); + }; + def[ CONSTRUCTOR ] && def[ CONSTRUCTOR ].apply( instance, args ); + return instance; + }; + + return { + POOL_OBJECT : 1, + ABSTRACT : 2, + FINAL : 4, + SUPER_ACCESS : 8, + PRIVATE_DATA : 16, + create : function( /* displayName, classSetting, opt_PrivateClass, props */ ){ + var args = copyArray( arguments ), + displayName = args[ 0 ], + classSetting, + opt_pool, opt_abstract, opt_final, opt_private, + privateDef, + props, + klass, + classDef = {}; + if( Type.isString( displayName ) === true ){ + classDef.displayName = displayName; + args.shift(); + }; + classSetting = args[ 0 ]; + if( Type.isNumber( classSetting ) === true ){ + opt_pool = !!( classSetting & Class.POOL_OBJECT ); + opt_abstract = !!( classSetting & Class.ABSTRACT ); + opt_final = !!( classSetting & Class.FINAL ); + opt_private = !!( classSetting & Class.PRIVATE_DATA ); + if( opt_final === true && opt_abstract === true ){ + throw new Error( 'final & Abstract!' ); + }; + args.shift(); + }; + + if( GET_INDEX( PRIVATE_CLASS_LIST, args[ 0 ] ) !== -1 ){ + privateDef = getClassDef( args[ 0 ] ); + if( privateDef.isPrivate !== true ){ + throw new Error( 'PrivateClass not found! please, Class.create( Class.PRIVATE, {...} ).' ); + } else + if( privateDef.Abstract === true ){ + throw new Error( 'PrivateClass is Abstract!' ); + }; + classDef.privateClass = args.shift(); + }; + props = args[ 0 ]; + if( props === null || Type.isObject( props ) === false ){ + throw new Error( 'No Class Def!' ); + }; + + if( Type.isFunction( props[ CONSTRUCTOR ] ) === true ){ + classDef[ CONSTRUCTOR ] = props[ CONSTRUCTOR ]; + }; + + klass = function(){ var a = arguments; if( f ) return C.apply( a.callee, a )}; + klass.prototype = override( override( traits || {}, props, true ), CommonProps, false ); + + if( opt_abstract === true ){ + classDef.Abstract = true; + } else + if( opt_pool === true ){ + classDef.pool = []; + if( opt_private === false )classDef.live = []; + }; + if( opt_final === true ){ + classDef.Final = true; + } else { + klass.inherits = inherits; + }; + if( opt_private === true ){ + if( classDef.privateClass ){ + throw new Error( 'Private Data Class has no PrivateClass!' ); + }; + classDef.isPrivate = true; + PRIVATE_CLASS_LIST.push( klass ); + PRIVATE_DEF_LIST.push( classDef ); + } else { + if( classDef.privateClass ){ + klass.newPrivateData = newPrivateData; + klass.getPrivateData = getPrivateData; + }; + CLASS_LIST.push( klass ); + DEF_LIST.push( classDef ); + }; + return klass; + }, + onShutdown : function(){ + + }, + getClass : function( instance ){ + return getClass( instance ); + }, + getClassDef : function(){ + + } + }; +})(); + +/** + * Callback 時に thisObject や args を指定したい場合に使用. + */ +var Callback = Class.create( + Class.POOL_OBJECT | Class.FINAL, { + Constructor : function( thisObject, callback, opt_args ){ + if( Type.isFunction( callback ) === false ){ + throw new Error( 'Not function!' ); + }; + this.callback = callback; + if( thisObject ) this.thisObject = thisObject; + if( Type.isArray( opt_args ) === true ){ + this.args = opt_args; + } else + if( opt_args !== undefined ){ + this.arg = opt_args; + }; + }, + fire : function( /* args */ ){ + var thisObject = this.thisObject || window, + args = Util.copyArray( arguments ); + if( 0 < args.length ){ + if( this.args !== undefined ){ + args.push.apply( args, this.args ); + } else + if( this.arg !== undefined ){ + args.push( this.arg ); + }; + this.callback.apply( thisObject, args ); + } else { + if( this.args !== undefined ){ + this.callback.apply( thisObject, this.args ); + } else + if( this.arg !== undefined ){ + this.callback.call( thisObject, this.arg ); + } else { + this.callback.call( thisObject ); + }; + }; + }, + registerUser : function( user ){ + if( !this.userList ){ + this.userList = [ user ]; + } else { + Util.getIndex( this.userList, user ) === -1 && this.userList.push( user ); + }; + }, + onKill : function(){ + var instance = this.thisObject; + this.userList && Class.getClass( instance ) && instance.releaseMyCalllback( this ); + } +}); + + +/* -------------------------------------------------------------- + * System Timer + * + */ + +var SystemTimer = ( function(){ + var setTimeout = window.setTimeout; + var clearTimeout = window.clearTimeout; + var INTERVAL_TIME = 16; + var TICKET_LIST = []; + var timerId = undefined; + var next = 0; + + function loop(){ + var i = 0, + list = TICKET_LIST; + for( i = 0; i < list.length; ){ + if( list[ i ].fire( next ) !== false ) ++i; + }; + timerId = undefined; + update(); + }; + function update(){ + var list = TICKET_LIST, + l = list.length, + n = 99999999, + c; + if( l === 0 ){ + timerId !== undefined && clearTimeout( timerId ); + timerId = undefined; + return; + }; + for( ; l; ){ + c = list[ --l ].count; + if( n > c ) n = c; + }; + if( next > n || timerId === undefined ){ + timerId !== undefined && clearTimeout( timerId ); + timerId = setTimeout( loop, INTERVAL_TIME * n ); + next = n; + }; + }; + + var TimerTicket = Class.create( + Class.POOL_OBJECT, { + Constructor : function( apiuser, callback, time, once, opt_thisObject ){ + this.apiuser = apiuser; + this.callback = callback; + this.time = time; + this.count = time; + if( once ) this.once = once; + this.thisObj = opt_thisObject || apiuser; + }, + fire : function( c ){ + this.count -= c; + if( 0 < this.count ) return; + this.callback.call( this.thisObj ); + if( this.once === true ){ + this.destroy(); + TICKET_LIST.splice( Util.getIndex( TICKET_LIST, this ), 1 ); + return false; + } else { + this.count = this.time; + }; + }, + destroy : function( apiuser, callback ){ + if( apiuser && apiuser !== this.apiuser ) return false; + if( callback && callback !== this.callback ) return false; + + this.kill(); + return true; + } + } + ); + + return { + add: function( _apiuser, _handler, _time, _once, opt_thisObject ){ + if( Type.isNumber( _time ) === false || _time < INTERVAL_TIME ) _time = INTERVAL_TIME; + + var _ticket = new TimerTicket( _apiuser, _handler, Math.ceil( _time / INTERVAL_TIME ), _once, opt_thisObject ); + TICKET_LIST.push( _ticket ); + + update(); + }, + remove: function( _apiuser, _handler ){ + var _ticket, + i = 0; + while( _ticket = TICKET_LIST[ i ] ){ + if( _ticket.destroy( _apiuser, _handler ) === true ){ + TICKET_LIST.splice( i, 1 ); + } else { + ++i; + }; + }; + update(); + } + }; +})(); + +/* -------------------------------------------------------------- + * Async Callback + * + */ +var AsyncCall = ( function(){ + var CALLBACK_LIST = []; + + var CallbackTicket = Class.create( + Class.POOL_OBJECT, { + Constructor : function( apiuser, callback, args, thisObject ){ + this.apiuser = apiuser; + this.callback = callback; + this.args = args; + this.thisObj = thisObject || apiuser; + }, + fire : function(){ + var f = this.callback, + a = this.args, + t = this.thisObj; + this.destroy(); + if( Type.isArray( a ) === true ){ + f.apply( t, a ); + } else { + f.call( t, a ); + }; + }, + destroy : function( apiuser, callback ){ + if( apiuser && apiuser !== this.apiuser ) return false; + if( callback && callback !== this.callback ) return false; + + this.kill(); + return true; + } + }); + + function dispatch(){ + var _ticket = CALLBACK_LIST.shift(); + if( _ticket ){ + _ticket.fire(); + CALLBACK_LIST.length !== 0 && SystemTimer.add( SUPER_USER_KEY, dispatch, 1, true ); + }; + }; + + return { + add: function( _apiuser, _callback, _argments, _thisObject ){ + CALLBACK_LIST.length === 0 && SystemTimer.add( SUPER_USER_KEY, dispatch, 1, true ); + CALLBACK_LIST.push( new CallbackTicket( _apiuser, _callback, _argments, _thisObject ) ); + }, + remove: function( _apiuser, _callback ){ + var _ticket, + i = 0; + while( _ticket = CALLBACK_LIST[ i ] ){ + if( _ticket.destroy( _apiuser, _callback ) === true ){ + CALLBACK_LIST.splice( i, 1 ); + } else { + ++i; + }; + }; + } + }; +})(); + +/* ----------------------------------------------------------- + * 画像一覧は + * お気に入り画像一覧 > tag:ペン次郎 > ペン次郎:笑う + * 最近アップロードされた画像 > images + * 最近使われた画像 > images + * キャラクター画像庫 > アニマル系 > tag:ペン次郎 > ペン次郎:笑う + * 風景画像庫 > + * 効果画像庫 > + * アイテム画像庫 > + * + * 画像一覧を読み込むタイミング + */ +var File = ( function(){ + var DRIVER_LIST = []; + + var FILE_TYPE_IS_FOLDER = Const.FILE.TYPE.FOLDER, + numFileType = Const.FILE.TYPE.XML, + FILEDATA_RESITER = [], // store all of fileData( json object ) + FILEDATA_ACCESS = [], // file operations for Kernel only ! hide from Out of File + FILE_OBJECT_POOL = [], + EVENT_LISTENER_REGISTER = [], + TREE_ARRAY = [], + TREE_ACCESS_ARRAY = []; + + var REQUEST_CONTROLER = ( function(){ + var REQUEST_TICKET_RESISTER = [], + currentTicket = null, + currentData = null, + DATA_TYPE_ARRAY = 'json,xml,html,text'.split( ',' ), + DATA_IS_JSON = 0, + DATA_IS_XML = 1, + DATA_IS_HTML = 2, + DATA_IS_TEXT = 3, + numError = 0; + + var RequestTicket = Class.create( + Class.POOL_OBJECT, { + Constructor : function( apiuser, type, data, url, onLoad, onError ){ + this.apiuser = apiuser; + this.type = type; + this.data = data; + this.url = url; + this.onLoad = onLoad; + this.onError = onError; + this.state = 0; + }, + load : function( data ){ + AsyncCall.add( this.apiuser, this.onLoad, [ this.data, data ] ); + }, + error : function(){ + AsyncCall.add( this.apiuser, this.onError, this.data ); + } + }); + + function request(){ + if( currentTicket !== null || REQUEST_TICKET_RESISTER.length === 0 ) return; + currentTicket = REQUEST_TICKET_RESISTER.shift(); + $.ajax({ + url: currentTicket.url, + dataType: DATA_TYPE_ARRAY[ currentTicket.type ], + success: onSuccess, + error: onError + }); + }; + function onSuccess( _data ){ + currentTicket.load( _data ); + currentTicket.kill(); + currentTicket = null; + request(); + }; + function onError(){ + ++numError; + currentTicket.error(); + currentTicket.kill(); // retry + currentTicket = null; + request(); + }; + + return { + getNumTask: function(){ + return REQUEST_TICKET_RESISTER.length; + }, + getNumError: function(){ + return numError; + }, + getJson: function( _apiuser, _data, _url, _onLoad, _onError ){ + REQUEST_TICKET_RESISTER.push( new RequestTicket( _apiuser, DATA_IS_JSON, _data, _url, _onLoad, _onError )); + currentTicket === null && request(); + } + }; + })(); + + var FILE_CONTROLER = { + createTree: function( _apiuser, _rootFileData ){ + var _tree = new TreeClass( _apiuser, _rootFileData ); + TREE_ARRAY.push( _tree ); + return _tree; + }, + getFileUID: function( FILEDATAorFILE ){ + if( FILEDATAorFILE instanceof FileClass ){ + return FILEDATAorFILE.getUID(); + }; + + var uid = Util.getIndex( FILEDATA_RESITER, FILEDATAorFILE ); + if( uid === -1 ){ + uid = FILEDATA_RESITER.length; + FILEDATA_RESITER.push( FILEDATAorFILE ); + }; + return uid; + }, + getFileDataAccess: function( UIDorFILEorFILEDATA ){ + var _uid, _data = FILE_CONTROLER.getFileData( UIDorFILEorFILEDATA ), _access; + + if( _data === null || typeof _data !== 'object' ) return null; + for( var i=0, l = FILEDATA_ACCESS.length; i= _bit; + }, + move: function( _prentUID, _targetfile, _newFolder, _newIndex, _opt_callback ){ + var _parentData = FILE_CONTROLER.getFileDataAccess( _prentUID ), + _parentType = _parentData.TYPE, + _targetData = FILE_CONTROLER.getFileDataAccess( _targetfile ), + _targetType = _targetData.TYPE; + }, + replace: function( _uid, _file, _newIndex ){ + + }, + addEventListener: function( FILEorNULL, _eventType, _callback, opt_thisObject ){ + var _uid = FILEorNULL instanceof FileClass ? FILEorNULL.getUID() : FILEorNULL; + EVENT_LISTENER_REGISTER.push( new FileEventTicket( _uid, _eventType, _callback, opt_thisObject )); + }, + removeEventListener: function( FILEorNULL, eventType, callback ){ + var uid = FILEorNULL instanceof FileClass ? FILEorNULL.getUID() : FILEorNULL, + list = EVENT_LISTENER_REGISTER, + i = 0, + ticket; + for( ; i < list.length; ){ + ticket = list[ i ]; + if( ticket.fileUID === uid && ticket.eventType === eventType && ticket.callBack === callback ){ + list.splice( i, 1 ); + ticket.kill(); + } else { + ++i; + }; + }; + }, + getTreeAccess: function(){ + + }, + fileEventRellay: function( _uid, _event ){ + var _fileAccess = FILE_CONTROLER.getFileDataAccess( _uid ); + if( _fileAccess === null ) return; + var _treeUID = _fileAccess.TREE.getUID(), + _treeAccess = TREE_ACCESS_ARRAY[ _treeUID ], + _data = _fileAccess.DATA, + _tree; + if( !_treeAccess ) return; + _treeAccess.dispatchFileEvent( _event ); + for( var i=0, l = TREE_ARRAY.length; i= l ) return null; + return PARENT_FILE_RESITER[ l -1 -_index ]; + }; + this.down = function( _index ){ + if( typeof _index !== 'number' || _index < 0 || _index >= currentFile.getChildFileLength()) return; + PARENT_FILE_RESITER.unshift( currentFile ); + currentFile = currentFile.getChildFileAt( _index ); + currentFile.getSeqentialFiles(); + return currentFile; + }; + this.up = function( _index ){ + var l = PARENT_FILE_RESITER.length; + if( l === 0 ) return null; + + if( currentFile ){ + var _currentFile = currentFile; + currentFile = null; + _currentFile.destroy(); + }; + if( typeof _index === 'number' ){ + if( _index >= l ) return null; + currentFile = this.getParentFileAt( _index ); + PARENT_FILE_RESITER.splice( 0, l -_index); + } else { + currentFile = PARENT_FILE_RESITER.shift(); + }; + currentFile.getSeqentialFiles(); + return currentFile; + }; + this.addTreeEventListener = function( _eventType, _callback, opt_thisObject ){ + FILE_CONTROLER.addEventListener( null, _eventType, _callback, opt_thisObject ); + }; + this.removeTreeEventListener = function( _eventType, _callback ){ + FILE_CONTROLER.removeEventListener( null, _eventType, _callback ); + }; + this.destroy = function( _apiuser ){ + if( _apiuser && apiuser !== _apiuser ) return false; + // removeEvent + var _currentFile = currentFile; + currentFile = rootFile = rootFileData = null; + // currentFile, rootFile を null にしないと .File.destroy() ができない. + _currentFile.destroy(); + while( PARENT_FILE_RESITER.length > 0 ){ + _currentFile = PARENT_FILE_RESITER.shift(); + _currentFile.destroy(); + }; + + AsyncCall.remove( apiuser ); + instance = apiuser = null; + return true; + }; + }; + + var FileEventTicket = Class.create( + Class.POOL_OBJECT, { + Constructor : function( uid, eventType, callback, opt_thisObject ){ + this.fileUID = uid; + this.eventType = eventType; + this.callBack = callback; + this.thisObject = opt_thisObject; + } + }); + + var FileEventClass = function( eventType, file, key, value ){ + this.eventType = eventType; + this.targetFile = file; + this.updatedAttribute = key; + this.updatedValue = value; + }; + +/* + * file の data は object で保持している。 + * File の外からファイルをみるときは、FileClassを通して操作する。 + * fileの変更、それに付随して追加されたイベントは、TreeClassで管理される。 + * treeがdestryされると、fileのイベントリスナーも全て削除される。 + * 他の tree も data の共通する currentFile に対してのみは、file の変更イベントを受け取って流す. + * + */ + + var FileClass = function( tree, parentData, data ){ + var uid = FILE_CONTROLER.getFileUID( data ); + + FILEDATA_ACCESS.push( { + TREE: tree, + parentData: parentData, + DATA: data + } ); + + tree = parentData = data = null; + + this.getUID = function(){ + return uid; + }; + }; + + FileClass.prototype = { + isChildFile: function( _FILEorFILEDATA ){ + return this.getChildFileIndex( _FILEorFILEDATA) !== -1; + }, + getSeqentialFiles: function(){ + var _driver = FILE_CONTROLER.getDriver( this ); + if( _driver !== null && typeof _driver.getSeqentialFiles === 'function' ){ + _driver.getSeqentialFiles( this ); + } + }, + addEventListener: function( _eventType, _callback ){ + FILE_CONTROLER.addEventListener( this, _eventType, _callback ); + }, + removeEventListener: function( _eventType, _callback ){ + FILE_CONTROLER.removeEventListener( this, _eventType, _callback ); + }, + dispatchEvent: function( e ){ + e instanceof FileEventClass && FILE_CONTROLER.fileEventRellay( this.getUID(), e ); + }, + getChildFileLength: function(){ + var children = FILE_CONTROLER.getChildren( this ); + return Type.isArray( children ) === true ? children.length : -1; + }, + getChildFileIndex: function( _FILEorFILEDATA ){ + var children = FILE_CONTROLER.getChildren( this ); + if( Type.isArray( children ) === false ) return -1; + var l = children.length, + _fileData = FILE_CONTROLER.getFileData( _FILEorFILEDATA ); + if( _fileData === null ) return -1; + for( var i=0; i= _children.length ) return null; + var _file = new FileClass( _access.TREE, _access.DATA, _children[ _index ]); + // _file.init(); + return _file; + }, + getName: function(){ + var driver = FILE_CONTROLER.getDriver( this ); + if( typeof driver.getName === 'function'){ + return driver.getName( this ); + } + return BASE_DRIVER.getName( this ); + }, + getThumbnail: function(){ + var driver = FILE_CONTROLER.getDriver( this ); + if( typeof driver.getThumbnail === 'function'){ + return driver.getThumbnail( this ); + } + return BASE_DRIVER.getThumbnail( this ); + }, + getType: function(){ + var _data = FILE_CONTROLER.getFileData( this ); + return typeof _data.type === 'number' ? _data.type : Const.FILE.TYPE.UNKNOWN; + }, + getState: function(){ + var _data = FILE_CONTROLER.getFileData( this ); + return typeof _data.state === 'number' ? _data.state : Const.FILE.STATE.OK; + }, + getSummary: function(){ + var driver = FILE_CONTROLER.getDriver( this ); + if( typeof driver.getSummary === 'function'){ + return driver.getSummary( this ); + } + return BASE_DRIVER.getSummary( this ); + }, + isWritable: function(){ + return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.WRITE ); + }, + isSortable: function(){ + return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.SORT ); + }, + isCreatable: function(){ + return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.CREATE ); + }, + isRenamable: function(){ + return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.RENAME ); + }, + isDeletable: function(){ + return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.DELETE ); + }, + read: function(){ + // simpleDeepCopy + var driver = FILE_CONTROLER.getDriver( this ), + data; + if( Type.isFunction( driver.read ) === true ){ + data = driver.read( this ); + }; + return BASE_DRIVER.read( data || this ); + }, + write: function( _newData, _onUpdateFunction ){ + var driver = FILE_CONTROLER.getDriver( this ); + if( typeof driver.write === 'function' ){ + return driver.write( this, _newData, _onUpdateFunction ); + }; + return BASE_DRIVER.write( this, _newData, _onUpdateFunction ); + }, + viewerApplicationList: function(){ + var driver = FILE_CONTROLER.getDriver( this ); + if( typeof driver.viewerApplicationList === 'function' ){ + return driver.viewerApplicationList( this ); + }; + return BASE_DRIVER.viewerApplicationList( this ); + }, + editorApplicationList: function(){ + var driver = FILE_CONTROLER.getDriver( this ); + if( typeof driver.editorApplicationList === 'function' ){ + return driver.editorApplicationList( this ); + }; + return BASE_DRIVER.viwerApps( this ); + }, + create: function(){ + + }, + sort: function(){ + + }, + onCopy: function(){ + + }, + onDelete: function(){ + + }, + move: function( _newFolder, _newIndex, opt_callback ){ + var _access = FILE_CONTROLER.getFileDataAccess( this ); + _access.TREE.move( _access.parentData, this.getUID(), _newFolder, _newIndex, opt_callback ); + }, + replace: function( _newIndex, opt_callback ){ + var _access = FILE_CONTROLER.getFileDataAccess( this ); + _access.TREE.replace( _access.parentData, this.getUID(), _newIndex, opt_callback); + }, + /** + * サーチ + * 探しているファイルの属性と値を指定.一致する child の index を配列で返す. + */ + search: function( obj, rule ){ + var _children = FILE_CONTROLER.getChildren( this ), + _child, + ret = [], k, c; + for( var i=0, l=_children.length; i this.w || this.application.MIN_HEIGHT > this.h ){ + if( Type.isHTMLElement( this.rootElement ) === true ){ + // 小さすぎる!、と表示 + }; + }; + if( this.bootParams.length > 2 ){ + this.application.onOpen.apply( this.application, this.bootParams ); + } else { + this.application.onOpen( this.w, this.h ); + }; + this.phase = 4; + }, + fetchResourceComplete : function(){ + --this.fetchResource; + } +}; +ApplicationPrivateData.list = []; +ApplicationPrivateData.get = function( app ){ + var list = ApplicationPrivateData.list, + i = list.length; + for( ; i; ){ + if( app instanceof list[ --i ].appClass ) return list[ i ]; + }; + return null; +}; + +var AbstractApplication = function( appClass, displayName, isOverlay ){ + ( new ApplicationPrivateData() ).init( appClass, displayName, isOverlay ); +}; +AbstractApplication.prototype = { + getUID : function(){ + var data = ApplicationPrivateData.get( this ); + return Util.getIndex( API_USER_LIST, data.appClass ); + }, + init : function(){ + var data = ApplicationPrivateData.get( this ); + // this.rootElement = data.rootElement; + // data.application = this; + data.phase = 1; + data.appClass === Page.appClass && Page.show(); + this.onInit(); + data.phase = 2; + }, + open : function( w, h /*, _option */ ){ + var data = ApplicationPrivateData.get( this ); + data.phase = 3; + data.bootParams = Util.copyArray( arguments ); + data.w = w; + data.h = h; + if( data.rootElement.innerHTML && data.rootElement.innerHTML.length > 0 ){ + SystemTimer.add( this, data.detect, 16, false, data ); + } else { + data.onOpen(); + }; + }, + resize : function( w, h ){ + var data = ApplicationPrivateData.get( this ); + if( data.phase !== 4 ) return; + if( this.MIN_WIDTH > w || this.MIN_HEIGHT > h ){ + if( Type.isHTMLElement( this.rootElement ) === true ){ + // 小さすぎる!、と表示 + }; + return; + }; + this.onPaneResize( w, h ); + }, + close : function(){ + var data = ApplicationPrivateData.get( this ); + data.phase = 5; + if( this.onClose() === false ){ + return false; + }; + if( data.uiList ){ + while( data.uiList.length > 0 ) data.uiList.shift().destroy(); + }; + if( data.finderList ){ + while( data.finderList.length > 0 ) data.finderList.shift().destroy(); + }; + + data.eventRoot && PointingDeviceEventTree.destroyTree( data.eventRoot ); + MouseEvent.remove( this ); + KeyEvent.remove( this ); + SystemTimer.remove( this ); + AsyncCall.remove( this ); + StyleSheet.unload( this ); + + var elm = this.rootElement; + Util.removeAllChildren( elm ); + elm.parentNode.removeChild( elm ); + + Application.shutdown( this, data.isOverlay ); + + data.appClass === Page.appClass && Page.hide(); + + data.phase = 6; + + var list = ApplicationPrivateData.list; + list.splice( Util.getIndex( list, data ), 1 ); + }, + createUIGroup : function( node ){ + var data = ApplicationPrivateData.get( this ), + ui = UI.createUIGroup( this, node ); + if( data.uiList === null ) data.uiList = []; + data.uiList.push( ui ); + return ui; + }, + createUIForm : function( nodeOrElm, opt_elmForm ){ + var data = ApplicationPrivateData.get( this ), + form = UIForm.createForm( this, nodeOrElm, opt_elmForm ); + if( data.formList === null ) data.formList = []; + data.formList.push( form ); + return form; + }, + createFinder : function( _elmTarget, _tree, _onSelect, _viewerOption, _editorOption ){ + var data = ApplicationPrivateData.get( this ), + finder = Finder.create( this, _elmTarget, _tree, _onSelect, _viewerOption, _editorOption ); + if( data.finderList === null ) data.finderList = []; + data.finderList.push( finder ); + return finder; + }, + createDHTML : function( _elm ){ + return DHTML.create( this, _elm ); + }, + addEventListener : function( element, eventType, handler, opt_thisObject ){ + MouseEvent.add( this, element, eventType, handler, opt_thisObject ); + }, + removeEventListener : function( element, eventType, handler ){ + MouseEvent.remove( this, element, eventType, handler ); + }, + getPointingDeviceEventTreeRoot : function(){ + var data = ApplicationPrivateData.get( this ); + if( data.phase === 1 ){ + data.eventRoot = PointingDeviceEventTree.create( this ); + data.styleCursor = PointingDeviceEventTree._getNodePrivateData( data.eventRoot ).elmMouseCatch.style; + }; + return data.eventRoot; + }, + updateCoursor : function( _cursor ){ + var data = ApplicationPrivateData.get( this ); + if( data.cursor !== _cursor ){ + data.styleCursor.cursor = data.cursor = _cursor; + }; + }, + fetchCSS : function( url, opt_onload, opt_onerror ){ + var data = ApplicationPrivateData.get( this ); + if( data.phase === 1 ){ + ++data.fetchResource; + StyleSheet.load( this, url, data.fetchResourceComplete, data.fetchResourceComplete, data ); + }; + }, + onInit : function(){}, + onOpen : function(){}, + onClose : function(){ return true; }, + onPaneResize : function( w, h ){}, + addKeyEventListener : function( _eventType, _handler, _keyCode, _shift, _ctrl ){ + KeyEvent.add( this, _eventType, _handler, _keyCode, _shift, _ctrl ); + }, + removeKeyEventListener : function( _eventType, _handler, _keyCode, _shift, _ctrl ){ + KeyEvent.remove( this, _eventType, _handler, _keyCode, _shift, _ctrl ); + }, + shiftEnabled : function(){ + return KeyEvent.shiftEnabled; + }, + ctrlEnabled : function(){ + return KeyEvent.ctrlEnabled; + }, + addTimer : function( handler, time, once ){ + SystemTimer.add( this, handler, time, !!once ); + }, + removeTimer : function( handler ){ + SystemTimer.remove( this, handler ); + }, + addAsyncCall : function( _callback, _argments, _thisObject ){ + AsyncCall.add( this, _callback, _argments, _thisObject ); + }, + removeAsyncCall : function( _callback ){ + AsyncCall.remove( this, _callback ); + }, + fetchHTMLElement : function( id ){ + var elm = document.getElementById( id ); + if( elm ){ + elm.removeAttribute( 'id' ); + elm.parentNode.removeChild( elm ); + return elm; + }; + } +}; + +var PointingDeviceEventTree = ( function(){ + var ROOT_LIST = [], + currentRootData = null, + targetNodeData = null, + forceNodeData = null, + hoverList = []; + + function eventRellay( e ){ + var data = forceNodeData, // || targetNodeData, + x = e.clientX, + y = e.clientY, + type = e.type, + list = hoverList, + i = 0, + ret, systemOnly = false, addClass, removeClass, + parent; + if( data && data.dispatchEvent( e, type, true ) === true ) return false; + if( currentRootData === null ) return; + targetNodeData = currentRootData; + currentRootData._capcher( x, y ); + targetNodeData.apiuser.updateCoursor( targetNodeData._cursor ); + data = targetNodeData; + while( data ){ + ret = data.dispatchEvent( e, type, true, systemOnly ); + if( ret === true || ret === false ) break; // systemOnly = true; + data = data.parentData; + }; + + addClass = Util.addClass; + removeClass = Util.removeClass; + for( ; i < list.length; ){ + parent = data = list[ i ]; + while( parent.parentData && parent === parent.parentData.hitChild ){ + parent = parent.parentData; + }; + if( parent !== currentRootData ){ + data.hover === true && removeClass( data.elm, data.hoverClass ); + delete data.isHover; + data.events && data.events.mouseout && data.fire( e, 'mouseout', false ); + delete data.hitSelf; + list.splice( i, 1 ); + continue; + }; + if( data.hover === true && data.isHover === false ){ + addClass( data.elm, data.hoverClass ); + data.isHover = true; + }; + if( data.hitSelf === false ){ + data.events && data.events.mouseover && data.fire( e, 'mouseover', true ); + data.hitSelf = true; + }; + ++i; + }; + return false; + }; + + var NodeClass = function( apiuser, rootData, /*parentLayer,*/ parentData, rangeOrElm, through, clip, hover, cursor, scroll, dragdrop ){ + ( new NodePrivateData() ).init( apiuser, rootData, /*parentLayer,*/ parentData, this, rangeOrElm, through, clip, hover, cursor, scroll, dragdrop ); + }; + NodeClass.prototype = { + createNode : function( rangeOrElmData, through, clip, hover, cursor, scroll, dragdrop ){ + var data = NodePrivateData.get( this ), + elm; + if( Type.isHTMLElement( rangeOrElmData ) === true ){ + elm = rangeOrElmData; + } else + if( Type.isString( rangeOrElmData ) === true ){ + elm = document.getElementById( rangeOrElmData ); + if( !elm ){ + elm = Util.pullHtmlAsTemplete( rangeOrElmData ); + }; + if( !elm || Type.isHTMLElement( elm ) === false || elm.nodeType !== 1 ){ + throw new Error( "invalid HTMLElement." ); + }; + } else + if( Type.isObject( rangeOrElmData ) === false || Type.isFinite( rangeOrElmData.x ) === false || Type.isFinite( rangeOrElmData.y ) === false ){ + throw new Error( "No range" ); + }; + + if( elm && data.elm === null ){ + throw new Error( "MetaLayer don't containe HTMLElement-Layer." ); + }; + if( data.elm && data.elm.style.hasLayout === false ){ + throw new Error( "[ie] OffsetParent is hasLayout === false." ); + }; + + var newNode = new NodeClass( data.apiuser, data.rootData, data, elm || rangeOrElmData, through, clip, hover, cursor, scroll, dragdrop ), + newData = NodePrivateData.get( newNode ); + + if( data.childData === null ) data.childData = []; + data.childData.push( newData ); + return newNode; + }, + createNodeAt : function(){ + }, + remove : function(){ + NodePrivateData.get( this ).remove(); + }, + nodeIndex : function( v ){ + return NodePrivateData.get( this ).nodeIndex( v ); + }, + numNode : function(){ + return NodePrivateData.get( this ).numNode(); + }, + disabled : function( v ){ + return NodePrivateData.get( this ).disabled( v ); + }, + childrenDisabled : function( v ){ + return NodePrivateData.get( this ).disabled( v ); + }, + mesure : function(){ + NodePrivateData.get( this ).mesure(); + }, + mesureChildren : function(){ + NodePrivateData.get( this ).mesureChildren(); + }, + update : function( x, y, w, h ){ + NodePrivateData.get( this ).update( x, y, w, h ); + }, + setPosition : function( x, y ){ + NodePrivateData.get( this ).setPosition( x, y ); + }, + setSize : function( w, h ){ + NodePrivateData.get( this ).setSize( w, h ); + }, + cursor : function( v ){ + return NodePrivateData.get( this ).cursor( v ); + }, + x : function( x ){ + return NodePrivateData.get( this ).positionX( x ); + }, + y : function( y ){ + return NodePrivateData.get( this ).positionY( y ); + }, + width : function( w ){ + return NodePrivateData.get( this ).width( w ); + }, + height : function( h ){ + return NodePrivateData.get( this ).height( h ); + }, + getAbsolutePositionX : function(){ + return NodePrivateData.get( this ).getAbsolutePositionX(); + }, + getAbsolutePositionY : function(){ + return NodePrivateData.get( this ).getAbsolutePositionY(); + }, + addEventListener : function( type, handler, opt_thisObject ){ + NodePrivateData.get( this ).addEventListener( type, handler, opt_thisObject ); + }, + removeEventListener : function( type, handler ){ + NodePrivateData.get( this ).removeEventListener( type, handler ); + }, + scrollTo : function( x, y ){ + NodePrivateData.get( this ).scrollTo( x, y ); + }, + scrollX : function( v ){ + return NodePrivateData.get( this ).scrollX( v ); + }, + scrollY : function( v ){ + return NodePrivateData.get( this ).scrollY( v ); + }, + invalidateScrollbar : function(){ + ScrollBarManager.update( NodePrivateData.get( this ) ); + } + }; + + /** + * clip : true の場合、子ノードの変更によってヒットエリアを変化させない.elm には overflow:hidden としておくのが通常. + */ + var NodePrivateData = function(){}; + NodePrivateData.prototype = { + elmMouseCatch : null, // rootData only + eventCounter : null, // rootData only + cursorStyle : null, // rootData only + node : null, + apiuser : null, + rootData : null, + elm : null, // resizeTarget + elmScroll : null, + elmScroller : null, + elmScrollbar : null, + x : 0, + y : 0, + w : 0, + h : 0, + t : 0, // top + l : 0, // left + b : 0, // bottom + r : 0, // right + absoluteX : 0, + absoluteY : 0, + _scrollX : 0, + _scrollY : 0, + scrollingX : 0, + scrollingY : 0, + _cursor : '', + // parentLayer : null, + parentData : null, + childData : null, + events : null, + hitChild : null, + hitSelf : false, + _disabled : false, + _childDisabled: false, + layoutManager : null, + through : false, + clip : false, + hover : false, + hoverClass : null, + isHover : false, + scroll : false, + dragdrop : false, + tooltip : null, + init: function( apiuser, rootData, /*parentLayer,*/ parentData, node, rangeOrElm, through, clip, hover, cursor, scroll, dragdrop ){ + this.apiuser = apiuser; + this.rootData = rootData || this; + // this.parentLayer = parentLayer; + this.parentData = parentData; + this.node = node; + this.through = through; + this.clip = !!clip; + if( cursor ) this._cursor = cursor; + + if( Type.isHTMLElement( rangeOrElm ) === true ){ + this.elm = rangeOrElm; + this.hover = !!hover; + this.hoverClass = hover; + this.scroll = clip && scroll; + this.mesure(); + this.scroll === true && ScrollBarManager.register( this ); + } else { + this.update( rangeOrElm.x, rangeOrElm.y, rangeOrElm.w, rangeOrElm.h ); + }; + + NodePrivateData.dataList.push( this ); + }, + mesure : function(){ + var x, y, w, h, parent, _this, _parent; + if( this.elm ){ + w = this.elm.offsetWidth; + h = this.elm.offsetHeight; + _this = Position.cumulativeOffset( this.elm ); + _parent = this.parentData ? Position.cumulativeOffset( this.parentData.elm ) : [ 0, 0 ]; + x = _this[ 0 ] - _parent[ 0 ]; + y = _this[ 1 ] - _parent[ 1 ]; + if( this.x !== x || this.y !== y || this.w !== w || this.h !== h ){ + this.x = x; + this.y = y; + this.w = w; + this.h = h; + parent = this.parentData; + parent && this._updateAbsoluteXY( parent.absoluteX, parent.absoluteY, parent.scrollingX, parent.scrollingY ); + this._updateRectangle(); + }; + } else { + this._updateRectangle(); + }; + }, + mesureChildren : function(){ + var nodes, i; + if( nodes = this.childData ){ + for( i = nodes.length; i; ){ + nodes[ --i ].mesure(); + }; + }; + }, + update : function( x, y, w, h ){ + var updateXY = false, + _this, _parent, + parent; + + if( this.elm ){ + // width + if( Type.isFinite( w ) === true ){ + this.elm.style.width = w + 'px'; + } else + if( Type.isString( w ) === true ){ + this.elm.style.width = w; + w = this.elm.offsetWidth; + }; + //update = this.w !== w; + + // height + if( Type.isFinite( h ) === true ){ + this.elm.style.height = h + 'px'; + } else + if( Type.isString( h ) === true ){ + this.elm.style.height = w; + h = this.elm.offsetHeight; + }; + //update = update || this.h !== h; + + // x + if( Type.isFinite( x ) === true ){ + this.elm.style.left = x + 'px'; + } else + if( Type.isString( x ) === true ){ + this.elm.style.left = x; + updateXY = true; + } else { + updateXY = true; + }; + + // y + if( Type.isFinite( y ) === true ){ + this.elm.style.top = y + 'px'; + } else + if( Type.isString( y ) === true ){ + this.elm.style.top = y; + updateXY = true; + } else { + updateXY = true; + }; + if( updateXY === true ){ + _this = Position.cumulativeOffset( this.elm ); + _parent = this.parentData ? Position.cumulativeOffset( this.parentData.elm ) : [ 0, 0 ]; + x = _this[ 0 ] - _parent[ 0 ]; + y = _this[ 1 ] - _parent[ 1 ]; + }; + //update = update || this.x !== x; + //update = update || this.y !== y; + + //update === true && this._updateRectangle(); + // return; + }; + x = Type.isFinite( x ) === true ? x : this.x; + y = Type.isFinite( y ) === true ? y : this.y; + w = Type.isFinite( w ) === true ? w : this.w; + h = Type.isFinite( h ) === true ? h : this.h; + if( this.x !== x || this.y !== y ){ + this.x = x; + this.y = y; + //console.log( 'xy ' + ( this.elm ? this.elm.id : '' ) + ' x:' + x + ' y:' + y + ' w:' + w + ' h:' + h + ' absX:' + this.parentData.absoluteX ) + parent = this.parentData; + parent && this._updateAbsoluteXY( parent.absoluteX, parent.absoluteY, parent.scrollingX, parent.scrollingY ); + this.w === w && this.h === h && this._updateRectangle(); + }; + if( this.w !== w || this.h !== h ){ + this.w = w; + this.h = h; + //console.log( 'wh ' + ( this.elm ? this.elm.id : '' ) + ' x:' + x + ' y:' + y + ' w:' + w + ' h:' + h ) + this._updateRectangle(); + }; + + ScrollBarManager.update( this ); + }, + _updateAbsoluteXY : function( x, y, sX, sY ){ + var nodes, i; + this.absoluteX = x = this.x + x; + this.absoluteY = y = this.y + y; + if( nodes = this.childData ){ + for( i = nodes.length; i; ){ + nodes[ --i ]._updateAbsoluteXY( x, y, this.scrollingX, this.scrollingY ); + }; + }; + }, + _updateRectangle : function(){ + var w = this.w, + h = this.h, + x = this.x, + y = this.y, + l = x, + t = y, + r = x + w, + b = y + h, + nodes = this.childData, + i, node; + // self; + // childnodes + if( this.clip === false && nodes ){ + for( i = nodes.length; i; ){ + node = nodes[ --i ]; + if( node.l + x < l ) l = x + node.l; + if( node.t + y < t ) t = y + node.t; + if( r < node.r + x ) r = x + node.r; + if( b < node.b + y ) b = y + node.b; + }; + }; + // update + if( b !== this.b || r !== this.r || t !== this.t || l !== this.l ){ + this.l = l; + this.t = t; + this.r = r; + this.b = b; + // this.w = r - x; + // this.h = b - y; + this.parentData && this.parentData.clip === false && this.parentData._updateRectangle(); + return true; + }; + }, + setPosition : function( x, y ){ + this.update( x, y ); + }, + setSize : function( w, h ){ + this.update( undefined, undefined, w, h ); + }, + positionX : function( x ){ + x !== undefined && this.update( x ); + return this.x; + }, + positionY : function( y ){ + y !== undefined && this.update( undefined, y ); + return this.y; + }, + width : function( w ){ + w !== undefined && this.update( undefined, undefined, w ); + return this.w; + }, + height : function( h ){ + h !== undefined && this.update( undefined, undefined, undefined, h ); + return this.h; + }, + getAbsolutePositionX : function(){ + return this.absoluteX; + }, + getAbsolutePositionY : function(){ + return this.absoluteY; + }, + cursor : function( v ){ + if( Type.isString( v ) === true ){ + this._cursor = v; + this === targetNodeData && this.apiuser.updateCoursor( v ); + }; + return this._cursor; + }, + addEventListener : function( eventType, handler, opt_thisObject ){ + var node = this.node, + counter = this.rootData.eventCounter, + list, i; + if( this.events === null ) this.events = {}; + list = this.events[ eventType ]; + if( !list ){ + list = this.events[ eventType ] = []; + } else { + for( i = list.length; i; ){ + if( list[ --i ].match( eventType, handler ) === true ){ + return; + }; + }; + }; + list.push( new EventTicketClass( this.node, eventType, handler, opt_thisObject ) ); + if( eventType !== 'mouseout' && eventType !== 'mouseover' ){ + if( counter[ eventType ] ){ + ++counter[ eventType ]; + } else { + //console.log( eventType ); + counter[ eventType ] = 1; + MouseEvent.add( this.apiuser, this.rootData.elmMouseCatch, eventType, eventRellay ); + }; + }; + }, + removeEventListener : function( eventType, handler ){ + var events = this.events, + counter = this.rootData.eventCounter, + type, list, i = 0; + if( events === null ) return; + console.log( ' *** remove ' + eventType ); + for( type in events ){ + list = events[ type ]; + if( eventType && eventType !== type ) continue; + for( ; i < list.length; ){ + if( list[ i ].destroy( type, handler ) === true ){ + console.log( ' *** removed! ' + type ); + list.splice( i, 1 ); + } else { + ++i; + }; + }; + if( list.length === 0 ){ + // delete this[ type ]; + delete events[ type ]; + }; + if( counter[ type ] ){ + --counter[ type ]; + if( counter[ type ] === 0 ){ + MouseEvent.remove( this.apiuser, this.rootData.elmMouseCatch, type, eventRellay ); + delete counter[ type ]; + }; + }; + }; + }, + _capcher : function( x, y ){ + var t = this, nodes, child, _x, _y, hit, i; + if( t._disabled === true ) return false; + delete t.hitChild; + x -= t.x; + y -= t.y; + if( nodes = t.childData ){ + _x = x - t.scrollingX; + _y = y - t.scrollingY; + for( i = nodes.length; i; ){ + child = nodes[ --i ]; + if( child._disabled === false && child.l <= _x && _x < child.r && child.t <= _y && _y < child.b && child._capcher( _x, _y ) === true ){ + t.hitChild = child; + break; + }; + }; + }; + if( t.through === true ){ + t.hitChild && t.hitSelf === false && hoverList.push( t ); + return !!t.hitChild; + }; + hit = 0 <= x && x < t.w && 0 <= y && y < t.h; + ( t.hitChild || hit ) && t.hitSelf === false && hoverList.push( t ); + if( hit === true && t.hitChild === null ) targetNodeData = t; + return hit || !!t.hitChild; + }, + fire : function( e, eventType, hit ){ + var list = this.events[ eventType ], + i = list.length; + e = NodePrivateData.createEvent( e, eventType, this, hit ); + for( ; i; ) list[ --i ].fire( e ); + // console.log( eventType + ' x:' + x + ' y:' + y ); + }, + dispatchEvent : function( e, eventType, hit ){ + var ret, list, i, p, child; + if( !this.events || !( list = this.events[ eventType ] ) ) return; + + child = !!this.hitChild; + e = NodePrivateData.createEvent( e, eventType, this, hit ); + for( i = list.length; i; ){ + ret = list[ --i ].fire( e ); + if( ret === true && child === false ){ + forceNodeData = this; + return true; + }; + if( ret === false ) return false; + }; + forceNodeData = null; + }, + scrollTo : function( x, y ){ + this._scrollX = x; + this._scrollY = y; + ScrollBarManager.update( this ); + }, + scrollX : function( v ){ + if( Type.isFinite( v ) === true ){ + this._scrillX = v; + ScrollBarManager.update( this ); + }; + return this.scrollingX; // this._scrollX; + }, + scrollY : function( v ){ + if( Type.isFinite( v ) === true ){ + this._scrillY = v; + ScrollBarManager.update( this ); + }; + return this.scrollingY; // this._scrollY; + }, + nodeIndex : function( v ){ + var list, i; + if( !this.parentData ) return 0; + + list = this.parentData.childData; + i = Util.getIndex( list, this ); + if( Type.isFinite( v ) === false || i === v && v < 0 && list.length <= v ) return i; + + list.splice( i, 1 ); + list.length === v ? list.push( this ) : list.splice( v, 0, this ); + this._free(); + return v; + }, + _free : function(){ + if( this.parentData.hitChild === this ){ + this.parentData.hitChild = null; + this.isHover === true && hoverList.splice( Util.getIndex( hoverList, this ), 1 ) && Util.removeClass( this.elm, this.hoverClass ); + this.isHover = false; + if( forceNodeData === this ) forceNodeData = null; + if( targetNodeData === this ) targetNodeData = null; + }; + }, + numNode : function(){ + return this.childData ? this.childData.length : 0; + }, + disabled : function( v ){ + if( Type.isBoolean( v ) === true ){ + this._disabled = v; + if( v === false ){ + this._free(); + }; + }; + return this._disabled; + }, + childrenDisabled : function( v ){ + if( Type.isBoolean( v ) === true ){ + this._childDisabled = v; + }; + return this._childDisabled; + }, + remove : function(){ + if( this === this.rootData ) return; + var parent = this.parentData, + nodes = parent.childData; + this._destroy(); + if( parent.hitChild === this ) delete parent.hitChild; + nodes.splice( Util.getIndex( nodes, this ), 1 ); + if( nodes.length === 0 ) delete parent.childData; + parent.clip === false && parent._updateRectangle(); + }, + _destroy : function(){ + var nodes = this.childData, + list = NodePrivateData.dataList, + node; + this.removeEventListener(); + ScrollBarManager.remove( this ); + if( nodes ){ + while( node = nodes.shift() ) node._destroy(); + delete this.childData; + }; + list.splice( Util.getIndex( list, this ), 1 ); + } + }; + NodePrivateData.dataList = []; + NodePrivateData.get = function( node ){ + // if( node instanceof NodePrivateData ) return node; + // return NodePrivateData.dataList[ layer._getUID() ]; + var list = NodePrivateData.dataList; + for( var i = list.length; i; ){ + if( list[ --i ].node === node ) return list[ i ]; + }; + return null; + }; + NodePrivateData.createEvent = function( e, eventType, data, hit ){ + var _e = { + layerX : e.clientX - data.absoluteX, + layerY : e.clientY - data.absoluteY, + clientX : e.clientX, + clientY : e.clientY, + dragOffsetX : e.dragOffsetX, + dragOffsetY : e.dragOffsetY, + dragPhase : e.dragPhase, + eventType : eventType, + hit : hit, + node : data.node, + wheelDelta : e.wheelDelta, + target : forceNodeData ? forceNodeData.node : targetNodeData ? targetNodeData.node : null + }; + return _e; + }; + + var EventTicketClass = function( node, eventType, handler, opt_thisObject ){ + this.node = node; + this.type = eventType; + this.handler = handler; + this.thisObj = opt_thisObject || node; + }; + EventTicketClass.prototype = { + match : function( eventType, handler ){ + if( handler && this.handler !== handler ) return false; + if( eventType && this.type !== eventType ) return false; + return true; + }, + destroy : function( eventType, handler ){ + if( this.match( eventType, handler ) === false ) return false; + delete this.node; + delete this.type; + delete this.handler; + delete this.thisObj; + return true; + }, + fire : ( function(){ + if( Function.prototype.call ){ + return function( e ){ + return this.handler.call( this.thisObj, e ); + }; + }; + return function( e ){ + var ret; + this.thisObj._currentHandler = this.handler; + ret = this.thisObj._currentHandler( e ); + delete this.thisObj._currentHandler; + return ret; + }; + })() + }; + +/*------------------------------------- + * StayHelper + */ + var StayEventTicketClass = function( node, data, stayhandler, opt_thisObject ){ + node.addEventListener( 'mouseover', this.mouseoverHandler, this ); + this.node = node; + this.data = data; + this.handler = stayhandler; + this.thisObject = opt_thisObject; + }; + StayEventTicketClass.prototype = Util.extend( new EventTicketClass( null, 'mousestay' ), { + // type : 'mousestay', + e : null, + mouseoverHandler : function( e ){ + this.e = NodePrivateData.createEvent( e, this.type, this.data, true ); + this.node.addEventListener( 'mouseout', this.mousestayHandler, this ); + this.node.addEventListener( 'mousemove', this.mousemoveHandler, this ); + SystemTimer.add( this.data.apiuser, this.timeoutHandler, null, this ); + }, + timeoutHandler : function(){ + this.mouseoutHandler(); + return this.fire( this.e ); + }, + mousemoveHandler : function( e ){ + this.e = NodePrivateData.createEvent( e, this.type, this.data, true ); + SystemTimer.remove( this.data.apiuser, this.timeoutHandler ); + SystemTimer.add( this.data.apiuser, this.timeoutHandler, null, this ); + }, + mouseoutHandler : function( e ){ + this.node.removeEventListener( 'mouseout', this.mousestayHandler ); + this.node.removeEventListener( 'mousemove', this.mousemoveHandler ); + SystemTimer.remove( this.data.apiuser, this.timeoutHandler ); + delete this.e; + } + }); + + var ScrollBarManager = ( function(){ + var elmScroller = document.createElement( 'div' ), + elmBar = document.createElement( 'div' ), + smoothList = [], + dragPhase = 2, + dragOut = false, + currentNodeData = null, + dragStartY = 0, + currentEvent; + + function tick(){ + var list = smoothList, + i, data, y; + for( i = 0; i < list.length; ){ + data = list[ i ]; + if( data.scrollingY !== data._scrollY ){ + y = data.scrollingY += data.smoothY; + if( data.smoothY < 0 ){ + y = y < data._scrollY ? data._scrollY : y; + } else { + y = data._scrollY < y ? data._scrollY : y; + }; + data.scrollingY = y; + data.elm.scrollTop = -y; + data.events && data.events.scroll && data.fire( currentEvent, 'scroll', true ); + }; + if( data.scrollingY === data._scrollY ){ + list.splice( i, 1 ); + // data.events && data.events.scroll && data.fire( currentEvent, 'scroll', true ); + } else { + ++i; + }; + }; + list.length === 0 && SystemTimer.remove( SUPER_USER_KEY, tick ); + currentEvent.type = 'updateAfterScroll'; + AsyncCall.add( data.apiuser, eventRellay, currentEvent ); // スクロール後の更新 + }; + + function scrollReady( e ){ + var data = this; + + dragOut = false; + if( data === currentNodeData || dragPhase !== 2 ) return; // Drag中の場合は 他にスクロールを作らない + currentNodeData && scrollRelease(); + + dragPhase = 2; + data.elm.parentNode.appendChild( elmScroller ); + elmScroller.appendChild( data.elm ); + + elmScroller.style.cssText = 'position:absolute;left:0;top:0;'; + elmScroller.appendChild( elmBar ); + + data.elm.scrollTop = -data.scrollingY; + data.rootData.addEventListener( 'mousewheel', onMouseWheelScroll, data ); + data.rootData.addEventListener( 'mousedrag', onMouseDragScroll, data ); + data.addEventListener( 'mouseout', onMouseOut, data ); + currentNodeData = data; + ScrollBarManager.update( data ); + }; + function scrollRelease(){ + var data = currentNodeData; + var parent = elmScroller.parentNode; + parent.appendChild( currentNodeData.elm ); + parent.removeChild( elmScroller ); + currentNodeData.elm.scrollTop = -data.scrollingY; + + data.rootData.removeEventListener( 'mousewheel', onMouseWheelScroll, data ); + data.rootData.removeEventListener( 'mousedrag', onMouseDragScroll, data ); + data.removeEventListener( 'mouseout', onMouseOut, data ); + currentNodeData = null; + }; + function onMouseOut( e ){ + dragOut = true; + console.log( 'mouseOut ' + dragPhase ); + dragPhase === 2 && scrollRelease(); // Dragしてのアウトの場合, scroll をリリースしない + }; + function onMouseWheelScroll( e ){ + var data = this; + this._scrollY += e.wheelDelta; + ScrollBarManager.update( this ); + currentEvent = e; + return true; + }; + function onMouseDragScroll( e ){ + var data = this; + //e.dragOffsetY; + currentEvent = e; + dragPhase = e.dragPhase; + switch( dragPhase ){ + case 0: + dragStartY = this.scrollingY; + data.rootData.removeEventListener( 'mousewheel', onMouseWheelScroll, data ); + case 1: + this._scrollY = dragStartY + e.dragOffsetY; + ScrollBarManager.update( this ); + return true; + case 2: + dragOut === true ? scrollRelease() : data.rootData.addEventListener( 'mousewheel', onMouseWheelScroll, data ); + return false; + }; + }; + + return { + register : function( data ){ + data.addEventListener( 'mouseover', scrollReady, data ); + }, + update : function( data ){ + // if( data !== currentNodeData ) return; + var isCurrent = data === currentNodeData; + + var contentH = data._scrollH = data.elm.scrollHeight, + clipH = data.h, + offsetH = contentH - clipH, + scrollY = data._scrollY = 0 < data._scrollY ? 0 : ( data._scrollY < -offsetH ? -offsetH : data._scrollY ), + barH, barY; + if( isCurrent === true ){ + elmScroller.style.width = data.w + 'px'; + elmScroller.style.height = clipH + 'px'; + }; + + if( offsetH < 1 ){ + data._scrollY = scrollY = 0; + if( isCurrent === true ) elmBar.style.display = 'none'; + } else + if( isCurrent === true ){ + barH = Math.floor( clipH * ( clipH / contentH ) ); + barY = Math.floor( ( clipH - barH ) * - scrollY / offsetH ); + elmBar.style.cssText = [ + 'position:absolute;', + 'width:10px;', + 'background-color:#333;', + 'right:2px;', + 'font-size:0;line-height:0;', + 'height:', barH, 'px;', + 'top:', data.y + barY, 'px;' + ].join( '' ); + }; + data.smoothY = ( scrollY - data.scrollingY ) / 10; + if( data.scrollingY !== scrollY && Util.getIndex( smoothList, data ) === -1 ){ + smoothList.length === 0 && SystemTimer.add( SUPER_USER_KEY, tick, 16 ); + smoothList.push( data ); + }; + }, + remove : function( data ){ + var list = smoothList, + i = Util.getIndex( list, data ); + data === currentNodeData && scrollRelease(); + i !== -1 && list.splice( i, 1 ); + } + }; + })(); + + return { + create : function( apiuser ){ + var elm = document.createElement( 'div' ), + root, data; + body.appendChild( elm ); + + root = new NodeClass( apiuser, null, null, elm ); + data = NodePrivateData.get( root ); + + // elm.style.cssText = 'position:absolute;top:0;left:0;height:100%;'; + elm.className = 'mouse-operation-catcher'; + elm.unselectable = 'on'; + data.elmMouseCatch = elm; + + data.eventCounter = {}; + ROOT_LIST.push( data ); + currentRootData = data; + targetNodeData = null; + forceNodeData = null; + + MouseEvent.add( apiuser, elm, 'mousemove', eventRellay ); + return root; + }, + onCurrentApplicationChange : function( _application ){ + currentRootData = null; + targetNodeData = null; + forceNodeData = null; + for( var i = ROOT_LIST.length; i; ){ + if( ROOT_LIST[ --i ].apiuser === _application ){ + currentRootData = ROOT_LIST[ i ]; + return; + }; + }; + }, + destroyTree : function( root ){ + var data = NodePrivateData.get( root ); + MouseEvent.remove( data.apiuser, data.elmMouseCatch, 'mousemove', eventRellay ); + body.removeChild( data.elmMouseCatch ); + data._destroy(); + ROOT_LIST.splice( Util.getIndex( ROOT_LIST, data ), 1 ); + if( currentRootData === data ){ + currentRootData = null; + targetNodeData = null; + forceNodeData = null; + }; + }, + onSystemShutdown : function(){ + + }, + isNodeInstance : function( node ){ + return node instanceof NodeClass; + }, + _getNodePrivateData : function( node ){ // system only + return NodePrivateData.get( node ); + } + }; +})(); + +var Application = ( function(){ + + var LIVE_APPLICATION_LIST = []; + + var currentApplication = null, + coveredApplication = null, + winW = 0, + winH = 0; + + var ApplicationReference = function( appClass, isOverlay, displayName, id, thumbnailUrl, tailColor ){ + var self = this; + var application = null; + this.id = id; + this.displayName = displayName; + this.thumbnailUrl = thumbnailUrl; + this.tailColor = tailColor; + + function asyncBoot(){ + application = Application.boot( appClass, displayName, self.getUID(), isOverlay, Util.copyArray( arguments ) ); + }; + this.getUID = function(){ + return Util.getIndex( API_USER_LIST, appClass ); + }; + this.getDisplayName = function(){ + return this.displayName; + }; + this.boot = function( /* _option */ ){ + AsyncCall.add( this, asyncBoot, Util.copyArray( arguments ) ); + }; + this.shutdown = function(){ + if( !application ) return false; + + AsyncCall.add( application, ( isOverlay === true ? Overlay.hide : application.close ) ); + }; + }; + + function asyncBootHome(){ + currentApplication === null && Home.boot(); + }; + function asyncOpen( /* arguments */ ){ + var _arg = Util.copyArray( arguments ); + _arg.unshift( winW, winH ); + currentApplication.open.apply( currentApplication, _arg ); + }; + return { + register: function( _class, _overlay, _tail, _displayName, _id, _thumbnailUrl, _tailColor ){ + APPLICATION_LIST.push( _class ); + API_USER_LIST.push( _class ); + var _ref = new ApplicationReference( _class, _overlay, _displayName, _id, _thumbnailUrl, _tailColor ); + _tail === true && Home.add( _ref ); + return _ref; + }, + isApplicationInstance: function( app ){ + return ApplicationPrivateData.get( app ) !== null; + }, + isApplicationReference: function( _reference ){ + return _reference instanceof ApplicationReference; + }, + isCurrentAppplication: function( app ){ + return app === currentApplication; + }, + boot: function( appClass, displayName, uid, isOverlay, arg ){ + if( currentApplication ){ + if( currentApplication.getUID() === uid ) return null; + if( isOverlay === false && currentApplication.close() === false ) return null; + }; + + appClass.prototype = new AbstractApplication( appClass, displayName, isOverlay ); + + var application = new appClass(), + data = ApplicationPrivateData.get( application ); + + application.rootElement = data.rootElement; + data.application = application; + + coveredApplication = isOverlay === true ? currentApplication : null; + + Application.onCurrentApplicationChange( application ); + + if( isOverlay === false ){ + body.style.backgroundColor = application.bgColor; + + body.appendChild( data.rootElement ); + data.rootElement.style.display = 'none'; + application.init(); + + application.addAsyncCall( asyncOpen, arg ); + } else { + Overlay.show( application, arg ); + }; + + return application; + }, + shutdown: function( _application, isOverlay ){ + if( isOverlay === false ){ + currentApplication = null; + AsyncCall.add( SUPER_USER_KEY, asyncBootHome ); + } else { + Application.onCurrentApplicationChange( coveredApplication ); + coveredApplication = null; + }; + }, + onCurrentApplicationChange: function( _application ){ + if( Application.isApplicationInstance( _application ) === false ) return; + if( currentApplication === _application ) return; + currentApplication = _application; + MouseEvent.onCurrentApplicationChange( _application ); + PointingDeviceEventTree.onCurrentApplicationChange( _application ); + KeyEvent.updateCurrentListener( _application ); + // InteractiveLayer.onCurrentApplicationChange( _application ); + }, + onApplicationShutdown: function( _application ){ + LIVE_APPLICATION_LIST.splice( Util.getIndex( LIVE_APPLICATION_LIST, _application ) ); + }, + onWindowResize: function( w, h ){ + winW = w; + winH = h; + currentApplication && currentApplication.resize( w, h ); + Overlay.onWindowResize( w, h ); + UI.onWindowResize( w, h ); + }, + onSystemShutdown: function(){ + + } + } +})(); + +/* -------------------------------------------------------------- + * Home + * + */ + var Home = ( function(){ + var APP_REF_LIST = []; + var ELM_TAIL_ORIGIN = ( function(){ + var ret = document.createElement( 'div' ), + h2 = document.createElement( 'h2' ); + ret.className = 'tail-wrapper'; + ret.appendChild( h2 ); + h2.appendChild( document.createTextNode( 'appName' ) ); + return ret; + })(); + + var TailClass = function( appRef ){ + this.elm = ELM_TAIL_ORIGIN.cloneNode( true ); + this.destroy = function(){ + appRef = self = elmName = null; + }; + + var self = this, + elmName = this.elm.getElementsByTagName( 'h2' )[ 0 ].firstChild; + + this.elm.style.backgroundColor = appRef.tailColor; + elmName.data = appRef.displayName; + }; + + var ref = Application.register( function(){ + var self = this, + winW = 0, + winH = 0, + tailList = [], + elmContainer, elmHeader; + + function draw(){ + var tail, elm; + for( var i=0, l=APP_REF_LIST.length; i 0 ){ + tailList.shift().destroy(); + } + self = tailList = elmContainer = null; + }; + }, false, false, 'home', 'home', null ); + + return { + add: function( _appRef ){ + if( Application.isApplicationReference( _appRef ) === false ) return; + Util.getIndex( APP_REF_LIST, _appRef ) === -1 && APP_REF_LIST.push( _appRef ); + }, + boot: function(){ + ref.boot(); + } + } + })(); + + var Page = ( function(){ + var pageNodes = [], + appClass, ref, + ignoreTagList = [ 'script', 'noscript', 'style' ]; + + var MemoryClass = function( node ){ + this.node = node; + }; + MemoryClass.prototype = { + init: function(){ + var node = this.node, + _nodeType = node.nodeType; + if( _nodeType === 1 && Util.getIndex( ignoreTagList, node.tagName.toLowerCase() ) === -1 ){ + this.type = _nodeType; + this.display = node.style.display; + } else + if( _nodeType === 3 ){ + if( node.data.replace( /\s/g, '' ).length !== 0 ){ + this.type = _nodeType; + this.before = pageNodes.length === 0 ? null : pageNodes[ pageNodes.length - 1 ].node; + } else { + body.removeChild( node ); + return false; + } + } else { + // body.removeChild( node ); + return false; + }; + }, + show: function(){ + if( this.type === 1 ){ + if( this.display ){ + this.node.style.display = this.display; + } else { + this.node.style.display = ''; + } + } else { + if( this.before ){ + body.insertBefore( this.node, this.before ); + } else { + body.appendChild( this.node ); + }; + }; + }, + hide: function(){ + if( !this.node.parentNode ){ + return; + }; + if( this.type === 1 ){ + this.node.style.display = 'none'; + } else { + body.removeChild( this.node ); + }; + } + }; + + return { + onReady: function(){ + var _children = Util.copyArray( body.childNodes ), + _mem; + for( var i = 0, l = _children.length; i= CLICK_OFFSET && this.mouseoutHandler(); + return false; + }, + mouseupHandler : function( e ){ + this.mouseoutHandler(); + return this.fire( ClickEventTicketClass.createEvent( e ) ); + }, + mouseoutHandler : function( e ){ + this.mousemoveTicket && this.mousemoveTicket.destroy(); + this.mouseupTicket && this.mouseupTicket.destroy(); + this.mouseoutTicket && this.mouseoutTicket.destroy(); + if( this.mousemoveTicket ) delete this.mousemoveTicket; + if( this.mouseupTicket ) delete this.mouseupTicket; + if( this.mouseoutTicket ) delete this.mouseoutTicket; + return false; + }, + destroy : function( _element, _eventType, _handler ){ + if( this.match( _element, _eventType, _handler ) === false ) return false; + + this.mouseoutHandler(); + this.mousedownTicket.destroy(); + + delete this.element; + delete this.handler; + delete this.thisObject; + delete this.mousedownTicket; + return true; + } + }; + if( document.createEvent ){ + ClickEventTicketClass.createEvent = function( e ){ + var _e = document.createEvent( 'MouseEvents' ); + _e.initMouseEvent( + 'click' , false, true, e.view, + e.detail, e.screenX, e.screenY, e.clientX, e.clientY, + e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, + e.button, e.relatedTarget + ); + return _e; + }; + } else + if( document.attachEvent ){ + ClickEventTicketClass.createEvent = function( e ){ + e.type = 'click'; + return e; + }; + } else { + + }; + + /*------------------------------------- + * WheelHelper + */ + var WheelEventTicketClass = ( function(){ + if( UA.GECKO ){ + return function( element, wheelhandler, opt_thisObject ){ + this.wheelTicket = new EventTicketClass( element, 'DOMMouseScroll', this.onGeckoWheel, this ); + this.element = element; + this.handler = wheelhandler; + this.thisObject = opt_thisObject; + }; + } else + if( true || UA.isIE ){ + return function( element, wheelhandler, opt_thisObject ){ + this.wheelTicket = new EventTicketClass( element, this.eventType, wheelhandler ); + this.element = element; + this.handler = wheelhandler; + this.thisObject = opt_thisObject; + }; + } else { + TMP.wheelHandlerList = []; + TMP.wheelThisObjList = []; + //TMP.wheelLegacy = undefined; + TMP.onWheel = function( e ){ + e = e || window.event; + var cancel = true, + f = TMP.wheelLegacy, i; + if( f ) cancel = f.call( this, e ); + + for( i = TMP.wheelHandlerList.length; i; ){ + if( TMP.wheelHandlerList[ --i ].call( TMP.wheelThisObjList[ i ] || this, e ) === false ) cancel = false; + }; + return cancel; + }; + return function( element, wheelhandler, opt_thisObject ){ + this.element = element; + this.handler = wheelhandler; + this.thisObject = opt_thisObject; + + if( TMP.wheelHandlerList.length === 0 ){ + //TMP.wheelLegacy = Type.isFunction( window.onmousewheel ) === true ? window.onmousewheel : undefined; + element.onmousewheel = TMP.onWheel; + }; + TMP.wheelHandlerList.push( wheelhandler ); + TMP.wheelThisObjList.push( opt_thisObject ) + }; + }; + })(); + WheelEventTicketClass.prototype = { + eventType : 'mousewheel', + match : EventTicketClass.prototype.match, + destroy : function( _element, _eventType, _handler ){ + if( this.match( _element, _eventType, _handler ) === false ) return false; + + this.wheelTicket && this.wheelTicket.destroy(); + + delete this.wheelTicket; + delete this.element; + delete this.handler; + delete this.thisObject; + + this.onDestroy && this.onDestroy(); + return true; + } + }; + if( UA.GECKO ){ + WheelEventTicketClass.prototype.onGeckoWheel = function( e ){ + var _e = document.createEvent( 'MouseEvents' ); + _e.initMouseEvent( + 'mousewheel' , false, true, e.view, + e.detail, e.screenX, e.screenY, e.clientX, e.clientY, + e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, + e.button, e.relatedTarget + ); + _e.wheelDelta = e.detail * -40; + return this.handler.call( this.thisObject || this.element, _e ); + }; + } else + if( true || UA.isIE ){ + + } else { + WheelEventTicketClass.prototype.onDestroy = function(){ + TMP.wheelHandlerList.splice( Util.getIndex( TMP.wheelHandlerList, this.handler ), 1 ); + TMP.wheelThisObjList.splice( Util.getIndex( TMP.wheelThisObjList, this.handler ), 1 ); + if( TMP.wheelHandlerList.length === 0 ) this.element.onmousewheel = ''; + }; + }; + + /*------------------------------------- + * DragHelper + */ + var DragEventTicketClass = function( element, draghandler, opt_thisObject ){ + this.mousedownTicket = new EventTicketClass( element, 'mousedown', this.mousedownHandler, this ); + this.element = element; + this.handler = draghandler; + this.thisObject = opt_thisObject; + }; + DragEventTicketClass.prototype = { + element : null, + handler : null, + thisObject : null, + startX : 0, + startY : 0, + dragging : false, + mousedownTicket : null, + mousemoveTicket : null, + mouseupTicket : null, + mouseoutTicket : null, + eventType : 'mousedrag', + fire : EventTicketClass.prototype.fire, + match : EventTicketClass.prototype.match, + mousedownHandler: function( e ){ + this.startX = e.clientX; + this.startY = e.clientY; + + this.mousemoveTicket = new EventTicketClass( this.element, 'mousemove', this.dragMoveHandler, this ); + this.mouseupTicket = new EventTicketClass( this.element, 'mouseup', this.dragEndHandler, this ); + this.mouseoutTicket = new EventTicketClass( this.element, 'mouseout', this.dragEndHandler, this ); + + return false; + }, + dragMoveHandler : function( e ){ + var offsetX = e.clientX - this.startX, + offsetY = e.clientY - this.startY; + if( this.dragging === false ){ + if( offsetX * offsetX + offsetY * offsetY < DRAG_OFFSET ) return; + console.log( 'Drag start' ); + // dragStart + this.dragging = true; + return this.fire( DragEventTicketClass.createEvent( e, offsetX, offsetY, 0 ) ); + }; + return this.fire( DragEventTicketClass.createEvent( e, offsetX, offsetY, 1 ) ); + }, + dragEndHandler : function( e ){ + if( this.dragging === true ){ + console.log( 'Drag End ' + e.type ); + this.removeEvents(); + // dragEnd + return this.fire( DragEventTicketClass.createEvent( e, e.clientX - this.startX, e.clientY - this.startY, 2 ) ); + }; + this.removeEvents(); + return false; + }, + removeEvents : function(){ + this.dragging = false; + if( this.mousemoveTicket ){ + this.mousemoveTicket.destroy(); + delete this.mousemoveTicket; + }; + if( this.mouseupTicket ){ + this.mouseupTicket.destroy(); + delete this.mouseupTicket; + }; + if( this.mouseoutTicke ){ + this.mouseoutTicket.destroy(); + delete this.mouseoutTicket; + }; + }, + destroy : function( _element, _eventType, _handler ){ + if( this.match( _element, _eventType, _handler ) === false ) return false; + + this.removeEvents(); + this.mousedownTicket.destroy(); + + delete this.element; + delete this.handler; + delete this.thisObject; + delete this.mousedownTicket; + return true; + } + }; + if( document.createEvent ){ + DragEventTicketClass.createEvent = function( e, offsetX, offsetY, dragPhase ){ + var _e = document.createEvent( 'MouseEvents' ); + _e.initMouseEvent( + DragEventTicketClass.prototype.eventType , false, true, e.view, + e.detail, e.screenX, e.screenY, e.clientX, e.clientY, + e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, + e.button, e.relatedTarget + ); + _e.dragPhase = dragPhase; + _e.dragOffsetX = offsetX; + _e.dragOffsetY = offsetY; + return _e; + }; + } else + if( document.attachEvent ){ + DragEventTicketClass.createEvent = function( e, offsetX, offsetY, dragPhase ){ + e.type = DragEventTicketClass.prototype.eventType; + e.dragPhase = dragPhase; + e.dragOffsetX = offsetX; + e.dragOffsetY = offsetY; + return e; + }; + } else { + + }; + + return { + add: function( _apiuser, _element, _eventType, _handler, opt_thisObject ){ + if( isApiUser( _apiuser ) === true && + ( Type.isHTMLElement( _element ) === true || _element === window || _element === document ) && + Type.isString( _eventType ) === true && + Type.isFunction( _handler ) === true + ){ + var _uid = _apiuser.getUID(), + _events = EVENT_LIST_MAP[ _uid ]; + if( Type.isArray( _events ) === false ){ + _events = EVENT_LIST_MAP[ _uid ] = []; + } else { + // 2重登録の禁止 + for( var i=0, l=_events.length; i 0; + } catch( e ){ + return false; + }; + }, + done: false + }; + + function getTicket( elm ){ + for( var i = TICKET_LIST.length, t; i; ){ + t = TICKET_LIST[ --i ]; + if( t.elm === elm ) return t; + }; + }; + + function detect(){ + var t = getTicket( this ), rs = this.readyState, c; + if( t && t.done === false && ( !rs || Util.getIndex( STATE_LIST, rs ) !== -1 ) ){ + t.done = true; + t.loaded(); + this.onreadystatechange = new Function(); + this.onload = null; + }; + }; + + function checkTimer(){ + var l = TICKET_LIST.length, + n = 0, t; + for( var i = 0; i < l; ++i ){ + t = TICKET_LIST[ i ]; + ++t.time; + if( t.check() === true ){ + t.loaded(); + ++n; + } else + if( t.time > 99 ){ + t.error(); + } else { + + }; + }; + l === n && SystemTimer.remove( SUPER_USER_KEY, checkTimer ); + }; + + return { + load: function( _apiuser, _url, opt_onload, opt_onerror, opt_thisObject ){ + _url = Util.getAbsolutePath( _url ); + var t; + for( var i=TICKET_LIST.length; i; ){ + t = TICKET_LIST[ --i ]; + if( t.match( null, _url ) === true ){ + if( t.match( _apiuser, _url ) === false ){ + t.apiusers.push( _apiuser ); + t.onload.push( opt_onload ); + t.onerror.push( opt_onerror ); + t.thisObj.push( opt_thisObject ); + }; + SystemTimer.add( SUPER_USER_KEY, checkTimer, 333 ); + return; + }; + }; + var elm = document.createElement( 'link' ); + head.appendChild( elm ); + elm.rel = 'stylesheet'; + elm.type = 'text\/css'; + elm.onreadystatechange = elm.onload = detect; + elm.href = _url; + + if( !sheet ){ // only assign these once + cssRules = 'cssRules'; + sheet = 'sheet'; + if ( !( sheet in elm ) ) { // MSIE uses non-standard property names + cssRules = 'rules'; + sheet = 'styleSheet'; + }; + }; + + TICKET_LIST.push( new FetchCssTicketClass( _apiuser, _url, elm, opt_onload, opt_onerror, opt_thisObject ) ); + + SystemTimer.add( SUPER_USER_KEY, checkTimer, 333 ); + }, + unload: function( _apiuser, _url ){ + _url = _url ? Util.getAbsolutePath( _url ) : null; + var t; + for( var i = 0; i < TICKET_LIST.length; ){ + t = TICKET_LIST[ i ]; + if( t.destroy( _apiuser, _url ) === true ){ + TICKET_LIST.splice( i, 1 ); + } else { + ++i; + } + }; + if( TICKET_LIST.length === 0 ){ + SystemTimer.remove( SUPER_USER_KEY, checkTimer ); + } + } + } +})(); + +/* + * AssetLoader + * fetchCSS + * fetchJson + * fetchHtml + * fetchImage + * fetchLocalFile + * fetchLocalStorage + */ + +var Image = ( function(){ + var TASK_LIST = []; + /* + * FetchClass original is + * + * LICENSE: MIT? + * URL: http://d.hatena.ne.jp/uupaa/20080413/1208067631 + * AUTHOR: uupaa.js@gmail.com + * + */ + function detect(){ + for( var i=0, t; i < TASK_LIST.length; ){ + t = TASK_LIST[ i ]; + if( t.complete() === true ){ + TASK_LIST.splice( i, 1 ); + } else { + ++i; + }; + }; + TASK_LIST.length === 0 && SystemTimer.remove( SUPER_USER_KEY, detect ); + }; + function getTask( img ){ + for( var i = TASK_LIST.length; i; ){ + if( TASK_LIST[ --i ].img === img ) return TASK_LIST[ i ]; + }; + }; + function onError(){ + var task = getTask( this ); + if( task.finish === true ) return; + task.finish = true; + AsyncCall.add( task.apiuser, task.asyncCallback, null, task ); + }; + function onLoad(){ + // if( finish === true ) return; // これがあると firefox3.6 で駄目、、、 + // if( timer ) return; // これがあると safari3.2 で駄目、、、 + var task = getTask( this ); + task.finish = true; + TASK_LIST.splice( Util.getIndex( TASK_LIST, task ), 1 ); + if( window.opera && !task.img.complete ){ + AsyncCall.add( task.apiuser, task.asyncCallback, null, task ); + return; + }; + task.size = Util.getImageSize( this ); + AsyncCall.add( task.apiuser, task.asyncCallback, null, task ); + }; + + + var FetchClass = function( apiuser, abspath, onLoadCallback, onErrorCallback, timeout ){ + this.apiuser = apiuser; + this.abspath = abspath; + this.onLoadCallback = onLoadCallback; + this.onErrorCallback = onErrorCallback; + this.timeout = timeout; + this.tick = 0; + }; + FetchClass.prototype = { + img: null, + size: null, + tick: 0, + finish: false, + load: function(){ + var img = this.img = document.createElement( 'img' ); //var img = new Image(); ではieでimgのsizeが取れない、、、removeChildも失敗し、imgSizeGetterにimgが残る + img.onabort = img.onerror = onError; + img.onload = onLoad; + img.src = this.abspath; + }, + complete: function(){ + if( this.finish === true ) return true; + if( this.img.complete ){ + this.finish = true; + if( this.img.width ) return true; + AsyncCall.add( this.apiuser, this.asyncCallback, null, this ); + return true; + }; + if( ( this.tick += 250 ) > this.timeout ){ + this.finish = true; + AsyncCall.add( this.apiuser, this.asyncCallback, null, this ); + return true; + }; + }, + asyncCallback: function(){ + this.size ? this.onLoadCallback( this.abspath, this.size.width, this.size.height ) : this.onErrorCallback( this.abspath ); + this.destroy(); + }, + destroy: function(){ + this.finish = true; + this.img.src = this.img.onload = this.img.onabort = this.img.onerror = ''; + delete this.img; + delete this.size; + delete this.onLoadCallback; + delete this.onErrorCallback; + }, + stop: function(){ + timer !== null && window.clearTimeout( timer ); + destroy(); + } + }; + + return { + load: function( URLorELM, onLoad, onError, opt_timeout ){ + var src, fetch; + if( Type.isString( URLorELM ) === true ){ + src = URLorELM; + } else + if( Type.isHTMLElement( URLorELM ) === true && URLorELM.tagName.toLowerCase() === 'img' ){ + src = URLorELM.src; + } else { + return; + }; + + fetch = new FetchClass( + Util.getAbsolutePath( src ), + onLoad, onError, + Type.isFinite( opt_timeout ) === true ? opt_timeout : undefined + ); + TASK_LIST.push( fetch ); + + SystemTimer.add( SUPER_USER_KEY, detect, 250 ); + }, + unload: function( ){ + + } + }; +})(); + + +/* ---------------------------------------- + * + */ + +var Overlay = ( function(){ + var elmContainer, elmShadow, elmCloseButton, + bootParams, + application = null, + visible = false, + bodyOverflow = '', + windowW, windowH; + + function onCloseClick( e ){ + Overlay.hide(); + return false; + }; + function asyncInit( /* arguments */ ){ + application.init(); + //application.rootElement.style.display = 'none'; + + elmContainer.style.cssText = "top:" + body.scrollTop + 'px;display:none;'; + $( elmContainer ).stop().fadeIn( onFadeInComplete ); + }; + function asyncOpen( /* arguments */ ){ + + + + }; + function onFadeInComplete(){ + KeyEvent.add( application, Const.KEY.EVENT.KEY_DOWN, Overlay.hide, 27 ); // 27.esc + MouseEvent.add( application, elmCloseButton, 'click', onCloseClick ); + + var _arg = bootParams; //Util.copyArray( arguments ); + _arg.unshift( windowW, windowH ); + application.open.apply( application, _arg ); + }; + function onFadeOutComplete(){ + Util.removeAllChildren( elmContainer ); + body.removeChild( elmContainer ); + elmContainer = elmShadow = elmCloseButton = null; + }; + return { + show: function( _application, _bootParams ){ + if( visible === true && application === _application ) return; + if( Application.isApplicationInstance( _application ) === false ) return; + + elmContainer = document.createElement( 'div' ); + body.appendChild( elmContainer ); + + elmContainer.id = 'overlay-container'; + + bodyOverflow = body.style.overflow; + body.style.overflow = 'hidden'; + + elmShadow = document.createElement( 'div' ); + elmContainer.appendChild( elmShadow ); + elmShadow.id = 'overlay-shadow'; + + elmCloseButton = document.createElement( 'div' ); + elmContainer.appendChild( elmCloseButton ); + elmCloseButton.id = 'overlay-close-button'; + elmCloseButton.appendChild( document.createTextNode( 'x' ) ); + + elmContainer.style.display = 'none'; // hide for fadeIn + + visible = true; + application = _application; + + //asyncInit(); + elmContainer.insertBefore( application.rootElement, elmCloseButton ); + _application.addAsyncCall( asyncInit ); + // _application.addAsyncCall( asyncOpen, ); + + bootParams = _bootParams; + }, + hide: function(){ + if( visible === false ) return; + if( application.close() === false ) return false; + + body.style.overflow = bodyOverflow; + + $( elmContainer ).stop().css( { + filter: '', + opacity: '' + }).fadeOut( onFadeOutComplete ); + visible = false; + + application = null; + }, + onWindowResize: function( _windowW, _windowH ){ + windowW = _windowW; + windowH = _windowH; + + if( application === null ) return; + + elmContainer.style.height = _windowH + 'px'; + elmContainer.style.top = body.scrollTop + 'px'; + + elmShadow.style.height = _windowH + 'px'; + + AsyncCall.add( application, application.resize, [ _windowW, _windowH ] ); + } + } +})(); + +/* ---------------------------------------- + * UI + * + * keyEventRellay + * form -> overlay -> view + * + */ + +var UI = ( function(){ + var UI_LIST = [], + currentUser = null, + currentList = null, + currentUi = null, + currentItem = null, + windowW = 0, + windowH = 0; + + var CLASSNAME_COMBOBOX_OPTION = 'combobox-option', + CLASSNAME_COMBOBOX_OPTION_CURRENT = CLASSNAME_COMBOBOX_OPTION + ' combobox-option-current', + ELM_COMBOBOX = ( function(){ + var ret = document.createElement( 'a' ), + elmToggle = document.createElement( 'span' ), + elmValue = document.createElement( 'span' ); + ret.href = '#'; + ret.appendChild( elmToggle ); + ret.appendChild( elmValue ); + elmToggle.className = 'combobox-toggle'; + elmValue.className = 'combobox-value'; + + elmToggle.appendChild( document.createTextNode( '▼' )); + elmValue.appendChild( document.createTextNode( 'null' )); + return ret; + })(); + + var UIItemPrivateData = function(){}; + UIItemPrivateData.prototype = { + groupData : null, + item : null, + elm : null, + node : null, + focus : false, + visible : true, + enabled : true, + value : null, + onUpdate : null, + validator : null, + elmValue : null, + elmBox : null, + elmA : null, + elmToggle : null, + elmValue : null, + selectIndex : 0, + optionList : null, + init : function( groupData, item, elm, value, onUpdate, validator, focus, visible, enabled ){ + this.groupData = groupData; + this.item = item; + this.elm = elm; + this.value = value; + this.onUpdate = onUpdate; + this.validator = validator; + this.focus = !!focus; + this.visible = !!visible; + this.enabled = !!enabled; + UIItemPrivateData.list.push( this ); + }, + destroy : function(){ + var list = UIItemPrivateData.list; + list.splice( Util.getIndex( list, this ), 1 ); + + list = this.groupData.itemList; + var i = Util.getIndex( list, this.item ); + i !== -1 && list.splice( i, 1 ); + + this.node && this.node.remove(); + } + }; + UIItemPrivateData.list = []; + UIItemPrivateData.get = function( item ){ + var list = UIItemPrivateData.list; + for( i = list.length; i; ){ + if( list[ --i ].item === item ) return list[ i ]; + }; + return null; + }; + +/* -------------------------------- + * TextInputManager + */ + var TextInputManager = ( function(){ + var elmInput = ( function(){ + var ret = document.createElement( 'input' ); + ret.type = 'text'; + ret.id = 'ui-textinput'; + return ret; + })(); + var currentData; + + function updateWrapperPosition(){ + var p = Position.cumulativeOffset( currentData.elmValue ), + w = currentData.elmValue.offsetWidth - 2, + _w; + elmInput.style.cssText = [ + 'left:', p[ 0 ], 'px;', + 'top:', p[ 1 ], 'px;',//, + 'width:', w, 'px;'//, + //'height:', data.elmValue.offsetHeight, 'px;', + //'position:absolute;' + ].join( '' ); + + //_w = elmInput.offsetWidth; + //if( w !== _w ) elmInput.style.width = ( w - ( _w - w ) ) + 'px;'; + }; + + return { + show: function( data ){ + // this.groupData.node.addEventListener( 'mouseout' ); + currentData = data; + + body.appendChild( elmInput ); + elmInput.value = data.value; + updateWrapperPosition(); + + elmInput.focus(); + elmInput.select(); + + SystemTimer.add( SUPER_USER_KEY, updateWrapperPosition, 500 ); + }, + hide : function( data ){ + if( currentData !== data ) return; + currentData = null; + body.removeChild( elmInput ); + var ret = elmInput.value; + elmInput.value = ''; + SystemTimer.remove( SUPER_USER_KEY, updateWrapperPosition ); + return ret; + }, + update : function( data ){ + elmInput.value = data.value; + }, + onWindowResize: function( _w, _h ){ + AsyncCall.add( currentUser, updateWrapperPosition ); + } + }; + })(); + + var TextInputClass = function( groupData, elmWrapper, elmValue, onUpdate, validater ){ + var data = new UIItemPrivateData(); + data.init( groupData, this, elmWrapper, elmValue.innerHTML, onUpdate, validater, false, true, true ); + Util.addClass( elmValue, 'editable-text' ); + data.elmValue = elmValue; + this.value( data.value ); + data.node = groupData.node.createNode( elmWrapper, false, true, 'ui-inpittext-hover', 'pointer' ); + data.node.addEventListener( 'click', this.focus, this ); + //MouseEvent.add( groupData.apiuser, elmWrapper, 'click', instance.focus ); + }; + TextInputClass.prototype = { + value : function( value ){ + var data = UIItemPrivateData.get( this ); + if( Type.isString( value ) === true || Type.isNumber( value ) === true ){ + data.elmValue.innerHTML = data.value = '' + value; + data.focus === true && TextInputManager.update( data ); + }; + data.focus === true && this.blur(); + return data.value; + }, + focus : function( e ){ + var data = UIItemPrivateData.get( this ); + data.focus = true; + start( data ); + TextInputManager.show( data ); + return false; + }, + blur : function( keep ){ + var data = UIItemPrivateData.get( this ), + newValue; + if( data.focus === false ) return; + newValue = TextInputManager.hide( data ); + newValue = keep !== 27 ? ( data.validater ? '' + data.validater( newValue ) : newValue ) : data.value; // 27:ESC + + data.elmValue.innerHTML = newValue; + + data.onUpdate && newValue !== data.value && AsyncCall.add( data.groupData.apiuser, data.onUpdate, [ newValue, data.value ], this ); + + data.value = newValue; + data.focus = false; + finish( data ); + }, + enabled : function( v ){ + var data = UIItemPrivateData.get( this ); + if( Type.isBoolean( v ) === true && data.enabled !== v ){ + Util.toggleClass( data.elm, 'ui-textinput-disabled', !v ); + if( data.focus === true && v === false ) this.blur(); + data.enabled = v; + data.node.disabled( !( data.visible && v ) ); + }; + return data.enabled; + }, + visible : function( v ){ + var data = UIItemPrivateData.get( this ); + if( Type.isBoolean( v ) === true && data.visible !== v ){ + data.elm.style.display = v ? '' : 'none'; + if( data.focus === true && v === false ) this.blur(); + data.visible = v; + data.node.disabled( !( data.enabled && v ) ); + }; + return data.visible; + }, + destroy : function(){ + var data = UIItemPrivateData.get( this ); + data.focus === true && TextInputManager.hide( data ); + data.destroy(); + } + }; + +/* -------------------------------- + * TextInputManager + */ + var FileInputManager = ( function(){ + var currentData, + elmForm, + elmFileInput, + elmWrap, + evt; + + function updateWrapperPosition(){ + var p = Position.cumulativeOffset( currentData.elmValue ), + w = currentData.elmValue.offsetWidth, + _w; + elmWrap.style.cssText = [ + 'left:', p[ 0 ], 'px;', + 'top:', p[ 1 ], 'px;',//, + 'width:', w, 'px;'//, + //'height:', data.elmValue.offsetHeight, 'px;', + //'position:absolute;' + ].join( '' ); + + _w = elmWrap.offsetWidth; + if( w !== _w ) elmWrap.style.width = ( w - ( _w - w ) ) + 'px'; + }; + + function change( e ){ + var data = currentData, + file = data.elmFileInputReal.value; + file = file.split( '\\' ); + file = file[ file.length - 1 ]; + if( data.value !== file ){ + data.onUpdate && AsyncCall.add( data.groupData.apiuser, data.onUpdate, [ file, data.value ], this ); + data.elmValue.innerHTML = data.value = file; + }; + currentData.item.blur(); + }; + function asyncMouseout(){ + currentData && currentData.item.blur(); + }; + function onClick(){ + MouseEvent.remove( currentUser, elmFileInput, 'mouseout', asyncMouseout ); + MouseEvent.remove( currentUser, elmFileInput, 'click', onClick ); + }; + return { + show : function( data ){ + currentData = data; + + elmFileInput = data.elmFileInputReal; + elmWrap = elmFileInput.parentNode; + // + + updateWrapperPosition(); + elmFileInput.focus(); + //data.node.addEventListener( 'change', change, data ); + evt = new EventTicketClass( elmFileInput, 'change', change ); + MouseEvent.add( currentUser, elmFileInput, 'mouseout', asyncMouseout ); + MouseEvent.add( currentUser, elmFileInput, 'click', onClick ); + // currentData.elmFileInputReal.onchange = change; + SystemTimer.add( SUPER_USER_KEY, updateWrapperPosition, 500 ); + }, + hide : function( data ){ + if( currentData !== data ) return; + // data.node.removeEventListener( 'change', change ); + evt.destroy(); + // MouseEvent.remove( currentUser, elmFileInput, 'mouseout', asyncMouseout ); + onClick(); + //currentData.elmFileInputReal.onchange = null; + elmWrap.style.display = 'none'; + currentData = elmFileInput = null; + SystemTimer.remove( SUPER_USER_KEY, updateWrapperPosition ); + }, + onWindowResize: function( _w, _h ){ + AsyncCall.add( currentUser, updateWrapperPosition ); + } + }; + })(); + + var FileInputClass = function( groupData, elmWrapper, onUpdate, validater, elmFileInputReal, elmValue ){ + var data = new UIItemPrivateData(); + data.init( groupData, this, elmWrapper, null, onUpdate, null, false, true, true ); + data.node = groupData.node.createNode( elmWrapper, false, true, 'ui-fileinput-hover', 'pointer' ); + data.elmValue = elmValue; + data.elmFileInputReal = elmFileInputReal; + data.node.addEventListener( 'mouseover', this.focus, this ); + }; + FileInputClass.prototype = { + value : function(){ + return data.value; + }, + focus : function(){ + var data = UIItemPrivateData.get( this ); + data.focus = true; + Util.addClass( data.elm, 'fileinput-has-focus' ); + start( data ); + FileInputManager.show( data ); + }, + blur : function( keyCode ){ + var data = UIItemPrivateData.get( this ); + Util.removeClass( data.elm, 'fileinput-has-focus' ); + data.focus = false; + FileInputManager.hide( data ); + finish( data ); + }, + enabled : function( v ){ + var data = UIItemPrivateData.get( this ); + if( Type.isBoolean( v ) === true && data.enabled !== v ){ + if( data.focus === true && v === false ) this.blur(); + Util.toggleClass( data.elm, 'fileinput-disabled', !v ); + data.enabled = v; + data.node.disabled( !( data.visible && v ) ); + }; + return data.enabled; + }, + visible : function( v ){ + var data = UIItemPrivateData.get( this ); + if( Type.isBoolean( v ) === true && data.visible !== v ){ + if( data.focus === true && v === false ) this.blur(); + data.elm.style.display = v ? '' : 'none'; + data.visible = v; + data.node.disabled( !( data.enabled && v ) ); + }; + return data.visible; + }, + destroy : function(){ + var data = UIItemPrivateData.get( this ); + data.focus === true && FileInputManager.hide( data ); + data.destroy(); + } + }; + + var ButtonClass = function( groupData, elmWrapper, onUpdate ){ + var data = new UIItemPrivateData(); + data.init( groupData, this, elmWrapper, null, onUpdate, null, false, true, true ); + data.node = groupData.node.createNode( elmWrapper, false, true, 'ui-button-hover', 'pointer' ); + data.node.addEventListener( 'click', onUpdate ); + //MouseEvent.add( groupData.apiuser, elmWrapper, 'click', onUpdate ); + }; + ButtonClass.prototype = { + focus : function(){ + var data = UIItemPrivateData.get( this ); + data.focus = true; + Util.addClass( data.elm, 'button-has-focus' ); + start( data ); + }, + blur : function( keyCode ){ + var data = UIItemPrivateData.get( this ); + keyCode === 13 && data.onUpdate && data.onUpdate(); + Util.removeClass( data.elm, 'button-has-focus' ); + data.focus = false; + finish( data ); + }, + enabled : function( v ){ + var data = UIItemPrivateData.get( this ); + if( Type.isBoolean( v ) === true && data.enabled !== v ){ + Util.toggleClass( data.elm, 'button-disabled', !v ); + data.enabled = v; + data.node.disabled( !( data.visible && v ) ); + }; + return data.enabled; + }, + visible : function( v ){ + var data = UIItemPrivateData.get( this ); + if( Type.isBoolean( v ) === true && data.visible !== v ){ + data.elm.style.display = v ? '' : 'none'; + data.visible = v; + data.node.disabled( !( data.enabled && v ) ); + }; + return data.visible; + }, + destroy : function(){ + var data = UIItemPrivateData.get( this ); + // MouseEvent.remove( data.groupData.apiuser, data.elm ); + data.destroy(); + } + }; + + var ComboBoxClass = function( groupData, elmWrapper, onUpdate ){ + var elmA = ELM_COMBOBOX.cloneNode( true ), + data = new UIItemPrivateData(); + data.init( groupData, this, elmWrapper, null, onUpdate, null, false, true, true ); + + data.elmBox = Util.getElementsByClassName( elmWrapper, 'combobox' )[ 0 ]; + data.elmBox.appendChild( elmA ); + data.elmA = elmA; + data.elmToggle = Util.getElementsByClassName( elmA, 'combobox-toggle' )[ 0 ]; + data.elmValue = Util.getElementsByClassName( elmA, 'combobox-value' )[ 0 ].firstChild; + data.selectIndex = 0; + data.optionList = []; + + data.node = groupData.node.createNode( elmWrapper, false, true, 'ui-combobox-hover', 'pointer' ); + data.node.addEventListener( 'click', this.focus, this ); + }; + ComboBoxClass.prototype = { + focus : function( e ){ + var data = UIItemPrivateData.get( this ); + data.node.removeEventListener( 'click', this.focus ); + data.focus = true; + data.elmA.className = 'combobox-has-focus'; + start( data ); + OptionControl.show( data ); + return false; + }, + blur : function( keyCode ){ + var data = UIItemPrivateData.get( this ); + OptionControl.hide( this ); + data.focus = false; + data.elmA.className = ''; + finish( data ); + data.node.addEventListener( 'click', this.focus, this ); + }, + enabled : function( v ){ + var data = UIItemPrivateData.get( this ); + if( Type.isBoolean( v ) === true && data.enabled !== v ){ + Util.toggleClass( data.elm, 'ui-combobox-disabled', !v ); + if( data.focus === true && v === false ) this.blur(); + data.enabled = v; + data.node.disabled( !( data.visible && v ) ); + }; + return data.enabled; + }, + visible : function( v ){ + var data = UIItemPrivateData.get( this ); + if( Type.isBoolean( v ) === true && data.visible !== v ){ + data.elm.style.display = v ? '' : 'none'; + if( data.focus === true && v === false ) this.blur(); + data.visible = v; + data.node.disabled( !( data.enabled && v ) ); + }; + return data.visible; + }, + value : function( _value ){ + var data = UIItemPrivateData.get( this ), + i = 0, + list = data.optionList, + l = list.length, + _option; + if( Type.isString( _value ) === true && data.value !== _value ){ + for( ; i < l; ++i ){ + _option = list[ i ]; + if( _value === _option.value ){ + data.value = _value; + data.index = i; + data.elmValue.data = _option.displayValue; + if( data.focus === true ){ + OptionControl.update( this, _value ); + }; + data.onUpdate && AsyncCall.add( data.groupData.apiuser, data.onUpdate, _value, this ); + break; + }; + }; + }; + return data.value; + }, + selectIndex : function(){ + var data = UIItemPrivateData.get( this ); + return data.selectIndex; + }, + createOption : function( _displayValue, _value, _isSelected ){ + var data = UIItemPrivateData.get( this ), + option = null, + list = data.optionList, + i = list.length, + _option, i; + _value = _value || _displayValue; + _isSelected = !!_isSelected; + for( ; i; ){ + _option = list[ --i ]; + if( _value === _option.value ){ + option = _option; + break; + }; + }; + if( _isSelected === true ){ + data.selectIndex = list.length; + data.elmValue.data = _displayValue; + }; + option === null && list.push( new OptionDataClass( _displayValue, _value, _isSelected ) ); + }, + destroy : function(){ + var data = UIItemPrivateData.get( this ); + data.focus === true && OptionControl.hide( this ); + // this.blur(); + // MouseEvent.remove( data.groupData.apiuser, data.elm ); + data.optionList.length = 0; + data.destroy(); + } + }; + var OptionDataClass = function( displayValue, value, isCurrent ){ + this.displayValue = displayValue; + this.value = value || displayValue; + this.current = isCurrent; + displayValue = value = null; + }; + + var OptionControl = ( function(){ + var ELM_OPTION_WRAPPER = ( function(){ + var ret = document.createElement( 'div' ); + ret.className = 'option-container'; + return ret; + })(), + ELM_OPTION_ORIGIN = ( function(){ + var ret = document.createElement( 'a' ); + ret.appendChild( document.createTextNode( 'option' ) ); + ret.href = '#'; + return ret; + })(); + + var OptionClass = function( option ){ + this.elm = ELM_OPTION_ORIGIN.cloneNode( true ); + this.data = option; + this.init(); + }; + OptionClass.prototype = { + init: function(){ + ELM_OPTION_WRAPPER.appendChild( this.elm ); + this.elm.firstChild.data = this.data.displayValue; + this.current( this.data.current ); + MouseEvent.add( SUPER_USER_KEY, this.elm, 'mousedown', onOptionSelect );// onclick では 選択ボックス 隠すように body に設定した onmouseup が先に動いてしまう! + }, + current: function( _current ){ + this.elm.className = _current === true ? CLASSNAME_COMBOBOX_OPTION_CURRENT : CLASSNAME_COMBOBOX_OPTION; + this.data.current = _current; + currentOption = _current === true ? this : currentOption; + }, + destroy: function(){ + MouseEvent.remove( SUPER_USER_KEY, this.elm ); + Util.removeAllChildren( this.elm ); + ELM_OPTION_WRAPPER.removeChild( this.elm ); + delete this.elm; + delete this.data; + } + }; + + function onOptionSelect( e ){ + var i = 0, + l = OPTION_LIST.length, + _option; + for( ; i < l; ++i ){ + _option = OPTION_LIST[ i ]; + if( this === _option.elm ){ + updateCurrrentOption( _option.data.value, true ); + currentCombobox.blur(); + break; + }; + }; + return false; + }; + + var OPTION_LIST = [], + currentCombobox = null, + apiuser, + elm, + currentOption, + currentIndex; + + function updateCurrrentOption( _value, _updateCombobox ){ + var _option, + i = OPTION_LIST.length; + for( ; i; ){ + _option = OPTION_LIST[ --i ]; + if( _value === _option.data.value ){ + currentOption && currentOption.current( false ); + _option.current( true ); + currentOption = _option; + currentIndex = i; + _updateCombobox === true && currentCombobox.value( _value ); + break; + }; + }; + }; + function bodyMouseupHandler(){ + currentCombobox.blur(); + OptionControl.hide( currentCombobox ); + }; + function updateWrapperPosition(){ + var position = Util.getAbsolutePosition( elm ); + + ELM_OPTION_WRAPPER.style.cssText = [ + 'width:', elm.offsetWidth - 2, 'px;', + 'left:', position.x, 'px;', + 'top:', position.y + elm.offsetHeight, 'px;' + ].join( '' ); + }; + function change( e ){ + var l = OPTION_LIST.length, + i = currentIndex + ( e.keyCode === 40 ? -1 : 1 ); + if( currentCombobox === null || l < 2 ) return; + i = i < 0 ? + l - 1 : + i < l ? i : 0; + updateCurrrentOption( OPTION_LIST[ i ].data.value, true ); + return false; + }; + return { + show: function( data ){ + var combobox = data.item, + list = data.optionList, + i = 0, + l = list.length; + if( currentItem !== combobox || currentCombobox === combobox ) return; + currentCombobox && currentCombobox.blur(); + + apiuser = data.groupData.apiuser; + currentCombobox = combobox; + elm = data.elmBox; + + for( ; i < l; ++i ){ + OPTION_LIST.unshift( new OptionClass( list[ i ] ) ); + }; + MouseEvent.add( SUPER_USER_KEY, document, 'mouseup', bodyMouseupHandler ); + KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, change, 38 ); + KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, change, 40 ); + //KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onEnter, 13 ); + //KeyEvent.updateCurrentListener( SUPER_USER_KEY ); + + body.appendChild( ELM_OPTION_WRAPPER ); + + updateCurrrentOption( combobox.value(), false ); + updateWrapperPosition(); + + SystemTimer.add( SUPER_USER_KEY, updateWrapperPosition, 500 ); + }, + hide: function( _combobox ){ + if( currentCombobox !== _combobox || currentCombobox === null ) return; + + var _option; + while( _option = OPTION_LIST.shift() ){ + _option.destroy(); + }; + + body.removeChild( ELM_OPTION_WRAPPER ); + + MouseEvent.remove( SUPER_USER_KEY, document, 'mouseup', bodyMouseupHandler ); + KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, change ); + KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, change ); + //KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onEnter ); + //KeyEvent.updateCurrentListener( apiuser ); + + SystemTimer.remove( SUPER_USER_KEY, updateWrapperPosition, 500 ); + + apiuser = null; + currentCombobox = null; + currentOption = null; + currentIndex = 0; + }, + onEnter: function(){ + currentCombobox.value( currentOption.data.value ); + //currentCombobox.blur(); + //OptionControl.hide( currentCombobox ); + }, + update: function( data, _value ){ + if( currentCombobox !== data.item || currentItem !== data.item ) return; + if( currentOption.data.value === _value ) return; + updateCurrrentOption( _value, true ); + }, + onWindowResize: function( _w, _h ){ + currentCombobox && AsyncCall.add( apiuser, updateWrapperPosition ); + } + }; + })(); + + var UIGroupPrivateData = function(){}; + UIGroupPrivateData.prototype = { + apiuser : null, + node : null, + uigroup : null, + itemList : null, + visible : true, + enabled : true, + init : function( apiuser, node, uigroup ){ + this.apiuser = apiuser; + this.node = node; + this.uigroup = uigroup; + this.itemList = []; + UIGroupPrivateData.list.push( this ); + }, + destroy : function(){ + + } + }; + UIGroupPrivateData.list = []; + UIGroupPrivateData.get = function( uigroup ){ + var list = UIGroupPrivateData.list, + i = list.length; + for( ; i; ){ + if( list[ --i ].uigroup === uigroup ) return list[ i ]; + }; + return null; + }; + + var UIGroupClass = function( apiuser, node ){ + ( new UIGroupPrivateData() ).init( apiuser, node, this ); + }; + UIGroupClass.prototype = { + focus : function( _value ){ + var data = UIGroupPrivateData.get( this ); + /* + if( _value === true ){ + if( currentItem ){ + start( apiuser, self, currentItem ); + } else + if( itemList.length > 0 ){ + start( apiuser, self, itemList[ 0 ] ); + }; + } else + if( _value === false ){ + finish( apiuser, self, currentItem ); + } else + */ + if( _value && Util.getIndex( data.itemList, _value ) !== -1 ){ + // currentItem = _value; + currentList = data.itemList; + }; + return currentUi === this; + }, + blur : function(){ + var data = UIGroupPrivateData.get( this ); + if( currentList === data.itemList ){ + currentList = null; + }; + }, + createInputText : function( elmWrapper, onUpdate, validater ){ + var data = UIGroupPrivateData.get( this ), + elmValue = Util.getElementsByClassName( elmWrapper, 'editable-value' )[ 0 ], + ret; + if( elmValue ){ + ret = new TextInputClass( data, elmWrapper, elmValue, onUpdate, validater ); + data.itemList.push( ret ); + return ret; + }; + alert( 'error createInputText' ); + }, + createButton : function( elm, onClick ){ + var data = UIGroupPrivateData.get( this ), + ret = new ButtonClass( data, elm, onClick ); + data.itemList.push( ret ); + return ret; + }, + createFileInput : function( elm, onUpdate, validater, elmFileInputReal ){ + var data = UIGroupPrivateData.get( this ), + elmValue = Util.getElementsByClassName( elm, 'fileinput-value' )[ 0 ], + ret; + if( elmValue ){ + ret = new FileInputClass( data, elm, onUpdate, validater, elmFileInputReal, elmValue ); + data.itemList.push( ret ); + return ret; + }; + return ret; + }, + createCombobox : function( elm, onUpdate, optionList ){ + var data = UIGroupPrivateData.get( this ), + ret = new ComboBoxClass( data, elm, onUpdate, optionList ); + data.itemList.push( ret ); + return ret; + }, + createCheckBox : function(){ + + }, + createRadio : function(){ + + }, + createSlider : function(){ + + }, + visible : function( v ){ + var data = UIGroupPrivateData.get( this ); + if( Type.isBoolean( v ) === true && data.visible !== v ){ + for( var i = data.itemList.length; i; ){ + data.itemList[ --i ].visible( v ); + }; + data.visible = v; + data.node.disabled( !( data.enabled && v ) ); + }; + return data.visible; + }, + enabled : function( v ){ + var data = UIGroupPrivateData.get( this ); + if( Type.isBoolean( v ) === true && data.enabled !== v ){ + for( var i = data.itemList.length; i; ){ + data.itemList[ --i ].enabled( v ); + }; + data.enabled = v; + data.node.disabled( !( data.visible && v ) ); + }; + return data.enabled; + }, + destroy : function(){ + var data = UIGroupPrivateData.get( this ), + _item; + if( currentUi === this ){ + currentItem.blur(); + // finish( UIItemPrivateData.get( currentItem ) ); + }; + while( _item = data.itemList.shift() ){ + _item.destroy(); + }; + data.destroy(); + } + }; + + function start( data ){ + if( currentItem !== data.item ){ + currentUi !== data.groupData.uigroup && currentUi && currentUi.blur(); + + currentItem !== null && currentItem.blur(); + + currentUser = data.groupData.apiuser; + currentUi = data.groupData.uigroup; + currentItem = data.item; + + currentUi.focus( currentItem ); + + // if( currentUser !== _apiuser ) { + KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 13 ); + KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 27 ); + KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 9 ); + KeyEvent.updateCurrentListener( SUPER_USER_KEY ); + // }; + }; + } + function finish( data ){ + if( currentItem === data.item ){ + currentUi.blur(); + + currentUser = null; + currentUi = null; + currentItem = null; + currentList = null; + + KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 13 ); + KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 27 ); + KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 9 ); + KeyEvent.updateCurrentListener( data.groupData.apiuser ); + }; + }; + + function onKeyDown( e ){ + if( currentItem === null ) return true; + var keyCode = e.keyCode, + index = Util.getIndex( currentList, currentItem ); + if( keyCode === 13 || keyCode === 27 || keyCode === 9 || keyCode === 18 || e.altKey === true ){ // 13.return 27.esc 9.tab 18.alt + keyCode === 9 && tabShift( index, e.shiftKey === true ? -1 : 1 ); + keyCode === 13 && currentItem instanceof ComboBoxClass && OptionControl.onEnter(); + keyCode === 13 && tabShift( index, 1 ); + currentItem && currentItem.blur( keyCode ); + return false; + }; + }; + + function tabShift( index, way ){ + var l = currentList.length, + i = index + way, + item; + if( l < 2 ) return; + while( i !== index ){ + i = i < 0 ? + l - 1 : + i < l ? i : 0; // 0 < i < l + item = currentList[ i ]; + if( item.enabled() === true && item.visible() === true ){ + AsyncCall.add( currentUser, item.focus, null, item ); + return; + }; + i += way; + }; + }; + + return { + createUIGroup: function( apiuser, node ){ + var uid = apiuser.getUID(), + list = UI_LIST[ uid ], + ui = new UIGroupClass( apiuser, node ); + if( Type.isArray( list ) === false ){ + list = UI_LIST[ uid ] = []; + }; + list.push( ui ); + return ui; + }, + onWindowResize: function( w, h ){ + windowW = w; + windowH = h; + currentItem instanceof ComboBoxClass && OptionControl.onWindowResize( w, h ); + currentItem instanceof TextInputClass && TextInputManager.onWindowResize( w, h ); + currentItem instanceof FileInputClass && FileInputManager.onWindowResize( w, h ); + }, + onCurrentApplicationChange: function( _apiuser ){ + currentList = UI_LIST[ _apiuser.getUID() ]; + }, + onApplicationShutdown: function( _apiuser ){ + KeyEvent.remove( _apiuser ); + }, + onSystemShutdown: function(){ + + } + }; +})(); + +var UIForm = ( function(){ + var FORM_LIST = []; + var CLASSNAME_FORM = 'uiform-invisible'; + var CLASSNAME_FILE_WRAP = 'ui-fileinput-wrapper'; + var FormItemData = function(){}; + var windowW, windowH; + FormItemData.prototype = { + formData : null, + uiItem : null, + init : function( formData, uiItem ){ + this.formData = formData; + this.uiItem = uiItem; + }, + onUpdate : function( v ){ + // var index = Util.getIndex( this.formData.itemList, this ); + } + }; + + var FormPrivateData = function(){}; + FormPrivateData.prototype = { + apiuser : null, + node : null, + form : null, + elmForm : null, + itemList : null, + visible : true, + enabled : true, + init : function( apiuser, from, node, elm, elmForm ){ + this.apiuser = apiuser; + this.form = form; + this.ui = apiuser.createUIGroup( node ); + this.node = node; + this.elm = elm; + this.elmForm = elmForm; + this.itemList = []; + elmForm.className = CLASSNAME_FORM; + FormPrivateData.list.push( this ); + + var forms = Util.copyArray( elmForm.getElementsByTagName( '*' ) ), + l = forms.length, + i = 0, + items = 'input,select,textarea,button', + form, data, el, wrap; + for( ; i
' ); + elm.appendChild( el ); + data = new FormItemData(); + wrap = document.createElement( 'div' ); + form.parentNode.insertBefore( wrap, form ); + wrap.className = CLASSNAME_FILE_WRAP; + wrap.appendChild( form ); + data.init( this, this.ui.createFileInput( el, data.onUpdate, null, form ) ); + this.itemList.push( data ); + break; + case 'button': + break; + default: + continue; + }; + break; + case 'select': + break; + case 'button': + break; + case 'textarea': + break; + default: + continue; + }; + }; + }, + destroy : function(){ + + } + }; + FormPrivateData.list = []; + FormPrivateData.get = function( from ){ + var list = FormPrivateData.list, + i = list.length; + for( ; i; ){ + if( list[ --i ].form === form ) return list[ i ]; + }; + return null; + }; + + var FormClass = function( apiuser, node, elm, elmForm ){ + ( new FormPrivateData() ).init( apiuser, this, node, elm, elmForm ); + }; + FormClass.prototype = { + createTextInput : function(){ + + }, + createMultiLineInput : function(){ + + }, + createFileInput : function(){ + + }, + createButton : function(){ + + }, + createComboBox : function(){ + + }, + submit : function(){ + + } + }; + + return { + createForm: function( apiuser, nodeOrElm, opt_elmForm ){ + var uid = apiuser.getUID(), + list = FORM_LIST[ uid ], + node, elm, form; + if( PointingDeviceEventTree.isNodeInstance( nodeOrElm ) === true ){ + node = nodeOrElm; + elm = PointingDeviceEventTree._getNodePrivateData( nodeOrElm ).elm; + } else { + // App が eventTree を持っている? + // App が eventTree を持っていない + elm = nodeOrElm; + }; + form = new FormClass( apiuser, node, elm, opt_elmForm ); + if( Type.isArray( list ) === false ){ + list = FORM_LIST[ uid ] = []; + }; + list.push( form ); + return form; + }, + onWindowResize: function( w, h ){ + windowW = w; + windowH = h; + currentItem instanceof ComboBoxClass && OptionControl.onWindowResize( w, h ); + currentItem instanceof TextInputClass && TextInputManager.onWindowResize( w, h ); + currentItem instanceof FileInputClass && FileInputManager.onWindowResize( w, h ); + }, + onCurrentApplicationChange: function( _apiuser ){ + }, + onApplicationShutdown: function( _apiuser ){ + }, + onSystemShutdown: function(){ + + } + }; +})(); + +var Finder = ( function(){ + var FINDER_LIST = [], + ELM_ORIGIN_LOCATION_ITEM = Util.pullHtmlAsTemplete( '
' ), + HTML_FINDER_ICON = ( function(){ + return ( UA.isIE === true && UA.ieVersion < 8 ? + [ + '
', + '
', + '
', + '', + '', + '', + 'file name', + '', + '', + '', + '', + '', + '', + 'file descriptiion', + '', + '', + '', + '
', + '
' + ] : + [ + '
', + '
', + '
', + '
file name
', + '
file descriptiion
', + '
>
', + '
' + ] ).join( '' ); + })(), + ELM_ORIGIN_FINDER_ICON = Util.pullHtmlAsTemplete( HTML_FINDER_ICON ), + ICON_HEIGHT = Util.getElementSize( ELM_ORIGIN_FINDER_ICON ).height; + + // t : 時間 + // b : 開始の値(開始時の座標やスケールなど) + // c : 開始と終了の値の差分 + // d : Tween(トゥイーン)の合計時間 + + function easeOutQuad( t, b, c, d ){ + t /= d; + return -c * t*( t-2 ) + b; + }; + +/** + * FinderIconClass + */ + var FinderIconClass = function(){}; + FinderIconClass.prototype = { + finderData : null, + file : null, + elm : null, + node : null, + _index : -1, + _style : -1, + init : function( page, file, w, index, style ){ + if( !this.elm ) this.elm = ELM_ORIGIN_FINDER_ICON.cloneNode( true ); + + if( this.page !== page ){ + this.page = page; + page.elm.appendChild( this.elm ); + this.node && this.node.remove(); + this.node = page.node.createNode( this.elm, false, true, 'finder-icon-hover', '' ); + }; + if( this.file !== file ){ + this.file && this.file.destroy(); + this.file = file; + this._index = index; + this.draw( w ); + return; + }; + if( this._index !== index ){ + this._index = index; + this.resize( w ); + }; + }, + index : function( _index ){ + return this._index; + }, + style : function( _style ){ + return this._style; + }, + draw : function( w ){ + var file = this.file, + elm = this.elm, + thumb = file.getThumbnail(), + elmThumb = Util.getElementsByClassName( elm, 'file-icon' )[ 0 ].firstChild, + elmName = Util.getElementsByClassName( elm, 'finder-icon-filename' )[ 0 ], + elmDesc = Util.getElementsByClassName( elm, 'finder-icon-summary' )[ 0 ]; + if( thumb.image ){ + elmThumb.className = 'has-thumbnail'; + elmThumb.style.backgroundImage = [ 'url(', thumb.image, ')' ].join( '' ); + } else { + elmThumb.className = thumb.className; + elmThumb.style.backgroundImage = ''; + }; + + elmName.firstChild.data = file.getName(); + elmDesc.firstChild.data = file.getSummary(); + + this.resize( w ); + }, + resize : function( w ){ + this.node.update( 0, this._index * ICON_HEIGHT, w ); + }, + onEditorClick : function( e ){ + this.onEditorCallback && this.onEditorCallback( this.file, this.file.editorApplicationList()[ 0 ] ); + return false; + }, + onViwerClick : function( e ){ + this.onViewerCallback && this.onViewerCallback( this.file, this.file.viewerApplicationList()[ 0 ] ); + return false; + }, + onActionClick : function( e ){ + this.onActionCallback && this.onActionCallback( this.file ); + return false; + }, + destroy : function(){ + this.elm && this.elm.parentNode.removeChild( this.elm ); + this.file && this.file.destroy(); + this.node && this.node.remove(); + delete this.page; + delete this.file; + delete this.node; + delete this._index; + delete this._style; + FinderIconClass.pool.push( this ); + } + }; + FinderIconClass.pool = []; + FinderIconClass.get = function( page, file, w, index, style ){ + var _icon = FinderIconClass.pool.length > 0 ? FinderIconClass.pool.shift() : new FinderIconClass(); + _icon.init( page, file, w, index, style ); + return _icon; + }; + +/** + * PathClass + */ + var PathClass = function(){}; + PathClass.prototype = { + finderData : null, + elm : null, + node : null, + file : null, + _index : null, + w : 0, + init : function( finderData, file, index ){ + if( !this.elm ) this.elm = ELM_ORIGIN_LOCATION_ITEM.cloneNode( true ); + + if( this.finderData !== finderData ){ + this.finderData = finderData; + finderData.elmPath.appendChild( this.elm ); + this.node && this.node.remove(); + delete this.node; + }; + if( this.file !== file ){ + this.file = file; + this.draw(); + }; + this._index = index; + if( !this.node ) this.node = finderData.nodePath.createNode( this.elm, false, true, 'finder-path-hover', 'pointer' ); + }, + draw : function(){ + this.elm.className = 'file-icon-' + this.file.getType(); + this.elm.innerHTML = this.file.getName(); + }, + textWidth : function(){ + this.elm.style.width = 'auto'; + var ret = this.elm.offsetWidth; + this.elm.style.width = ''; + return ret + 15; + }, + update : function( x, w ){ + this.node.update( x - 15, undefined, w ); + }, + index : function( _index ){ + return this._index; + }, + destroy : function(){ + this.finderData.elmPath.removeChild( this.elm ); + this.node && this.node.remove(); + + delete this.finderData; + delete this.elm; + delete this.node; + delete this.file; + delete this._index; + PathClass.pool.push( this ); + } + }; + PathClass.pool = []; + PathClass.get = function( finderData, file, index ){ + var _bread = PathClass.pool.length > 0 ? PathClass.pool.shift() : new PathClass(); + _bread.init( finderData, file, index ); + return _bread; + }; + + + /** + * Page + */ + var PageClass = function(){}; + PageClass.prototype = { + nodeRoot : null, + elmRoot : null, + elmScroll : null, + elm : null, + node : null, + folder : null, + iconList : null, + sliding : false, + currentX : 0, + panTime : 0, + startX : 0, + offsetX : 0, + panTotalTime : 0, + isPanOut : false, + init : function( nodeRoot, elmRoot, elmScroll ){ + this.nodeRoot = nodeRoot; + this.elmRoot = elmRoot; + this.elmScroll = elmScroll; + + if( this.elm === null ){ + this.elm = document.createElement( 'div' ); + }; + elmScroll.appendChild( this.elm ); + this.elm.style.cssText = 'position:absolute;top:0;'; + // this.elm.style.display = 'none'; + this.node = this.nodeRoot.createNode( this.elm, true, false ); + if( this.iconList === null ){ + this.iconList = []; + }; + }, + panInReady : function( way ){ + this.elm.style.display = ''; + var x = this.sliding === true ? this.currentX : way * this.nodeRoot.width(); + this.startX = this.currentX = x; + this.targetX = 0; + this.offsetX = -x; + this.panTime = 0; + this.panTotalTime = 20; + this.sliding = true; + this.isPanOut = false; + // this.elm.style.left = x + 'px'; + this.node.x( x ); + }, + panOutReady : function( way ){ + var x = -way * this.nodeRoot.width(); + this.startX = this.currentX || 0; + this.targetX = x; + this.offsetX = x - this.startX; + this.panTime = 0; + this.panTotalTime = 20; + this.sliding = true; + this.isPanOut = true; + }, + pan : function(){ + var page = this, + x = page.currentX = easeOutQuad( page.panTime, page.startX, page.offsetX, page.panTotalTime ); + // page.elm.style.left = x + 'px'; + this.node.x( x ); + if( page.panTotalTime < ++page.panTime ){ + delete page.panTime; + delete page.startX; + delete page.offsetX; + delete page.panTotalTime; + delete page.sliding; + if( this.isPanOut === true ) this.elm.style.display = 'none'; + }; + }, + draw : function( folder ){ + var _w = this.nodeRoot.width(); + this.folder = folder; + var data = this, + iconList = data.iconList, + i = 0, + j = 0, + l = folder.getChildFileLength(), + m = iconList.length, + scrollY = -this.nodeRoot.scrollY(), + rootH = scrollY + this.nodeRoot.height(), + icon; + + for( ; i < l; ++i ){ + if( ( i + 1 ) * ICON_HEIGHT < scrollY || rootH < i * ICON_HEIGHT ) continue; + if( j < m ){ + iconList[ j ].init( this, folder.getChildFileAt( i ), _w, i, data.style ); + } else { + iconList.push( FinderIconClass.get( this, folder.getChildFileAt( i ), _w, i, data.style ) ); + }; + j++; + }; + data.elmRoot.className = folder.getState() === Const.FILE.STATE.LOADING ? 'finder-body loading' : 'finder-body'; + // data.elmRoot.style.height = ( data.h - data.headH ) + 'px'; + + while( j < iconList.length ) iconList.pop().destroy(); + data.elmScroll.style.height = ( l * ICON_HEIGHT ) + 'px'; + }, + onScroll : function(){ + var _w = this.nodeRoot.width(); + + var data = this, + iconList = data.iconList, + folder = this.folder, + i = 0, + j = 0, + l = folder.getChildFileLength(), + scrollY = -this.nodeRoot.scrollY(), + rootH = scrollY + this.nodeRoot.height(), + startIndex = 0 < iconList.length ? iconList[ 0 ]._index : 0, + icon; + + // console.log( ' > ' + scrollY + ' , ' + rootH ) + for( ; i < l; ++i ){ + if( ( i + 1 ) * ICON_HEIGHT < scrollY || rootH < i * ICON_HEIGHT ){ + if( iconList.length <= j ) continue; + icon = iconList[ j ]; + if( icon._index !== i ) continue; + icon.destroy(); + iconList.splice( j, 1 ); + continue; + }; + if( iconList.length <= j || iconList[ j ]._index !== i ){ + if( i < startIndex ){ + iconList.splice( j, 0, FinderIconClass.get( this, folder.getChildFileAt( i ), _w, i, data.style ) ); + } else + if( startIndex + iconList.length <= i ){ + iconList.push( FinderIconClass.get( this, folder.getChildFileAt( i ), _w, i, data.style ) ); + }; + }; + ++j; + }; + + //while( j < iconList.length ) iconList.pop().destroy(); + }, + resize : function( w ){ + var list = this.iconList, + i = list.length; + for( ; i; ) list[ --i ].resize( w ); + }, + destroy : function(){ + var icon; + while( icon = this.iconList.shift() ) icon.destroy(); + + this.elm.parentNode.removeChild( this.elm ); + } + }; + + var ApplicationButton = function(){}; + ApplicationButton.prototype = { + elm : null, + button : null, + app : null, + file : null, + fileUID : -1, + init : function( ui, elmParent, app, file ){ + if( this.elm === null ){ + this.elm = document.createElement( 'div' ); + }; + elmParent.appendChild( this.elm ); + this.elm.className = 'button'; + this.elm.innerHTML = app.getDisplayName(); + + var that = this; + this.button = ui.createButton( this.elm, function(){ + that.onClick(); + // that = null; + } ); + + this.app = app; + this.file = file; + this.fileUID = file.getUID(); + }, + onClick : function(){ + this.app.boot( this.file ); + return false; + }, + destroy : function(){ + var elm = this.elm; + elm.parentNode.removeChild( elm ); + + this.button.destroy(); + //this.kill() + //this.elm = elm; + } + }; + + var DetailPageClass = function(){}; + DetailPageClass.prototype = Util.extend( new PageClass(), { + appButtons : null, + init : function( finderData ){ + this.finderData = finderData; + this.apiuser = finderData.apiuser; + this.nodeRoot = finderData.nodeRoot; + this.elmRoot = finderData.elmRoot; + this.elmScroll = finderData.elmScroll; + + if( this.elm === null ){ + this.elm = Util.pullHtmlAsTemplete( [ + '
', + '
', + '
file name
', + '
file descriptiion
', + '
View this file
', + '
', + '
Edit this file
', + '
', + '
' + ].join( '' ) ); + }; + this.elm.style.display = 'none'; + this.elmScroll.appendChild( this.elm ); + this.node = this.nodeRoot.createNode( this.elm, true, false ); + + this.ui = this.apiuser.createUIGroup( this.node ); + this.appButtons = []; + }, + draw : function( file ){ + var elm = this.elm, + thumb = file.getThumbnail(), + elmThumb = Util.getElementsByClassName( elm, 'file-icon' )[ 0 ].firstChild, + elmName = Util.getElementsByClassName( elm, 'finder-detail-filename' )[ 0 ], + elmDesc = Util.getElementsByClassName( elm, 'finder-detail-summary' )[ 0 ], + tmpButtons = Util.copyArray( this.appButtons ), + apps, app, elmContainer, button; + if( thumb.image ){ + elmThumb.className = 'has-thumbnail'; + elmThumb.style.backgroundImage = [ 'url(', thumb.image, ')' ].join( '' ); + } else { + elmThumb.className = thumb.className; + elmThumb.style.backgroundImage = ''; + }; + + elmName.firstChild.data = file.getName(); + elmDesc.firstChild.data = file.getSummary(); + this.node.width( this.nodeRoot.width() ); + this.node.height( this.nodeRoot.height() ); + + this.appButtons.length = 0; + + apps = file.viewerApplicationList(); + elmContainer = Util.getElementsByClassName( elm, 'viewer-apps' )[ 0 ]; + for( i = 0; i < apps.length; ++i ){ + button = 0 < tmpButtons.length ? tmpButtons.shift() : new ApplicationButton(); + button.init( this.ui, elmContainer, apps[ i ], file ); + this.appButtons.push( button ); + }; + apps = file.editorApplicationList(); + elmContainer = Util.getElementsByClassName( elm, 'editor-apps' )[ 0 ]; + for( i = 0; i < apps.length; ++i ){ + button = 0 < tmpButtons.length ? tmpButtons.shift() : new ApplicationButton(); + button.init( this.ui, elmContainer, apps[ i ], file ); + this.appButtons.push( button ); + }; + + while( button = tmpButtons.shift() ) button.destroy(); + + this.resize(); + }, + pan : function(){ + var page = this, + x = page.currentX = easeOutQuad( page.panTime, page.startX, page.offsetX, page.panTotalTime ); + // page.elm.style.left = x + 'px'; + this.node.x( x ); + if( page.panTotalTime < ++page.panTime ){ + delete page.panTime; + delete page.startX; + delete page.offsetX; + delete page.panTotalTime; + delete page.sliding; + if( this.isPanOut === true ) this.elm.style.display = 'none'; + }; + }, + onScroll : function(){ + + }, + resize : function(){ + this.elmScroll.style.height = this.nodeRoot.height() + 'px'; + }, + destroy : function(){ + var button; + while( button = this.appButtons.shift() ) button.destroy(); + this.ui.destroy(); + this.node.remove(); + } + }); + +/** + * FinderPrivateData + */ + var FinderPrivateData = Class.create( + Class.PRIVATE_DATA, { + finder : null, + apiuser : null, + elmRoot : null, + nodeRoot : null, + elmScroll : null, + elmPath : null, + nodePath : null, + tree : null, + onSelect : null, + viewerOption : null, + editorOption : null, + pathList : null, + headH : 0, + iconW : 0, + iconH : 0, + style : 0, + pageIcons1 : null, + pageIcons2 : null, + panInPage : null, + panOutPage : null, + pageDetail : null, + currentFile : null, + Constructor : function( finder, apiuser, elm, tree, onSelect, viewerOption, editorOption ){ + this.finder = finder; + this.apiuser = apiuser; + if( PointingDeviceEventTree.isNodeInstance( elm ) === true ){ + this.nodeRoot = elm; + this.elmRoot = PointingDeviceEventTree._getNodePrivateData( elm ).elm; + } else { + // App が eventTree を持っている? + // App が eventTree を持っていない + this.elmRoot = elm; + }; + this.nodeRoot.addEventListener( 'click', this.onIconClick, this ); + this.nodeRoot.addEventListener( 'scroll', this.onScroll, this ); + + this.elmScroll = document.createElement( 'div' ); + this.elmRoot.appendChild( this.elmScroll ); + this.elmScroll.className = 'finder-elm-scroll'; + this.elmScroll.style.cssText = 'width:100%;overflow:hidden;'; + + this.tree = tree; + this.onSelect = onSelect; + this.viewerOption = viewerOption; + this.editorOption = editorOption; + + var size = Util.getElementSize( ELM_ORIGIN_FINDER_ICON ); + this.iconW = size.width; + this.iconH = size.height; + + tree.addTreeEventListener( Const.TREE.EVENT.UPDATE, this.draw, this ); + Util.addClass( this.elmRoot, 'finder-body' ); + + if( this.panInPage === null ){ + this.pageIcons1 = new PageClass(); + this.pageIcons2 = new PageClass(); + this.pageDetail = new DetailPageClass(); + }; + this.pageIcons1.init( this.nodeRoot, this.elmRoot, this.elmScroll ); + this.pageIcons2.init( this.nodeRoot, this.elmRoot, this.elmScroll ); + this.pageDetail.init( this ); + }, + onIconClick : function( e ){ + if( this.panInPage === this.pageDetail ) return; + + var target = e.target, + list = this.panInPage.iconList, + i, icon, + file; + if( target === this.nodeRoot ) return; + for( i = list.length; i; ){ + icon = list[ --i ]; + if( icon.node === target ){ + i = icon._index; + file = this.currentFile.getChildFileAt( i ); + if( target.width() - 30 < e.layerX ){ + this.tree.down( i ); + this.draw( this.w, this.h, 1, true ); + } else + if( file.getChildFileLength() !== -1 || file.getType() === Const.FILE.TYPE.FOLDER ){ + this.tree.down( i ); + this.draw( this.w, this.h, 1 ); + } else + if( Type.isFunction( this.onSelect ) === true ){ /* && this.onSelect( file ) === true */ + this.onSelect( file ); + } else { + this.tree.down( i ); + this.draw( this.w, this.h, 1 ); + }; + file.destroy(); + break; + }; + }; + }, + onScroll : function( e ){ + this.panInPage.onScroll( e ); + }, + onPathClick : function( e ){ + var target = e.target, + i = target.nodeIndex(); + if( target === this.nodePath || this.nodePath.numNode() - 1 === i ) return; + this.tree.up( i ); + this.draw( this.w, this.h, -1 ); + }, + draw : function( w, h, way, showDetail ){ + var data = this, page; + data.w = w = Type.isFinite( w ) === true ? w : data.w; + data.h = h = Type.isFinite( h ) === true ? h : data.h; + + var file = this.currentFile = this.tree.getCurrentFile(), + isFolder = showDetail !== true && ( file.getChildFileLength() !== -1 || file.getType() === Const.FILE.TYPE.FOLDER ); + + data.elmPath && data.drawPath( w ); + page = this.panInPage; + if( Type.isNumber( way ) === true ){ + if( page.sliding === false ){ + if( isFolder === true ){ + this.panInPage = page === this.pageIcons1 ? this.pageIcons2 : ( page === this.pageIcons2 ? this.pageIcons1 : this.panOutPage ); + } else { + this.panInPage = this.pageDetail; + }; + this.panOutPage = page; + }; + this.panInPage.panInReady( way ); + //this.panInPage.elm.className = 'panIN'; + this.panOutPage.panOutReady( way ); + //this.panOutPage.elm.className = 'panOut'; + this.nodeRoot.disabled( true ); + SystemTimer.add( this.apiuser, this.tick, 16, false, this ); + } else { + if( isFolder === true ){ + this.panInPage = page === null ? this.pageIcons1 : page; + } else { + this.panInPage = this.pageDetail; + }; + }; + this.panInPage.draw( file ); + + data.nodeRoot.invalidateScrollbar(); + }, + tick : function(){ + if( this.panInPage.sliding === false && this.panOutPage.sliding === false ){ + SystemTimer.remove( this.apiuser, this.tick ); + this.nodeRoot.disabled( false ); + this.nodeRoot.invalidateScrollbar(); + return; + }; + this.panInPage.sliding === true && this.panInPage.pan(); + this.panOutPage.sliding === true && this.panOutPage.pan(); + }, + drawPath : function( w ){ + if( !this.elmPath.parentNode ) return; + w = this.nodePath.width(); + var data = this, + tree = data.tree, + pathList = data.pathList, + i = 0, + l = tree.hierarchy() + 1, + m = pathList.length, + wList = [], + totalW = 0, + minW = FinderPrivateData.MIN_PATH_WIDTH, + file, path, pathW, offset, remove, pathX = 0, fit = false; + + for( ; i < l; ++i ){ + file = i !== l - 1 ? tree.getParentFileAt( i ) : this.currentFile; + if( i < m ){ + pathList[ i ].init( this, file, i ); + } else { + pathList.push( PathClass.get( this, file, i ) ); + }; + }; + while( l < pathList.length ) pathList.pop().destroy(); + + for( i = l; i; ){ + pathW = pathList[ --i ].textWidth(); + wList.push( pathW ); + totalW += pathW; + }; + + //if( minW * ( l + 1 ) * 1.2 < w ){ + console.log( totalW + ' , ' + w ) + while( true ){ + if( fit === true ) break; + for( i = 0; i < l; ++i ){ + offset = totalW - w; + if( offset <= 0 ){ + fit = true; + break; + }; + remove = l - i; + remove = offset < remove ? offset : remove; + pathW = wList[ i ]; + if( pathW - remove < minW ){ + totalW -= ( pathW - minW ); + wList[ i ] = minW; + } else { + wList[ i ] = pathW - remove; + totalW -= remove; + }; + }; + }; + for( i = 0; i < l; ++i ){ + path = pathList[ i ]; + pathW = wList[ i ]; + path.update( pathX, pathW ); + pathX += pathW; + }; + //} else { + + //}; + }, + createPath : function( node ){ + if( this.elmPath ) return; + + if( PointingDeviceEventTree.isNodeInstance( node ) === true ){ + this.nodePath = node; + this.elmPath = PointingDeviceEventTree._getNodePrivateData( node ).elm; + + node.addEventListener( 'click', this.onPathClick, this ); + Util.addClass( this.elmPath, 'finder-path' ); + // this.elmPath = document.createElement( 'div' ); + // this.elmPath.className = ; + this.pathList = []; + // this.headH = 0; + AsyncCall.add( this.apiuser, this.draw, null, this ); + }; + }, + onKill : function(){ + this.tree.removeTreeEventListener( Const.TREE.EVENT.UPDATE, this.draw ); + + if( this.pathList ){ + while( this.pathList.length > 0 ) this.pathList.shift().destroy(); + }; + + this.pageIcons1.destroy(); + this.pageIcons2.destroy(); + this.pageDetail.destroy(); + this.nodeRoot.remove(); + + FINDER_LIST.splice( Util.getIndex( FINDER_LIST, this.finder ), 1 ); + var data = ApplicationPrivateData.get( this.apiuser ), + list = data.finderList, + i = Util.getIndex( list, this.finder ); + i !== -1 && list.splice( i, 1 ); + } + }); + FinderPrivateData.MIN_PATH_WIDTH = 25; + +/** + * FinderClass + */ + var Finder = Class.create( + FinderPrivateData, { + Constructor : function( application, elmRoot, tree, onSelect, viewerOption, editorOption ){ + Finder.newPrivateData( this, this, application, elmRoot, tree, onSelect, viewerOption, editorOption ); + }, + MIN_WIDTH : 200, + MIN_HEIGHT : 200, + resize : function( w, h ){ + var data = Finder.getPrivateData( this ); + data.panInPage && data.panInPage.resize( w ); + }, + createPath : function( node ){ + return Finder.getPrivateData( this ).createPath( node ); + }, + destroy : function(){ + this.kill(); + } + }); + + return { + init: function(){ + + }, + create: function( application, elmTarget, tree, onSelect, viewerOption, editorOption ){ + //if( Application.isApplicationInstance( _application ) === false ) return; + + var finder = new Finder( application, elmTarget, tree, onSelect, viewerOption, editorOption ); + FINDER_LIST.push( finder ); + return finder; + }, + registerFinderHead: function(){ + + }, + registerFinderPane: function( _finderPane ){ + + }, + isFinderInstance: function( _finder ){ + return _finder instanceof Finder; + }, + isFinderPaneInstance: function(){ + + }, + isFinderHeadInstance: function(){ + } + }; +})(); + + +/* + * -- len, % + * marginBottom, marginLeft, marginRight, marginTop, margin + * padding, paddingBottom, paddingLeft, paddingRight, paddingTop + * fontSize, textIndent + * height, width + * bottom, left, right, top (len, %) + * + * -- len + * borderBottomWidth, borderLeftWidth, borderRightWidth, borderTopWidth, borderWidth, + * letterSpacing + * + * -- color + * backgroundColor + * borderBottomColor, borderLeftColor, borderRightColor, borderTopColor, borderColor + * color + * + * -- special + * clip rect(0px, 40px, 40px, 0px); + * backgroundPosition (len, %) + * opacity + * lineHeight (len, %, num) + * zIndex ( order ) + */ + +var DHTML = ( function(){ + + var TICKET_ARRAY = [], + fpms = 50, + round = Math.round, + cround = function( v ){ return round( v * 100 ) / 100 }; + + function startAnimation( _elm, _cssObject, _onComplete, _onEnterFrame, _numFrames ){ + var _ticket, i = TICKET_ARRAY.length; + for( ; i; ){ + _ticket = TICKET_ARRAY[ --i ]; + if( _ticket.elm === _elm ){ + return; + }; + }; + + var _currentValues = [], + _offsetValues = [], + _endValues = [], + _targetProperties = [], + _units = []; + var target, current, + inlineStyle = CSS.getInlineStyle( _elm ), + currentStyle = CSS.getWrappedStyle( _elm ), + targetStyle = CSS.getWrappedStyle( _elm, _cssObject ); + targetStyle.pxPerEm = currentStyle.get( 'fontSize' )._toPx(); + for( var p in _cssObject ){ + p = Util.camelize( p ); + target = targetStyle.get( p ); + current = currentStyle.get( p ); + + if( target.isValid() === false || current.isValid() === false || current.equal( target ) !== false ){ + target.clear(); + current.clear(); + continue; + }; + + current.convert( target ); + // alert( current.getValue() + ' , ' + target.getValue() ) + _currentValues.push( current.getValue() ); + _offsetValues.push( current.getOffset( target ) ); + _endValues.push( target.getValue() ); + _targetProperties.push( p ); + _units.push( target.getUnit() ); + + // IE has trouble with opacity if it does not have layout + // Force it by setting the zoom level + if( p === 'opacity' && SPECIAL.hasLayout ){ + if( SPECIAL.hasLayout( _elm ) === false ) inlineStyle.zoom = 1; + inlineStyle.filter = current.getValueText(); + } else { + inlineStyle[ p ] = current.getValueText(); + }; + + target.clear(); + current.clear(); + }; + + var i, cssTexts = []; + for( i = 0; i < _numFrames; ++i ){ + if( i < _numFrames - 1 ){ + tickValue( _currentValues, _offsetValues, _numFrames ); + cssTexts.push( createCssText( _currentValues, _targetProperties, targetStyle, inlineStyle ) ); + } else { + cssTexts.push( createCssText( _endValues, _targetProperties, targetStyle, inlineStyle ) ); + }; + }; + + TICKET_ARRAY.push( new AnimationTaskClass( + _elm, cssTexts, + Type.isFunction( _onComplete ) === true ? _onComplete : null, + Type.isFunction( _onEnterFrame ) === true ? _onEnterFrame : null, + _numFrames + ) ); + + currentStyle.clear(); + targetStyle.clear(); + SystemTimer.add( SUPER_USER_KEY, onEnterFrame, 1000 / fpms ); + }; + + function tickValue( current, offset, numFrames ){ + if( Type.isArray( current ) === true ){ + var ret, i = current.length; + for( ; i; ){ + --i; + ret = tickValue( current[ i ], offset[ i ], numFrames ); + if( Type.isNumber( ret ) === true ) current[ i ] = ret; + }; + } else { + return current + offset / numFrames; + }; + }; + function createCssText( update, props, style, inline ){ + var prop; + for( var i = props.length; i; ){ + prop = style.get( props[ --i ] ); + prop.setValue( update[ i ] ); + inline[ Util.uncamelize( prop.name ) ] = prop.getValueText(); + //if( prop.name === 'backgroundColor' ) alert( prop.getValueText() + '|' + update[ i ].join( ',') ) + prop.clear(); + }; + return CSS.toCssText( inline ); + }; + + function onEnterFrame(){ + var _ticket, l, + i = 0; + while( i < TICKET_ARRAY.length ){ + _ticket = TICKET_ARRAY[ i ]; + l = _ticket.cssTexts.length; + _ticket.elm.style.cssText = _ticket.cssTexts.shift(); + if( l === 1 ){ + _ticket.onComplete && _ticket.onComplete(); + delete _ticket.elm; + delete _ticket.cssTexts; + delete _ticket.onComplete; + delete _ticket.onEnterFrame; + delete _ticket.numFrame; + TICKET_ARRAY.splice( i, 1 ); + } else { + _ticket.onEnterFrame && _ticket.onEnterFrame( l / _ticket.numFrame ); + ++i; + }; + }; + if( TICKET_ARRAY.length === 0 ){ + SystemTimer.remove( SUPER_USER_KEY, onEnterFrame ); + }; + }; + + var AnimationTaskClass = function( elm, cssTexts, onEnterFrame, onComplete, numFrame ){ + this.elm = elm; + this.cssTexts = cssTexts; + this.onEnterFrame = onEnterFrame; + this.onComplete = onComplete; + this.numFrame = numFrame; + }; + + var VisualEffectClass = function( elm ){ + this.elm = elm; + }; + VisualEffectClass.prototype = { + anime : function( _cssObject, _onComplete, _onEnterFrame, _time ){ + var _numFrames = Math.floor( _time / fpms ); + startAnimation( this.elm, _cssObject, _onComplete, _onEnterFrame, _numFrames ); + }, + fadeIn : function(){ + + }, + fadeOut : function(){ + + }, + update : function( x, y, w, h ){ + var _cssText = this.elm.style.cssText; + } + }; + + return { + create: function( application, _elm ){ + return new VisualEffectClass( _elm ); + }, + isInstanceOfVisualEffect: function( _instance){ + return _instance instanceof VisualEffectClass; + } + } +})(); + + +/* -------------------------------------------- + * + */ + + Application.onCurrentApplicationChange( SUPER_USER_KEY ); + + SERVICE_LIST.push( MouseEvent ); + + new EventTicketClass( window, 'unload', function(){ + var _service; + while( SERVICE_LIST.length > 0 ){ + _service = SERVICE_LIST.shift(); + Type.isFunction( _service.onSystemShutdown ) === true && _service.onSystemShutdown(); + } + }); + // beforeunload + + +/* --------------------------------------------- + * broadcast to global + */ + window.gOS = {}; + + gOS.registerApplication = Application.register; + gOS.registerDriver = File.registerDriver; + +})( window, document ); -- 2.11.0 From acc1454b8956c5191f5a7492c47f373957c527ee Mon Sep 17 00:00:00 2001 From: itozyun Date: Tue, 26 Feb 2013 07:16:16 +0900 Subject: [PATCH 07/16] add xdoc.js --- 0.5.x/javascripts/xdoc.js | 1986 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1986 insertions(+) create mode 100644 0.5.x/javascripts/xdoc.js diff --git a/0.5.x/javascripts/xdoc.js b/0.5.x/javascripts/xdoc.js new file mode 100644 index 0000000..712ba3d --- /dev/null +++ b/0.5.x/javascripts/xdoc.js @@ -0,0 +1,1986 @@ +var BoxModel; + +var DOM = ( function( window, document ){ + var DIV_LIST = [], + SPAN_LIST = [], + TEXT_LIST = []; + + var elmTextSize; + + function correctNodes( node ){ + var child; + if( node && node.parentNode ){ + while( node.lastChild ) correctNodes( node.lastChild ); + node.parentNode.removeChild( node ); + if( node.nodeType === 1 ){ + switch( node.tagName ){ + case 'DIV': + DIV_LIST.push( node ); + break; + case 'SPAN': + SPAN_LIST.push( node ); + break; + + }; + node.removeAttribute( 'className' ); + node.removeAttribute( 'style' ); + node.removeAttribute( 'id' ); + } else + if( node.nodeType === 3 ){ + node.data = ''; + TEXT_LIST.push( node ); + }; + }; + }; + + return { + createDiv : function(){ + return 0 < DIV_LIST.length ? DIV_LIST.shift() : document.createElement( 'div' ); + }, + createSpan : function(){ + + }, + createText : function(){ + + }, + getTextSize : function( elm, content ){ + var span = DOM.createSpan(), + text = DOM.createText(), + w, h; + elm.appendChild( span ); + span.style.cssText = 'visibility:hidden;position:absolute;'; + span.appendChild( text ); + text.data = content; + w = span.offsetWidth; + h = span.offsetHeight; + DOM.correctNodes( span ); + return [ w, h ]; + }, + getTextHeight : function( elm, w, content ){ + var div = DOM.createSpan(), + text = DOM.createText(), + w, h; + elm.appendChild( div ); + div.style.cssText = 'visibility:hidden;position:absolute;width:' + w + 'px;'; + div.appendChild( text ); + text.data = content; + w = div.offsetWidth; + h = div.offsetHeight; + DOM.correctNodes( div ); + return h; + }, + correctNodes : function( node ){ + var child; + if( node && node.parentNode ){ + while( node.lastChild ) DOM.correctNodes( node.lastChild ); + node.parentNode.removeChild( node ); + if( node.nodeType === 1 ){ + switch( node.tagName ){ + case 'DIV': + DIV_LIST.push( node ); + break; + case 'SPAN': + SPAN_LIST.push( node ); + break; + + }; + node.removeAttribute( 'className' ); + node.removeAttribute( 'style' ); + node.removeAttribute( 'id' ); + } else + if( node.nodeType === 3 ){ + node.data = ''; + TEXT_LIST.push( node ); + }; + }; + } + } +})( window, document ); + +var XBrowserStyle = ( function(){ + var EMPTY = '', + CORON = ':', + SEMICORON = ';', + SPACE = ' ', + UNITS = 'px,cm,mm,in,pt,pc,em,%'.split( ',' ), + CLIP_SEPARATOR = UA.isIE === true && UA.ieVersion < 8 ? ' ' : ','; + + var SPECIAL = ( function(){ + var special = {}; + if( UA.isIE === true && UA.ieVersion < 9 ){ + if( UA.ACTIVEX === true ){ + // special.opacity = 'ActiveXOpacity'; + special.setFilters = function( style ){ + var filters = ( style.filter || '' ).split( ') ' ), + data = {}, + i = filters.length, + filter, names, props, prop, j, l, key, v; + for( ; i; ){ + filter = filters[ --i ].split( ' ' ).join( '' ).split( '(' ); + if( filter.length !== 2 ) continue; + names = filter[ 0 ].split( '.' ); // progid:DXImageTransform.Microsoft.Shadow(color=#666666,direction=120,strength=9) + props = filter[ 1 ].split( ',' ); // + filter = {}; + for( j = 0, l = props.length; j < l; ++j ){ + prop = props[ j ].split( '=' ); + key = prop[ 0 ].toLowerCase(); + v = prop[ 1 ]; + filter[ key ] = v; //v.charAt( 0 ) === '#' ? v : parseInt( v ); + }; + data[ names[ names.length - 1 ] ] = filter; + }; + + style.filter = data; + style.opacity = data.alpha && data.alpha.opacity ? data.alpha.opacity / 100 : 1; + }; + special.hasLayout = function( elm ){ + return elm.currentStyle.hasLayout; + }; + } else { + special.opacity = null; + }; + } else { + var style = document.documentElement.style; + special.opacity = style.opacity !== undefined ? 'opacity' : + style.MozOpacity !== undefined ? 'MozOpacity' : + style.KhtmlOpacity !== undefined ? 'KhtmlOpacity' : + style[ '-khtml-opacity' ] !== undefined ? 'KhtmlOpacity' : null; + + // if( style.backgroundPositionX === undefined ){ + special.setBackgroundPositionXY = function( style ){ + var bgp = ( style.backgroundPosition || '' ).split( ' ' ); + style.backgroundPositionX = bgp[ 0 ] || 0; + style.backgroundPositionY = bgp[ 1 ] || 0; + }; + // }; + if( style.clipTop === undefined && style[ 'clip-top' ] === undefined ){ + special.setClipTopRightBottomLeft = function( style ){ + var clip = style.clip; + if( !cliop || clip.indexOf( 'rect(' ) === -1 ){ + style.clipTop = 0; + style.clipRight = 0; + style.clipBottom = 0; + style.clipLeft = 0; + return; + }; + clip = clip.split( '(' )[ 1 ].split( ')' )[ 0 ].split( clip.indexOf( ',' ) !== -1 ? ',' : ' ' ); + ret.clipTop = clip[ 0 ]; + ret.clipRight = clip[ 1 ]; + ret.clipBottom = clip[ 2 ]; + ret.clipLeft = clip[ 3 ]; + }; + }; + }; + return special; + })(); + + function cssToObject( css ){ + var ret = {}, i, nv, n, v, + parse = Util.parse, + isNumber = Type.isNumber, + camelize = Util.camelize; + if( Type.isString( css ) === true ){ + css = css.split( SEMICORON ); + for( i = css.length; i; ){ + nv = css[ --i ].split( CORON ); // filter の場合, progid: がくる + n = nv.shift(); + if( isNumber( parse( n ) ) === true ) continue; + v = nv.join( EMPTY ); + while( v.charAt( 0 ) === ' ' ) v = v.substr( 1 ); + ret[ camelize( n ) ] = parse( v ); + }; + } else { + for( n in css ){ + if( Type.isNumber( parse( n ) ) === false ) ret[ n ] = parse( css[ n ] ); + }; + }; + + if( SPECIAL.setFilters ){ + SPECIAL.setFilters( ret ); + } else { + ret.opacity = SPECIAL.opacity !== null ? ret[ SPECIAL.opacity ] : 1; + }; + + SPECIAL.setBackgroundPositionXY && SPECIAL.setBackgroundPositionXY( ret ); + SPECIAL.setClipTopRightBottomLeft && SPECIAL.setClipTopRightBottomLeft( ret ); + + return ret; + }; + + var COLOR = ( function(){ + var ret = {}, v, name, + list = [ + '0', 'BLACK', + 'FF0000', 'RED', + '00FF00', 'LIME', + '0000FF', 'BLUE', + 'FFFF00', 'YELLOW', + '00FFFF', 'AQUA', + '00FFFF', 'CYAN', + 'FF00FF', 'MAGENTA', + 'FF00FF', 'FUCHSIA', + 'FFFFFF', 'WHITE', + '008000', 'GREEN', + '800080', 'PURPLE', + '800000', 'MAROON', + '000080', 'NAVY', + '808000', 'OLIVE', + '008080', 'TEAL', + '808080', 'GRAY', + 'C0C0C0', 'SILVER', + '696969', 'DIMGRAY', + '708090', 'SLATEGRAY', + 'A9A9A9', 'DARKGRAY', + 'DCDCDC', 'GAINSBORO', + '191970', 'MIDNIGHTBLUE', + '6A5ACD', 'SLATEBLUE', + '0000CD', 'MEDIUMBLUE', + '4169E1', 'ROYALBLUE', + '1E90FF', 'DODGERBLUE', + '87CEEB', 'SKYBLUE', + '4682B4', 'STEELBLUE', + 'ADD8E6', 'LIGHTBLUE', + 'AFEEEE', 'PALETURQUOISE', + '40E0D0', 'TURQUOISE', + 'E0FFFF', 'LIGHTCYAN', + '7FFFD4', 'AQUAMARINE', + '006400', 'DARKGREEN', + '2E8B57', 'SEAGREEN', + '90EE90', 'LIGHTGREEN', + '7FFF00', 'CHARTREUSE', + 'ADFF2F', 'GREENYELLOW', + '32CD32', 'LIMEGREEN', + '9ACD32', 'YELLOWGREEN', + '6B8E23', 'OLIVEDRAB', + 'BCB76B', 'DARKKHAKI', + 'EEE8AA', 'PALEGOLDENROD', + 'FFFFE0', 'LIGHTYELLOW', + 'FFD700', 'GOLD', + 'DAA520', 'GOLDENROD', + 'B8860B', 'DARKGOLDENROD', + 'BC8F8F', 'ROSYBROWN', + 'CD5C5C', 'INDIANRED', + '8B4513', 'SADDLEBROWN', + 'A0522D', 'SIENNA', + 'CD853F', 'PERU', + 'DEB887', 'BURLYWOOD', + 'F5F5DC', 'BEIGE', + 'F5DEB3', 'WHEAT', + 'F4A460', 'SANDYBROWN', + 'D2B48C', 'TAN', + 'D2691E', 'CHOCOLATE', + 'B22222', 'FIREBRICK', + 'A52A2A', 'BROWN', + 'FA8072', 'SALMON', + 'FFA500', 'ORANGE', + 'FF7F50', 'CORAL', + 'FF6347', 'TOMATO', + 'FF69B4', 'HOTPINK', + 'FFC0CB', 'PINK', + 'FF1493', 'DEEPPINK', + 'DB7093', 'PALEVIOLETRED', + 'EE82EE', 'VIOLET', + 'DDA0DD', 'PLUM', + 'DA70D6', 'ORCHILD', + '9400D3', 'DARKVIOLET', + '8A2BE2', 'BLUEVIOLET', + '9370DB', 'MEDIUMPURPLE', + 'D8BFD8', 'THISTLE', + 'E6E6FA', 'LAVENDER', + 'FFE4E1', 'MISTYROSE', + 'FFFFF0', 'IVORY', + 'FFFACD', 'LEMONCHIFFON' + ]; + for( i = list.length; i; ){ + v = list[ --i ]; + name = list[ --i ]; + ret[ name ] = parseInt( v, 16 ); + }; + return ret; + })(); + + var PARAMS = ( function(){ + var ret = {}; + register( ret.percent = {}, + 'marginBottom,marginLeft,marginRight,marginTop,paddingBottom,paddingLeft,paddingRight,paddingTop,fontSize,textIndent' + ); + register( ret.offset = {}, + 'height,width,bottom,left,right,top' + ); + register( ret.size = {}, + 'borderBottomWidth,borderLeftWidth,borderRightWidth,borderTopWidth,letterSpacing' + ); + register( ret.color = {}, + 'backgroundColor,borderBottomColor,borderLeftColor,borderRightColor,borderTopColor,color' + ); + register( ret.region = {}, + 'margin,padding,borderWidth,borderColor' + ); + register( ret.special = {}, + 'clip,backgroundPosition,opacity,lineHeight,zIndex' + ); + register( ret.unit = {}, 'px,cm,mm,in,pt,pc,em,%' ); + + register( ret.margin = {}, 'marginBottom,marginLeft,marginRight,marginTop,paddingBottom' ); + register( ret.padding = {}, 'paddingBottom,paddingLeft,paddingRight,paddingTop' ); + register( ret.borderWidth = {}, 'borderBottomWidth,borderLeftWidth,borderRightWidth,borderTopWidth' ); + register( ret.borderColor = {}, 'borderBottomColor,borderLeftColor,borderRightColor,borderTopColor' ); + + function register( obj, params ){ + params = params.split( ',' ); + for( var i=params.length; i; ) obj[ params[ --i ] ] = true; + }; + return ret; + })(); + + /* + * + */ + var Property = Class.create( + 'Property', + Class.POOL_OBJECT, + { + Constructor : function( name, value, unit, pxPerEm ){ + this.name = name; + this.value = value; + this.unit = unit; + this.pxPerEm = pxPerEm; // XXpx = 1em; + }, + name : '', + value : 0, + pxPerEm : 12, // 1em === ??px + unit : '', + equal : function( prop ){ + if( this.unit === prop.unit ){ + return this.value === prop.value; + }; + return Math.abs( this.toPx() - prop.toPx() ) < 1; + }, + convert: function( prop ){ + var u = prop.unit, v; + if( this.unit === u ) return; + this.value = v = this.toPx(); + this.unit = u; + if( u !== px ){ + this.value = u === 'em' ? v / this.pxPerEm : Util.pxTo( v, u ); + }; + }, + setValue: function( v ){ + this.value = v; + }, + getValue: function(){ + return this.value; + }, + getOffset: function( prop ){ + return prop.value - this.value; + }, + getUnit: function(){ + return this.unit; + }, + getValueText: function(){ + return this.value === 0 ? '0' : this.value + this.unit; + }, + toPx: function(){ + var v = this.value, u = this.unit; + if( u === px ) return v; + if( u === 'em' ) return v * this.pxPerEm; + if( u === '' && this.name === 'lineHeight' ) return v * this.pxPerEm; + return Util.toPx( v, u ); + }, + isValid: function( t ){ + t = t || this; + var n = t.name, + v = t.value, + u = t.unit, + z = u !== '' ? true : v === 0; + if( PARAMS.percent[ n ] === true ) return z; + if( PARAMS.offset[ n ] === true ) return z; + if( PARAMS.size[ n ] === true ) return z && u !== '%'; + if( PARAMS.special[ n ] === true ){ + if( n === 'lineHeight' ) return true; + if( n === 'opacity' ) return 0 <= v && v <= 1 && u === ''; + if( n === 'zIndex' ) return u === ''; + }; + return false; + } + } + ); + + /** + * backgroundPosition, clip + */ + var PropertyGroup = Class.create( + 'PropertyGroup', + Class.POOL_OBJECT, + { + Constructor : function( name ){ + this.name = name; + this.props = []; + for( var i = 1, l = arguments.length; i 1 ) return false; + }; + return true; + }, + convert : function( prop ){ + var u = prop.pct, x; + if( this.pct === u ) return; + x = u === true ? 100 / 255 : 2.55; + this.r *= x; + this.g *= x; + this.b *= x; + this.pct = u; + }, + setValue : function( rgb ){ + this.r = rgb[ 0 ]; + this.g = rgb[ 1 ]; + this.b = rgb[ 2 ]; + }, + getValue : function(){ + return [ this.r, this.g, this.b ]; + }, + getOffset : function( prop ){ + return [ prop.r - this.r, prop.g - this.g, prop.b - this.b ]; + }, + getUnit : function(){ + return this.pct === true ? '%' : ''; + }, + getValueText : function(){ + if( this.pct === true ){ + return [ 'rgb(', this.r, '%,', this.g, '%,', this.b, '%)' ].join( '' ); + }; + var round = Math.round; + //return [ 'rgb(', round( this.r ), ',', round( this.g ), ',', round( this.b ), ')' ].join( '' ); + + var rgb = '00000' + ( ( round( this.r ) << 16 ) + ( round( this.g ) << 8 ) + round( this.b ) ).toString( 16 ); + return '#' + rgb.substr( rgb.length - 6 ); + }, + _toPct : function(){ + if( this.pct === true ) return [ this.r, this.g, this.b ]; + return [ this.r / 2.55, this.g / 2.55, this.b / 2.55 ]; + }, + isValid : function( t ){ + var isFinite = window.isFinite; + if( !isFinite( this.r ) || !isFinite( this.g ) || !isFinite( this.b ) ) return false; + if( 0 > this.r || 0 > this.g || 0 > this.b ) return false; + if( this.pct === true ) return this.r <= 100 && this.g <= 100 && this.b <= 100; + return this.r <= 255 && this.g <= 255 && this.b <= 255; + } + } + ); + + var isString = Type.isString, + isNumber = Type.isNumber; + var REG_UINIT = /.*\d(\w{1,2})?/, + $1 = '$1', + px = 'px', + REG_XXXXXX = /^#[\da-fA-F]{6}?/, + REG_XXX = /^#[\da-fA-F]{3}?/; + + var WrappedStyle = Class.create( + 'WrappedStyle', + Class.POOL_OBJECT, + { + Constructor : function( style ){ + this.style = style; + var fontsize = this.get( 'fontSize' ); + this.pxPerEm = fontsize.toPx(); + fonstsize.kill(); + }, + get: function( p ){ + if( PARAMS.special[ p ] === true || PARAMS.region[ p ] === true ){ + if( p === 'clip' ) return this.getClip(); + if( p === 'margin' ) return this.getMarginPaddingBorder( p, '' ); + if( p === 'padding' ) return this.getMarginPaddingBorder( p, '' ); + if( p === 'borderWidth' ) return this.getMarginPaddingBorder( 'border', 'Width' ); + if( p === 'borderColor' ) return this.getBorderColor( 'borderColor' ); + if( p === 'backgroundPosition' ) return this.getBackgroundPosition( p ); + // opacity, zindex, lineHeight + return new Property( p, this.getValue( x ), this.getUnit( x ), this.pxPerEm ); + }; + var x = this.style[ p ], e, v, u; + if( PARAMS.offset[ p ] === true ){ + return new Property( p, this.getValue( x ), this.getUnit( x, p ), this.pxPerEm ); + /* + e = this.elm; + if( p === 'width' ) v = e.offsetWidth; + if( p === 'height' ) v = e.offsetHeight; + if( p === 'top' ) v = e.offsetTop; + if( p === 'bottom' ) v = e.offsetBottom; + if( p === 'left' ) v = e.offsetLeft; + if( p === 'right' ) v = e.offsetRight; + u = this.getUnit( x, p ); + // alert( p + this.pxTo( v, u ) + u ) + return new Property( p, this.pxTo( v, u ), u, this.pxPerEm ); */ + }; + if( p === 'fontSize' ){ // xx-small 等 + v = Util.absoluteFontSizeToPx( x ); + if( v !== 0 ){ + return new Property( p, v, px, this.pxPerEm ); + }; + }; + if( PARAMS.percent[ p ] === true ){ + // alert( p + ' , ' + x + ' , ' + this.getUnit( x, p ) ) + return new Property( p, this.getValue( x ), this.getUnit( x, p ), this.pxPerEm ); + }; + if( PARAMS.size[ p ] === true ){ + return new Property( p, this.getValue( x ), this.getUnit( x, p ), this.pxPerEm ); + }; + if( PARAMS.color[ p ] === true ){ + return this.getColor( x, p ); + }; + }, + pxTo: function( px, unit ){ + if( unit === 'em' ) return px / this.pxPerEm; + return Util.pxTo( px, unit ); + }, + getValue: function( x ){ + return isString( x ) === true ? parseInt( x ) : + isNumber( x ) === true ? x : 0; + }, + getUnit: function( x, p ){ + var u; + if( isString( x ) === true ){ + u = x.replace( REG_UINIT, $1 ); + if( p === 'lineHeight' ) return u; + if( PARAMS.unit[ u ] !== true ) return px; + return u; + }; + return px; + }, + getColor: function( x, p ){ + var rgb = COLOR[ x.toUpperCase() ], + pct = false, + r = 0, + g = 0, + b = 0; + if( isNumber( rgb ) === true ){ + r = ( rgb & 0xff0000 ) >> 16; + g = ( rgb & 0xff00 ) >> 8; + b = ( rgb & 0xff ); + } else + if( x.match( REG_XXXXXX ) ){ + r = parseInt( x.charAt( 1 ) + x.charAt( 2 ), 16 ); + g = parseInt( x.charAt( 3 ) + x.charAt( 4 ), 16 ); + b = parseInt( x.charAt( 5 ) + x.charAt( 6 ), 16 ); + //alert( x + ' g: ' + g ) + } else + if( x.match( REG_XXX ) ){ + r = parseInt( x.charAt( 1 ) + x.charAt( 1 ), 16 ); + g = parseInt( x.charAt( 2 ) + x.charAt( 2 ), 16 ); + b = parseInt( x.charAt( 3 ) + x.charAt( 3 ), 16 ); + } else + if( x.indexOf( 'rgb(' ) === 0 ){ + rgb = x.substr( 4 ).split( ',' ); + r = parseFloat( rgb[ 0 ] ); + g = parseFloat( rgb[ 1 ] ); + b = parseFloat( rgb[ 2 ] ); + if( x.indexOf( '%' ) !== -1 ) pct = true; + } else { + r = 255; + g = 255; + b = 255; + }; + return new ColorProperty( p, r, g, b, pct ); + }, + getClip: function( name ){ + // rect(...) クリップします。, は上端からの、 , は左端からのオフセットで指定します。Internet Explorer 4~7 では、カンマの代わりにスペースで区切る必要があります。 + // position:absolute または position:fixed を適用した要素に対してのみ有効です。 + var top = this.get( name + 'Top' ), + right = this.get( name + 'Right' ), + bottom = this.get( name + 'Bottom' ), + left = this.get( name + 'Left' ), + ret = new PropertyGroup( name, top, right, bottom, left), + all; + if( ret.isValid() === true ) return ret; + ret.kill(); + all = this.style[ name ].split( '(' )[ 1 ].split( ')' )[ 0 ].split( CLIP_SEPARATOR ); + return new PropertyGroup( name, + new Property( name + 'Top', all[ 0 ], px, this.pxPerEm ), + new Property( name + 'Right', all[ 1 ], px, this.pxPerEm ), + new Property( name + 'Bottom', all[ 2 ], px, this.pxPerEm ), + new Property( name + 'Left', all[ 3 ], px, this.pxPerEm ) + ); + }, + getBackgroundPosition: function( name ){ + var x = this.get( name + 'X' ), + y = this.get( name + 'Y' ), + ret = new PropertyGroup( name, x, y ), + xy; + if( ret.isValid() === true ) return ret; + ret.kill(); + xy = this.style[ name ].split( ' ' ); + return new PropertyGroup( name, + new Property( name + 'X', this.getValue( xy[ 0 ] ), this.getUnit( xy[ 0 ] ), this.pxPerEm ), + new Property( name + 'Y', this.getValue( xy[ 1 ] ), this.getUnit( xy[ 1 ] ), this.pxPerEm ) + ); + }, + getMarginPaddingBorder: function( name, width ){ + var props = [ name + 'Top' + width, + name + 'Right' + width, + name + 'Bottom' + width, + name + 'Left' + width ], + top = this.get( props[ 0 ] ), + right = this.get( props[ 1 ] ), + bottom = this.get( props[ 2 ] ), + left = this.get( props[ 3 ] ), + ret = new FrexibleProperty( name, top, right, bottom, left ), + klass, pxPerEm, getValue, getUnit, + all, _0, _1, _2, _3, v, u; + if( ret.isValid() === true ) return ret; + ret.kill(); + klass = Property; + pxPerEm = this.pxPerEm; + getValue = this.getValue; + getUnit = this.getUnit; + all = this.style[ name + width ].split( ' ' ); + _0 = all[ 0 ]; + _1 = all[ 1 ]; + _2 = all[ 2 ]; + _3 = all[ 3 ]; + v = getValue( _0 ); + u = getUnit( _0 ); + switch( all.length ){ + case 1 : + top = new klass( props[ 0 ], v, u, pxPerEm ); + right = new klass( props[ 1 ], v, u, pxPerEm ); + bottom = new klass( props[ 2 ], v, u, pxPerEm ); + left = new klass( props[ 3 ], v, u, pxPerEm ); + break; + case 2 : + top = new klass( props[ 0 ], v, u, pxPerEm ); + bottom = new klass( props[ 2 ], v, u, pxPerEm ); + v = getValue( _1 ); + u = getUnit( _1 ); + right = new klass( props[ 1 ], v, u, pxPerEm ); + left = new klass( props[ 3 ], v, u, pxPerEm ); + break; + case 3 : + top = new klass( props[ 0 ], v, u, pxPerEm ); + v = getValue( _1 ); + u = getUnit( _1 ); + right = new klass( props[ 1 ], v, u, pxPerEm ); + left = new klass( props[ 3 ], v, u, pxPerEm ); + bottom = new klass( props[ 2 ], getValue( _2 ), getUnit( _2 ), pxPerEm ); + break; + case 4 : + top = new klass( props[ 0 ], v, u, pxPerEm ); + right = new klass( props[ 1 ], getValue( _1 ), getUnit( _1 ), pxPerEm ); + bottom = new klass( props[ 2 ], getValue( _2 ), getUnit( _2 ), pxPerEm ); + left = new klass( props[ 3 ], getValue( _3 ), getUnit( _3 ), pxPerEm ); + break; + }; + return new FrexibleProperty( name, top, right, bottom, left ); + }, + getBorderColor: function( name ){ + var props = 'borderTopColor,borderRightColor,borderBottomColor,borderLeftColor'.split( ',' ), + top = this.get( props[ 0 ] ), + right = this.get( props[ 1 ] ), + bottom = this.get( props[ 2 ] ), + left = this.get( props[ 3 ] ), + ret = new FrexibleProperty( name, top, right, bottom, left ), + all, _0, _1, getColor; + if( ret.isValid() === true ) return ret; + ret.kill(); + getColor = this.getColor; + all = this.style[ name ].split( ' ' ); + _0 = all[ 0 ]; + _1 = all[ 1 ]; + switch( all.length ){ + case 1 : + top = getColor( _0, props[ 0 ] ); + right = getColor( _0, props[ 1 ] ); + bottom = getColor( _0, props[ 2 ] ); + left = getColor( _0, props[ 3 ] ); + break; + case 2 : + top = getColor( _0, props[ 0 ] ); + right = getColor( _1, props[ 1 ] ); + bottom = getColor( _0, props[ 2 ] ); + left = getColor( _1, props[ 3 ] ); + break; + case 3 : + top = getColor( _0, props[ 0 ] ); + right = getColor( _1, props[ 1 ] ); + bottom = getColor( all[ 2 ], props[ 2 ] ); + left = getColor( _1, props[ 3 ] ); + break; + case 4 : + top = getColor( _0, props[ 0 ] ); + right = getColor( _1, props[ 1 ] ); + bottom = getColor( all[ 2 ], props[ 2 ] ); + left = getColor( all[ 3 ], props[ 3 ] ); + break; + }; + return new FrexibleProperty( name, top, right, bottom, left ); + } + } + ); + function camelizeHash( obj ){ + var p, _p, came = Util.camelize; + for( p in obj ){ + _p = came( p ); + if( _p === p ) continue; + obj[ _p ] = obj[ _p ] || obj[ p ]; + delete obj[ p ]; + }; + }; + return { + create: function( css ){ + return new WrappedStyle( camelizeHash( p ) ); + } + }; +})(); + +var XDocument = ( function( window, document ){ + + var getIndex = Util.getIndex; + var ROOT_LIST = []; + var DEF_ATTRS = {}; + var AUTO = Number.POSITIVE_INFINITY; + var FULL = DEF_ATTRS; // something unigue value; + var FLOOR = Math.floor; + + DEF_ATTRS.LENGTH = 1; + DEF_ATTRS.PERCENT = 2; + DEF_ATTRS.COLOR = 4; + DEF_ATTRS.U_DECIMAL = 8; + DEF_ATTRS.NUMERICAL = 16; + DEF_ATTRS.BOOLEAN = 32; + DEF_ATTRS.QUARTET = 64; + DEF_ATTRS.URL = 128; + DEF_ATTRS.FONT_NAME = 256; + DEF_ATTRS.LIST = 512; + DEF_ATTRS.AUTO = 1024; + DEF_ATTRS.COMBI = 2048; + DEF_ATTRS.BORDER_STYLE = 'none,hidden,dotted,dashed,solid,double,groove,ridge,inset,outset'.split(','); + DEF_ATTRS.POSITION_X = 'left,center,right'.split(','); + DEF_ATTRS.POSITION_Y = 'top,center,bottom'.split(','); + DEF_ATTRS.ALIGN = 'left,center,right,justify'.split(','); + DEF_ATTRS.TEXT_DECORATION = 'none,underline,overline,line-through,blink'.split(','); + DEF_ATTRS.TEXT_TRANSFORM = 'none,capitalize,lowercase,uppercase'.split(','); + DEF_ATTRS.WIDTH_HEIGHT = 'auto'.split(','); + DEF_ATTRS.BOX_SIZING = 'content-box,padding-box,border-box,margin-box'.split(','); + DEF_ATTRS.PAINT = 1; // 再描画のみ必要 + DEF_ATTRS.REFLOW = 2; // レイアウトの再計算が必要 + DEF_ATTRS.FONT = 3; // フォントサイズが変更された + DEF_ATTRS.CONTENT_UPDATE = 4; // コンテンツが変更された + + DEF_ATTRS.borderWidth = [ DEF_ATTRS.REFLOW, 0, DEF_ATTRS.QUARTET | DEF_ATTRS.LENGTH ]; // em [ top, right, bottom, left ] + DEF_ATTRS.borderColor = [ DEF_ATTRS.PAINT, 4, DEF_ATTRS.QUARTET | DEF_ATTRS.DEF_COLOR ]; // color [ top, right, bottom, left ] + DEF_ATTRS.borderStyle = [ DEF_ATTRS.PAINT, 8, DEF_ATTRS.QUARTET | DEF_ATTRS.LIST, DEF_ATTRS.BORDER_STYLE ]; // string [ top, right, bottom, left ] + DEF_ATTRS.cornerRadius = [ DEF_ATTRS.PAINT, 12, DEF_ATTRS.QUARTET | DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; // em, px [ top, right, bottom, left ] + DEF_ATTRS.bgColor = [ DEF_ATTRS.PAINT, 16, DEF_ATTRS.COLOR ]; // color + DEF_ATTRS.bgAlpha = [ DEF_ATTRS.PAINT, 17, DEF_ATTRS.U_DECIMAL ]; // 0 - 1 + DEF_ATTRS.bgImgUrl = [ DEF_ATTRS.PAINT, 18, DEF_ATTRS.URL ]; // url + DEF_ATTRS.bgImgRepeatX = [ DEF_ATTRS.PAINT, 19, DEF_ATTRS.BOOLEAN ]; // true / false + DEF_ATTRS.bgImgRepeatY = [ DEF_ATTRS.PAINT, 20, DEF_ATTRS.BOOLEAN ]; // true / false + DEF_ATTRS.bgImgPositionX = [ DEF_ATTRS.PAINT, 21, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT | DEF_ATTRS.LIST, DEF_ATTRS.POSITION_X ]; // em %, px, string + DEF_ATTRS.bgImgPositionY = [ DEF_ATTRS.PAINT, 22, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT | DEF_ATTRS.LIST, DEF_ATTRS.POSITION_Y ]; // em %, px, string + DEF_ATTRS.shadowColor = [ DEF_ATTRS.PAINT, 23, DEF_ATTRS.COLOR ]; // color + DEF_ATTRS.shadowAlpha = [ DEF_ATTRS.PAINT, 24, DEF_ATTRS.U_DECIMAL ]; // 0 - 1 + DEF_ATTRS.shadowOffsetX = [ DEF_ATTRS.PAINT, 25, DEF_ATTRS.LENGTH ]; // em + DEF_ATTRS.shadowOffsetY = [ DEF_ATTRS.PAINT, 26, DEF_ATTRS.LENGTH ]; // em + DEF_ATTRS.shadowBlur = [ DEF_ATTRS.PAINT, 27, DEF_ATTRS.LENGTH ]; // em + DEF_ATTRS.shadowSpread = [ DEF_ATTRS.PAINT, 28, DEF_ATTRS.LENGTH ]; // em + DEF_ATTRS.shadowInset = [ DEF_ATTRS.PAINT, 29, DEF_ATTRS.BOOLEAN ]; // true / false + + DEF_ATTRS.color = [ DEF_ATTRS.PAINT, 30, DEF_ATTRS.COLOR ]; // color + DEF_ATTRS.fontFamily = [ DEF_ATTRS.FONT, 31, DEF_ATTRS.FONT_NAME ]; // string + DEF_ATTRS.fontSize = [ DEF_ATTRS.FONT, 32, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; // em, % + DEF_ATTRS.bold = [ DEF_ATTRS.FONT, 33, DEF_ATTRS.BOOLEAN ]; // true / false + DEF_ATTRS.italic = [ DEF_ATTRS.FONT, 34, DEF_ATTRS.BOOLEAN ]; // true / false + DEF_ATTRS.lineHeight = [ DEF_ATTRS.FONT, 35, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT | DEF_ATTRS.NUMERICAL ]; // em, %, + DEF_ATTRS.letterSpacing = [ DEF_ATTRS.FONT, 36, DEF_ATTRS.LENGTH ]; // em + DEF_ATTRS.wordSpacing = [ DEF_ATTRS.FONT, 37, DEF_ATTRS.LENGTH ]; + DEF_ATTRS.align = [ DEF_ATTRS.FONT, 38, DEF_ATTRS.LIST, DEF_ATTRS.ALIGN ]; + DEF_ATTRS.decoration = [ DEF_ATTRS.PAINT, 39, DEF_ATTRS.LIST, DEF_ATTRS.TEXT_DECORATION ]; + DEF_ATTRS.transform = [ DEF_ATTRS.FONT, 40, DEF_ATTRS.LIST, DEF_ATTRS.TEXT_TRANSFORM ]; + DEF_ATTRS.textShadowColor = [ DEF_ATTRS.PAINT, 41, DEF_ATTRS.COLOR ]; + DEF_ATTRS.textShadowOffsetX = [ DEF_ATTRS.PAINT, 42, DEF_ATTRS.LENGTH ]; + DEF_ATTRS.textShadowOffsetY = [ DEF_ATTRS.PAINT, 43, DEF_ATTRS.LENGTH ]; + DEF_ATTRS.shadowBlur = [ DEF_ATTRS.PAINT, 44, DEF_ATTRS.LENGTH ]; + + DEF_ATTRS.width = [ DEF_ATTRS.REFLOW, 45, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT, DEF_ATTRS.WIDTH_HEIGHT ]; + DEF_ATTRS.minWidth = [ DEF_ATTRS.REFLOW, 46, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; + DEF_ATTRS.maxWidth = [ DEF_ATTRS.REFLOW, 47, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; + DEF_ATTRS.height = [ DEF_ATTRS.REFLOW, 48, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT, DEF_ATTRS.WIDTH_HEIGHT ]; + DEF_ATTRS.minHeight = [ DEF_ATTRS.REFLOW, 49, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; + DEF_ATTRS.maxHeight = [ DEF_ATTRS.REFLOW, 50, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; + DEF_ATTRS.padding = [ DEF_ATTRS.REFLOW, 51, DEF_ATTRS.QUARTET | DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; + DEF_ATTRS.margin = [ DEF_ATTRS.REFLOW, 55, DEF_ATTRS.QUARTET | DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; + DEF_ATTRS.sizing = [ DEF_ATTRS.REFLOW, 59, DEF_ATTRS.LIST, DEF_ATTRS.BOX_SIZING ]; + DEF_ATTRS.pageBox = [ DEF_ATTRS.REFLOW, 60, DEF_ATTRS.BOOLEAN ]; // true / false + DEF_ATTRS.x = DEF_ATTRS.left = [ DEF_ATTRS.REFLOW, 61, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; + DEF_ATTRS.y = DEF_ATTRS.top = [ DEF_ATTRS.REFLOW, 62, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; + DEF_ATTRS.bottom = [ DEF_ATTRS.REFLOW, 63, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; + DEF_ATTRS.right = [ DEF_ATTRS.REFLOW, 64, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; + + var ATTRS = ( function(){ + var ret = {}, + obj = DEF_ATTRS, + p; + for( p in obj ){ + if( Type.isArray( obj[ p ] ) === true ){ + ret[ p ] = obj[ p ][ 1 ]; + }; + }; + return ret; + })(); + + /** + * 再計算と再描画 + * redraw 再描画はパラメータ変更後に setTimeout で + * reflow 再計算は値が get された場合 invalidate が サイズだったら + * または再描画前に invalidate がサイズなフラグが足っていたら + */ + + var BasicLayoutManager = Class.create( + 'BasicLayoutManager', + Class.POOL_OBJECT, + { + Constructor : function(){ + + }, + redraw : function( nodeData ){ + var root = nodeData.__root; + root.dirty === DEF_ATTRS.REFLOW && this.reflow( root ); + + // draw + }, + reflow : function( nodeData, allowW, allowH ){ + nodeData.preMesure( allowW, allowH ); + + var children = nodeData.children, + contentW = nodeData.contentWidth, + contentH = nodeData.contentHeight, + autoW = contentW === AUTO, + autoH = contentH === AUTO, + auto, calc, childW, childH, child, i, style, data, + t, r, b, l; + if( children ){ + auto = autoW && autoH; + childW = 0; + childH = 0; + calc = BasicLayoutManager.calcValue; + for( i = children.length; i; ){ + child = children[ --i ]; + style = child.__style; + if( style ){ + data = style.data; + t = calc( data[ ATTRS.top ], contentH ); + r = calc( data[ ATTRS.right ], contentW ); + b = calc( data[ ATTRS.bottom ], contentH ); + l = calc( data[ ATTRS.left ], contentW ); + } else { + t = r = b = l = 0; + }; + if( child instanceof LayoutBoxPrivate ){ + child.layoutManager.reflow( child, contentW - r - l, contentH - t - b ); + } else { + child.preMesure( contentW - r - l, contentH - t - b ); + child.mesure(); + child.postMesure(); + }; + if( !auto ) continue; + if( autoW && childW < child.boxWidth + r + l ) childW = child.boxWidth + r + l; + if( autoH && childH < child.boxHeight + t + b ) childH = child.boxHeight + t + b; + }; + if( autoW ) nodeData.contentWidth = childW; + if( autoH ) nodeData.contentHeight = childH; + }; + ( autoW || autoH ) && nodeData.postMesure(); + + delete nodeData.dirty; + } + } + ); + BasicLayoutManager.finalValue = function( styleValue, styleMin, styleMax, srcValue ){ + var calc = BasicLayoutManager.calcValue, + v = calc( styleValue, srcValue ), + min = calc( styleMin, srcValue ), + max = calc( styleMax, srcValue ); + if( v < min ) return min; + if( max < v ) return max; + return v; + }; + BasicLayoutManager.calcValue = function( styleValue, srcValue ){ + switch( styleValue ){ + case 0 : + return 0; + case AUTO : + return AUTO; + case FULL : + return srcValue; // 100% + default : + if( 1 <= styleValue ) return styleValue; // legth + if( -1 < styleValue ) return FLOOR( srcValue * styleValue ); // % + }; + return styleValue; // - length + }; + BasicLayoutManager.advancedCalcValue = function( styleValue, srcValue ){ + switch( styleValue ){ + case 0 : + return 0; + case AUTO : + return srcValue; + case FULL : + throw new Error( 'advancedCalcValue FULL' ); + // return ; // 100% + default : + if( 1 <= styleValue ) return styleValue; + if( -1 < styleValue ) return FLOOR( ( srcValue / ( 1 - styleValue ) ) * styleValue ); // % + }; + return styleValue; // - length + }; + + var NodeStylePrivate = Class.create( + Class.PRIVATE_DATA | Class.POOL_OBJECT, + { + fontCssText : null, + colorCssText : null, + layoutCssText : null, + Constructor : function(){ + this.data = []; + this.dirty = 0; + }, + register : function( node ){ + var root = node.__root, + roots = this.rootList, + nodes = this.nodeList; + if( !roots ){ + this.rootList = [ root ]; + } else + if( getIndex( roots, root ) === -1 ) roots[ roots.length ] = root; + + if( !nodes ){ + this.nodeList = [ node ]; + return; + }; + if( getIndex( nodes, node ) === -1 ) nodes[ nodes.length ] = node; + }, + unRegister : function( node ){ + var nodes = this.nodeList, + i = getIndex( nodes, node ), + root = node._root, + roots = this.rootList, + j = getIndex( roots, root ); + if( i !== -1 && nodes.splice( i, 1 ) && nodes.length === 0 ) delete this.nodeList; + if( j !== -1 && roots.splice( j, 1 ) && roots.length === 0 ) delete this.rootList; + }, + clone : function(){ + var styleClass = Class.getClass( this.User ), + dataClass = Class.getClass( this ); + }, + /* + * opt_unit は getter のみ + */ + attr : function( prop, v, opt_unit ){ + var update = prop[ 0 ], + propID = prop[ 1 ], + type = prop[ 2 ], + list = prop[ 3 ], + length = !!( type & DEF_ATTRS.LENGTH ), + percent = !!( type & DEF_ATTRS.PERCENT ), + color = !!( type & DEF_ATTRS.COLOR ), + uDecimal = !!( type & DEF_ATTRS.U_DECIMAL ), + numerical = !!( type & DEF_ATTRS.NUMERICAL ), + flag = !!( type & DEF_ATTRS.BOOLEAN ), + quartet = !!( type & DEF_ATTRS.QUARTET ), + url = !!( type & DEF_ATTRS.URL ), + fontName = !!( type & DEF_ATTRS.FONT_NAME ), + //list = !!( type & DEF_ATTRS.LIST ), + combi = !!( type & DEF_ATTRS.COMBI ), + data = this.data, + _v = -1, + i, l, nodes, root; + /* + * Setter + */ + if( v !== undefined ){ + if( Type.isNumber( v ) === true ){ + if( numerical === false ){ + if( uDecimal === false || v < 0 || 1 < v ) throw new Error( '' ); + }; + } else + if( Type.isBoolean( v ) === true ){ + if( flag === false ) throw new Error( '' ); + } else + if( Type.isString( v ) === true ){ + if( url === false && fontName === false ){ + if( v.indexOf( ' ' ) !== -1 ){ + v = v.split( ' ' ); + } else { + if( length === false && percent === false && color === false ) throw new Error( '' ); + }; + }; + }; + if( Type.isArray( v ) === true ){ + if( v.length <= 4 && quartet === true ){ + type ^= DEF_ATTRS.QUARTET; + } else + if( v.length === 2 && combi === true ){ + type ^= DEF_ATTRS.COMBI; + } else { + throw new Error( '' ); + }; + switch( v.length ){ + case 1 : + this.attr( [ propID , type, list ], v[ 0 ] ); + this.attr( [ ++propID, type, list ], v[ 0 ] ); + this.attr( [ ++propID, type, list ], v[ 0 ] ); + this.attr( [ ++propID, type, list ], v[ 0 ] ); + break; + case 2 : + this.attr( [ propID , type, list ], v[ 0 ] ); + this.attr( [ ++propID, type, list ], v[ 1 ] ); + this.attr( [ ++propID, type, list ], v[ 0 ] ); + this.attr( [ ++propID, type, list ], v[ 1 ] ); + break; + case 3 : + this.attr( [ propID , type, list ], v[ 0 ] ); + this.attr( [ ++propID, type, list ], v[ 1 ] ); + this.attr( [ ++propID, type, list ], v[ 2 ] ); + this.attr( [ ++propID, type, list ], v[ 1 ] ); + break; + case 4 : + this.attr( [ propID , type, list ], v[ 0 ] ); + this.attr( [ ++propID, type, list ], v[ 1 ] ); + this.attr( [ ++propID, type, list ], v[ 2 ] ); + this.attr( [ ++propID, type, list ], v[ 3 ] ); + break; + default : + }; + return this.User; + }; + switch( update ){ + case DEF_ATTRS.REFLOW : + delete this.layoutCssText; + break; + case DEF_ATTRS.PAINT : + delete this.colorCssText; + break; + case DEF_ATTRS.FONT : + delete this.fontCssText; + }; + + if( this.dirty < update ){ + this.dirty = update; + roots = this.rootList; + for( i = 0, l = roots.length; i < l; ++i ){ + root = roots[ i ]; + if( root.dirty < update ) root.dirty = update; + }; + }; + + if( list ) _v = Util.getIndex( list, v ); + data[ propID ] = _v !== -1 ? _v : v; + + switch( prop ){ + case DEF_ATTRS.left : + case DEF_ATTRS.right : + this.ltrtWidth = data[ DEF_ATTRS.left[ 0 ] ] === undefined && data[ DEF_ATTRS.right[ 0 ] ] === undefined; + break; + case DEF_ATTRS.top : + case DEF_ATTRS.bottom : + this.tpbtHeight = data[ DEF_ATTRS.top[ 0 ] ] === undefined && data[ DEF_ATTRS.bottom[ 0 ] ] === undefined; + break; + case DEF_ATTRS.width : + this.autoWidth = v === AUTO; + this.prctWidth = v === FULL || v < 1; + break; + case DEF_ATTRS.height : + this.autoHeight = v === AUTO; + this.prctHeight = v === FULL || v < 1; + break; + }; + return this.User; + }; + v = data[ propID ]; + // Unit + if( quartet === true ) return [ v, data[ ++propID ], data[ ++propID ], data[ ++propID ] ]; + if( combi === true ) return [ v, data[ ++propID ] ]; + if( list && Type.isNumber( v ) === true ) return list[ v ]; + return v; + }, + cssText : function(){ + if( this.fontCssText === null ) this.fontCssText = this.createFontCssText(); + if( this.layoutCssText === null ) this.layoutCssText = this.createLayoutCssText(); + if( this.colorCssText === null ) this.colorCssText = this.createColorCssText(); + return [ this.fontCssText, this.colorCssText, this.layoutCssText ].join( ';' ); + }, + createFontCssText : function(){ + var data = this.data, + css = [], + v; + if( v = data[ ATTRS.fontFamily ] ) css[ 0 ] = 'font-family:' + v; + if( v = data[ ATTRS.fontSize ] ) css[ css.length - 1 ] = 'font-size:' + v; + if( v = data[ ATTRS.bold ] ) css[ css.length - 1 ] = 'font-weight:bold'; + if( v = data[ ATTRS.bold ] ) css[ css.length - 1 ] = 'font-style:italic'; + if( v = data[ ATTRS.lineHeight ] ) css[ css.length - 1 ] = 'line-height:' + v; + if( v = data[ ATTRS.letterSpacing ] ) css[ css.length - 1 ] = 'letter-spacing:' + v; + if( v = data[ ATTRS.wordSpacing ] ) css[ css.length - 1 ] = 'word-spacing:' + v; + if( v = data[ ATTRS.align ] ) css[ css.length - 1 ] = 'text-align:' + DEF_ATTRS.ALIGN[ v ]; + if( v = data[ ATTRS.transform ] ) css[ css.length - 1 ] = 'text-transform:' + DEF_ATTRS.TEXT_TRANSFORM[ v ]; + return css.join( ',' ); + }, + createColorCssText : function(){ + var data = this.data, + css = [], + v, x, y, c, b; + if( v = data[ ATTRS.borderColor ] ) css[ 0 ] = 'border-color:' + v; + if( v = data[ ATTRS.borderStyle + 0 ] ) css[ css.length - 1 ] = 'border-top-style:' + DEF_ATTRS.BORDER_STYLE[ v ]; + if( v = data[ ATTRS.borderStyle + 1 ] ) css[ css.length - 1 ] = 'border-right-style:' + DEF_ATTRS.BORDER_STYLE[ v ]; + if( v = data[ ATTRS.borderStyle + 2 ] ) css[ css.length - 1 ] = 'border-bottom-style:' + DEF_ATTRS.BORDER_STYLE[ v ]; + if( v = data[ ATTRS.borderStyle + 3 ] ) css[ css.length - 1 ] = 'border-left-style:' + DEF_ATTRS.BORDER_STYLE[ v ]; + if( v = data[ ATTRS.cornerRadius + 0 ] ) css[ css.length - 1 ] = 'corner-radius-top:' + v; + if( v = data[ ATTRS.cornerRadius + 1 ] ) css[ css.length - 1 ] = 'corner-radius-right:' + v; + if( v = data[ ATTRS.cornerRadius + 2 ] ) css[ css.length - 1 ] = 'border-radius-bottom:' + v; + if( v = data[ ATTRS.cornerRadius + 3 ] ) css[ css.length - 1 ] = 'border-radius-left:' + v; + if( v = data[ ATTRS.bgColor ] ) css[ css.length - 1 ] = 'background-color:' + v; + // ATTRS.bgAlpha + if( v = data[ ATTRS.bgImgUrl ] ) css[ css.length - 1 ] = 'background-image:url(' + v + ')'; + x = data[ ATTRS.bgImgRepeatX ]; + y = data[ ATTRS.bgImgRepeatY ]; + if( x && y ){ + css[ css.length - 1 ] = 'background-repeat:repeat'; + } else + if( x ){ + css[ css.length - 1 ] = 'background-repeat:repeat-x'; + } else + if( y ){ + css[ css.length - 1 ] = 'background-repeat:repeat-y'; + }; + x = data[ ATTRS.bgImgPositionX ]; + y = data[ ATTRS.bgImgPositionY ]; + if( x && y ){ + css[ css.length - 1 ] = 'background-position:' + x + ' ' + y; + } else + if( x ){ + css[ css.length - 1 ] = 'background-position:' + x + ' 0'; + } else + if( y ){ + css[ css.length - 1 ] = 'background-position:0 ' + y; + }; + if( v = data[ ATTRS.color ] ) css[ css.length - 1 ] = 'color:' + v; + if( v = data[ ATTRS.decoration ] ) css[ css.length - 1 ] = 'text-decoration:' + DEF_ATTRS.TEXT_DECORATION[ v ]; + x = data[ ATTRS.textShadowOffsetX ]; + y = data[ ATTRS.textShadowOffsetY ]; + b = data[ ATTRS.textShadowBlur ]; + c = data[ ATTRS.textShadowColor ]; + if( c || x || y || b ){ + css[ css.length - 1 ] = 'text-shadow:' + x + ' ' + y + ' ' + b + ' ' + c; + }; + /* + ATTRS.shadowColor = [ DEF_ATTRS.PAINT, 23, DEF_ATTRS.COLOR ]; // color + ATTRS.shadowAlpha = [ DEF_ATTRS.PAINT, 24, DEF_ATTRS.U_DECIMAL ]; // 0 - 1 + ATTRS.shadowOffsetX = [ DEF_ATTRS.PAINT, 25, DEF_ATTRS.LENGTH ]; // em + ATTRS.shadowOffsetY = [ DEF_ATTRS.PAINT, 26, DEF_ATTRS.LENGTH ]; // em + ATTRS.shadowBlur = [ DEF_ATTRS.PAINT, 27, DEF_ATTRS.LENGTH ]; // em + ATTRS.shadowSpread = [ DEF_ATTRS.PAINT, 28, DEF_ATTRS.LENGTH ]; // em + ATTRS.shadowInset = [ DEF_ATTRS.PAINT, 29, DEF_ATTRS.BOOLEAN ]; // true / false + */ + }, + createBoxShadowCssText : function(){ + + }, + createBGAlphaCssText : function(){ + + }, + createTextShadowCssText : function(){ + + }, + createLayoutCssText : function(){ + + } + } + ); + + var NodeStyle = Class.create( + 'NodeStyle', + Class.POOL_OBJECT, + NodeStylePrivate, + { + Constructor : function(){ + NodeStyle.newPrivateData( this ); + }, + borderWidth : function( v ){ + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.borderWidth, v ); + }, + borderColor : function(){ + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.borderColor, v ); + }, + borderStyle : function(){ + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.borderStyle, v ); + }, + cornerRadius : function(){ + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.cornerRadius, v ); + }, + bgColor : function(){ + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.bgColor, v ); + }, + bgAlpha : function(){ + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.bgAlpha, v ); + }, + bgImgUrl : function(){ + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.bgImgUrl, v ); + }, + bgImgRepeatX : function(){ + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.bgImgRepeatX, v ); + }, + bgImgRepeatY : function(){ + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.bgImgRepeatY, v ); + }, + bgImgPositionX : function(){ + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.bgImgPositionX, v ); + }, + bgImgPositionY : function(){ + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.bgImgPositionY, v ); + }, + shadowColor : function(){ + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.shadowColor, v ); + }, + shadowAlpha : function(){ + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.shadowAlpha, v ); + }, + shadowOffsetX : function(){ + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.shadowOffsetX, v ); + }, + shadowOffsetY : function(){ + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.shadowOffsetY, v ); + }, + shadowBlur : function(){ + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.shadowBlur, v ); + }, + shadowSpread : function(){ + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.shadowSpread, v ); + }, + shadowInset : function(){ + return NodeStyle.getPrivateData( this ).attr( DEF_ATTRS.shadowInset, v ); + }, + color : function( v ){ + return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.color, v ); + }, + fontFamily : function( v ){ + return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.fontFamily, v ); + }, + fontSize : function( v ){ + return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.fontSize, v ); + }, + bold : function( v ){ + return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.bold, v ); + }, + italic : function( v ){ + return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.italic, v ); + }, + lineHeight : function( v ){ + return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.lineHeight, v ); + }, + letterSpacing : function( v ){ + return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.letterSpacing, v ); + }, + wordSpacing : function( v ){ + return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.wordSpacing, v ); + }, + align : function( v ){ + return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.align, v ); + }, + decoration : function( v ){ + return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.decoration, v ); + }, + transform : function( v ){ + return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.transform, v ); + }, + textShadowColor : function( v ){ + return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.textShadowColor, v ); + }, + textShadowOffsetX : function( v ){ + return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.textShadowOffsetX, v ); + }, + textShadowOffsetY : function( v ){ + return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.textShadowOffsetY, v ); + }, + shadowBlur : function( v ){ + return TypoStyle.getPrivateData( this ).attr( DEF_ATTRS.shadowBlur, v ); + }, + cssText : function(){ + return TypoStyle.getPrivateData( this ).cssText(); + } + } + ); + + var NodePrivate = Class.create( + 'NodePrivate', + Class.PRIVATE_DATA | Class.POOL_OBJECT, + { + elmWrap : null, + elmExtend : null, + textNode : null, + boxX : 0, + boxY : 0, + boxWidth : 0, + boxHeight : 0, + contentL : 0, + contentT : 0, + contentR : 0, + contentB : 0, + borderL : 0, + borderT : 0, + borderR : 0, + borderB : 0, + paddingL : 0, + paddingT : 0, + paddingR : 0, + paddingB : 0, + marginL : 0, + marginT : 0, + marginR : 0, + marginB : 0, + boxSizingOffsetLR : 0, + boxSizingOffsetTB : 0, + contentWidth : 0, + minContentWidth : 0, + maxContentWidth : AUTO, + contentHeight : 0, + minContentHeight : 0, + maxContentHeight : AUTO, + Constructor : function( __root, __parent ){ + this.__root = __root; + if( __parent ) this.__parent = __parent; + }, + style : function( v ){ + if( v instanceof NodeStyle ){ + this.__style && this.__style.unRegister( this ); + this._style = v; + this.__style = StylePrivate.getPrivateData( v ); + this.__style.register( this ); + return this.User; + } else + if( v === null ){ + this.__style && this.__style.unRegister( this ); + delete this._style; + delete this.__style; + return this.User; + }; + return this._style; + }, + content : function( v ){ + if( Type.isString( v ) === true ){ + if( !this.textNode || ( this.textNode && this.textNode.data !== v ) ){ + this._content = v; + this.updateContent = true; + }; + return this.User; + } else + if( v === null ){ + if( this._content !== v && this.textNode ){ + this._content = v; + this.updateContent = true; + }; + return this.User; + }; + if( this._content ) return this._content; + if( this._content === null ) return null; + if( this.textNode ) return this.textNode.data; + return null; + }, + /** + * 要素の追加・削除 + * 1. ペイントがある // 予約のみ + * 2. コンテンツがある // 予約のみ * + * 3. コンテンツを削除 // 予約のみ + * 4. 要素を削除 // 予約のみ + * + * コンテンツの再計算 + * 0. 要素追加して css セット + * 1. コンテンツの変更 + * 2. font 指定の変更 + * 3. contentWidth の変更 (コンテンツの高さの再計算) 前回の contentWidth の保持 + * + * contentSize, scrollSize の決定 + */ + musure : function( dirty ){ + var content = this._content, + root = this.__root, + style = this.__style, + w = this.contentWidth, + h = this.contentHeight; + switch( this.updateContent === true ? DEF_ATTRS.CONTENT_UPDATE : dirty ){ + case DEF_ATTRS.CONTENT_UPDATE : // コンテンツが変更された + this.paint( 0 ); + this.lastContentWidth = -1; + case DEF_ATTRS.FONT : // フォントサイズが変更された + case DEF_ATTRS.REFLOW : // レイアウトの再計算が必要 + /* http://web-designs.seesaa.net/article/188400668.html + * min-width の値が max-width の値より大きい場合は、max-width の値は min-width の値に設定される。 + * + * テキストノードがあり + * 1. contentWidth === AUTO + * style を更新して contentWidth の決定 + * min or max に引っかかったら style 更新 + * contentHeight === AUTO の場合 + * textHeight の決定 + * contentHeight !== AUTO の場合 scrollHeight のみ更新 + * 2. contentHeight === AUTO かつ + * コンテンツの高さの再取得が必要( contentWidth が最終計測時の contentWidth と一致 かつ フォント・コンテンツに変更無し の場合再取得不要) + * style を更新して contentHeight の決定 + * 必要でない + * 3. content のサイズがすでに決定している + * コンテンツの高さの再取得が必要 + * 必要でない + */ + if( this.textNode ){ + if( w === AUTO ){ + this.commitStyle(); + w = this.contentWidth = this.textNode.offsetWidth; + this.scrollWidth = w + this.contentL + this.contentR; + if( this.maxContentWidth < w - this.boxSizingOffsetLR ) this.contentWidth = this.maxContentWidth + this.boxSizingOffsetLR; + if( w - this.boxSizingOffsetLR < this.minContentWidth ) this.contentWidth = this.minContentWidth + this.boxSizingOffsetLR; + this.lastContentWidth = this.contentWidth; + + w !== this.contentWidth && this.commitStyle(); + + if( h === AUTO ){ + h = this.conetntHeight = this.textNode.offsetHeight; + this.scrollHeight = h + this.contentT + this.contentB; + if( this.maxContentHeight < h - this.boxSizingOffsetTB ) this.contentHeight = this.maxContentHeight + this.boxSizingOffsetTB; + if( h - this.boxSizingOffsetTB < this.minContentHeight ) this.contentHeight = this.minContentHeight + this.boxSizingOffsetTB; + } else { + this.scrollHeight = this.textNode.offsetHeight + this.contentT + this.contentB; + }; + } else + if( h === AUTO ){ + if( w !== this.lastContentWidth || dirty !== DEF_ATTRS.REFLOW ){ + this.commitStyle(); + this.lastContentWidth = w; + h = this.conetntHeight = this.textNode.offsetHeight; + this.scrollWidth = w + this.contentL + this.contentR; + this.scrollHeight = h + this.contentT + this.contentB; + if( this.maxContentHeight < h - this.boxSizingOffsetTB ) this.contentHeight = this.maxContentHeight + this.boxSizingOffsetTB; + if( h - this.boxSizingOffsetTB < this.minContentHeight ) this.contentHeight = this.minContentHeight + this.boxSizingOffsetTB; + } else { + this.scrollWidth = w + this.contentL + this.contentR; + this.scrollHeight = h + this.contentT + this.contentB; + root.paintReserve( this ); + }; + } else { + if( dirty !== DEF_ATTRS.REFLOW ){ + this.commitStyle(); + this.scrollWidth = this.textNode.offsetWidth + this.contentL + this.contentR; + this.scrollHeight = this.textNode.offsetHeight + this.contentT + this.contentB; + } else { + root.paintReserve( this ); + this.scrollWidth = w + this.contentL + this.contentR; + this.scrollHeight = h + this.contentT + this.contentB; + }; + }; + } else { + if( w === AUTO ) this.contentWidth = w = 0 < this.minContentWidth ? this.minContentWidth : 0; + if( h === AUTO ) this.contentHeight = h = 0 < this.minContentHeight ? this.minContentHeight : 0; + this.scrollWidth = w + this.contentL + this.contentR; + this.scrollHeight = h + this.contentT + this.contentB; + root.paintReserve( this ); + }; + break; + case DEF_ATTRS.PAINT : // 再描画のみ必要 + root.paintReserve( this ); + break; + }; + }, + paint : function( dirty ){ + var content = this._content, + style = this.__style; + if( this.updateContent === true || ( style && style.hasPaint === true ) ){ + if( !this.elmWrap ){ + this.elmWrap = DOM.createDiv(); + this.__parent.addDisplayElement( this ); + }; + dirty !== 0 && this.commitStyle(); + if( this.updateContent === true ){ + if( content !== null ){ + if( !this.textNode ){ + this.textNode = DOM.cerateText(); + this.elmWrap.appendChild( this.textNode ); + }; + this.textNode.data = content; + } else + if( this.textNode ){ + DOM.correct( this.textNode ); + delete this.textNode; + delete this.contentWidth; + delete this.conetntHeight; + delete this.scrollWidth; + delete this.scrollHeight; + }; + }; + } else + if( this.elmWrap && content === null && ( !style || style.hasPaint === false ) ){ + this.__parent.removeDisplayElement( this ); + DOM.correct( this.elmWrap ); + delete this.contentWidth; + delete this.conetntHeight; + }; + }, + commitStyle : function(){ + var css; + if( this.elmWrap ){ + css = this.__style ? this.__style.cssText( this ) : ''; + if( this.contentWidth !== AUTO ) css += 'width:' + this.contentWidth + 'px'; + if( this.contentHeight !== AUTO ) css += 'height:' + this.contentHeight + 'px'; + this.elmWrap.style.cssText = css; + }; + }, + /* + * 親の サイズを元に自身のサイズを計算していく + */ + preMesure : function( allowW, allowH ){ + var style = this.__style, + styles, calc, box, min, max, + contentW, contentH, allowSize, boxMinus, + paddingT, paddingR, paddingB, paddingL, + borderT, borderR, borderB, borderL, + marginT, marginR, marginB, marginL; + + if( style ){ + styles = style.data; + calc = BasicLayoutManager.calcValue; + box = styles[ ATTRS.sizing ]; + + // Width + // 自身が ltrtWidth の場合 親が AUTO ではない + // 自身が ltrtWidth でない場合自身が AUTO はなくかつ親 が AUTO の場合自身は % でない + if( style.ltrtWidth ? allowW !== AUTO : !style.autoWidth && ( allowW !== AUTO || !style.prctWidth ) ){ + if( style.ltrtWidth ){ + contentW = allowW; // - calc( styles[ ATTRS.left ], allowW ) - calc( styles[ ATTRS.right ], allowW ); + } else { + contentW = BasicLayoutManager.finalValue( styles[ ATTRS.width ], styles[ ATTRS.minWidth ], styles[ ATTRS.maxWidth ], allowW ); + }; + paddingR = calc( styles[ ATTRS.padding + 1 ], allowW ); + paddingL = calc( styles[ ATTRS.padding + 3 ], allowW ); + borderR = styles[ ATTRS.border + 1 ]; + borderL = styles[ ATTRS.margin + 3 ]; + marginR = calc( styles[ ATTRS.margin + 1 ], allowW ); + marginL = calc( styles[ ATTRS.margin + 3 ], allowW ); + this.boxWidth = contentW; + boxMinus = 0; + switch( box ){ + case 3 : // margin-box + boxMinus = - marginR - marginL; + case 2 : // border-box + boxMinus -= borderR + borderL; + case 1 : // padding-box + boxMinus -= paddingR + paddingL; + // case 0 : // content-box + }; + this.contentL = marginL + borderL + paddingL; + this.contentR = marginR + borderR + paddingR; + this.contentWidth = contentW + boxMinus; + this.boxSizingOffsetLR = boxMinus; + } else { + this.boxWidth = this.contentWidth = AUTO; + min = styles[ ATTRS.minWidth ]; + max = styles[ ATTRS.maxWidth ]; + this.minContentWidth = 1 <= min ? min : 0; + this.maxContentWidth = 1 <= max ? max : AUTO; + delete this.boxSizingOffsetLR; + }; + + // Height + if( style.tpbtHeight ? allowH !== AUTO : !style.autoHeight && ( allowH !== AUTO || !style.prctHeight ) ){ + if( style.tpbtHeight ){ + contentH = allowH; // - calc( styles[ ATTRS.top ], allowH ) - calc( styles[ ATTRS.bottom ], allowH ); + } else { + contentH = BasicLayoutManager.finalValue( styles[ ATTRS.height ], styles[ ATTRS.minHeight ], styles[ ATTRS.maxHeight ], allowH ); + }; + allowSize = styles[ ATTRS.pageBox ] === true ? allowH : allowW; + paddingT = calc( styles[ ATTRS.padding + 0 ], allowSize );// paddingTRBL の % 指定は 最大幅に対して TB でも幅に対して + paddingB = calc( styles[ ATTRS.padding + 2 ], allowSize ); + borderT = styles[ ATTRS.border + 0 ]; + borderB = styles[ ATTRS.border + 2 ]; + marginT = calc( styles[ ATTRS.margin + 0 ], allowSize );// marginTRBL の % 指定は 最大幅に対して TB でも幅に対して + marginB = calc( styles[ ATTRS.margin + 2 ], allowSize ); + this.boxHeight = contentH; + boxMinus = 0; + switch( box ){ + case 3 : // margin-box + boxMinus = - marginT - marginR; + case 2 : // border-box + boxMinus -= borderT + borderR; + case 1 : // padding-box + boxMinus -= paddingT + paddingR; + // case 0 : // content-box + }; + this.contentT = marginT + borderT + paddingT; + this.conetntB = marginB + borderB + paddingB; + this.contentHeight = contentH + boxMinus; + this.boxSizingOffsetTB = boxMinus; + } else { + this.boxHeight = this.contentHeight = AUTO; + min = styles[ ATTRS.minHeight ]; + max = styles[ ATTRS.maxHeight ]; + this.minContentHeight = 1 <= min ? min : 0; + this.maxContentHeight = 1 <= max ? max : AUTO; + delete this.boxSizingOffsetTB; + }; + } else { + this.boxWidth = this.contentWidth = allowW; + this.boxHeight = this.contentHeight = allowH; + delete this.minContentHeight; + delete this.maxContentHeight; + delete this.contentL; + delete this.contentT; + delete this.contentR; + delete this.contentB; + }; + }, + /** + * 自身のコンテンツサイズを元に AUTO な width, height を確定していく + */ + postMesure : function(){ + var style = this.__style, + styles, calc, box, + contentW, contentH, w, h + contentSize, contentPlus; + if( style ){ + styles = style.data; + calc = BasicLayoutManager.advancedCalcValue; + contentW = this.contentWidth; + box = styles[ ATTRS.sizing ]; + + // Width + if( this.boxWidth === AUTO ){ + paddingR = calc( styles[ ATTRS.padding + 1 ], contentW ); + paddingL = calc( styles[ ATTRS.padding + 3 ], contentW ); + borderR = styles[ ATTRS.border + 1 ]; + borderL = styles[ ATTRS.border + 3 ]; + marginR = calc( styles[ ATTRS.margin + 1 ], contentW ); + marginL = calc( styles[ ATTRS.margin + 3 ], contentW ); + contentPlus = 0; + switch( box ){ + case 3 : // margin-box + contentPlus = ( marginR + marginL ); + case 2 : // border-box + contentPlus += ( borderR + borderL ); + case 1 : // padding-box + contentPlus += ( paddingR + paddingL ); + // case 0 : // content-box + }; + this.contentWidth = contentW; + contentW += contentPlus; + if( !style.ltrtWidth ){ + min = styles[ ATTRS.minWidth ]; + max = styles[ ATTRS.maxWidth ]; + if( contentW < min && 1 <= min && contentPlus < min ){ + this.contentWidth = min - contentPlus; + } else + if( max < contentW && 1 <= max && contentPlus < max ){ + this.contentWidth = max - contentPlus; + }; + }; + this.contentL = marginL + borderL + paddingL; + this.contentR = marginR + borderR + paddingR; + this.boxWidth = this.contentWidth + this.contentL + this.contentR; + }; + // Height + if( this.boxHeight === AUTO ){ + contentH = this.contentHeight; + contentSize = styles[ ATTRS.pageBox ] === true ? contentH : contentW; + paddingT = calc( styles[ ATTRS.padding + 0 ], contentSize );// paddingTRBL の % 指定は 最大幅に対して TB でも幅に対して + paddingB = calc( styles[ ATTRS.padding + 2 ], contentSize ); + borderT = styles[ ATTRS.border + 0 ]; + borderB = styles[ ATTRS.border + 2 ]; + marginT = calc( styles[ ATTRS.margin + 0 ], contentSize );// marginTRBL の % 指定は 最大幅に対して TB でも幅に対して + marginB = calc( styles[ ATTRS.margin + 2 ], contentSize ); + contentPlus = 0; + switch( box ){ + case 3 : // margin-box + contentPlus = ( marginT + marginB ); + case 2 : // border-box + contentPlus += ( borderT + borderB ); + case 1 : // padding-box + contentPlus += ( paddingT + paddingB ); + // case 0 : // content-box + }; + this.contentHeight = contentH; + contentH += contentPlus; + if( !style.tpbtHeight ){ + min = styles[ ATTRS.minHeight ]; + max = styles[ ATTRS.maxHeight ]; + if( contentH < min && 1 <= min && contentPlus < min ){ + this.contentHeight = min - contentPlus; + } else + if( max < contentH && 1 <= max && contentPlus < max ){ + this.contentHeight = max - contentPlus; + }; + }; + this.contentT = marginT + borderT + paddingT; + this.contentB = marginB + borderB + paddingB; + this.boxHeight = this.contentHeight + this.contentT + this.contentB; + }; + } else { + this.boxWidth = this.contentWidth; + this.boxHeight = this.contentHeight; + delete this.minContentHeight; + delete this.maxContentHeight; + delete this.contentL; + delete this.contentT; + delete this.contentR; + delete this.contentB; + }; + }, + addDisplayElement : function( nodeData ){ + // 描画更新リストに追加 + }, + removeDisplayElement : function( nodeData ){ + // 描画更新リストに追加 + DOM.correct( nodeData.elmWrap ); + delete nodeData.elmWrap; + delete nodeData.textNode; + delete nodeData.contentWidth; + delete nodeData.conetntHeight; + delete nodeData.currentWidth; + delete nodeData.currentHeight; + } + } + ); + var Node = Class.create( + 'Node', + Class.POOL_OBJECT, + NodePrivate, + { + Constructor : function( root, parent ){ + Node.newPrivateData( this, LayoutBox.getPrivateData( root ), parent ? LayoutBox.getPrivateData( parent ) : undefined, this ); + }, + content : function( v ){ + return Node.getPrivateData( this ).content( v ); + }, + style : function( v ){ + return Node.getPrivateData( this ).paint( v ); + }, + remove : function(){ + Node.getPrivateData( this ).remove(); + }, + nodeIndex : function( v ){ + return Node.getPrivateData( this ).nodeIndex( v ); + }, + displayIndex : function(){ + + }, + disabled : function( v ){ + return Node.getPrivateData( this ).disabled( v ); + }, + cursor : function( v ){ + return Node.getPrivateData( this ).cursor( v ); + }, + getX : function(){ + + }, + getY : function(){ + + }, + getWidth : function(){ + + }, + getHeight : function(){ + + }, + getAbsolutePositionX : function(){ + return Node.getPrivateData( this ).getAbsolutePositionX(); + }, + getAbsolutePositionY : function(){ + return Node.getPrivateData( this ).getAbsolutePositionY(); + }, + scrollTo : function( x, y ){ + Node.getPrivateData( this ).scrollTo( x, y ); + }, + scrollX : function( v ){ + return Node.getPrivateData( this ).scrollX( v ); + }, + scrollY : function( v ){ + return Node.getPrivateData( this ).scrollY( v ); + }, + addEventListener : function( type, handler, opt_thisObject ){ + Node.getPrivateData( this ).addEventListener( type, handler, opt_thisObject ); + }, + removeEventListener : function( type, handler ){ + Node.getPrivateData( this ).removeEventListener( type, handler ); + } + } + ); + + var LayoutBoxPrivate = NodePrivate.inherits( + 'LayoutBoxPrivate', + Class.POOL_OBJECT | Class.SUPER_ACCESS, + { + Constructor : function( layoutManager, _root, _parent ){ + this.layoutManager = layoutManager; + this._root = _root; + this.paintList = []; + if( _parent ) this._parent = _parent; + }, + mesure : function(){ + this.layoutManager.reflow( this ); + }, + paintReserve : function( nodeData ){ + var list = this.paintList; + if( Util.getIndex( list, nodeData ) === -1 ) list[ list.length - 1 ] = nodeData; + }, + paintRelease : function( nodeData ){ + var list = this.paintList, + i = Util.getIndex( list, nodeData ); + i === -1 && list.splice( i, 1 ); + }, + paint : function(){ + var list = this.paintList, i = list.length; + for( ; i; ){ + list[ --i ].paint(); + }; + } + } + ); + + var LayoutBox = Node.inherits( + 'LayoutBox', + Class.POOL_OBJECT, + LayoutBoxPrivate, + { + Constructor : function( layoutManager, root, parent ){ + LayoutBox.newPrivateData( this, layoutManager, LayoutBox.getPrivateData( root ), parent ? LayoutBox.getPrivateData( parent ) : undefined ); + }, + layoutManager : function( v ){ + + }, + createLayoutBox : function(){ + + }, + createContentBox : function(){ + + } + } + ); + + var RootNode = Node.inherits( + 'RootNode', + Class.POOL_OBJECT, + LayoutBoxPrivate, + { + Constructor : function(){ + RootNode.newPrivateData( this, BasicLayoutManager ); + } + } + ); + +})( window, document ); \ No newline at end of file -- 2.11.0 From 427d907328dadd487acc03c45f2977196f6d286d Mon Sep 17 00:00:00 2001 From: itozyun Date: Tue, 12 Mar 2013 06:31:34 +0900 Subject: [PATCH 08/16] cleanup pettanr.balloon --- 0.5.x/javascripts/peta-apps.js | 29 ++++++-- 0.5.x/javascripts/peta-common.js | 139 ++++++++++++++++++++++----------------- 0.5.x/javascripts/system.js | 10 ++- 0.5.x/javascripts/xdoc.js | 10 +-- 4 files changed, 116 insertions(+), 72 deletions(-) diff --git a/0.5.x/javascripts/peta-apps.js b/0.5.x/javascripts/peta-apps.js index 1d822e6..08ae46d 100644 --- a/0.5.x/javascripts/peta-apps.js +++ b/0.5.x/javascripts/peta-apps.js @@ -1,6 +1,6 @@ /* * pettanR peta.apps.js - * version 0.5.47 + * version 0.5.48 * * author: * itozyun @@ -87,7 +87,15 @@ data = createFileData( json, LICENSE_GROUP_ARRAY, 'name,caption,url,classname' ); addChildData( FILE_DATA_LISENCE_GROUP, data ); break; - + + // Speech Balloon Templete + case FILE_DATA_BALLOON_ROOT : + case BALLOON_TEMPLETE_ARRAY : + json.type = FILE_TYPE.BALLOON_TEMPLETE; + data = createFileData( json, BALLOON_TEMPLETE_ARRAY, 'name,caption,classname,settings' ); + addChildData( FILE_DATA_BALLOON_ROOT, data ); + break; + // Author case FILE_DATA_AUTHOR_ROOT : case AUTHOR_ARRAY : @@ -338,6 +346,8 @@ return [ data.name, '先生' ].join( '' ); case FILE_TYPE.ARTIST : return [ data.name, '画伯' ].join( '' ); + case FILE_TYPE.BALLOON_TEMPLETE : + return [ data.id, data.caption ].join( ':' ); case FILE_TYPE.FOLDER : }; return data.name; @@ -370,6 +380,8 @@ return { className: 'file-type-author' }; case FILE_TYPE.ARTIST : return { className: 'file-type-artist' }; + case FILE_TYPE.BALLOON_TEMPLETE : + return { className: 'file-type-balloon' }; case FILE_TYPE.FOLDER : return { className: 'file-type-folder' }; }; @@ -400,6 +412,8 @@ return 'author id:' + data.id; case FILE_TYPE.ARTIST : return [ 'artist id:', data.id, ' Email:', data.email || 'empty' , ', HP:', data.homepage_url || 'empty' ].join( '' ); + case FILE_TYPE.BALLOON_TEMPLETE : + return data.name + ', ' + data.settings; case FILE_TYPE.FOLDER : return 'pettanR folder'; }; @@ -488,14 +502,15 @@ STORY : FileAPI.createFileTypeID(), PANEL : FileAPI.createFileTypeID(), PANEL_ELEMENT : FileAPI.createFileTypeID(), - BALLOON : FileAPI.createFileTypeID(), + BALLOON : FileAPI.createFileTypeID(), + BALLOON_TEMPLETE : FileAPI.createFileTypeID(), ORIGINAL_PICTURE : FileAPI.createFileTypeID(), RESOURCE_PICTURE : FileAPI.createFileTypeID(), PICTURE : FileAPI.createFileTypeID(), AUTHOR : FileAPI.createFileTypeID(), ARTIST : FileAPI.createFileTypeID(), LICENSE : FileAPI.createFileTypeID(), - LICENSE_GROUP : FileAPI.createFileTypeID() + LICENSE_GROUP : FileAPI.createFileTypeID(), } ), AUTHOR_ARRAY = [], @@ -616,9 +631,11 @@ children: [] }, FILE_DATA_BALLOON_ROOT = { - name: 'Balloon templetes', + name: 'Balloon Templetes', type: FILE_TYPE.FOLDER, - children: [] + children: [], + driver: Driver, + json: pettanr.CONST.SPEECH_BALOON_TEMPLETE }; FILE_DATA_SERVICE_ROOT.children.push( FILE_DATA_COMICS_ROOT, FILE_DATA_RESOURCE_PICTURES_ROOT, FILE_DATA_ORIGINAL_PICTURES_ROOT, FILE_DATA_LISENCE_ROOT, FILE_DATA_BALLOON_ROOT ); FILE_DATA_COMICS_ROOT.children.push( FILE_DATA_MY_COMICS_ROOT, FILE_DATA_LATEST_COMICS, FILE_DATA_AUTHOR_ROOT, FILE_DATA_STORY_ROOT, FILE_DATA_PANELS_ROOT ); diff --git a/0.5.x/javascripts/peta-common.js b/0.5.x/javascripts/peta-common.js index 8b49c55..0237fc7 100644 --- a/0.5.x/javascripts/peta-common.js +++ b/0.5.x/javascripts/peta-common.js @@ -1,6 +1,6 @@ /* * pettanR peta.common.js - * version 0.5.47 + * version 0.5.48 * * author: * itozyun @@ -93,6 +93,7 @@ pettanr.CONST = ( function(){ URL_MY_COMICS_JSON : ( SERVER_SUPPORT === false ? 'json\/' : PETTANR_ROOT_PATH ) + 'home\/comic.json', URL_PANELS_JSON : ( SERVER_SUPPORT === false ? 'json\/' : PETTANR_ROOT_PATH ) + 'panels.json', URL_MY_PANELS_JSON : ( SERVER_SUPPORT === false ? 'json\/' : PETTANR_ROOT_PATH ) + 'home\/panel.json', + SPEECH_BALOON_TEMPLETE : ( SERVER_SUPPORT === false ? 'json\/' : PETTANR_ROOT_PATH ) + 'speech_balloon_templates.json\/', NS_PETTANR_COMIC : 'pettanr-comic', THUMBNAIL_PATH : SERVER_SUPPORT === false ? RELATIVE + 'resource_pictures\/thumbnail\/' : PETTANR_ROOT_PATH + 'resource_pictures\/', RESOURCE_PICTURE_PATH : SERVER_SUPPORT === false ? RELATIVE + 'resource_pictures\/' : PETTANR_ROOT_PATH + 'resource_pictures\/full\/', @@ -147,7 +148,7 @@ pettanr.balloon = ( function() { ELM_BALLOON_ORIGIN = ( function(){ var ret; try { - if( IS_VML === true){ + if( IS_VML === true ){ ret = document.createElement( 'DIV'); var shape = document.createElement( 'v:shape'); shape.coordorigin = "0,0"; @@ -187,22 +188,57 @@ pettanr.balloon = ( function() { TARGET = TAIL_WIDTH * TAIL_WIDTH, isFinit = Type.isFinite, ACCURACY = 1, // 有効少数桁 - cround = function ( v, r ){ + cround = function( v, r ){ r = r || ACCURACY; return round( v * pow( 10.0, r )) / pow( 10.0, r ); }, DEG_TO_RAD = Math.PI / 180; var XBROWSER_BALLOON_CLASS = function( w, h, a ){ - var balloonElm = vectorEnabled === true ? ELM_BALLOON_ORIGIN.cloneNode( true ) : document.createElement( 'img' ), // pettanr.imageに変更 - path = balloonElm.getElementsByTagName( 'path' )[ 0 ], - shape = balloonElm.getElementsByTagName( 'shape' )[ 0 ], - instance = this, - l = ','; - - function draw( _a ){ - var rx = w / 2, - ry = h / 2, + this.elm = vectorEnabled === true ? ELM_BALLOON_ORIGIN.cloneNode( true ) : document.createElement( 'img' ); // pettanr.imageに変更 + this.path = this.elm.getElementsByTagName( IS_VML === true ? 'shape' : 'path' )[ 0 ]; + this.resize( a, w, h ); + }; + XBROWSER_BALLOON_CLASS.prototype = { + elm : null, + path : null, + w : 0, + h : 0, + a : 0, + resize : function ( _a, _w, _h ){ + this.w = isFinit( _w ) === true ? _w - PADDING_TOP * 2 : this.w; + this.h = isFinit( _h ) === true ? _h - PADDING_LEFT * 2 : this.h; + // ie6 でリサイズが反応しない対策 + if( vectorEnabled === false && UA.isIE === true && UA.ieVersion < 7 ){ + var parent = this.elm.parentNode; + parent.removeChild( this.elm ); + parent.insertBefore( this.elm, parent.firstChild ); + }; + this.angle( _a ); + }, + angle : function( _a ){ + if( isFinit( _a ) === true ){ + this.a = _a; + if( vectorEnabled === false ){ + this.elm.src = pettanr.balloon.getBalloonUrl( this.w, this.h, _a ); + } else { + this.draw( _a ); + }; + }; + return this.a; + }, + type : function( _type ){ + //draw( _a); + }, + destroy : function(){ + this.elm.parentNode && this.elm.parentNode.removeChild( this.elm ); + delete this.elm; + delete this.path; + }, + draw : function( _a ){ + var rx = this.w / 2, + ry = this.h / 2, + l = ',', tailRad = _a * DEG_TO_RAD, tailX = rx + ( rx + TAIL_HEIGHT ) * sin( tailRad ), tailY = ry - ( ry + TAIL_HEIGHT ) * cos( tailRad ), @@ -215,7 +251,7 @@ pettanr.balloon = ( function() { tailDeg = 0, d; for( var i = 45; i > 0.01; i /= 2){ - d = ( tailDeg + i ) /2; + d = ( tailDeg + i ) / 2; startRad = ( _a + d ) * DEG_TO_RAD; endRad = ( _a - d ) * DEG_TO_RAD; @@ -239,27 +275,27 @@ pettanr.balloon = ( function() { if( IS_VML === true ){ var _tailX = tailX *10, _tailY = tailY *10, - __w = w *10, - __h = h *10; + __w = this.w *10, + __h = this.h *10; - shape.style.width = w + 'px'; - shape.style.height = h + 'px'; - shape.coordsize = [ __w, __h ].join( l ); - shape.path = [ + this.path.style.width = this.w + 'px'; + this.path.style.height = this.h + 'px'; + this.path.coordsize = [ __w, __h ].join( l ); + this.path.path = [ ' ar ', 0, l, 0, l, __w, l, __h, l, round( endX * 10 ), l, round( endY * 10 ), l, round( startX * 10 ), l, round( startY * 10 ), ' l ', round( _tailX ), l, round( _tailY ), ' x e' - ].join( ''); + ].join( '' ); - balloonElm.style.marginTop = _tailY < 0 ? floor( ( 60 + _tailY) / 10 ) : 10; - balloonElm.style.marginLeft = _tailX < 0 ? floor( ( 60 + _tailX) / 10 ) : 10; + this.elm.style.marginTop = _tailY < 0 ? floor( ( 60 + _tailY) / 10 ) : 10; + this.elm.style.marginLeft = _tailX < 0 ? floor( ( 60 + _tailX) / 10 ) : 10; } else { - balloonElm.setAttribute( 'width', w + PADDING_LEFT *2 ); - balloonElm.setAttribute( 'height', h + PADDING_TOP *2 ); - path.setAttribute( 'd', [ - 'M', cround( tailX + PADDING_LEFT ), l, cround( tailY + PADDING_TOP ), + this.elm.setAttribute( 'width', this.w + PADDING_LEFT *2 ); + this.elm.setAttribute( 'height', this.h + PADDING_TOP *2 ); + this.path.setAttribute( 'd', [ + 'M', cround( tailX + PADDING_LEFT ), l, cround( tailY + PADDING_TOP ), 'L', cround( startX + PADDING_LEFT ), l, cround( startY + PADDING_TOP ), 'A', rx, l, ry, '0 1 1', // flag @@ -268,40 +304,6 @@ pettanr.balloon = ( function() { ].join( ' ')); } } - - this.elm = balloonElm; - this.resize = function ( _a, _w, _h ){ - w = isFinit( _w ) === true ? _w - PADDING_TOP * 2 : w; - h = isFinit( _h ) === true ? _h - PADDING_LEFT * 2 : h; - // ie6 でリサイズが反応しない対策 - if( vectorEnabled === false && UA.isIE === true && UA.ieVersion < 7 ){ - var parent = balloonElm.parentNode; - parent.removeChild( balloonElm ); - parent.insertBefore( balloonElm, parent.firstChild ); - } - instance.angle( _a ); - }; - this.angle = function( _a ){ - if( isFinit( _a ) === true ){ - a = _a; - if( vectorEnabled === false ){ - balloonElm.src = pettanr.balloon.getBalloonUrl( w, h, _a ); - } else { - draw( _a ); - } - } - return a; - } - this.type = function( _type ){ - //draw( _a); - } - this.destroy = function(){ - delete instance.destroy; - balloonElm.parentNode && balloonElm.parentNode.removeChild( balloonElm ); - balloonElm = path = shape = instance = null; - } - - instance.resize( a, w, h ); }; return { @@ -329,6 +331,20 @@ pettanr.balloon = ( function() { } })(); +pettanr.newBalloon = ( function(){ + return { + register : function( className ){ + + }, + isBalloonClass : function(){ + + }, + isBalloonInstance : function(){ + + } + } +})(); + /* ---------------------------------------- * pettanr.image * @@ -348,7 +364,8 @@ pettanr.balloon = ( function() { * - VML * - flash(lite) * - silverlight - * + * - pettan server + * * -moz-transform:scale( -1, -1); */ pettanr.image = ( function(){ diff --git a/0.5.x/javascripts/system.js b/0.5.x/javascripts/system.js index 7ab89d8..364938c 100644 --- a/0.5.x/javascripts/system.js +++ b/0.5.x/javascripts/system.js @@ -1,6 +1,6 @@ /* * pettanR system.js - * version 0.5.47 + * version 0.5.48 * * gadgetOS * author: @@ -301,6 +301,14 @@ var Class = ( function(){ if( iList.length !== 0 ) return; delete def.callbackInstanceList; delete def.callbackRegisterList; + }, + listenTo : function( eventDispatcher, eventType, callback ){ + //if( eventDispatcher instanceof EventDsipatcher ){ + eventDispatcher.addEventListener( eventType, callback, this ); + //} + }, + unlistenTo : function( eventDispatcher, eventType, callback ){ + } }; diff --git a/0.5.x/javascripts/xdoc.js b/0.5.x/javascripts/xdoc.js index 712ba3d..c47c14f 100644 --- a/0.5.x/javascripts/xdoc.js +++ b/0.5.x/javascripts/xdoc.js @@ -1463,10 +1463,12 @@ var XDocument = ( function( window, document ){ }, style : function( v ){ if( v instanceof NodeStyle ){ - this.__style && this.__style.unRegister( this ); - this._style = v; - this.__style = StylePrivate.getPrivateData( v ); - this.__style.register( this ); + if( v !== this._style ){ + this.__style && this.__style.unRegister( this ); + this._style = v; + this.__style = StylePrivate.getPrivateData( v ); + this.__style.register( this ); + }; return this.User; } else if( v === null ){ -- 2.11.0 From 0531153c39734fbbb020088381a346ea2ad2742e Mon Sep 17 00:00:00 2001 From: itozyun Date: Fri, 19 Jul 2013 07:02:33 +0900 Subject: [PATCH 09/16] Version 0.6.x starting. --- 0.5.x/javascripts/peta-apps.js | 51 +++++---- 0.5.x/javascripts/peta-common.js | 223 ++++++++++++++++++++++++++++++++++----- 2 files changed, 222 insertions(+), 52 deletions(-) diff --git a/0.5.x/javascripts/peta-apps.js b/0.5.x/javascripts/peta-apps.js index 08ae46d..16cabfe 100644 --- a/0.5.x/javascripts/peta-apps.js +++ b/0.5.x/javascripts/peta-apps.js @@ -1,6 +1,6 @@ /* * pettanR peta.apps.js - * version 0.5.48 + * version 0.5.49 * * author: * itozyun @@ -92,6 +92,8 @@ case FILE_DATA_BALLOON_ROOT : case BALLOON_TEMPLETE_ARRAY : json.type = FILE_TYPE.BALLOON_TEMPLETE; + // register pettanr.balloon + pettanr.newBalloon.register( json.settings ); data = createFileData( json, BALLOON_TEMPLETE_ARRAY, 'name,caption,classname,settings' ); addChildData( FILE_DATA_BALLOON_ROOT, data ); break; @@ -3697,7 +3699,7 @@ var Editor = gOS.registerApplication( function(){ this.$ = jqImageElementOrigin.clone( true ); this.data = data; this.z = data.z; - this.timing = data.t || PANEL_ELEMENT_ARRAY.length + 1; + this.timing = data.t || PANEL_ELEMENT_ARRAY.length; this.keepSize = false; this.flipV = data.height < 0 ? -1 : 1; this.flipH = data.width < 0 ? -1 : 1; @@ -3829,7 +3831,7 @@ var Editor = gOS.registerApplication( function(){ })(); this.balloon = pettanr.balloon.createBalloon( data.width, data.height, data.tail, this.type ); this.z = data.z; - this.timing = data.t || PANEL_ELEMENT_ARRAY.length + 1; + this.timing = data.t || PANEL_ELEMENT_ARRAY.length; this.$.find( 'img' ).eq( 0 ).replaceWith( this.balloon.elm ); @@ -4090,7 +4092,7 @@ var Editor = gOS.registerApplication( function(){ x : Math.floor( panelW / 2 - data.width / 2 ), y : Math.floor( panelH / 2 - data.height / 2 ), z : -1, - t : PANEL_ELEMENT_ARRAY.length + 1, + t : 0, width : 1, height : 1 }); @@ -4114,7 +4116,7 @@ var Editor = gOS.registerApplication( function(){ x: Math.floor( panelW / 2 - 100 + Math.random() * 10 ), y: Math.floor( panelH / 2 - 100 + Math.random() * 10 ), z: -1, - t: PANEL_ELEMENT_ARRAY.length + 1, + t: 0, width: 200, height: 200, speeches_attributes: { @@ -5127,7 +5129,7 @@ var Model = ( function(){ '}' ].join( ''); }; - function imageToJson( _imageElement, _timing ){ + function imageToJson( _imageElement, t ){ var cr = pettanr.LINE_FEED_CODE_TEXTAREA; return [ '{', cr, @@ -5135,36 +5137,40 @@ var Model = ( function(){ '"x": ', _imageElement.x, ',', cr, '"y": ', _imageElement.y, ',', cr, '"z": ', _imageElement.z + 1, ',', cr, - '"t": ', _timing, ',', cr, + '"t": ', t, ',', cr, '"width": ', _imageElement.flipH * _imageElement.w, ',', cr, '"height": ', _imageElement.flipV * _imageElement.h, cr, '}' ].join( ''); }; - function balloonToJson( _textElement, _timing ){ + function balloonToJson( _textElement, t ){ var cr = pettanr.LINE_FEED_CODE_TEXTAREA; return [ '{', cr, - '"balloon_template_id": ', 1, ',', cr, - '"system_picture_id": ', 1, ',', cr, - '"size": ', 1, ',', cr, - '"tail": ', _textElement.a, ',', cr, - '"x": ', _textElement.x, ',', cr, - '"y": ', _textElement.y, ',', cr, - '"z": ', _textElement.z + 1, ',', cr, - '"t": ', timing, ',', cr, - '"width": ', _textElement.w, ',', cr, - '"height": ', _textElement.h, ',', cr, - '"speeches_attributes": {', cr, - '"newf', timing, '": {', cr, - '"content": "', _textElement.content, '",', cr, + '"speech_balloon_template_id": ', 1, ',', cr, + '"classname": "Square",', + '"z": ', _textElement.z + 1, ',', cr, + '"t": ', t, ',', cr, + '"settings": "{\'tail\':' + _textElement.a + '}",', + '"balloons_attributes": {', cr, + '"newb', t, '": {', cr, + '"system_picture_id": ', 2, ',', cr, + '"caption": "alt text",', cr, '"x": ', _textElement.x, ',', cr, '"y": ', _textElement.y, ',', cr, - '"t": ', timing, ',', cr, '"width": ', _textElement.w, ',', cr, '"height": ', _textElement.h, cr, '}', cr, + '},', cr, + '"speeches_attributes": {', cr, + '"news', t, '": {', cr, + '"content": "', _textElement.content, '",', cr, + '"x": ', Math.floor( _textElement.w * 0.16 ), ',', cr, + '"y": ', Math.floor( _textElement.w * 0.16 ), ',', cr, + '"width": ', Math.floor( _textElement.w * 0.66 ), ',', cr, + '"height": ', Math.floor( _textElement.h * 0.66 ), cr, + '}', cr, '}', cr, '}' ].join( ''); @@ -5296,7 +5302,6 @@ var OutputConsole = gOS.registerApplication( function(){ comboboxFormat, inputOption, buttonSubmit, buttonClose, windowW, windowH, - timing = 0, comicID, panelID, panelTimming, panelW, panelH, borderSize, panelElementArray, app = this, model = null; diff --git a/0.5.x/javascripts/peta-common.js b/0.5.x/javascripts/peta-common.js index 0237fc7..13a4244 100644 --- a/0.5.x/javascripts/peta-common.js +++ b/0.5.x/javascripts/peta-common.js @@ -1,6 +1,6 @@ /* * pettanR peta.common.js - * version 0.5.48 + * version 0.5.49 * * author: * itozyun @@ -110,29 +110,7 @@ pettanr.CONST = ( function(){ })(); /* ---------------------------------------- - * Vector Support - * - * __________ - * / \ - * / \ - * |,startX,Y | - * tailX,Y - < | - * |'endX,Y | - * \ / - * \__________/ - * - * SVG - * ----------------------- - * ie9, other modern browser - * - * XML - * ----------------------- - * ie5.5-8 - * - * 内部の角度計算は radian で統一したい。 - * 当初 vectorEnabled = true で一度書いてみる。 - * 駄目なら、代替のイメージのsrcの用意もここで担当。 - * 閲覧と編集両方で使う。 + * old balloon. * */ pettanr.balloon = ( function() { @@ -331,16 +309,203 @@ pettanr.balloon = ( function() { } })(); +/* ---------------------------------------- + * New Balloon + * + * Vector : SVG, Canvas, VML, Flash, None + * + */ pettanr.newBalloon = ( function(){ - return { - register : function( className ){ + var TEMPLETES = {}; + + var STROKE_WIDTH = 1.2, + IS_VML = UA.isIE === true && UA.ieVersion < 9, + ELM_BALLOON_ORIGIN = ( function(){ + var ret; + try { + if( IS_VML === true ){ + ret = document.createElement( 'DIV' ); + var shape = document.createElement( 'v:shape' ); + shape.coordorigin = "0,0"; + shape.strokecolor = "black"; + shape.strokeweight = STROKE_WIDTH; + shape.fillcolor = "white"; + ret.appendChild( shape); + } else { + var kSVGNS = 'http://www.w3.org/2000/svg'; + // http://modernizr.com/downloads/modernizr.js + // Thanks to Erik Dahlstrom + if( !document.createElementNS || !document.createElementNS(kSVGNS, 'svg' ).createSVGRect ){ + return null; + }; + ret = document.createElementNS( kSVGNS, 'svg' ); + var path = document.createElementNS( kSVGNS, 'path' ); + path.setAttribute( 'fill', "white" ); + path.setAttribute( 'stroke', "black" ); + path.setAttribute( 'strokeWidth', STROKE_WIDTH ); + ret.appendChild( path ); + }; + return ret; + } catch( e ){ + return null; + }; + })(), + vectorEnabled = ELM_BALLOON_ORIGIN !== null && + pettanr.URL_PARAMS.vector !== false && + !( IS_VML === true && UA.VML === false ), + BalloonClass; + + if( vectorEnabled === true ){ + BalloonClass = function( templete ){ + this.elm = ELM_BALLOON_ORIGIN.cloneNode( true ); + this.path = this.elm.getElementsByTagName( IS_VML === true ? 'shape' : 'path' )[ 0 ]; + this.klass = klass; + this.getPath = klass.getPath; + }; + BalloonClass.prototype = { + elm : null, + path : null, + klass : null, + getPath : null, + args : null, + update : IS_VML === true ? + function( /* w, h [, angle, ,,, ] */ ){ + var w = arguments[ 0 ], + h = arguments[ 1 ]; + var path = this.getPath.call( this.klass, arguments ); + if( !path ) return false; + path = /* SVG2VML */ path; + this.path.style.width = w + 'px'; + this.path.style.height = h + 'px'; + this.path.coordsize = ( w * 10 ) + ',' + ( h * 10 ); + this.path.path = path; + // this.elm.style.marginTop = _tailY < 0 ? floor( ( 60 + _tailY) / 10 ) : 10; + // this.elm.style.marginLeft = _tailX < 0 ? floor( ( 60 + _tailX) / 10 ) : 10; + } : + function( /* w, h [, angle, ,,, ] */ ){ + var w = arguments[ 0 ], + h = arguments[ 1 ], + d = this.getPath.call( this.klass, arguments ); + if( !d ) return false; + this.elm.width = w + PADDING_LEFT * 2; + this.elm.height = h + PADDING_TOP * 2; + this.path.setAttribute( 'd', d ); + }, + destroy : function(){ + this.elm.parentNode && this.elm.parentNode.removeChild( this.elm ); + delete this.elm; + delete this.path; + } + }; + } else { + BalloonClass = function( klass ){ + // templete の vector の有無 + this.elm = document.createElement( 'img' ); // pettanr.imageに変更 + this.klass = klass; + this.getPictureID = klass.getPictureID; + }; + BalloonClass.prototype = { + elm : null, + klass : null, + getPictureID : null, + args : null, + update : function( /* w, h [, angle, ,,, ] */ ){ + var id = this.getPictureID.call( this.klass, arguments ); + if( id !== 0 && !id ) return false; + this.elm.src = pettanr.CONST.SYSTEM_PICTURE_PATH + id + '.gif'; + }, + destroy : function(){ + this.elm.parentNode && this.elm.parentNode.removeChild( this.elm ); + } + }; + }; + + /* + * http://sourceforge.jp/projects/pettanr/wiki/HowToMakeSpeechBalloon + */ + var NonVectorBalloonClass = function( templete ){ + this.elm = document.createElement( 'img' ); // pettanr.imageに変更 + this.size = this.elm.style; + //this.templete = templete; + //this.speech = templete.speech_template_attributes; + //this.defaultW = templete.default_width; + //this.defaultH = templete.default_height; + //this.sizeCount = templete.size_count; + this.wOffset = templete.width_offset; + this.hOffset = templete.height_offset; + this.wStep = templete.width_step; + this.hStep = templete.height_step; + // r_offset + // r_steps + + var obj = templete.balloon_template_attributes, v, p; + + if( templete.size_count && 1 < templete.size_count ){ + this.picIDs = []; // system picture id list + for( p in obj ){ + v = obj[ v ]; + this.picIDs[ v.size ] = v.system_picture_id; + }; + } else { + for( p in obj ){ + v = obj[ v ]; + this.picID = v.system_picture_id; + }; + }; + }; + NonVectorBalloonClass.prototype = { + elm : null, + size : null, + templete : null, + args : null, + picIDs : null, + picID : 0, + path : pettanr.CONST.SYSTEM_PICTURE_PATH, + update : function( w, h /* [, angle, ,,, ] */ ){ + var l, id, _w, _h; + if( this.picIDs ){ + _w = ( w - this.wOffset ) / this.wStep; + _h = ( h - this.hOffset ) / this.hStep; + l = this.picIDs.length - 1; + _w = _w < 0 ? 0 : ( _w > l ? l : _w ); + _h = _h < 0 ? 0 : ( _h > l ? l : _h ); + id = this.picIDs[ _w > _h ? _w : _h ]; + } else { + id = this.picID; + }; + this.elm.src = this.path + id + '.gif'; + this.size.width = w + 'px'; + this.size.height = h + 'px'; }, - isBalloonClass : function(){ - + destory : function(){ + this.elm.parentNode && this.elm.parentNode.removeChild( this.elm ); + } + }; + + return { + /** + * balloon_templetes.json 取得時に呼ばれる + * className は存在しない場合もある + */ + register : function( templete ){ + templete = $.parseJSON( templete ); + if( templete.classname && !TEMPLETES[ templete.classname ] ){ + TEMPLETES[ templete.classname ] = templete; + delete templete.classname; + }; }, - isBalloonInstance : function(){ + create : function( name ){ + if( Type.isString( name ) === true && name in window ){ + return new BalloonClass( window[ name ] ); + }; + return new NonVectorBalloonClass( TEMPLETES[ name ] ); + }, + isTemplete : function( templete ){ + }, + isInstance : function( balloon ){ + return balloon instanceof BalloonClass || balloon instanceof NonVectorBalloonClass; } } })(); -- 2.11.0 From 274d0a6291860ae033cd637df296d4327b0fa38c Mon Sep 17 00:00:00 2001 From: itozyun Date: Fri, 19 Jul 2013 07:03:59 +0900 Subject: [PATCH 10/16] Version 0.6.x starting. --- 0.6.x/css/ju.css | 21 + 0.6.x/index.html | 43 ++ 0.6.x/js/JU/AbstractDisplayContainer.js | 234 +++++++++ 0.6.x/js/JU/AbstractDisplayNode.js | 93 ++++ 0.6.x/js/JU/Box.js | 39 ++ 0.6.x/js/JU/ChromeBox.js | 86 ++++ 0.6.x/js/JU/DisplayNodeStyle.js | 232 +++++++++ 0.6.x/js/JU/HBox.js | 73 +++ 0.6.x/js/JU/LayoutManagerBase.js | 10 + 0.6.x/js/JU/PageRoot.js | 64 +++ 0.6.x/js/JU/Text.js | 59 +++ 0.6.x/js/JU/TileBox.js | 56 +++ 0.6.x/js/JU/VBox.js | 76 +++ 0.6.x/js/_old/Attr.js | 54 ++ 0.6.x/js/_old/AttrNo.js | 9 + 0.6.x/js/_old/BasicLayoutManager.js | 105 ++++ 0.6.x/js/_old/Dirty.js | 7 + 0.6.x/js/_old/LayoutBox.js | 50 ++ 0.6.x/js/_old/Node.js | 487 ++++++++++++++++++ 0.6.x/js/_old/NodeStyle.js | 378 ++++++++++++++ 0.6.x/js/_old/Option.js | 10 + 0.6.x/js/_old/Type.js | 20 + 0.6.x/js/_old/xdoc.js | 866 ++++++++++++++++++++++++++++++++ 0.6.x/js/core/00_builtin.js | 114 +++++ 0.6.x/js/core/01_XUa.js | 30 ++ 0.6.x/js/core/02_XType.js | 47 ++ 0.6.x/js/core/03_XCancel.js | 7 + 0.6.x/js/core/04_XCallback.js | 182 +++++++ 0.6.x/js/core/05_XClass.js | 309 ++++++++++++ 0.6.x/js/core/06_XTimer.js | 113 +++++ 0.6.x/js/core/07_XEventDispatcher.js | 84 ++++ 0.6.x/js/core/10_XStyle.js | 30 ++ 0.6.x/js/core/11_XDom.js | 190 +++++++ 0.6.x/js/core/12_XDomEvent.js | 168 +++++++ 0.6.x/js/core/13_XViewEvent.js | 18 + 0.6.x/js/core/14_XView.js | 113 +++++ 0.6.x/js/core/19_XQuery.js | 589 ++++++++++++++++++++++ 0.6.x/js/core/bootstrap.js | 248 +++++++++ 38 files changed, 5314 insertions(+) create mode 100644 0.6.x/css/ju.css create mode 100644 0.6.x/index.html create mode 100644 0.6.x/js/JU/AbstractDisplayContainer.js create mode 100644 0.6.x/js/JU/AbstractDisplayNode.js create mode 100644 0.6.x/js/JU/Box.js create mode 100644 0.6.x/js/JU/ChromeBox.js create mode 100644 0.6.x/js/JU/DisplayNodeStyle.js create mode 100644 0.6.x/js/JU/HBox.js create mode 100644 0.6.x/js/JU/LayoutManagerBase.js create mode 100644 0.6.x/js/JU/PageRoot.js create mode 100644 0.6.x/js/JU/Text.js create mode 100644 0.6.x/js/JU/TileBox.js create mode 100644 0.6.x/js/JU/VBox.js create mode 100644 0.6.x/js/_old/Attr.js create mode 100644 0.6.x/js/_old/AttrNo.js create mode 100644 0.6.x/js/_old/BasicLayoutManager.js create mode 100644 0.6.x/js/_old/Dirty.js create mode 100644 0.6.x/js/_old/LayoutBox.js create mode 100644 0.6.x/js/_old/Node.js create mode 100644 0.6.x/js/_old/NodeStyle.js create mode 100644 0.6.x/js/_old/Option.js create mode 100644 0.6.x/js/_old/Type.js create mode 100644 0.6.x/js/_old/xdoc.js create mode 100644 0.6.x/js/core/00_builtin.js create mode 100644 0.6.x/js/core/01_XUa.js create mode 100644 0.6.x/js/core/02_XType.js create mode 100644 0.6.x/js/core/03_XCancel.js create mode 100644 0.6.x/js/core/04_XCallback.js create mode 100644 0.6.x/js/core/05_XClass.js create mode 100644 0.6.x/js/core/06_XTimer.js create mode 100644 0.6.x/js/core/07_XEventDispatcher.js create mode 100644 0.6.x/js/core/10_XStyle.js create mode 100644 0.6.x/js/core/11_XDom.js create mode 100644 0.6.x/js/core/12_XDomEvent.js create mode 100644 0.6.x/js/core/13_XViewEvent.js create mode 100644 0.6.x/js/core/14_XView.js create mode 100644 0.6.x/js/core/19_XQuery.js create mode 100644 0.6.x/js/core/bootstrap.js diff --git a/0.6.x/css/ju.css b/0.6.x/css/ju.css new file mode 100644 index 0000000..dbce5ff --- /dev/null +++ b/0.6.x/css/ju.css @@ -0,0 +1,21 @@ +html, body { + margin : 0; + padding : 0; + width : 100%; + height : 100%; + overflow : hidden; +} + +.PageRoot { + position : relative; +} + +.Box, +.VBox, +.HBox, +.TileBox, +.ChromeBox { + position : absolute; + box-sizing : border-box; + -moz-box-sizing : border-box; +} \ No newline at end of file diff --git a/0.6.x/index.html b/0.6.x/index.html new file mode 100644 index 0000000..0bb150c --- /dev/null +++ b/0.6.x/index.html @@ -0,0 +1,43 @@ + + + + + + + + + Js UI + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/0.6.x/js/JU/AbstractDisplayContainer.js b/0.6.x/js/JU/AbstractDisplayContainer.js new file mode 100644 index 0000000..59e82a3 --- /dev/null +++ b/0.6.x/js/JU/AbstractDisplayContainer.js @@ -0,0 +1,234 @@ +var _AbstractDisplayContainer = _AbstractDisplayNode.inherits( + '_AbstractDisplayContainer', + X.Class.PRIVATE_DATA, + { + layout : null, + chromeNodes : null, + nodes : null, + forContainer : false, + tmpCss : null, + Constructor : function( layout, args ){ + if( !( this.User instanceof AbstractDisplayContainer ) ){ + throw new Error( 'AbstractDisplayContainer を継承したインスタンスだけが _AbstractDisplayContainer のオーナーになれます' ); + }; + var i = 0, + l = args.length, + nodes = [], + arg, _data; + for( ; i < l; ++i ){ + arg = args[ i ]; + if( arg instanceof AbstractDisplayNode ){ + _data = X.Class._getPrivate( arg ); + nodes[ nodes.length ] = _data; + if( _data.parent ){ + throw new Error( 'インスタンスはすでに親に追加されています ' + arg ); + }; + } else + if( arg instanceof LayoutManagerBase ){ + layout = arg; + } else + if( X.Type.isObject( arg ) === true ){ + this.tmpCss = arg; + } else { + throw new Error( 'AbstractDisplayNode を継承したインスタンスを渡してください ' + arg ); + }; + }; + this.layout = layout; + this.nodes = nodes; + }, + /* Rellay */ + initialize : function( root, rootData, parent, parentData ){ + var nodes = this.nodes, + i = nodes.length; + this.root = root; + this.rootData = rootData; + this.parent = parent; + this.parentData = parentData; + this.rawElement = document.createElement( 'div' ); + this.rawStyle = this.rawElement.style; + + for( ; i; ){ + nodes[ --i ].initialize( root, rootData, this.User, this ); + }; + + this.phase = 1; + this.User.dispatch( { type : X.ViewEvent.INIT } ); + }, + + addToParent : function( parentElement, skip ){ + var nodes = this.nodes, + l = nodes.length, + i = 0; + skip !== true && parentElement.appendChild( this.rawElement ); + + for( i = 0, l = nodes.length; i < l; ++i ){ + nodes[ i ].addToParent( this.rawElement ); + }; + + this.styleData.initialize(); + + this.phase = 2; + this.User.dispatch( { type : X.ViewEvent.ADDED } ); + }, + + /* Rellay */ + afterAddition : function(){ + var nodes = this.nodes, + i = nodes.length; + for( ; i; ){ + nodes[ --i ].afterAddition(); + }; + this.styleData.afterAddition(); + this.phase = 3; + this.User.dispatch( { type : X.ViewEvent.CREATION_COMPLETE } ); + }, + + calculate : function( x, y, w, h ){ + this.layout.calculate( this, x, y, w, h ); + this.phase = 4; + }, + + commitUpdate : function(){ + + }, + + addAt : function( index, _nodes ){ + //console.log( '# AddAt ' + this.phase ) + var nodes = this.nodes, + num = nodes.length, + p1 = 1 <= this.phase, + p2 = 2 <= this.phase, + p3 = 3 <= this.phase, + _p1, _p2, + i = 0, l, data; + + //console.log( '### AddAt ' + this.phase ) + for( l = _nodes.length; i < l; ++i ){ + data = X.Class._getPrivate( _nodes[ i ] ); + _p1 = p1 && data.phase < 1; + _p2 = p2 && data.phase < 2; + _p1 && data.initialize( this.root, this.rootData, this.User, this, this.rawElement ); + if( index <= num ){ + _p2 && this.rawElement.insertBefore( data.rawElement, nodes[ index + i ].rawElement ); + _p2 && data.addToParent( null, true ); + nodes.splice( index + i, 0, data ); + } else { + _p2 && data.addToParent( this.rawElement ); + nodes[ nodes.length ] = data; + }; + p3 && data.phase < 3 && data.afterAddition(); + }; + 4 <= this.phase && this.rootData.reserveCalc(); + }, + + remove : function( _nodes ){ + //console.log( '# AddAt ' + this.phase ) + var nodes = this.nodes, + i = _nodes.length, + n, node; + + //console.log( '### AddAt ' + this.phase ) + for( ; i; ){ + node = X.Class._getPrivate( _nodes[ --i ] ); + if( ( n = nodes.indexOf( node ) ) !== -1 ){ + nodes.splice( n, 1 ); + node._remove(); + }; + }; + 4 <= this.phase && this.rootData.reserveCalc(); + }, + + removeAt : function( from, length ){ + var nodes = this.nodes, + i = nodes.length, + to = from + ( X.Type.isNumber( length ) && 1 <= length ? length : 1 ), + node; + for( ; i; ){ + node = nodes[ --i ]; + if( from <= i && i < to ){ + nodes.splice( i, 1 ); + node._remove(); + }; + }; + 4 <= this.phase && this.rootData.reserveCalc(); + }, + + _remove : function(){ + var nodes = this.nodes, + i = nodes.length; + for( ; i; ){ nodes[ --i ]._remove(); }; + + switch( this.phase ){ + case 4: + case 3: + //this.styleData.afterAddition(); + case 2: + //this.styleData.initialize(); + this.rawElement.parentNode.removeChild( this.rawElement ); + case 1: + delete this.root; + delete this.rootData; + delete this.parent; + delete this.parentData; + delete this.rawElement; + delete this.rawStyle; + }; + delete this.phase; + } + } +); + +var AbstractDisplayContainer = AbstractDisplayNode.inherits( + 'AbstractDisplayContainer', + X.Class.ABSTRACT | X.Class.SUPER_ACCESS, + _AbstractDisplayContainer, + { + add : function( node /* , node, node ... */ ){ + X.Class._getPrivate( this ).addAt( this.numNodes() + 1, Array.prototype.slice.call( arguments ) ); + return this; + }, + addAt : function( index, node /* , node, node ... */ ){ + if( index < 0 ) index = 0; + X.Class._getPrivate( this ).addAt( arguments[ 0 ], Array.prototype.slice.call( arguments, 1 ) ); + return this; + }, + remove : function( node /* , node, node ... */ ){ + X.Class._getPrivate( this ).remove( Array.prototype.slice.call( arguments ) ); + return this; + }, + removeAt : function( from, length ){ + X.Class._getPrivate( this ).removeAt( from, length ); + return this; + }, + getNodesByClass : function( klass ){ + var ret = [], + nodes = X.Class._getPrivate( this ).nodes, + i, l, node; + if( !nodes || nodes.length === 0 ) return ret; + for( i = 0, l = nodes.length; i < l; ++i ){ + node = nodes[ i ]; + if( node instanceof klass ) ret[ ret.length ] = node.User; + }; + return ret; + }, + getFirstChild : function(){ + return this.getNodeAt( 0 ); + }, + getLastChild : function(){ + var nodes = X.Class._getPrivate( this ).nodes; + return nodes && nodes.length ? nodes[ nodes.length - 1 ].User || null : null; + }, + getNodeByUID : function( uid ){ + + }, + getNodeAt : function( index ){ + if( index < 0 ) return null; + var nodes = X.Class._getPrivate( this ).nodes; + return nodes ? nodes[ index ].User || null : null; + }, + numNodes : function(){ + var nodes = X.Class._getPrivate( this ).nodes; + return nodes ? nodes.length : 0; + } + } +); \ No newline at end of file diff --git a/0.6.x/js/JU/AbstractDisplayNode.js b/0.6.x/js/JU/AbstractDisplayNode.js new file mode 100644 index 0000000..878bc72 --- /dev/null +++ b/0.6.x/js/JU/AbstractDisplayNode.js @@ -0,0 +1,93 @@ +var _AbstractDisplayNode = X.Class.create( + '_AbstractDisplayNode', + X.Class.ABSTRACT | X.Class.PRIVATE_DATA, + { + phase : 0, + root : null, + rootData : null, + parent : null, + parentData : null, + rawElement : null, + rawStyle : null, + style : null, + styleData : null, + forChrome : false, // メッキ + //initialize : function( root, rootData, parent, parentData, parentElement ){}, + //afterAddition : function(){} + //commitUpdate + _remove : function(){ + switch( this.phase ){ + case 4: + case 3: + //this.styleData.afterAddition(); + case 2: + //this.styleData.initialize(); + this.rawElement.parentNode.removeChild( this.rawElement ); + case 1: + delete this.root; + delete this.rootData; + delete this.parent; + delete this.parentData; + delete this.rawElement; + delete this.rawStyle; + }; + delete this.phase; + } + //killed + } +); + +var AbstractDisplayNode = X.EventDispatcher.inherits( + 'AbstractDisplayNode', + X.Class.ABSTRACT | X.Class.SUPER_ACCESS, + { + style : null, + parent : function(){ + return X.Class._getPrivate( this ).parent; + }, + root : function(){ + return X.Class._getPrivate( this ).root; + }, + getNextNode : function(){ + + }, + getPrevNode : function(){ + + }, + dispatch : function( e ){ + var ret = X.EventDispatcher.prototype.dispatch.call( this, e ), + bubleup = X.ViewEvent._NO_BUBLEUP < e.type, + parent; // root の場合 parent が存在しない + if( bubleup === true && ret !== false && ( parent = X.Class._getPrivate( this ).parent ) ) return parent.dispatch( e ); + return ret; + }, + nodeIndex : function( v ){ + var data = X.Class._getPrivate( this ); + if( typeof v === 'number' ){ + return; + }; + return data.parentData ? data.parentData.nodes.indexOf( data ) : 0; + }, + displayIndex : function(){ + + }, + getX : function(){ + + }, + getY : function(){ + + }, + getAbsoluteX : function(){ + + }, + getAbsoluteY: function(){ + + }, + getWidth : function(){ + + }, + getHeight : function(){ + + } + } +); \ No newline at end of file diff --git a/0.6.x/js/JU/Box.js b/0.6.x/js/JU/Box.js new file mode 100644 index 0000000..4b6360c --- /dev/null +++ b/0.6.x/js/JU/Box.js @@ -0,0 +1,39 @@ +var BasicLayoutManager = ( new LayoutManagerBase() ).define( { + allowForSelf : { + childW : false, + childH : false, + gapX : false, + gapY : false, + padding : false + }, + allowForChild : { + x : true, + y : true, + w : true, + h : true + }, + calculate : function( data, x, y, w, h ){ + var nodes = data.nodes, + i = 0, l = nodes.length, node; + for( ; i < l; ++i ){ + node = nodes[ i ]; + if( node instanceof _AbstractDisplayContainer ){ + node.calculate( x, y, w, h ); + } else { + //node.styleData.layout( x, y, w, h ); + }; + }; + data.styleData.layout( x, y, w, h ); + } +}); + +var Box = AbstractDisplayContainer.inherits( + 'Box', + X.Class.SUPER_ACCESS, + { + Constructor : function(){ + this.style = DisplayNodeStyle( this, X.Class._newPrivate( this, BasicLayoutManager, arguments ) ); + this.style.addName( 'Box' ); + } + } +); \ No newline at end of file diff --git a/0.6.x/js/JU/ChromeBox.js b/0.6.x/js/JU/ChromeBox.js new file mode 100644 index 0000000..a040dca --- /dev/null +++ b/0.6.x/js/JU/ChromeBox.js @@ -0,0 +1,86 @@ +var _ChromeBox = _AbstractDisplayContainer.inherits( + '_ChromeBox', + X.Class.PRIVATE_DATA | X.Class.SUPER_ACCESS, + { + chromeNodes : null, + containerNode : null, + Constructor : function( layout, args ){ + this.SuperConstructor( layout, args ); + + var nodes = this.nodes, + i = nodes.length, + node; + this.chromeNodes = []; + for( ; i; ){ + node = nodes[ --i ]; + if( node.forContainer === true ){ + if( this.containerNode ){ + throw new Error( 'ContainerNode が複数設定されています!ContainerNode はクロームボックスにひとつ、生成時に設定できます ' + node ); + }; + this.containerNode = node; + } else { + this.chromeNodes[ this.chromeNodes.length ] = node; + }; + }; + if( !this.containerNode ){ + throw new Error( 'ContainerNode が設定されてい\ません!ContainerNode はクロームボックスにひとつ、生成時に設定できます ' ); + }; + } + } +); + +var ChromeBox = AbstractDisplayContainer.inherits( + 'ChromeBox', + X.Class.SUPER_ACCESS, + _ChromeBox, + { + Constructor : function(){ + this.style = DisplayNodeStyle( this, X.Class._newPrivate( this, BasicLayoutManager, arguments ) ); + this.style.addName( 'ChromeBox' ); + }, + add : function( node /* , node, node ... */ ){ + X.Class._getPrivate( this ).containerNode.addAt( this.numNodes(), Array.prototype.slice.call( arguments ) ); + return this; + }, + addAt : function( index, node /* , node, node ... */ ){ + X.Class._getPrivate( this ).containerNode.addAt( index, Array.prototype.slice.call( arguments, 1 ) ); + return this; + }, + remove : function( node /* , node, node ... */ ){ + X.Class._getPrivate( this ).containerNode.remove( arguments ); + return this; + }, + removeAt : function( from, length ){ + X.Class._getPrivate( this ).containerNode.removeAt( from, length ); + return this; + }, + getNodesByClass : function( klass ){ + X.Class._getPrivate( this ).containerNode.User.getNodesByClass( klass ); + return ret; + }, + getFirstChild : function(){ + return X.Class._getPrivate( this ).containerNode.User.getFirstChild(); + }, + getLastChild : function(){ + return X.Class._getPrivate( this ).containerNode.User.getLastChild(); + }, + getNodeByUID : function( uid ){ + return X.Class._getPrivate( this ).containerNode.User.getNodeByUID(); + }, + getNodeAt : function( index ){ + return X.Class._getPrivate( this ).containerNode.User.getNodeByUID( index ); + }, + numNodes : function(){ + return X.Class._getPrivate( this ).containerNode.User.numNodes(); + }, + getChromeAt : function( index ){ + if( index < 0 ) return null; + var nodes = X.Class._getPrivate( this ).chromeNodes; + return nodes ? nodes[ index ] || null : null; + }, + numChromeNodes : function(){ + var nodes = X.Class._getPrivate( this ).chromeNodes; + return nodes ? nodes.length : 0; + } + } +); \ No newline at end of file diff --git a/0.6.x/js/JU/DisplayNodeStyle.js b/0.6.x/js/JU/DisplayNodeStyle.js new file mode 100644 index 0000000..6ce3047 --- /dev/null +++ b/0.6.x/js/JU/DisplayNodeStyle.js @@ -0,0 +1,232 @@ +var _DisplayNodeStyle = X.Class.create( + '_DisplayNodeStyle', + X.Class.PRIVATE_DATA, + { + node : null, + nodeData : null, + _name : '', + allow : null, + _css : null, + Constructor : function( node, nodeData ){ + this.node = node; + this.nodeData = nodeData; + + nodeData.style = this.User; + nodeData.styleData = this; + + this._css = {}; + + if( nodeData.tmpCss ){ + if( nodeData.tmpCss.role === 'container' ) this.nodeData.forContainer = true; + if( nodeData.tmpCss.role === 'chrome' ) this.nodeData.forChrome = true; + }; + }, + /* Rellay */ + initialize : function(){ + if( this.nodeData.layout ){ + this.allow = this.nodeData.layout.allowForSelf; // これに加えて親の allowForChild を合成 + } else + if( this.nodeData.parentData.layout ){ + this.allow = this.nodeData.parentData.layout.allowForChild; + } else { + this.allow = void 0; + }; + + if( this.nodeData.tmpCss ){ + this.css( this.nodeData.tmpCss ); + delete this.nodeData.tmpCss; + }; + }, + + afterAddition : function(){ + var elm = this.nodeData.rawElement; + if( elm ){ + if( this._name && elm.className !== this._name ){ + elm.className = this._name; + // dirty flag + }; + if( this._cssText && elm.style.cssText !== this._cssText ){ + elm.style.cssText = this._cssText; + }; + }; + }, + + name : function( v ){ + var elm; + if( this._name !== v ){ + if( !v || !v.length ){ + delete this._name; + v = ''; + } else { + this._name = v; + }; + if( elm = this.nodeData.rawElement ){ + elm.className = v; + }; + }; + return this.User; + }, + addName : function( _names ){ + var sp = ' ', + names; + if( this.hasName( _names ) === false ){ + names = this._name; + if( !names.length ){ + return this.name( _names ); + }; + names = names.split( sp ); + names[ names.length ] = _names; + return this.name( names.join( sp ) ); + }; + return this.User; + }, + removeName : function( _names ){ + var sp = ' ', + names = this._name, + name, i; + if( !names.length ) return this.User; + names = names.split( sp ); + _names = _names.split( sp ); + for( i = _names.length; i; ){ + name = _names[ --i ]; + name !== '' && names.indexOf( name ) === -1 && names.splice( i, 1 ); + }; + return this.name( names.join( sp ) ); + }, + hasName : function( _names ){ + var names = this._name, + name, i; + if( !names ) return false; + names = names.split( ' ' ); + _names = _names.split( ' ' ); + for( i = _names.length; i; ){ + name = _names[ --i ]; + if( name !== '' && names.indexOf( name ) === -1 ) return false; + }; + return true; + }, + cssText : function( v ){ + var style; + if( this._cssText !== v ){ + this._cssText = v; + if( style = this.nodeData.rawStyle ){ + style.cssText = v; + }; + }; + }, + css : function( v ){ + var css = this._css, + allow = this.allow, + TRANS = { + x : 'left', + y : 'top' + }, + REMOVE = { + role : 0 + }, + p; + for( p in v ){ + if( REMOVE[ p ] === 0 ) continue; + + switch( p = TRANS[ p ] || p ){ + case 'name' : + this.addName( v[ p ] ); + continue; + case 'left' : + if( allow.x === false ) continue; + break; + case 'top' : + if( allow.y === false ) continue; + break; + case 'width' : + if( allow.w === false ) continue; + break; + case 'height' : + if( allow.w === false ) continue; + break; + case 'gapX' : + if( allow.gapX === false ) continue; + break; + case 'gapY' : + if( allow.gapY === false ) continue; + break; + case 'padding' : + if( allow.padding === false ) continue; + break; + }; + css[ p ] = v[ p ]; + }; + this.cssText( X.Style.objToCssText( css ) ); + }, + layout : function( x, y, w, h ){ + var style = this.nodeData.rawStyle, + obj = this._css, + f = X.Type.isFinite; + + if( f( x ) ) x += 'px'; + if( f( y ) ) y += 'px'; + if( f( w ) ) w += 'px'; + if( f( h ) ) h += 'px'; + + if( x ){ + obj.left = x; + if( style ) style.left = x; + }; + if( y ){ + obj.top = y; + if( style ) style.top = y; + }; + if( w ){ + obj.width = w; + if( style ) style.width = w; + }; + if( h ){ + obj.height = h; + if( style ) style.height = h; + }; + } + } +); + +var DisplayNodeStyle = X.Class.create( + 'DisplayNodeStyle', + X.Class.FINAL, + _DisplayNodeStyle, + { + Constructor : function( node, nodeData ){ + X.Class._newPrivate( this, node, nodeData ); + }, + name : function( v ){ + var data = X.Class._getPrivate( this ); + if( v ){ + return data.name( v ); + }; + return data._name; + }, + addName : function( names ){ + return X.Class._getPrivate( this ).addName( names ); + }, + removeName : function( names ){ + return X.Class._getPrivate( this ).removeName( names ); + }, + hasName : function( names ){ + return X.Class._getPrivate( this ).hasName( names ); + }, + cssText : function( v ){ + var data = X.Class._getPrivate( this ); + if( v ){ + data.cssText( v ); + return this; + }; + return data._cssText; + }, + css : function( v ){ + var data = X.Class._getPrivate( this ); + if( v ){ + data.css( v ); + return this; + }; + // return data._css; + } + } +); diff --git a/0.6.x/js/JU/HBox.js b/0.6.x/js/JU/HBox.js new file mode 100644 index 0000000..703d2b2 --- /dev/null +++ b/0.6.x/js/JU/HBox.js @@ -0,0 +1,73 @@ +var HorizontalLayoutManager = ( new LayoutManagerBase() ).define( { + allowForSelf : { + childX : false, + childY : false, + childW : true, + childH : true, + gapX : true, + gapY : false, + padding : true + }, + allowForChild : { + x : false, + y : false, + w : true, + h : true + }, + calculate : function( data, x, y, w, h ){ + var nodes = data.nodes, + styleData = data.styleData, + cssObj = styleData._css, + //childW = cssObj.childW, + childH = cssObj.childH, + gapX = cssObj.gapX, + //gapY = cssObj.gapY, + padding = cssObj.padding, + _x = padding, + _y = padding, + i = 0, l = nodes.length, node; + + if( childH || childH === 0 ){ + for( ; i < l; ++i ){ + node = nodes[ i ]; + if( node instanceof _AbstractDisplayContainer ){ + node.calculate( 0, y, w - x, childH ); + } else { + node.styleData.layout( 0, y, w - x, childH ); + }; + y += childH + gapY; + }; + } else { + for( ; i < l; ++i ){ + node = nodes[ i ]; + if( node instanceof _AbstractDisplayContainer ){ + node.calculate( 0, y, w - x ); + } else { + node.styleData.layout( 0, y, w - x ); + }; + y += node.rawElement.offsetHeight + gapY; + }; + }; + data.styleData.layout( x, y, w, _y + childH + padding ); + } +}); + +/* +var HBox = function(){ + var arg = arguments; + arg[ arg.length ] = HorizontalLayoutManager; + ++arg.length; + return Box.apply( null, arg ); +}; */ + + +var HBox = AbstractDisplayContainer.inherits( + 'HBox', + X.Class.SUPER_ACCESS, + { + Constructor : function(){ + this.style = DisplayNodeStyle( this, X.Class._newPrivate( this, HorizontalLayoutManager, arguments ) ); + this.style.addName( 'HBox' ); + } + } +); \ No newline at end of file diff --git a/0.6.x/js/JU/LayoutManagerBase.js b/0.6.x/js/JU/LayoutManagerBase.js new file mode 100644 index 0000000..e39bb7b --- /dev/null +++ b/0.6.x/js/JU/LayoutManagerBase.js @@ -0,0 +1,10 @@ +var LayoutManagerBase = X.Class.create( + 'LayoutManagerBase', + { + allowForSelf : null, + allowForChild : null, + define : function( src ){ + return X.Class._override( this, src, true ); + } + } +); diff --git a/0.6.x/js/JU/PageRoot.js b/0.6.x/js/JU/PageRoot.js new file mode 100644 index 0000000..2f6a7d9 --- /dev/null +++ b/0.6.x/js/JU/PageRoot.js @@ -0,0 +1,64 @@ +var _PageRoot = _AbstractDisplayContainer.inherits( + '_PageRoot', + X.Class.FINAL | X.Class.PRIVATE_DATA | X.Class.SUPER_ACCESS, + { + calcReserved : false, + Constructor : function( layout, args ){ + this.SuperConstructor( layout, args ); + + if( X.View.ready === true ){ + X.Timer.once( 0, this, this.start ); + } else { + X.View.listenOnce( X.ViewEvent.SYS_READY, this, this.start ); + }; + }, + start : function(){ + this.initialize( this.User, this, this.User, this ); + X.Timer.once( 0, this, this.addToView ); + }, + addToView : function(){ + this.addToParent( document.body ); + X.Timer.once( 0, this, this.afterAddToView ); + }, + afterAddToView : function(){ + this.afterAddition(); + X.Timer.once( 0, this, this.doFirstCalc ); + }, + doFirstCalc : function(){ + this.doCalculate(); + X.View.listen( X.ViewEvent.VIEW_RESIZED, this, this.doCalculate ); + }, + reserveCalc : function(){ + if( this.calcReserved === false ){ + this.calcReserved = true; + X.Timer.once( 0, this, this.doCalculate ); + }; + }, + doCalculate : function( e ){ + var size, w, h; + if( !e ){ + size = X.View.getSize(); + w = size[ 0 ]; + h = size[ 1 ]; + } else { + w = e.w; + h = e.h; + }; + this.layout.calculate( this, 0, 0, w, h ); + this.calcReserved = false; + } + } +); + +var PageRoot = Box.inherits( + 'PageRoot', + X.Class.FINAL | X.Class.SUPER_ACCESS, + _PageRoot, + { + Constructor : function( /* opt_manager */ ){ + var data = X.Class._newPrivate( this, BasicLayoutManager, arguments ); + this.style = DisplayNodeStyle( this, data ); + this.style.addName( 'PageRoot' ); + } + } +); \ No newline at end of file diff --git a/0.6.x/js/JU/Text.js b/0.6.x/js/JU/Text.js new file mode 100644 index 0000000..3e6c0f9 --- /dev/null +++ b/0.6.x/js/JU/Text.js @@ -0,0 +1,59 @@ +var _Text = _AbstractDisplayNode.inherits( + '_Text', + X.Class.PRIVATE_DATA, + { + content : null, + Constructor : function( content ){ + if( !( this.User instanceof Text ) ){ + throw new Error( 'Text を継承したインスタンスだけが _Text のオーナーになれます' ); + }; + this.content = content; + }, + initialize : function( root, rootData, parent, parentData, parentElement ){ + this.root = root; + this.rootData = rootData; + this.parent = parent; + this.parentData = parentData; + this.rawElement = document.createElement( 'div' ); + this.rawStyle = this.rawElement.style; + + this.phase = 1; + this.User.dispatch( { type : X.ViewEvent.INIT } ); + }, + addToParent : function( parentElement, skip ){ + skip !== true && parentElement.appendChild( this.rawElement ); + + this.styleData.initialize(); + + this.phase = 2; + this.User.dispatch( { type : X.ViewEvent.ADDED } ); + }, + afterAddition : function(){ + // if( this.phase === 0 ) return; + + this.rawElement.innerHTML = this.content; + this.styleData.afterAddition(); + this.phase = 3; + this.User.dispatch( { type : X.ViewEvent.CREATION_COMPLETE } ); + } + } +); + +var Text = AbstractDisplayNode.inherits( + 'Text', + X.Class.SUPER_ACCESS, + _Text, + { + Constructor : function( content, cssObj ){ + var data = X.Class._newPrivate( this, content ); + this.style = DisplayNodeStyle( this, data ); + cssObj && this.style.css( cssObj ); + if( cssObj ){ + if( cssObj.role === 'chrome' ) data.forChrome = true; + }; + }, + content : function(){ + + } + } +); \ No newline at end of file diff --git a/0.6.x/js/JU/TileBox.js b/0.6.x/js/JU/TileBox.js new file mode 100644 index 0000000..e02a1ce --- /dev/null +++ b/0.6.x/js/JU/TileBox.js @@ -0,0 +1,56 @@ +var TileLayoutManager = ( new LayoutManagerBase() ).define( { + allowForSelf : { + childW : true, + childH : true, + gapX : true, + gapY : true, + padding : true + }, + allowForChild : { + x : false, + y : false, + w : false, + h : false + }, + calculate : function( data, x, y, w, h ){ + var nodes = data.nodes, + styleData = data.styleData, + cssObj = styleData._css, + childW = cssObj.childW, + childH = cssObj.childH, + gapX = cssObj.gapX, + gapY = cssObj.gapY, + padding = cssObj.padding, + _x = padding, + _y = padding, + i = 0, l = nodes.length, node; + if( l === 0 ){ + styleData.layout( x, y, w, 0 ); + return; + }; + for( ; i < l; ++i ){ + node = nodes[ i ]; + if( node instanceof _AbstractDisplayContainer ){ + node.calculate( _x, _y, childW, childH ); + } else { + node.styleData.layout( _x, _y, childW, childH ); + }; + _x += childW + gapX; + if( w < _x ){ + _y += childH + gapY; + }; + }; + styleData.layout( x, y, w, _y + childH + padding ); + } +}); + +var TileBox = AbstractDisplayContainer.inherits( + 'TileBox', + X.Class.SUPER_ACCESS, + { + Constructor : function(){ + this.style = DisplayNodeStyle( this, X.Class._newPrivate( this, TileLayoutManager, arguments ) ); + this.style.addName( 'TileBox' ); + } + } +); \ No newline at end of file diff --git a/0.6.x/js/JU/VBox.js b/0.6.x/js/JU/VBox.js new file mode 100644 index 0000000..8fc2492 --- /dev/null +++ b/0.6.x/js/JU/VBox.js @@ -0,0 +1,76 @@ +var VerticalLayoutManager = ( new LayoutManagerBase() ).define( { + name : 'VerticalLayout', + allowForSelf : { + childX : false, + childY : false, + childW : false, + childH : true, + gapX : false, + gapY : true, + padding : true + }, + allowForChild : { + x : false, + y : false, + w : true, + h : true + }, + calculate : function( data, x, y, w, h ){ + var nodes = data.nodes, + styleData = data.styleData, + cssObj = styleData._css, + //childW = cssObj.childW, + childH = cssObj.childH, + gapX = cssObj.gapX || 0, + gapY = cssObj.gapY || 0, + padding = cssObj.padding || 0, + _x = padding, + _y = padding, + i = 0, l = nodes.length, node; + + if( childH || childH === 0 ){ + for( ; i < l; ++i ){ + console.log( _y ) + node = nodes[ i ]; + if( node instanceof _AbstractDisplayContainer ){ + node.calculate( 0, _y, w - x, childH ); + } else { + node.styleData.layout( 0, _y, w - x, childH ); + }; + _y += childH + gapY; + }; + } else { + for( ; i < l; ++i ){ + console.log( _y ) + node = nodes[ i ]; + if( node instanceof _AbstractDisplayContainer ){ + node.calculate( 0, _y, w - x ); + } else { + node.styleData.layout( 0, _y, w - x ); + }; + _y += node.rawElement.offsetHeight + gapY; + }; + }; + data.styleData.layout( x, y, w, _y + gapY + padding ); + } +}); + +/* +var VBox = function(){ + var arg = arguments; + arg[ arg.length ] = VerticalLayoutManager; + ++arg.length; + return Box.apply( null, arg ); +}; */ + + +var VBox = AbstractDisplayContainer.inherits( + 'VBox', + X.Class.SUPER_ACCESS, + { + Constructor : function(){ + this.style = DisplayNodeStyle( this, X.Class._newPrivate( this, VerticalLayoutManager, arguments ) ); + this.style.addName( 'VBox' ); + } + } +); \ No newline at end of file diff --git a/0.6.x/js/_old/Attr.js b/0.6.x/js/_old/Attr.js new file mode 100644 index 0000000..8c48645 --- /dev/null +++ b/0.6.x/js/_old/Attr.js @@ -0,0 +1,54 @@ +X.Css.Attr = { + borderWidth : [ X.Css.Dirty.REFLOW, 0, X.Css.Type.QUARTET | X.Css.Type.LENGTH ], // em [ top, right, bottom, left ] + borderColor : [ X.Css.Dirty.PAINT, 4, X.Css.Type.QUARTET | X.Css.Type.DEF_COLOR ], // color [ top, right, bottom, left ] + borderStyle : [ X.Css.Dirty.PAINT, 8, X.Css.Type.QUARTET | X.Css.Type.LIST, X.Css.Option.BORDER_STYLE ], // string [ top, right, bottom, left ] + cornerRadius : [ X.Css.Dirty.PAINT, 12, X.Css.Type.QUARTET | X.Css.Type.LENGTH | X.Css.Type.PERCENT ], // em, px [ top, right, bottom, left ] + bgColor : [ X.Css.Dirty.PAINT, 16, X.Css.Type.COLOR ], // color + bgAlpha : [ X.Css.Dirty.PAINT, 17, X.Css.Type.U_DECIMAL ], // 0 - 1 + bgImgUrl : [ X.Css.Dirty.PAINT, 18, X.Css.Type.URL ], // url + bgImgRepeatX : [ X.Css.Dirty.PAINT, 19, X.Css.Type.BOOLEAN ], // true / false + bgImgRepeatY : [ X.Css.Dirty.PAINT, 20, X.Css.Type.BOOLEAN ], // true / false + bgImgPositionX : [ X.Css.Dirty.PAINT, 21, X.Css.Type.LENGTH | X.Css.Type.PERCENT | X.Css.Type.LIST, X.Css.Option.POSITION_X ], // em %, px, string + bgImgPositionY : [ X.Css.Dirty.PAINT, 22, X.Css.Type.LENGTH | X.Css.Type.PERCENT | X.Css.Type.LIST, X.Css.Option.POSITION_Y ], // em %, px, string + shadowColor : [ X.Css.Dirty.PAINT, 23, X.Css.Type.COLOR ], // color + shadowAlpha : [ X.Css.Dirty.PAINT, 24, X.Css.Type.U_DECIMAL ], // 0 - 1 + shadowOffsetX : [ X.Css.Dirty.PAINT, 25, X.Css.Type.LENGTH ], // em + shadowOffsetY : [ X.Css.Dirty.PAINT, 26, X.Css.Type.LENGTH ], // em + shadowBlur : [ X.Css.Dirty.PAINT, 27, X.Css.Type.LENGTH ], // em + shadowSpread : [ X.Css.Dirty.PAINT, 28, X.Css.Type.LENGTH ], // em + shadowInset : [ X.Css.Dirty.PAINT, 29, X.Css.Type.BOOLEAN ], // true / false + + color : [ X.Css.Dirty.PAINT, 30, X.Css.Type.COLOR ], // color + fontFamily : [ X.Css.Dirty.FONT, 31, X.Css.Dirty.FONT_NAME ], // string + fontSize : [ X.Css.Dirty.FONT, 32, X.Css.Type.LENGTH | X.Css.Type.PERCENT ], // em, % + bold : [ X.Css.Dirty.FONT, 33, X.Css.Type.BOOLEAN ], // true / false + italic : [ X.Css.Dirty.FONT, 34, X.Css.Type.BOOLEAN ], // true / false + lineHeight : [ X.Css.Dirty.FONT, 35, X.Css.Type.LENGTH | X.Css.Type.PERCENT | X.Css.Type.NUMERICAL ], // em, %, + letterSpacing : [ X.Css.Dirty.FONT, 36, X.Css.Type.LENGTH ], // em + wordSpacing : [ X.Css.Dirty.FONT, 37, X.Css.Type.LENGTH ], + align : [ X.Css.Dirty.FONT, 38, X.Css.Type.LIST, X.Css.Type.ALIGN ], + decoration : [ X.Css.Dirty.PAINT, 39, X.Css.Type.LIST, X.Css.Type.TEXT_DECORATION ], + transform : [ X.Css.Dirty.FONT, 40, X.Css.Type.LIST, X.Css.Type.TEXT_TRANSFORM ], + textShadowColor : [ X.Css.Dirty.PAINT, 41, X.Css.Type.COLOR ], + textShadowOffsetX : [ X.Css.Dirty.PAINT, 42, X.Css.Type.LENGTH ], + textShadowOffsetY : [ X.Css.Dirty.PAINT, 43, X.Css.Type.LENGTH ], + shadowBlur : [ X.Css.Dirty.PAINT, 44, X.Css.Type.LENGTH ], + + width : [ X.Css.Dirty.REFLOW, 45, X.Css.Type.LENGTH | X.Css.Type.PERCENT, X.Css.Option.WIDTH_HEIGHT ], + minWidth : [ X.Css.Dirty.REFLOW, 46, X.Css.Type.LENGTH | X.Css.Type.PERCENT ], + maxWidth : [ X.Css.Dirty.REFLOW, 47, X.Css.Type.LENGTH | X.Css.Type.PERCENT ], + height : [ X.Css.Dirty.REFLOW, 48, X.Css.Type.LENGTH | X.Css.Type.PERCENT, X.Css.Option.WIDTH_HEIGHT ], + minHeight : [ X.Css.Dirty.REFLOW, 49, X.Css.Type.LENGTH | X.Css.Type.PERCENT ], + maxHeight : [ X.Css.Dirty.REFLOW, 50, X.Css.Type.LENGTH | X.Css.Type.PERCENT ], + padding : [ X.Css.Dirty.REFLOW, 51, X.Css.Type.QUARTET | X.Css.Type.LENGTH | X.Css.Type.PERCENT ], + margin : [ X.Css.Dirty.REFLOW, 55, X.Css.Type.QUARTET | X.Css.Type.LENGTH | X.Css.Type.PERCENT ], + sizing : [ X.Css.Dirty.REFLOW, 59, X.Css.Type.LIST, X.Css.Option.BOX_SIZING ], + pageBox : [ X.Css.Dirty.REFLOW, 60, X.Css.Type.BOOLEAN ], // true / false + left : [ X.Css.Dirty.REFLOW, 61, X.Css.Type.LENGTH | X.Css.Type.PERCENT ], + top : [ X.Css.Dirty.REFLOW, 62, X.Css.Type.LENGTH | X.Css.Type.PERCENT ], + bottom : [ X.Css.Dirty.REFLOW, 63, X.Css.Type.LENGTH | X.Css.Type.PERCENT ], + right : [ X.Css.Dirty.REFLOW, 64, X.Css.Type.LENGTH | X.Css.Type.PERCENT ] +}; + +X.Css.Attr.x = X.Css.Attr.left; +X.Css.Attr.y = X.Css.Attr.top; \ No newline at end of file diff --git a/0.6.x/js/_old/AttrNo.js b/0.6.x/js/_old/AttrNo.js new file mode 100644 index 0000000..a7a4d1a --- /dev/null +++ b/0.6.x/js/_old/AttrNo.js @@ -0,0 +1,9 @@ +X.Css.AttrNo = ( function(){ + var ret = {}, + obj = X.Css.Attr, + p; + for( p in obj ){ + ret[ p ] = obj[ p ][ 1 ]; + }; + return ret; +})(); diff --git a/0.6.x/js/_old/BasicLayoutManager.js b/0.6.x/js/_old/BasicLayoutManager.js new file mode 100644 index 0000000..460f8d3 --- /dev/null +++ b/0.6.x/js/_old/BasicLayoutManager.js @@ -0,0 +1,105 @@ + /** + * 再計算と再描画 + * redraw 再描画はパラメータ変更後に setTimeout で + * reflow 再計算は値が get された場合 invalidate が サイズだったら + * または再描画前に invalidate がサイズなフラグが足っていたら + */ + +var BasicLayoutManager = X.Class.create( + 'BasicLayoutManager', + X.Class.POOL_OBJECT, + { + Constructor : function(){ + + }, + redraw : function( nodeData ){ + var root = nodeData.__root; + root.dirty === X.Css.Dirty.REFLOW && this.reflow( root ); + + // draw + }, + reflow : function( nodeData, allowW, allowH ){ + nodeData.preMesure( allowW, allowH ); + + var children = nodeData.children, + contentW = nodeData.contentWidth, + contentH = nodeData.contentHeight, + autoW = contentW === AUTO, + autoH = contentH === AUTO, + auto, calc, childW, childH, child, i, style, data, + t, r, b, l; + if( children ){ + auto = autoW && autoH; + childW = 0; + childH = 0; + calc = BasicLayoutManager.calcValue; + for( i = children.length; i; ){ + child = children[ --i ]; + style = child.__style; + if( style ){ + data = style.data; + t = calc( data[ X.Css.AttrNo.top ], contentH ); + r = calc( data[ X.Css.AttrNo.right ], contentW ); + b = calc( data[ X.Css.AttrNo.bottom ], contentH ); + l = calc( data[ X.Css.AttrNo.left ], contentW ); + } else { + t = r = b = l = 0; + }; + if( child instanceof LayoutBoxPrivate ){ + child.layoutManager.reflow( child, contentW - r - l, contentH - t - b ); + } else { + child.preMesure( contentW - r - l, contentH - t - b ); + child.mesure(); + child.postMesure(); + }; + if( !auto ) continue; + if( autoW && childW < child.boxWidth + r + l ) childW = child.boxWidth + r + l; + if( autoH && childH < child.boxHeight + t + b ) childH = child.boxHeight + t + b; + }; + if( autoW ) nodeData.contentWidth = childW; + if( autoH ) nodeData.contentHeight = childH; + }; + ( autoW || autoH ) && nodeData.postMesure(); + + delete nodeData.dirty; + } + } +); +BasicLayoutManager.finalValue = function( styleValue, styleMin, styleMax, srcValue ){ + var calc = BasicLayoutManager.calcValue, + v = calc( styleValue, srcValue ), + min = calc( styleMin, srcValue ), + max = calc( styleMax, srcValue ); + if( v < min ) return min; + if( max < v ) return max; + return v; +}; +BasicLayoutManager.calcValue = function( styleValue, srcValue ){ + switch( styleValue ){ + case 0 : + return 0; + case AUTO : + return AUTO; + case FULL : + return srcValue; // 100% + default : + if( 1 <= styleValue ) return styleValue; // legth + if( -1 < styleValue ) return FLOOR( srcValue * styleValue ); // % + }; + return styleValue; // - length +}; +BasicLayoutManager.advancedCalcValue = function( styleValue, srcValue ){ + switch( styleValue ){ + case 0 : + return 0; + case AUTO : + return srcValue; + case FULL : + throw new Error( 'advancedCalcValue FULL' ); + // return ; // 100% + default : + if( 1 <= styleValue ) return styleValue; + if( -1 < styleValue ) return FLOOR( ( srcValue / ( 1 - styleValue ) ) * styleValue ); // % + }; + return styleValue; // - length +}; \ No newline at end of file diff --git a/0.6.x/js/_old/Dirty.js b/0.6.x/js/_old/Dirty.js new file mode 100644 index 0000000..9251070 --- /dev/null +++ b/0.6.x/js/_old/Dirty.js @@ -0,0 +1,7 @@ +X.Css.Dirty = { + CLEAN : 0, + PAINT : 1, // 再描画のみ必要 + REFLOW : 2, // レイアウトの再計算が必要 + FONT : 3, // フォントサイズが変更された + CONTENT_UPDATE : 4 // コンテンツが変更された +} \ No newline at end of file diff --git a/0.6.x/js/_old/LayoutBox.js b/0.6.x/js/_old/LayoutBox.js new file mode 100644 index 0000000..d7ba76b --- /dev/null +++ b/0.6.x/js/_old/LayoutBox.js @@ -0,0 +1,50 @@ +var _LayoutBox = _Node.inherits( + '_LayoutBox', + X.Class.POOL_OBJECT | X.Class.SUPER_ACCESS, + { + Constructor : function( layoutManager, _root, _parent ){ + this.layoutManager = layoutManager; + this._root = _root; + this.paintList = []; + if( _parent ) this._parent = _parent; + }, + mesure : function(){ + this.layoutManager.reflow( this ); + }, + paintReserve : function( nodeData ){ + var list = this.paintList; + if( list.indexOf( nodeData ) === -1 ) list[ list.length ] = nodeData; + }, + paintRelease : function( nodeData ){ + var list = this.paintList, + i = list.indexOf( nodeData ); + i === -1 && list.splice( i, 1 ); + }, + paint : function(){ + var list = this.paintList, i = list.length; + for( ; i; ){ + list[ --i ].paint(); + }; + } + } +); + +var LayoutBox = Node.inherits( + 'LayoutBox', + X.Class.POOL_OBJECT, + _LayoutBox, + { + Constructor : function( layoutManager, root, parent ){ + LayoutBox.newPrivateData( this, layoutManager, X.Class._getPrivate( root ), parent ? X.Class._getPrivate( parent ) : undefined ); + }, + layoutManager : function( v ){ + + }, + createLayoutBox : function(){ + + }, + createContentBox : function(){ + + } + } +); \ No newline at end of file diff --git a/0.6.x/js/_old/Node.js b/0.6.x/js/_old/Node.js new file mode 100644 index 0000000..40e713c --- /dev/null +++ b/0.6.x/js/_old/Node.js @@ -0,0 +1,487 @@ +var _Node = X.Class.create( + '_Node', + X.Class.PRIVATE_DATA | X.Class.POOL_OBJECT, + { + elmWrap : null, + elmExtend : null, + textNode : null, + boxX : 0, + boxY : 0, + boxWidth : 0, + boxHeight : 0, + contentL : 0, + contentT : 0, + contentR : 0, + contentB : 0, + boxSizingOffsetLR : 0, + boxSizingOffsetTB : 0, + contentWidth : 0, + minContentWidth : 0, + maxContentWidth : AUTO, + lastContentWidth : -1, + contentHeight : 0, + minContentHeight : 0, + maxContentHeight : AUTO, + Constructor : function( __root, __parent ){ + this.__root = __root; + if( __parent ) this.__parent = __parent; + }, + style : function( v ){ + if( v instanceof NodeStyle ){ + if( v !== this._style ){ + this.__style && this.__style.unRegister( this ); + this._style = v; + this.__style = X.Class._getPrivate( v ); + this.__style.register( this ); + }; + return this.User; + } else + if( v === null ){ + this.__style && this.__style.unRegister( this ); + delete this._style; + delete this.__style; + return this.User; + }; + return this._style; + }, + content : function( v ){ + if( Type.isString( v ) === true ){ + if( !this.textNode || ( this.textNode && this.textNode.data !== v ) ){ + this._content = v; + this.updateContent = true; + }; + return this.User; + } else + if( v === null ){ + if( this._content !== v && this.textNode ){ + this._content = v; + this.updateContent = true; + }; + return this.User; + }; + if( this._content ) return this._content; + if( this._content === null ) return null; + if( this.textNode ) return this.textNode.data; + return null; + }, + /** + * 要素の追加・削除 + * 1. ペイントがある // 予約のみ + * 2. コンテンツがある // 予約のみ * + * 3. コンテンツを削除 // 予約のみ + * 4. 要素を削除 // 予約のみ + * + * コンテンツの再計算 + * 0. 要素追加して css セット + * 1. コンテンツの変更 + * 2. font 指定の変更 + * 3. contentWidth の変更 (コンテンツの高さの再計算) 前回の contentWidth の保持 + * + * contentSize, scrollSize の決定 + */ + musure : function( dirty ){ + var content = this._content, + root = this.__root, + style = this.__style, + w = this.contentWidth, + h = this.contentHeight; + switch( this.updateContent === true ? X.Css.Dirty.CONTENT : dirty ){ + case X.Css.Dirty.CONTENT : // コンテンツが変更された + this.paint( 0 ); + this.lastContentWidth = -1; + case X.Css.Dirty.FONT : // フォントサイズが変更された + case X.Css.Dirty.REFLOW : // レイアウトの再計算が必要 + /* http://web-designs.seesaa.net/article/188400668.html + * min-width の値が max-width の値より大きい場合は、max-width の値は min-width の値に設定される。 + * + * テキストノードがあり + * 1. contentWidth === AUTO + * style を更新して contentWidth の決定 + * min or max に引っかかったら style 更新 + * contentHeight === AUTO の場合 + * textHeight の決定 + * contentHeight !== AUTO の場合 scrollHeight のみ更新 + * 2. contentHeight === AUTO かつ + * コンテンツの高さの再取得が必要( contentWidth が最終計測時の contentWidth と一致 かつ フォント・コンテンツに変更無し の場合再取得不要) + * style を更新して contentHeight の決定 + * 必要でない + * 3. content のサイズがすでに決定している + * コンテンツの高さの再取得が必要 + * 必要でない + */ + if( this.textNode ){ + if( w === AUTO ){ + this.commitStyle(); + w = this.contentWidth = this.textNode.offsetWidth; + this.scrollWidth = w + this.contentL + this.contentR; + if( this.maxContentWidth < w - this.boxSizingOffsetLR ) this.contentWidth = this.maxContentWidth + this.boxSizingOffsetLR; + if( w - this.boxSizingOffsetLR < this.minContentWidth ) this.contentWidth = this.minContentWidth + this.boxSizingOffsetLR; + this.lastContentWidth = this.contentWidth; + + w !== this.contentWidth && this.commitStyle(); + + if( h === AUTO ){ + h = this.conetntHeight = this.textNode.offsetHeight; + this.scrollHeight = h + this.contentT + this.contentB; + if( this.maxContentHeight < h - this.boxSizingOffsetTB ) this.contentHeight = this.maxContentHeight + this.boxSizingOffsetTB; + if( h - this.boxSizingOffsetTB < this.minContentHeight ) this.contentHeight = this.minContentHeight + this.boxSizingOffsetTB; + } else { + this.scrollHeight = this.textNode.offsetHeight + this.contentT + this.contentB; + }; + } else + if( h === AUTO ){ + if( w !== this.lastContentWidth || dirty !== X.Css.Dirty.REFLOW ){ + this.commitStyle(); + this.lastContentWidth = w; + h = this.conetntHeight = this.textNode.offsetHeight; + this.scrollWidth = w + this.contentL + this.contentR; + this.scrollHeight = h + this.contentT + this.contentB; + if( this.maxContentHeight < h - this.boxSizingOffsetTB ) this.contentHeight = this.maxContentHeight + this.boxSizingOffsetTB; + if( h - this.boxSizingOffsetTB < this.minContentHeight ) this.contentHeight = this.minContentHeight + this.boxSizingOffsetTB; + } else { + this.scrollWidth = w + this.contentL + this.contentR; + this.scrollHeight = h + this.contentT + this.contentB; + root.paintReserve( this ); + }; + } else { + if( dirty !== X.Css.Dirty.REFLOW ){ + this.commitStyle(); + this.scrollWidth = this.textNode.offsetWidth + this.contentL + this.contentR; + this.scrollHeight = this.textNode.offsetHeight + this.contentT + this.contentB; + } else { + root.paintReserve( this ); + this.scrollWidth = w + this.contentL + this.contentR; + this.scrollHeight = h + this.contentT + this.contentB; + }; + }; + } else { + if( w === AUTO ) this.contentWidth = w = 0 < this.minContentWidth ? this.minContentWidth : 0; + if( h === AUTO ) this.contentHeight = h = 0 < this.minContentHeight ? this.minContentHeight : 0; + this.scrollWidth = w + this.contentL + this.contentR; + this.scrollHeight = h + this.contentT + this.contentB; + root.paintReserve( this ); + }; + break; + case X.Css.Dirty.PAINT : // 再描画のみ必要 + root.paintReserve( this ); + break; + }; + }, + paint : function( dirty ){ + var content = this._content, + style = this.__style; + if( this.updateContent === true || ( style && style.hasPaint === true ) ){ + if( !this.elmWrap ){ + this.elmWrap = DOM.createDiv(); + this.__parent.addDisplayElement( this ); + }; + dirty !== 0 && this.commitStyle(); + if( this.updateContent === true ){ + if( content !== null ){ + if( !this.textNode ){ + this.textNode = DOM.cerateText(); + this.elmWrap.appendChild( this.textNode ); + }; + this.textNode.data = content; + } else + if( this.textNode ){ + DOM.correct( this.textNode ); + delete this.textNode; + delete this.contentWidth; + delete this.conetntHeight; + delete this.scrollWidth; + delete this.scrollHeight; + }; + }; + } else + if( this.elmWrap && content === null && ( !style || style.hasPaint === false ) ){ + this.__parent.removeDisplayElement( this ); + DOM.correct( this.elmWrap ); + delete this.contentWidth; + delete this.conetntHeight; + }; + }, + commitStyle : function(){ + var css; + if( this.elmWrap ){ + css = this.__style ? this.__style.cssText( this ) : ''; + if( this.contentWidth !== AUTO ) css += 'width:' + this.contentWidth + 'px'; + if( this.contentHeight !== AUTO ) css += 'height:' + this.contentHeight + 'px'; + this.elmWrap.style.cssText = css; + }; + }, + /* + * 親の サイズを元に自身のサイズを計算していく + */ + preMesure : function( allowW, allowH ){ + var style = this.__style, + styles, calc, box, min, max, + contentW, contentH, allowSize, boxMinus, + paddingT, paddingR, paddingB, paddingL, + borderT, borderR, borderB, borderL, + marginT, marginR, marginB, marginL; + + if( style ){ + styles = style.data; + calc = BasicLayoutManager.calcValue; + box = styles[ X.Css.AttrNo.sizing ]; + + // Width + // 自身が constraintW の場合 親が AUTO ではない + // 自身が constraintW でない場合自身が AUTO はなくかつ親 が AUTO の場合 or 自身は % でない + if( style.constraintW ? allowW !== AUTO : !style.autoWidth && ( allowW !== AUTO || !style.percentWidth ) ){ + if( style.constraintW ){ + contentW = allowW;// - calc( styles[ X.Css.AttrNo.left ], allowW ) - calc( styles[ X.Css.AttrNo.right ], allowW ); + } else { + contentW = BasicLayoutManager.finalValue( styles[ X.Css.AttrNo.width ], styles[ X.Css.AttrNo.minWidth ], styles[ X.Css.AttrNo.maxWidth ], allowW ); + }; + paddingR = calc( styles[ X.Css.AttrNo.padding + 1 ], allowW ); + paddingL = calc( styles[ X.Css.AttrNo.padding + 3 ], allowW ); + borderR = styles[ X.Css.AttrNo.border + 1 ]; + borderL = styles[ X.Css.AttrNo.margin + 3 ]; + marginR = calc( styles[ X.Css.AttrNo.margin + 1 ], allowW ); + marginL = calc( styles[ X.Css.AttrNo.margin + 3 ], allowW ); + this.boxWidth = contentW; + boxMinus = 0; + switch( box ){ + case 3 : // margin-box + boxMinus = - marginR - marginL; + case 2 : // border-box + boxMinus -= borderR + borderL; + case 1 : // padding-box + boxMinus -= paddingR + paddingL; + // case 0 : // content-box + }; + this.contentL = marginL + borderL + paddingL; + this.contentR = marginR + borderR + paddingR; + this.contentWidth = contentW + boxMinus; + this.boxSizingOffsetLR = boxMinus; + } else { + this.boxWidth = this.contentWidth = AUTO; + min = styles[ X.Css.AttrNo.minWidth ]; + max = styles[ X.Css.AttrNo.maxWidth ]; + this.minContentWidth = 1 <= min ? min : 0; + this.maxContentWidth = 1 <= max ? max : AUTO; + delete this.boxSizingOffsetLR; + }; + + // Height + if( style.constraintH ? allowH !== AUTO : !style.autoHeight && ( allowH !== AUTO || !style.percentHeight ) ){ + if( style.constraintH ){ + contentH = allowH; // - calc( styles[ X.Css.AttrNo.top ], allowH ) - calc( styles[ X.Css.AttrNo.bottom ], allowH ); + } else { + contentH = BasicLayoutManager.finalValue( styles[ X.Css.AttrNo.height ], styles[ X.Css.AttrNo.minHeight ], styles[ X.Css.AttrNo.maxHeight ], allowH ); + }; + allowSize = styles[ X.Css.AttrNo.pageBox ] === true ? allowH : allowW; + paddingT = calc( styles[ X.Css.AttrNo.padding + 0 ], allowSize );// paddingTRBL の % 指定は 最大幅に対して TB でも幅に対して + paddingB = calc( styles[ X.Css.AttrNo.padding + 2 ], allowSize ); + borderT = styles[ X.Css.AttrNo.border + 0 ]; + borderB = styles[ X.Css.AttrNo.border + 2 ]; + marginT = calc( styles[ X.Css.AttrNo.margin + 0 ], allowSize );// marginTRBL の % 指定は 最大幅に対して TB でも幅に対して + marginB = calc( styles[ X.Css.AttrNo.margin + 2 ], allowSize ); + this.boxHeight = contentH; + boxMinus = 0; + switch( box ){ + case 3 : // margin-box + boxMinus = - marginT - marginR; + case 2 : // border-box + boxMinus -= borderT + borderR; + case 1 : // padding-box + boxMinus -= paddingT + paddingR; + // case 0 : // content-box + }; + this.contentT = marginT + borderT + paddingT; + this.conetntB = marginB + borderB + paddingB; + this.contentHeight = contentH + boxMinus; + this.boxSizingOffsetTB = boxMinus; + } else { + this.boxHeight = this.contentHeight = AUTO; + min = styles[ X.Css.AttrNo.minHeight ]; + max = styles[ X.Css.AttrNo.maxHeight ]; + this.minContentHeight = 1 <= min ? min : 0; + this.maxContentHeight = 1 <= max ? max : AUTO; + delete this.boxSizingOffsetTB; + }; + } else { + this.boxWidth = this.contentWidth = allowW; + this.boxHeight = this.contentHeight = allowH; + delete this.minContentHeight; + delete this.maxContentHeight; + delete this.contentL; + delete this.contentT; + delete this.contentR; + delete this.contentB; + }; + }, + /** + * 自身のコンテンツサイズを元に AUTO な width, height を確定していく + */ + postMesure : function(){ + var style = this.__style, + styles, calc, box, + contentW, contentH, w, h + contentSize, contentPlus; + if( style ){ + styles = style.data; + calc = BasicLayoutManager.advancedCalcValue; + contentW = this.contentWidth; + box = styles[ X.Css.AttrNo.sizing ]; + + // Width + if( this.boxWidth === AUTO ){ + paddingR = calc( styles[ X.Css.AttrNo.padding + 1 ], contentW ); + paddingL = calc( styles[ X.Css.AttrNo.padding + 3 ], contentW ); + borderR = styles[ X.Css.AttrNo.border + 1 ]; + borderL = styles[ X.Css.AttrNo.border + 3 ]; + marginR = calc( styles[ X.Css.AttrNo.margin + 1 ], contentW ); + marginL = calc( styles[ X.Css.AttrNo.margin + 3 ], contentW ); + contentPlus = 0; + switch( box ){ + case 3 : // margin-box + contentPlus = ( marginR + marginL ); + case 2 : // border-box + contentPlus += ( borderR + borderL ); + case 1 : // padding-box + contentPlus += ( paddingR + paddingL ); + // case 0 : // content-box + }; + contentW += contentPlus; + if( !style.constraintW ){ + min = styles[ X.Css.AttrNo.minWidth ]; + max = styles[ X.Css.AttrNo.maxWidth ]; + if( contentW < min && 1 <= min && contentPlus < min ){ + this.contentWidth = min - contentPlus; + } else + if( max < contentW && 1 <= max && contentPlus < max ){ + this.contentWidth = max - contentPlus; + }; + }; + this.contentL = marginL + borderL + paddingL; + this.contentR = marginR + borderR + paddingR; + this.boxWidth = this.contentWidth + this.contentL + this.contentR; + }; + // Height + if( this.boxHeight === AUTO ){ + contentH = this.contentHeight; + contentSize = styles[ X.Css.AttrNo.pageBox ] === true ? contentH : contentW; + paddingT = calc( styles[ X.Css.AttrNo.padding + 0 ], contentSize );// paddingTRBL の % 指定は 最大幅に対して TB でも幅に対して + paddingB = calc( styles[ X.Css.AttrNo.padding + 2 ], contentSize ); + borderT = styles[ X.Css.AttrNo.border + 0 ]; + borderB = styles[ X.Css.AttrNo.border + 2 ]; + marginT = calc( styles[ X.Css.AttrNo.margin + 0 ], contentSize );// marginTRBL の % 指定は 最大幅に対して TB でも幅に対して + marginB = calc( styles[ X.Css.AttrNo.margin + 2 ], contentSize ); + contentPlus = 0; + switch( box ){ + case 3 : // margin-box + contentPlus = ( marginT + marginB ); + case 2 : // border-box + contentPlus += ( borderT + borderB ); + case 1 : // padding-box + contentPlus += ( paddingT + paddingB ); + // case 0 : // content-box + }; + contentH += contentPlus; + if( !style.constraintH ){ + min = styles[ X.Css.AttrNo.minHeight ]; + max = styles[ X.Css.AttrNo.maxHeight ]; + if( contentH < min && 1 <= min && contentPlus < min ){ + this.contentHeight = min - contentPlus; + } else + if( max < contentH && 1 <= max && contentPlus < max ){ + this.contentHeight = max - contentPlus; + }; + }; + this.contentT = marginT + borderT + paddingT; + this.contentB = marginB + borderB + paddingB; + this.boxHeight = this.contentHeight + this.contentT + this.contentB; + }; + } else { + this.boxWidth = this.contentWidth; + this.boxHeight = this.contentHeight; + delete this.minContentHeight; + delete this.maxContentHeight; + delete this.contentL; + delete this.contentT; + delete this.contentR; + delete this.contentB; + }; + }, + addDisplayElement : function( nodeData ){ + // 描画更新リストに追加 + }, + removeDisplayElement : function( nodeData ){ + // 描画更新リストに追加 + DOM.correct( nodeData.elmWrap ); + delete nodeData.elmWrap; + delete nodeData.textNode; + delete nodeData.contentWidth; + delete nodeData.conetntHeight; + delete nodeData.currentWidth; + delete nodeData.currentHeight; + } + } +); +var Node = X.Class.create( + 'Node', + X.Class.POOL_OBJECT, + _Node, + { + Constructor : function( root, parent ){ + X.Class._newPrivate( this, X.Class._getPrivate( root ), parent ? X.Class._getPrivate( parent ) : undefined, this ); + }, + content : function( v ){ + return X.Class._getPrivate( this ).content( v ); + }, + style : function( v ){ + return X.Class._getPrivate( this ).paint( v ); + }, + remove : function(){ + X.Class._getPrivate( this ).remove(); + }, + nodeIndex : function( v ){ + return X.Class._getPrivate( this ).nodeIndex( v ); + }, + displayIndex : function(){ + + }, + disabled : function( v ){ + return X.Class._getPrivate( this ).disabled( v ); + }, + cursor : function( v ){ + return X.Class._getPrivate( this ).cursor( v ); + }, + getX : function(){ + + }, + getY : function(){ + + }, + getWidth : function(){ + + }, + getHeight : function(){ + + }, + getAbsolutePositionX : function(){ + return X.Class._getPrivate( this ).getAbsolutePositionX(); + }, + getAbsolutePositionY : function(){ + return X.Class._getPrivate( this ).getAbsolutePositionY(); + }, + scrollTo : function( x, y ){ + X.Class._getPrivate( this ).scrollTo( x, y ); + }, + scrollX : function( v ){ + return X.Class._getPrivate( this ).scrollX( v ); + }, + scrollY : function( v ){ + return X.Class._getPrivate( this ).scrollY( v ); + }, + addEventListener : function( type, handler, opt_thisObject ){ + X.Class._getPrivate( this ).addEventListener( type, handler, opt_thisObject ); + }, + removeEventListener : function( type, handler ){ + X.Class._getPrivate( this ).removeEventListener( type, handler ); + } + } +); \ No newline at end of file diff --git a/0.6.x/js/_old/NodeStyle.js b/0.6.x/js/_old/NodeStyle.js new file mode 100644 index 0000000..9df17ec --- /dev/null +++ b/0.6.x/js/_old/NodeStyle.js @@ -0,0 +1,378 @@ +var _NodeStyle = X.Class.create( + '_NodeStyle', + X.Class.PRIVATE_DATA | Class.POOL_OBJECT, + { + fontCssText : null, + colorCssText : null, + layoutCssText : null, + Constructor : function(){ + this.data = []; + this.dirty = 0; + }, + register : function( node ){ + var root = node.__root, + roots = this.rootList, + nodes = this.nodeList; + if( !roots ){ + this.rootList = [ root ]; + } else + if( roots.indexOf( root ) === -1 ) roots[ roots.length ] = root; + + if( !nodes ){ + this.nodeList = [ node ]; + return; + }; + if( nodes.indexOf( node ) === -1 ) nodes[ nodes.length ] = node; + }, + unRegister : function( node ){ + var nodes = this.nodeList, + i = nodes.indexOf( node ), + root = node._root, + roots = this.rootList, + j = roots.indexOf( root ); + if( i !== -1 && nodes.splice( i, 1 ) && nodes.length === 0 ) delete this.nodeList; + if( j !== -1 && roots.splice( j, 1 ) && roots.length === 0 ) delete this.rootList; + }, + clone : function(){ + var styleClass = Class.getClass( this.User ), + dataClass = Class.getClass( this ); + }, + /* + * opt_unit は getter のみ + */ + attr : function( prop, v, opt_unit ){ + var update = prop[ 0 ], + propID = prop[ 1 ], + type = prop[ 2 ], + list = prop[ 3 ], + length = !!( type & X.Css.Type.LENGTH ), + percent = !!( type & X.Css.Type.PERCENT ), + color = !!( type & X.Css.Type.COLOR ), + uDecimal = !!( type & X.Css.Type.U_DECIMAL ), + numerical = !!( type & X.Css.Type.NUMERICAL ), + flag = !!( type & X.Css.Type.BOOLEAN ), + quartet = !!( type & X.Css.Type.QUARTET ), + url = !!( type & X.Css.Type.URL ), + fontName = !!( type & X.Css.Type.FONT_NAME ), + //list = !!( type & X.Css.Type.LIST ), + combi = !!( type & X.Css.Type.COMBI ), + data = this.data, + _v = -1, + i, l, nodes, root; + /* + * Setter + */ + if( v !== undefined ){ + if( Type.isNumber( v ) === true ){ + if( numerical === false ){ + if( uDecimal === false || v < 0 || 1 < v ) throw new Error( '' ); + }; + } else + if( Type.isBoolean( v ) === true ){ + if( flag === false ) throw new Error( '' ); + } else + if( Type.isString( v ) === true ){ + if( url === false && fontName === false ){ + if( v.indexOf( ' ' ) !== -1 ){ + v = v.split( ' ' ); + } else { + if( length === false && percent === false && color === false ) throw new Error( '' ); + }; + }; + }; + if( Type.isArray( v ) === true ){ + if( v.length <= 4 && quartet === true ){ + type ^= X.Css.Type.QUARTET; + } else + if( v.length === 2 && combi === true ){ + type ^= X.Css.Type.COMBI; + } else { + throw new Error( '' ); + }; + switch( v.length ){ + case 1 : + this.attr( [ propID , type, list ], v[ 0 ] ); + this.attr( [ ++propID, type, list ], v[ 0 ] ); + this.attr( [ ++propID, type, list ], v[ 0 ] ); + this.attr( [ ++propID, type, list ], v[ 0 ] ); + break; + case 2 : + this.attr( [ propID , type, list ], v[ 0 ] ); + this.attr( [ ++propID, type, list ], v[ 1 ] ); + this.attr( [ ++propID, type, list ], v[ 0 ] ); + this.attr( [ ++propID, type, list ], v[ 1 ] ); + break; + case 3 : + this.attr( [ propID , type, list ], v[ 0 ] ); + this.attr( [ ++propID, type, list ], v[ 1 ] ); + this.attr( [ ++propID, type, list ], v[ 2 ] ); + this.attr( [ ++propID, type, list ], v[ 1 ] ); + break; + case 4 : + this.attr( [ propID , type, list ], v[ 0 ] ); + this.attr( [ ++propID, type, list ], v[ 1 ] ); + this.attr( [ ++propID, type, list ], v[ 2 ] ); + this.attr( [ ++propID, type, list ], v[ 3 ] ); + break; + default : + }; + return this.User; + }; + switch( update ){ + case X.Css.Dirty.REFLOW : + delete this.layoutCssText; + break; + case X.Css.Dirty.PAINT : + delete this.colorCssText; + break; + case X.Css.Dirty.FONT : + delete this.fontCssText; + }; + + if( this.dirty < update ){ + this.dirty = update; + roots = this.rootList; + for( i = 0, l = roots.length; i < l; ++i ){ + root = roots[ i ]; + if( root.dirty < update ) root.dirty = update; + }; + }; + + if( list ) _v = list.indexOf( v ); + data[ propID ] = _v !== -1 ? _v : v; + + switch( propID ){ + case X.Css.AttrNo.left : + case X.Css.AttrNo.right : + this.constraintW = Type.isNumber( data[ X.Css.AttrNo.left ] ) || Type.isNumber( data[ X.Css.AttrNo.right ] ); + break; + case X.Css.AttrNo.top : + case X.Css.AttrNo.bottom : + this.constraintH = Type.isNumber( data[ X.Css.AttrNo.top ] ) || Type.isNumber( data[ X.Css.AttrNo.bottom ] ); + break; + case X.Css.AttrNo.width : + this.autoWidth = v === AUTO; + this.prctWidth = v === FULL || v < 1; + break; + case X.Css.AttrNo.height : + this.autoHeight = v === AUTO; + this.prctHeight = v === FULL || v < 1; + break; + }; + return this.User; + }; + /* + * Getter + */ + v = data[ propID ]; + // Unit + if( quartet === true ) return [ v, data[ ++propID ], data[ ++propID ], data[ ++propID ] ]; + if( combi === true ) return [ v, data[ ++propID ] ]; + if( list && Type.isNumber( v ) === true ) return list[ v ]; + return v; + }, + cssText : function(){ + if( this.fontCssText === null ) this.fontCssText = this.createFontCssText(); + if( this.layoutCssText === null ) this.layoutCssText = this.createLayoutCssText(); + if( this.colorCssText === null ) this.colorCssText = this.createColorCssText(); + return [ this.fontCssText, this.colorCssText, this.layoutCssText ].join( ';' ); + }, + createFontCssText : function(){ + var data = this.data, + css = [], + v; + if( v = data[ X.Css.AttrNo.fontFamily ] ) css[ 0 ] = 'font-family:' + v; + if( v = data[ X.Css.AttrNo.fontSize ] ) css[ css.length ] = 'font-size:' + v; + if( v = data[ X.Css.AttrNo.bold ] ) css[ css.length ] = 'font-weight:bold'; + if( v = data[ X.Css.AttrNo.italic ] ) css[ css.length ] = 'font-style:italic'; + if( v = data[ X.Css.AttrNo.lineHeight ] ) css[ css.length ] = 'line-height:' + v; + if( v = data[ X.Css.AttrNo.letterSpacing ] ) css[ css.length ] = 'letter-spacing:' + v; + if( v = data[ X.Css.AttrNo.wordSpacing ] ) css[ css.length ] = 'word-spacing:' + v; + if( v = data[ X.Css.AttrNo.align ] ) css[ css.length ] = 'text-align:' + X.Css.Option.ALIGN[ v ]; + if( v = data[ X.Css.AttrNo.transform ] ) css[ css.length ] = 'text-transform:' + X.Css.Option.TEXT_TRANSFORM[ v ]; + return css.join( ',' ); + }, + createColorCssText : function(){ + var data = this.data, + css = [], + v, x, y, c, b; + if( v = data[ X.Css.AttrNo.borderColor ] ) css[ 0 ] = 'border-color:' + v; + if( v = data[ X.Css.AttrNo.borderStyle + 0 ] ) css[ css.length ] = 'border-top-style:' + X.Css.Option.BORDER_STYLE[ v ]; + if( v = data[ X.Css.AttrNo.borderStyle + 1 ] ) css[ css.length ] = 'border-right-style:' + X.Css.Option.BORDER_STYLE[ v ]; + if( v = data[ X.Css.AttrNo.borderStyle + 2 ] ) css[ css.length ] = 'border-bottom-style:' + X.Css.Option.BORDER_STYLE[ v ]; + if( v = data[ X.Css.AttrNo.borderStyle + 3 ] ) css[ css.length ] = 'border-left-style:' + X.Css.Option.BORDER_STYLE[ v ]; + if( v = data[ X.Css.AttrNo.cornerRadius + 0 ] ) css[ css.length ] = 'corner-radius-top:' + v; + if( v = data[ X.Css.AttrNo.cornerRadius + 1 ] ) css[ css.length ] = 'corner-radius-right:' + v; + if( v = data[ X.Css.AttrNo.cornerRadius + 2 ] ) css[ css.length ] = 'border-radius-bottom:' + v; + if( v = data[ X.Css.AttrNo.cornerRadius + 3 ] ) css[ css.length ] = 'border-radius-left:' + v; + if( v = data[ X.Css.AttrNo.bgColor ] ) css[ css.length ] = 'background-color:' + v; + // X.Css.AttrNo.bgAlpha + if( v = data[ X.Css.AttrNo.bgImgUrl ] ) css[ css.length ] = 'background-image:url(' + v + ')'; + x = data[ X.Css.AttrNo.bgImgRepeatX ]; + y = data[ X.Css.AttrNo.bgImgRepeatY ]; + if( x && y ){ + css[ css.length ] = 'background-repeat:repeat'; + } else + if( x ){ + css[ css.length ] = 'background-repeat:repeat-x'; + } else + if( y ){ + css[ css.length ] = 'background-repeat:repeat-y'; + }; + x = data[ X.Css.AttrNo.bgImgPositionX ]; + y = data[ X.Css.AttrNo.bgImgPositionY ]; + if( x && y ){ + css[ css.length ] = 'background-position:' + x + ' ' + y; + } else + if( x ){ + css[ css.length ] = 'background-position:' + x + ' 0'; + } else + if( y ){ + css[ css.length ] = 'background-position:0 ' + y; + }; + if( v = data[ X.Css.AttrNo.color ] ) css[ css.length ] = 'color:' + v; + if( v = data[ X.Css.AttrNo.decoration ] ) css[ css.length ] = 'text-decoration:' + X.Css.Option.TEXT_DECORATION[ v ]; + x = data[ X.Css.AttrNo.textShadowOffsetX ]; + y = data[ X.Css.AttrNo.textShadowOffsetY ]; + b = data[ X.Css.AttrNo.textShadowBlur ]; + c = data[ X.Css.AttrNo.textShadowColor ]; + if( c || x || y || b ){ + css[ css.length ] = 'text-shadow:' + x + ' ' + y + ' ' + b + ' ' + c; + }; + /* +X.Css.AttrNo.shadowColor = [ X.Css.Dirty.PAINT, 23, X.Css.Type.COLOR ]; // color +X.Css.AttrNo.shadowAlpha = [ X.Css.Dirty.PAINT, 24, X.Css.Type.U_DECIMAL ]; // 0 - 1 +X.Css.AttrNo.shadowOffsetX = [ X.Css.Dirty.PAINT, 25, X.Css.Type.LENGTH ]; // em +X.Css.AttrNo.shadowOffsetY = [ X.Css.Dirty.PAINT, 26, X.Css.Type.LENGTH ]; // em +X.Css.AttrNo.shadowBlur = [ X.Css.Dirty.PAINT, 27, X.Css.Type.LENGTH ]; // em +X.Css.AttrNo.shadowSpread = [ X.Css.Dirty.PAINT, 28, X.Css.Type.LENGTH ]; // em +X.Css.AttrNo.shadowInset = [ X.Css.Dirty.PAINT, 29, X.Css.Type.BOOLEAN ]; // true / false + */ + }, + createBoxShadowCssText : function(){ + + }, + createBGAlphaCssText : function(){ + + }, + createTextShadowCssText : function(){ + + }, + createLayoutCssText : function(){ + + } + } +); + +var NodeStyle = X.Class.create( + 'NodeStyle', + X.Class.POOL_OBJECT, + _NodeStyle, + { + Constructor : function(){ + X.Class._newPrivate( this ); + }, + borderWidth : function( v ){ + return X.Class._getPrivate( this ).attr( X.Css.Attr.borderWidth, v ); + }, + borderColor : function( v ){ + return X.Class._getPrivate( this ).attr( X.Css.Attr.borderColor, v ); + }, + borderStyle : function( v ){ + return X.Class._getPrivate( this ).attr( X.Css.Attr.borderStyle, v ); + }, + cornerRadius : function( v ){ + return X.Class._getPrivate( this ).attr( X.Css.Attr.cornerRadius, v ); + }, + bgColor : function( v ){ + return X.Class._getPrivate( this ).attr( X.Css.Attr.bgColor, v ); + }, + bgAlpha : function( v ){ + return X.Class._getPrivate( this ).attr( X.Css.Attr.bgAlpha, v ); + }, + bgImgUrl : function( v ){ + return X.Class._getPrivate( this ).attr( X.Css.Attr.bgImgUrl, v ); + }, + bgImgRepeatX : function( v ){ + return X.Class._getPrivate( this ).attr( X.Css.Attr.bgImgRepeatX, v ); + }, + bgImgRepeatY : function( v ){ + return X.Class._getPrivate( this ).attr( X.Css.Attr.bgImgRepeatY, v ); + }, + bgImgPositionX : function( v ){ + return X.Class._getPrivate( this ).attr( X.Css.Attr.bgImgPositionX, v ); + }, + bgImgPositionY : function( v ){ + return X.Class._getPrivate( this ).attr( X.Css.Attr.bgImgPositionY, v ); + }, + shadowColor : function( v ){ + return X.Class._getPrivate( this ).attr( X.Css.Attr.shadowColor, v ); + }, + shadowAlpha : function( v ){ + return X.Class._getPrivate( this ).attr( X.Css.Attr.shadowAlpha, v ); + }, + shadowOffsetX : function( v ){ + return X.Class._getPrivate( this ).attr( X.Css.Attr.shadowOffsetX, v ); + }, + shadowOffsetY : function( v ){ + return X.Class._getPrivate( this ).attr( X.Css.Attr.shadowOffsetY, v ); + }, + shadowBlur : function( v ){ + return X.Class._getPrivate( this ).attr( X.Css.Attr.shadowBlur, v ); + }, + shadowSpread : function(){ + return X.Class._getPrivate( this ).attr( X.Css.Attr.shadowSpread, v ); + }, + shadowInset : function(){ + return X.Class._getPrivate( this ).attr( X.Css.Attr.shadowInset, v ); + }, + color : function( v ){ + return X.Class._getPrivate( this ).attr( X.Css.Attr.color, v ); + }, + fontFamily : function( v ){ + return X.Class._getPrivate( this ).attr( X.Css.Attr.fontFamily, v ); + }, + fontSize : function( v ){ + return X.Class._getPrivate( this ).attr( X.Css.Attr.fontSize, v ); + }, + bold : function( v ){ + return X.Class._getPrivate( this ).attr( X.Css.Attr.bold, v ); + }, + italic : function( v ){ + return X.Class._getPrivate( this ).attr( X.Css.Attr.italic, v ); + }, + lineHeight : function( v ){ + return X.Class._getPrivate( this ).attr( X.Css.Attr.lineHeight, v ); + }, + letterSpacing : function( v ){ + return X.Class._getPrivate( this ).attr( X.Css.Attr.letterSpacing, v ); + }, + wordSpacing : function( v ){ + return X.Class._getPrivate( this ).attr( X.Css.Attr.wordSpacing, v ); + }, + align : function( v ){ + return X.Class._getPrivate( this ).attr( X.Css.Attr.align, v ); + }, + decoration : function( v ){ + return X.Class._getPrivate( this ).attr( X.Css.Attr.decoration, v ); + }, + transform : function( v ){ + return X.Class._getPrivate( this ).attr( X.Css.Attr.transform, v ); + }, + textShadowColor : function( v ){ + return X.Class._getPrivate( this ).attr( X.Css.Attr.textShadowColor, v ); + }, + textShadowOffsetX : function( v ){ + return X.Class._getPrivate( this ).attr( X.Css.Attr.textShadowOffsetX, v ); + }, + textShadowOffsetY : function( v ){ + return X.Class._getPrivate( this ).attr( X.Css.Attr.textShadowOffsetY, v ); + }, + shadowBlur : function( v ){ + return X.Class._getPrivate( this ).attr( X.Css.Attr.shadowBlur, v ); + }, + cssText : function(){ + return X.Class._getPrivate( this ).cssText(); + } + } +); \ No newline at end of file diff --git a/0.6.x/js/_old/Option.js b/0.6.x/js/_old/Option.js new file mode 100644 index 0000000..c605d47 --- /dev/null +++ b/0.6.x/js/_old/Option.js @@ -0,0 +1,10 @@ +X.Css.Option = { + BORDER_STYLE : 'none,hidden,dotted,dashed,solid,double,groove,ridge,inset,outset'.split(','), + POSITION_X : 'left,center,right'.split(','), + POSITION_Y : 'top,center,bottom'.split(','), + ALIGN : 'left,center,right,justify'.split(','), + TEXT_DECORATION : 'none,underline,overline,line-through,blink'.split(','), + TEXT_TRANSFORM : 'none,capitalize,lowercase,uppercase'.split(','), + WIDTH_HEIGHT : [ 'auto' ], + BOX_SIZING : 'content-box,padding-box,border-box,margin-box'.split(',') +}; \ No newline at end of file diff --git a/0.6.x/js/_old/Type.js b/0.6.x/js/_old/Type.js new file mode 100644 index 0000000..55c502f --- /dev/null +++ b/0.6.x/js/_old/Type.js @@ -0,0 +1,20 @@ +X.Css = {}; + +X.Css.Type = { + LENGTH : 1, + PERCENT : 2, + COLOR : 4, + U_DECIMAL : 8, + NUMERICAL : 16, + BOOLEAN : 32, + QUARTET : 64, + URL : 128, + FONT_NAME : 256, + LIST : 512, + AUTO : 1024, + COMBI : 2048 +}; + +var AUTO = Number.POSITIVE_INFINITY; +var FULL = X.Css; // something unigue value; +var FLOOR = Math.floor; diff --git a/0.6.x/js/_old/xdoc.js b/0.6.x/js/_old/xdoc.js new file mode 100644 index 0000000..3b5d3ae --- /dev/null +++ b/0.6.x/js/_old/xdoc.js @@ -0,0 +1,866 @@ +var BoxModel; + +var DOM = ( function( window, document ){ + var DIV_LIST = [], + SPAN_LIST = [], + TEXT_LIST = []; + + var elmTextSize; + + function correctNodes( node ){ + var child; + if( node && node.parentNode ){ + while( node.lastChild ) correctNodes( node.lastChild ); + node.parentNode.removeChild( node ); + if( node.nodeType === 1 ){ + switch( node.tagName ){ + case 'DIV': + DIV_LIST.push( node ); + break; + case 'SPAN': + SPAN_LIST.push( node ); + break; + + }; + node.removeAttribute( 'className' ); + node.removeAttribute( 'style' ); + node.removeAttribute( 'id' ); + } else + if( node.nodeType === 3 ){ + node.data = ''; + TEXT_LIST.push( node ); + }; + }; + }; + + return { + createDiv : function(){ + return 0 < DIV_LIST.length ? DIV_LIST.shift() : document.createElement( 'div' ); + }, + createSpan : function(){ + + }, + createText : function(){ + + }, + getTextSize : function( elm, content ){ + var span = DOM.createSpan(), + text = DOM.createText(), + w, h; + elm.appendChild( span ); + span.style.cssText = 'visibility:hidden;position:absolute;'; + span.appendChild( text ); + text.data = content; + w = span.offsetWidth; + h = span.offsetHeight; + DOM.correctNodes( span ); + return [ w, h ]; + }, + getTextHeight : function( elm, w, content ){ + var div = DOM.createSpan(), + text = DOM.createText(), + w, h; + elm.appendChild( div ); + div.style.cssText = 'visibility:hidden;position:absolute;width:' + w + 'px;'; + div.appendChild( text ); + text.data = content; + w = div.offsetWidth; + h = div.offsetHeight; + DOM.correctNodes( div ); + return h; + }, + correctNodes : function( node ){ + var child; + if( node && node.parentNode ){ + while( node.lastChild ) DOM.correctNodes( node.lastChild ); + node.parentNode.removeChild( node ); + if( node.nodeType === 1 ){ + switch( node.tagName ){ + case 'DIV': + DIV_LIST.push( node ); + break; + case 'SPAN': + SPAN_LIST.push( node ); + break; + + }; + node.removeAttribute( 'className' ); + node.removeAttribute( 'style' ); + node.removeAttribute( 'id' ); + } else + if( node.nodeType === 3 ){ + node.data = ''; + TEXT_LIST.push( node ); + }; + }; + } + } +})( window, document ); + +var XBrowserStyle = ( function(){ + var EMPTY = '', + CORON = ':', + SEMICORON = ';', + SPACE = ' ', + UNITS = 'px,cm,mm,in,pt,pc,em,%'.split( ',' ), + CLIP_SEPARATOR = UA.isIE === true && UA.ieVersion < 8 ? ' ' : ','; + + var SPECIAL = ( function(){ + var special = {}; + if( UA.isIE === true && UA.ieVersion < 9 ){ + if( UA.ACTIVEX === true ){ + // special.opacity = 'ActiveXOpacity'; + special.setFilters = function( style ){ + var filters = ( style.filter || '' ).split( ') ' ), + data = {}, + i = filters.length, + filter, names, props, prop, j, l, key, v; + for( ; i; ){ + filter = filters[ --i ].split( ' ' ).join( '' ).split( '(' ); + if( filter.length !== 2 ) continue; + names = filter[ 0 ].split( '.' ); // progid:DXImageTransform.Microsoft.Shadow(color=#666666,direction=120,strength=9) + props = filter[ 1 ].split( ',' ); // + filter = {}; + for( j = 0, l = props.length; j < l; ++j ){ + prop = props[ j ].split( '=' ); + key = prop[ 0 ].toLowerCase(); + v = prop[ 1 ]; + filter[ key ] = v; //v.charAt( 0 ) === '#' ? v : parseInt( v ); + }; + data[ names[ names.length - 1 ] ] = filter; + }; + + style.filter = data; + style.opacity = data.alpha && data.alpha.opacity ? data.alpha.opacity / 100 : 1; + }; + special.hasLayout = function( elm ){ + return elm.currentStyle.hasLayout; + }; + } else { + special.opacity = null; + }; + } else { + var style = document.documentElement.style; + special.opacity = style.opacity !== undefined ? 'opacity' : + style.MozOpacity !== undefined ? 'MozOpacity' : + style.KhtmlOpacity !== undefined ? 'KhtmlOpacity' : + style[ '-khtml-opacity' ] !== undefined ? 'KhtmlOpacity' : null; + + // if( style.backgroundPositionX === undefined ){ + special.setBackgroundPositionXY = function( style ){ + var bgp = ( style.backgroundPosition || '' ).split( ' ' ); + style.backgroundPositionX = bgp[ 0 ] || 0; + style.backgroundPositionY = bgp[ 1 ] || 0; + }; + // }; + if( style.clipTop === undefined && style[ 'clip-top' ] === undefined ){ + special.setClipTopRightBottomLeft = function( style ){ + var clip = style.clip; + if( !cliop || clip.indexOf( 'rect(' ) === -1 ){ + style.clipTop = 0; + style.clipRight = 0; + style.clipBottom = 0; + style.clipLeft = 0; + return; + }; + clip = clip.split( '(' )[ 1 ].split( ')' )[ 0 ].split( clip.indexOf( ',' ) !== -1 ? ',' : ' ' ); + ret.clipTop = clip[ 0 ]; + ret.clipRight = clip[ 1 ]; + ret.clipBottom = clip[ 2 ]; + ret.clipLeft = clip[ 3 ]; + }; + }; + }; + return special; + })(); + + function cssToObject( css ){ + var ret = {}, i, nv, n, v, + parse = Util.parse, + isNumber = Type.isNumber, + camelize = Util.camelize; + if( Type.isString( css ) === true ){ + css = css.split( SEMICORON ); + for( i = css.length; i; ){ + nv = css[ --i ].split( CORON ); // filter の場合, progid: がくる + n = nv.shift(); + if( isNumber( parse( n ) ) === true ) continue; + v = nv.join( EMPTY ); + while( v.charAt( 0 ) === ' ' ) v = v.substr( 1 ); + ret[ camelize( n ) ] = parse( v ); + }; + } else { + for( n in css ){ + if( Type.isNumber( parse( n ) ) === false ) ret[ n ] = parse( css[ n ] ); + }; + }; + + if( SPECIAL.setFilters ){ + SPECIAL.setFilters( ret ); + } else { + ret.opacity = SPECIAL.opacity !== null ? ret[ SPECIAL.opacity ] : 1; + }; + + SPECIAL.setBackgroundPositionXY && SPECIAL.setBackgroundPositionXY( ret ); + SPECIAL.setClipTopRightBottomLeft && SPECIAL.setClipTopRightBottomLeft( ret ); + + return ret; + }; + + var COLOR = ( function(){ + var ret = {}, v, name, + list = [ + '0', 'BLACK', + 'FF0000', 'RED', + '00FF00', 'LIME', + '0000FF', 'BLUE', + 'FFFF00', 'YELLOW', + '00FFFF', 'AQUA', + '00FFFF', 'CYAN', + 'FF00FF', 'MAGENTA', + 'FF00FF', 'FUCHSIA', + 'FFFFFF', 'WHITE', + '008000', 'GREEN', + '800080', 'PURPLE', + '800000', 'MAROON', + '000080', 'NAVY', + '808000', 'OLIVE', + '008080', 'TEAL', + '808080', 'GRAY', + 'C0C0C0', 'SILVER', + '696969', 'DIMGRAY', + '708090', 'SLATEGRAY', + 'A9A9A9', 'DARKGRAY', + 'DCDCDC', 'GAINSBORO', + '191970', 'MIDNIGHTBLUE', + '6A5ACD', 'SLATEBLUE', + '0000CD', 'MEDIUMBLUE', + '4169E1', 'ROYALBLUE', + '1E90FF', 'DODGERBLUE', + '87CEEB', 'SKYBLUE', + '4682B4', 'STEELBLUE', + 'ADD8E6', 'LIGHTBLUE', + 'AFEEEE', 'PALETURQUOISE', + '40E0D0', 'TURQUOISE', + 'E0FFFF', 'LIGHTCYAN', + '7FFFD4', 'AQUAMARINE', + '006400', 'DARKGREEN', + '2E8B57', 'SEAGREEN', + '90EE90', 'LIGHTGREEN', + '7FFF00', 'CHARTREUSE', + 'ADFF2F', 'GREENYELLOW', + '32CD32', 'LIMEGREEN', + '9ACD32', 'YELLOWGREEN', + '6B8E23', 'OLIVEDRAB', + 'BCB76B', 'DARKKHAKI', + 'EEE8AA', 'PALEGOLDENROD', + 'FFFFE0', 'LIGHTYELLOW', + 'FFD700', 'GOLD', + 'DAA520', 'GOLDENROD', + 'B8860B', 'DARKGOLDENROD', + 'BC8F8F', 'ROSYBROWN', + 'CD5C5C', 'INDIANRED', + '8B4513', 'SADDLEBROWN', + 'A0522D', 'SIENNA', + 'CD853F', 'PERU', + 'DEB887', 'BURLYWOOD', + 'F5F5DC', 'BEIGE', + 'F5DEB3', 'WHEAT', + 'F4A460', 'SANDYBROWN', + 'D2B48C', 'TAN', + 'D2691E', 'CHOCOLATE', + 'B22222', 'FIREBRICK', + 'A52A2A', 'BROWN', + 'FA8072', 'SALMON', + 'FFA500', 'ORANGE', + 'FF7F50', 'CORAL', + 'FF6347', 'TOMATO', + 'FF69B4', 'HOTPINK', + 'FFC0CB', 'PINK', + 'FF1493', 'DEEPPINK', + 'DB7093', 'PALEVIOLETRED', + 'EE82EE', 'VIOLET', + 'DDA0DD', 'PLUM', + 'DA70D6', 'ORCHILD', + '9400D3', 'DARKVIOLET', + '8A2BE2', 'BLUEVIOLET', + '9370DB', 'MEDIUMPURPLE', + 'D8BFD8', 'THISTLE', + 'E6E6FA', 'LAVENDER', + 'FFE4E1', 'MISTYROSE', + 'FFFFF0', 'IVORY', + 'FFFACD', 'LEMONCHIFFON' + ]; + for( i = list.length; i; ){ + v = list[ --i ]; + name = list[ --i ]; + ret[ name ] = parseInt( v, 16 ); + }; + return ret; + })(); + + var PARAMS = ( function(){ + var ret = {}; + register( ret.percent = {}, + 'marginBottom,marginLeft,marginRight,marginTop,paddingBottom,paddingLeft,paddingRight,paddingTop,fontSize,textIndent' + ); + register( ret.offset = {}, + 'height,width,bottom,left,right,top' + ); + register( ret.size = {}, + 'borderBottomWidth,borderLeftWidth,borderRightWidth,borderTopWidth,letterSpacing' + ); + register( ret.color = {}, + 'backgroundColor,borderBottomColor,borderLeftColor,borderRightColor,borderTopColor,color' + ); + register( ret.region = {}, + 'margin,padding,borderWidth,borderColor' + ); + register( ret.special = {}, + 'clip,backgroundPosition,opacity,lineHeight,zIndex' + ); + register( ret.unit = {}, 'px,cm,mm,in,pt,pc,em,%' ); + + register( ret.margin = {}, 'marginBottom,marginLeft,marginRight,marginTop,paddingBottom' ); + register( ret.padding = {}, 'paddingBottom,paddingLeft,paddingRight,paddingTop' ); + register( ret.borderWidth = {}, 'borderBottomWidth,borderLeftWidth,borderRightWidth,borderTopWidth' ); + register( ret.borderColor = {}, 'borderBottomColor,borderLeftColor,borderRightColor,borderTopColor' ); + + function register( obj, params ){ + params = params.split( ',' ); + for( var i=params.length; i; ) obj[ params[ --i ] ] = true; + }; + return ret; + })(); + + /* + * + */ + var Property = Class.create( + 'Property', + Class.POOL_OBJECT, + { + Constructor : function( name, value, unit, pxPerEm ){ + this.name = name; + this.value = value; + this.unit = unit; + this.pxPerEm = pxPerEm; // XXpx = 1em; + }, + name : '', + value : 0, + pxPerEm : 12, // 1em === ??px + unit : '', + equal : function( prop ){ + if( this.unit === prop.unit ){ + return this.value === prop.value; + }; + return Math.abs( this.toPx() - prop.toPx() ) < 1; + }, + convert: function( prop ){ + var u = prop.unit, v; + if( this.unit === u ) return; + this.value = v = this.toPx(); + this.unit = u; + if( u !== px ){ + this.value = u === 'em' ? v / this.pxPerEm : Util.pxTo( v, u ); + }; + }, + setValue: function( v ){ + this.value = v; + }, + getValue: function(){ + return this.value; + }, + getOffset: function( prop ){ + return prop.value - this.value; + }, + getUnit: function(){ + return this.unit; + }, + getValueText: function(){ + return this.value === 0 ? '0' : this.value + this.unit; + }, + toPx: function(){ + var v = this.value, u = this.unit; + if( u === px ) return v; + if( u === 'em' ) return v * this.pxPerEm; + if( u === '' && this.name === 'lineHeight' ) return v * this.pxPerEm; + return Util.toPx( v, u ); + }, + isValid: function( t ){ + t = t || this; + var n = t.name, + v = t.value, + u = t.unit, + z = u !== '' ? true : v === 0; + if( PARAMS.percent[ n ] === true ) return z; + if( PARAMS.offset[ n ] === true ) return z; + if( PARAMS.size[ n ] === true ) return z && u !== '%'; + if( PARAMS.special[ n ] === true ){ + if( n === 'lineHeight' ) return true; + if( n === 'opacity' ) return 0 <= v && v <= 1 && u === ''; + if( n === 'zIndex' ) return u === ''; + }; + return false; + } + } + ); + + /** + * backgroundPosition, clip + */ + var PropertyGroup = Class.create( + 'PropertyGroup', + Class.POOL_OBJECT, + { + Constructor : function( name ){ + this.name = name; + this.props = []; + for( var i = 1, l = arguments.length; i 1 ) return false; + }; + return true; + }, + convert : function( prop ){ + var u = prop.pct, x; + if( this.pct === u ) return; + x = u === true ? 100 / 255 : 2.55; + this.r *= x; + this.g *= x; + this.b *= x; + this.pct = u; + }, + setValue : function( rgb ){ + this.r = rgb[ 0 ]; + this.g = rgb[ 1 ]; + this.b = rgb[ 2 ]; + }, + getValue : function(){ + return [ this.r, this.g, this.b ]; + }, + getOffset : function( prop ){ + return [ prop.r - this.r, prop.g - this.g, prop.b - this.b ]; + }, + getUnit : function(){ + return this.pct === true ? '%' : ''; + }, + getValueText : function(){ + if( this.pct === true ){ + return [ 'rgb(', this.r, '%,', this.g, '%,', this.b, '%)' ].join( '' ); + }; + var round = Math.round; + //return [ 'rgb(', round( this.r ), ',', round( this.g ), ',', round( this.b ), ')' ].join( '' ); + + var rgb = '00000' + ( ( round( this.r ) << 16 ) + ( round( this.g ) << 8 ) + round( this.b ) ).toString( 16 ); + return '#' + rgb.substr( rgb.length - 6 ); + }, + _toPct : function(){ + if( this.pct === true ) return [ this.r, this.g, this.b ]; + return [ this.r / 2.55, this.g / 2.55, this.b / 2.55 ]; + }, + isValid : function( t ){ + var isFinite = window.isFinite; + if( !isFinite( this.r ) || !isFinite( this.g ) || !isFinite( this.b ) ) return false; + if( 0 > this.r || 0 > this.g || 0 > this.b ) return false; + if( this.pct === true ) return this.r <= 100 && this.g <= 100 && this.b <= 100; + return this.r <= 255 && this.g <= 255 && this.b <= 255; + } + } + ); + + var isString = Type.isString, + isNumber = Type.isNumber; + var REG_UINIT = /.*\d(\w{1,2})?/, + $1 = '$1', + px = 'px', + REG_XXXXXX = /^#[\da-fA-F]{6}?/, + REG_XXX = /^#[\da-fA-F]{3}?/; + + var WrappedStyle = Class.create( + 'WrappedStyle', + Class.POOL_OBJECT, + { + Constructor : function( style ){ + this.style = style; + var fontsize = this.get( 'fontSize' ); + this.pxPerEm = fontsize.toPx(); + fonstsize.kill(); + }, + get: function( p ){ + if( PARAMS.special[ p ] === true || PARAMS.region[ p ] === true ){ + if( p === 'clip' ) return this.getClip(); + if( p === 'margin' ) return this.getMarginPaddingBorder( p, '' ); + if( p === 'padding' ) return this.getMarginPaddingBorder( p, '' ); + if( p === 'borderWidth' ) return this.getMarginPaddingBorder( 'border', 'Width' ); + if( p === 'borderColor' ) return this.getBorderColor( 'borderColor' ); + if( p === 'backgroundPosition' ) return this.getBackgroundPosition( p ); + // opacity, zindex, lineHeight + return new Property( p, this.getValue( x ), this.getUnit( x ), this.pxPerEm ); + }; + var x = this.style[ p ], e, v, u; + if( PARAMS.offset[ p ] === true ){ + return new Property( p, this.getValue( x ), this.getUnit( x, p ), this.pxPerEm ); + /* + e = this.elm; + if( p === 'width' ) v = e.offsetWidth; + if( p === 'height' ) v = e.offsetHeight; + if( p === 'top' ) v = e.offsetTop; + if( p === 'bottom' ) v = e.offsetBottom; + if( p === 'left' ) v = e.offsetLeft; + if( p === 'right' ) v = e.offsetRight; + u = this.getUnit( x, p ); + // alert( p + this.pxTo( v, u ) + u ) + return new Property( p, this.pxTo( v, u ), u, this.pxPerEm ); */ + }; + if( p === 'fontSize' ){ // xx-small 等 + v = Util.absoluteFontSizeToPx( x ); + if( v !== 0 ){ + return new Property( p, v, px, this.pxPerEm ); + }; + }; + if( PARAMS.percent[ p ] === true ){ + // alert( p + ' , ' + x + ' , ' + this.getUnit( x, p ) ) + return new Property( p, this.getValue( x ), this.getUnit( x, p ), this.pxPerEm ); + }; + if( PARAMS.size[ p ] === true ){ + return new Property( p, this.getValue( x ), this.getUnit( x, p ), this.pxPerEm ); + }; + if( PARAMS.color[ p ] === true ){ + return this.getColor( x, p ); + }; + }, + pxTo: function( px, unit ){ + if( unit === 'em' ) return px / this.pxPerEm; + return Util.pxTo( px, unit ); + }, + getValue: function( x ){ + return isString( x ) === true ? parseInt( x ) : + isNumber( x ) === true ? x : 0; + }, + getUnit: function( x, p ){ + var u; + if( isString( x ) === true ){ + u = x.replace( REG_UINIT, $1 ); + if( p === 'lineHeight' ) return u; + if( PARAMS.unit[ u ] !== true ) return px; + return u; + }; + return px; + }, + getColor: function( x, p ){ + var rgb = COLOR[ x.toUpperCase() ], + pct = false, + r = 0, + g = 0, + b = 0; + if( isNumber( rgb ) === true ){ + r = ( rgb & 0xff0000 ) >> 16; + g = ( rgb & 0xff00 ) >> 8; + b = ( rgb & 0xff ); + } else + if( x.match( REG_XXXXXX ) ){ + r = parseInt( x.charAt( 1 ) + x.charAt( 2 ), 16 ); + g = parseInt( x.charAt( 3 ) + x.charAt( 4 ), 16 ); + b = parseInt( x.charAt( 5 ) + x.charAt( 6 ), 16 ); + //alert( x + ' g: ' + g ) + } else + if( x.match( REG_XXX ) ){ + r = parseInt( x.charAt( 1 ) + x.charAt( 1 ), 16 ); + g = parseInt( x.charAt( 2 ) + x.charAt( 2 ), 16 ); + b = parseInt( x.charAt( 3 ) + x.charAt( 3 ), 16 ); + } else + if( x.indexOf( 'rgb(' ) === 0 ){ + rgb = x.substr( 4 ).split( ',' ); + r = parseFloat( rgb[ 0 ] ); + g = parseFloat( rgb[ 1 ] ); + b = parseFloat( rgb[ 2 ] ); + if( x.indexOf( '%' ) !== -1 ) pct = true; + } else { + r = 255; + g = 255; + b = 255; + }; + return new ColorProperty( p, r, g, b, pct ); + }, + getClip: function( name ){ + // rect(...) クリップします。, は上端からの、 , は左端からのオフセットで指定します。Internet Explorer 4~7 では、カンマの代わりにスペースで区切る必要があります。 + // position:absolute または position:fixed を適用した要素に対してのみ有効です。 + var top = this.get( name + 'Top' ), + right = this.get( name + 'Right' ), + bottom = this.get( name + 'Bottom' ), + left = this.get( name + 'Left' ), + ret = new PropertyGroup( name, top, right, bottom, left), + all; + if( ret.isValid() === true ) return ret; + ret.kill(); + all = this.style[ name ].split( '(' )[ 1 ].split( ')' )[ 0 ].split( CLIP_SEPARATOR ); + return new PropertyGroup( name, + new Property( name + 'Top', all[ 0 ], px, this.pxPerEm ), + new Property( name + 'Right', all[ 1 ], px, this.pxPerEm ), + new Property( name + 'Bottom', all[ 2 ], px, this.pxPerEm ), + new Property( name + 'Left', all[ 3 ], px, this.pxPerEm ) + ); + }, + getBackgroundPosition: function( name ){ + var x = this.get( name + 'X' ), + y = this.get( name + 'Y' ), + ret = new PropertyGroup( name, x, y ), + xy; + if( ret.isValid() === true ) return ret; + ret.kill(); + xy = this.style[ name ].split( ' ' ); + return new PropertyGroup( name, + new Property( name + 'X', this.getValue( xy[ 0 ] ), this.getUnit( xy[ 0 ] ), this.pxPerEm ), + new Property( name + 'Y', this.getValue( xy[ 1 ] ), this.getUnit( xy[ 1 ] ), this.pxPerEm ) + ); + }, + getMarginPaddingBorder: function( name, width ){ + var props = [ name + 'Top' + width, + name + 'Right' + width, + name + 'Bottom' + width, + name + 'Left' + width ], + top = this.get( props[ 0 ] ), + right = this.get( props[ 1 ] ), + bottom = this.get( props[ 2 ] ), + left = this.get( props[ 3 ] ), + ret = new FrexibleProperty( name, top, right, bottom, left ), + klass, pxPerEm, getValue, getUnit, + all, _0, _1, _2, _3, v, u; + if( ret.isValid() === true ) return ret; + ret.kill(); + klass = Property; + pxPerEm = this.pxPerEm; + getValue = this.getValue; + getUnit = this.getUnit; + all = this.style[ name + width ].split( ' ' ); + _0 = all[ 0 ]; + _1 = all[ 1 ]; + _2 = all[ 2 ]; + _3 = all[ 3 ]; + v = getValue( _0 ); + u = getUnit( _0 ); + switch( all.length ){ + case 1 : + top = new klass( props[ 0 ], v, u, pxPerEm ); + right = new klass( props[ 1 ], v, u, pxPerEm ); + bottom = new klass( props[ 2 ], v, u, pxPerEm ); + left = new klass( props[ 3 ], v, u, pxPerEm ); + break; + case 2 : + top = new klass( props[ 0 ], v, u, pxPerEm ); + bottom = new klass( props[ 2 ], v, u, pxPerEm ); + v = getValue( _1 ); + u = getUnit( _1 ); + right = new klass( props[ 1 ], v, u, pxPerEm ); + left = new klass( props[ 3 ], v, u, pxPerEm ); + break; + case 3 : + top = new klass( props[ 0 ], v, u, pxPerEm ); + v = getValue( _1 ); + u = getUnit( _1 ); + right = new klass( props[ 1 ], v, u, pxPerEm ); + left = new klass( props[ 3 ], v, u, pxPerEm ); + bottom = new klass( props[ 2 ], getValue( _2 ), getUnit( _2 ), pxPerEm ); + break; + case 4 : + top = new klass( props[ 0 ], v, u, pxPerEm ); + right = new klass( props[ 1 ], getValue( _1 ), getUnit( _1 ), pxPerEm ); + bottom = new klass( props[ 2 ], getValue( _2 ), getUnit( _2 ), pxPerEm ); + left = new klass( props[ 3 ], getValue( _3 ), getUnit( _3 ), pxPerEm ); + break; + }; + return new FrexibleProperty( name, top, right, bottom, left ); + }, + getBorderColor: function( name ){ + var props = 'borderTopColor,borderRightColor,borderBottomColor,borderLeftColor'.split( ',' ), + top = this.get( props[ 0 ] ), + right = this.get( props[ 1 ] ), + bottom = this.get( props[ 2 ] ), + left = this.get( props[ 3 ] ), + ret = new FrexibleProperty( name, top, right, bottom, left ), + all, _0, _1, getColor; + if( ret.isValid() === true ) return ret; + ret.kill(); + getColor = this.getColor; + all = this.style[ name ].split( ' ' ); + _0 = all[ 0 ]; + _1 = all[ 1 ]; + switch( all.length ){ + case 1 : + top = getColor( _0, props[ 0 ] ); + right = getColor( _0, props[ 1 ] ); + bottom = getColor( _0, props[ 2 ] ); + left = getColor( _0, props[ 3 ] ); + break; + case 2 : + top = getColor( _0, props[ 0 ] ); + right = getColor( _1, props[ 1 ] ); + bottom = getColor( _0, props[ 2 ] ); + left = getColor( _1, props[ 3 ] ); + break; + case 3 : + top = getColor( _0, props[ 0 ] ); + right = getColor( _1, props[ 1 ] ); + bottom = getColor( all[ 2 ], props[ 2 ] ); + left = getColor( _1, props[ 3 ] ); + break; + case 4 : + top = getColor( _0, props[ 0 ] ); + right = getColor( _1, props[ 1 ] ); + bottom = getColor( all[ 2 ], props[ 2 ] ); + left = getColor( all[ 3 ], props[ 3 ] ); + break; + }; + return new FrexibleProperty( name, top, right, bottom, left ); + } + } + ); + function camelizeHash( obj ){ + var p, _p, came = Util.camelize; + for( p in obj ){ + _p = came( p ); + if( _p === p ) continue; + obj[ _p ] = obj[ _p ] || obj[ p ]; + delete obj[ p ]; + }; + }; + return { + create: function( css ){ + return new WrappedStyle( camelizeHash( p ) ); + } + }; +})(); + +var XDocument = ( function( window, document ){ + + var ROOT_LIST = []; + var AUTO = Number.POSITIVE_INFINITY; + var FULL = X.Css.Attr; // something unigue value; + var FLOOR = Math.floor; + + var RootNode = Node.inherits( + 'RootNode', + Class.POOL_OBJECT, + LayoutBoxPrivate, + { + Constructor : function(){ + RootNode.newPrivateData( this, BasicLayoutManager ); + } + } + ); + +})( window, document ); \ No newline at end of file diff --git a/0.6.x/js/core/00_builtin.js b/0.6.x/js/core/00_builtin.js new file mode 100644 index 0000000..c491406 --- /dev/null +++ b/0.6.x/js/core/00_builtin.js @@ -0,0 +1,114 @@ +/* + * ビルトインオブジェクトに拡張したい10のメソッド + * http://d.hatena.ne.jp/ofk/20080922/1222047483 + */ + +Function.prototype.apply || (Function.prototype.apply = function (x, y) { + x = x || window; + y = y ||[]; + x.__apply = this; + if (!x.__apply) x.constructor.prototype.__apply = this; + var r, j = y.length; + switch (j) { + case 0: r = x.__apply(); break; + case 1: r = x.__apply(y[0]); break; + case 2: r = x.__apply(y[0], y[1]); break; + case 3: r = x.__apply(y[0], y[1], y[2]); break; + case 4: r = x.__apply(y[0], y[1], y[2], y[3]); break; + case 5: r = x.__apply(y[0], y[1], y[2], y[3], y[4]); break; + case 6: r = x.__apply(y[0], y[1], y[2], y[3], y[4], y[5]); break; + case 7: r = x.__apply(y[0], y[1], y[2], y[3], y[4], y[5], y[6]); break; + case 8: r = x.__apply(y[0], y[1], y[2], y[3], y[4], y[5], y[6], y[7]); break; + case 9: r = x.__apply(y[0], y[1], y[2], y[3], y[4], y[5], y[6], y[7], y[8]); break; + default: + var a = []; + for (var i = 0; i < j; ++i) + a[i] = 'y[' + i + ']'; + r = eval('x.__apply(' + a.join(',') + ')'); + break; + } + delete x.__apply ? x.__apply : x.constructor.prototype.__apply; + return r; +}); +Function.prototype.call || (Function.prototype.call = function () { + var a = arguments, x = a[0], y = []; + for (var i = 1, j = a.length; i < j; ++i) + y[i - 1] = a[i] + return this.apply(x, y); +}); + +Array.prototype.pop || (Array.prototype.pop = function () { + var r = this[this.length - 1]; + --this.length; + return r; +}); +Array.prototype.push || (Array.prototype.push = function () { + for (var a = arguments, i = 0, j = a.length, l = this.length; i < j; ++i) + this[l + i] = a[i]; + return this.length; +}); +Array.prototype.shift || (Array.prototype.shift = function () { + var r = this[0]; + for(var i = 1, j = this.length; i < j; ++i) + this[i - 1] = this[i]; + --this.length; + return r; +}); +Array.prototype.unshift || (Array.prototype.unshift = function () { + var a = arguments, l = a.length, j = this.length += l - 1; + for (var i = j; i >= l; --i) + this[i] = this[i - l]; + for (var i = 0; i < l; ++i) + this[i] = a[i]; + return j; +}); +Array.prototype.splice || (Array.prototype.splice = function (x, y) { + var a = arguments, s = a.length - 2 - y, r = this.slice(x, x + y); + if (s > 0) { + for (var i = this.length - 1, j = x + y; i >= j; --i) + this[i + s] = this[i]; + } + else if (s < 0) { + for (var i = x + y, j = this.length; i < j; ++i) + this[i + s] = this[i]; + this.length += s; + } + for (var i = 2, j = a.length; i < j; ++i) + this[i - 2 + x] = a[i]; + return r; +}); + +/* + * JavaScript 1.6, Array.indexOfを下位互換実装する + * http://www.inazumatv.com/contents/archives/7965 + */ + +Array.prototype.indexOf || (Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) { + if( this == null ){ + //throw new TypeError(); + }; + var t = Object(this); + var len = t.length >>> 0; + if (len === 0) return -1; + + var n = 0; + if (arguments.length > 1) { + n = Number(arguments[1]); + if (n != n) { // shortcut for verifying if it's NaN + n = 0; + } else if (n != 0 && n != Infinity && n != -Infinity) { + n = (n > 0 || -1) * Math.floor(Math.abs(n)); + } + } + if (n >= len) { + return -1; + } + var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0); + for (; k < len; k++) { + if (t[k] === searchElement) { + return k; + } + } + return -1; + }); + diff --git a/0.6.x/js/core/01_XUa.js b/0.6.x/js/core/01_XUa.js new file mode 100644 index 0000000..5320fa7 --- /dev/null +++ b/0.6.x/js/core/01_XUa.js @@ -0,0 +1,30 @@ +/* + * UA + */ +var X = X || {}; + +X.UA = (function(undefined){ + var acme = {}, + n = navigator, + dua = n.userAgent, + dav = n.appVersion, + tv = parseFloat(dav); + acme.Opera = ( dua.indexOf("Opera") >= 0 ) ? tv : undefined; + if(document.all && !acme.Opera){ + acme.IE = parseFloat(dav.split("MSIE ")[1]) || undefined; + return acme; + }; + acme.Khtml = ( dav.indexOf("Konqueror") >= 0 ) ? tv : undefined; + acme.WebKit = parseFloat(dua.split("WebKit\/")[1]) || undefined; + acme.Chrome = parseFloat(dua.split("Chrome\/")[1]) || undefined; + // replace( reg, ) don't work for Sigmarion2 pocketIE + acme.Gecko = eval( '(dua.indexOf("Gecko\/") >= 0) ? parseFloat(dua.split("rv:")[1].replace( /^(\d*\.\d*)\.(\d*)/, "$1$2" )) : undefined' ); + var index = Math.max(dav.indexOf("WebKit"), dav.indexOf("Safari"), 0); + if(index && !acme.Chrome){ + acme.Safari = parseFloat(dav.split("Version/")[1]); + if(!acme.Safari || parseFloat(dav.substr(index + 7)) <= 419.3){ + acme.Safari = 2; + }; + }; + return acme; +})(); \ No newline at end of file diff --git a/0.6.x/js/core/02_XType.js b/0.6.x/js/core/02_XType.js new file mode 100644 index 0000000..88930f0 --- /dev/null +++ b/0.6.x/js/core/02_XType.js @@ -0,0 +1,47 @@ +/* + * http://pettanr.sourceforge.jp/test/type.html + * + * need xua + */ +var X = X || {}; + +X.Type = { + isObject : function(v) { + return v !== null && typeof v === 'object'; + }, + isFunction : function(v) { + return typeof v === 'function'; + }, + isArray : + X.UA.IE < 5 ? (function(v){ return v && typeof v.length === 'number';}) : + window['Array'] ? (new Function('v', 'return v instanceof Array;')) : + (function(v){ return Object.prototype.toString.call(v) === '[object Array]';}), + isBoolean : function(v) { + return typeof v === 'boolean'; + }, + isString : function(v) { + return typeof v === 'string'; + }, + isNumber : function(v) { + return typeof v === 'number'; + }, + isFinite : function(v){ + return X.Type.isNumber(v) === true && isFinite(v); + }, + isHTMLElement : + // ie4 + X.UA.IE < 5 ? (function(v){ return v && v.tagName && v.all;}) : + window['HTMLElement'] ? (new Function('v', 'return v instanceof HTMLElement')) : + (function(v){ return v && v.nodeType === 1 && v.appendChild;}), + /* + isElementCollection : function(v) { + return (Object.prototype.toString.call(v) === "[object HTMLCollection]"); + }, + */ + isNull : function(v) { + return v === null; + }, + isUndefined : function(v) { + return typeof v === 'undefined'; + } +}; diff --git a/0.6.x/js/core/03_XCancel.js b/0.6.x/js/core/03_XCancel.js new file mode 100644 index 0000000..be8bc6c --- /dev/null +++ b/0.6.x/js/core/03_XCancel.js @@ -0,0 +1,7 @@ +X.Cancel = { + UN_LISTEN : 1, + CANCEL_BUBBLEUP : 2, // 上位階層への伝播のキャンセル + CANCEL_NEXT : 4, // 同一階層のリスナーのキャンセル + CANCEL_DEFAULT : 8, // 結果動作のキャンセル, + SYS_CANCEL : 16 +}; diff --git a/0.6.x/js/core/04_XCallback.js b/0.6.x/js/core/04_XCallback.js new file mode 100644 index 0000000..7568af2 --- /dev/null +++ b/0.6.x/js/core/04_XCallback.js @@ -0,0 +1,182 @@ + +var X = X || {}; + +X.Callback = { + _LIVE_LIST : [], + _POOL_LIST : [], + create : function( arg0, arg1, arg2 /* [ listener || ( context + function ) || function ][ args... ] */ ){ + var self = X.Callback, + live = self._LIVE_LIST, + f, listener, context, callback; + if( typeof arg1 === 'function' ){ + context = arg0; + callback = arg1; + } else + if( typeof arg0 === 'function' ){ + callback = arg0; + arg2 = arg1; + } else + if( arg0 && typeof arg0.handleEvent === 'function' ){ + listener = arg0; + arg2 = arg1; + } else { + //throw new Error( 'Callback.create() fail!' ); + }; + + f = self._POOL_LIST.pop(); + if( !f ){ + f = new Function( 'var a=arguments,f=a.callee;f.a=a;return f.c()' ); // f.t=this; + f.kill = self._kill; + f.same = self._same; + }; + live[ live.length ] = f; + if( listener ){ + f.c = self._contextCallback; + f.listener = listener; + f.context = listener; + f.callback = listener.handleEvent; + } else + if( context ){ + f.c = self._contextCallback; + f.context = context; + f.callback = callback; + } else { + f.c = self._generalCallback; + f.callback = callback; + }; + + if( arg2 && typeof arg2.length === 'number' ){ + f.add = arg2; + }; + return f; + }, + once : function(){ + var f = X.Callback.create.apply( null, arguments ); + f.once = true; + return f; + }, + find : function( arg0, arg1 /* [ listener || ( context + function ) || function ] */ ){ + var live = X.Callback._LIVE_LIST, + i = live.length, + listener, context, callback, + f; + if( typeof arg1 === 'function' ){ + context = arg0; + callback = arg1; + } else + if( typeof arg0 === 'function' ){ + callback = arg0; + } else + if( arg0 && typeof arg0.handleEvent === 'function' ){ + listener = arg0; + }; + + for( ; i; ){ + f = live[ --i ]; + if( listener && f.listener === listener ){ + return f; + } else + if( context && f.context === context && f.callback === callback ){ + return f; + } else + if( f.callback === callback ){ + return f; + }; + }; + return null; + }, + _contextCallback : function(){ + var f = this, + a = f.a, + s = f.add, + c = f.callback, + x = f.context, + i = 0, l, r; + s && s.push.apply( a, s ); + l = a.length; + r = l === 0 ? c.call( x ) : + l === 1 ? c.call( x, a[ 0 ] ) : c.apply( x, a ); + delete f.a; + //delete f.t; + f.once && X.Callback._correct( f ); + return r; + }, + _generalCallback : function(){ + var f = this, + a = f.a, + s = f.add, + c = f.callback, + i = 0, l, r; + s && s.push.apply( a, s ); + l = a.length; + r = l === 0 ? c() : + l === 1 ? c( a[ 0 ] ) : c.apply( null, a ); + delete f.a; + //delete f.t; + f.once && X.Callback._correct( f ); + return r; + }, + _kill : function(){ + X.Callback._correct( this ); + }, + _same : function( arg0, arg1, arg2 ){ + var listener, context, callback, + f = this; + if( typeof arg1 === 'function' ){ + context = arg0; + callback = arg1; + } else + if( typeof arg0 === 'function' ){ + callback = arg0; + arg2 = arg1; + } else + if( arg0 && typeof arg0.handleEvent === 'function' ){ + listener = arg0; + arg2 = arg1; + }; + + if( arg2 && f.add && f.add !== arg2 ){ + return false; + }; + + if( listener && f.listener === listener ){ + return true; + } else + if( context && f.context === context && f.callback === callback ){ + return true; + } else + if( f.callback === callback ){ + return true; + }; + return false; + }, + _correct : function( f ){ + var self = X.Callback, + i = self._LIVE_LIST.indexOf( f ); + if( f.c ) delete f.c; + if( f.listener ) delete f.listener; + if( f.context ) delete f.context; + if( f.callback ) delete f.callback; + if( f.once ) delete f.once; + if( f.add ) delete f.add; + if( i === -1 ) return; + self._LIVE_LIST.splice( i, 1 ); + self._POOL_LIST.push( f ); + }, + sys_monitor : function(){ + return { + 'Live callback' : X.Callback._LIVE_LIST.length, + 'Pool callback' : X.Callback._POOL_LIST.length + }; + }, + sys_gc : function(){ + var self = X.Callback, + list = self._POOL_LIST, f; + while( 0 < list.length ){ + f = list.shift(); + self._correct( f ); + delete f.kill; + delete f.same; + }; + } +}; diff --git a/0.6.x/js/core/05_XClass.js b/0.6.x/js/core/05_XClass.js new file mode 100644 index 0000000..9dcfbd4 --- /dev/null +++ b/0.6.x/js/core/05_XClass.js @@ -0,0 +1,309 @@ +/** + * Class を定義し システムの管理下に置く. + * 全てのクラスと pool が有効の場合インスタンスへの参照が保持される. + * 1. X.Class.create( def, opt_final, opt_pool, opt_abstract ) でクラスを登録. + * 2. コンストラクタ となるメソッドは、Constructor : function( arg ){ ... }, に書く. + * 3. 通常通り new で インスタンス生成 + * 4. kill() でオブジェクトをクリーンして削除、pool が有効の場合は pool される. + * 5. pool が有効の場合、new で pool されたインスタンスが返される. + * 6. + * + */ +X.Class = ( function(){ + var CLASS_LIST = [], + DEF_LIST = [], + PRIVATE_CLASS_LIST = [], + PRIVATE_DEF_LIST = [], + CONSTRUCTOR = 'Constructor', + killPrivateFlag = false, + traits = null, + _slice = Array.prototype.slice; + + function copyArray( list ){ + //return _slice.call( list, 0 ); + var i = list.length, ret = new Array( i ); + for( ; i; ){ + ret[ --i ] = list[ i ]; + }; + return ret; + }; + + /* サブクラスを作るメソッド + * var subClass = superClass.inherits( ... ) + * http://d.hatena.ne.jp/m-hiyama/20051018/1129605002 + */ + function inherits( /* displayName, classSetting, opt_PrivateClass, props */ ){ + var args = copyArray( arguments ), + params = [], + Super = this, + superDef = X.Class._getClassDef( Super ), + displayName = args[ 0 ], + classSetting, + opt_super, + klass, def; + if( superDef.Final === true ) throw new Error( 'Class is final!' ); + + if( X.Type.isString( displayName ) === true ){ + args.shift(); + } else { + displayName = 'SubClass of ' + superDef.displayName; + }; + params.push( displayName ); + + classSetting = args[ 0 ]; + if( X.Type.isNumber( classSetting ) === true ){ + if( superDef.isPrivate === true ) classSetting = classSetting | X.Class.PRIVATE_DATA; + opt_super = !!( classSetting & X.Class.SUPER_ACCESS ); + params.push( classSetting ); + args.shift(); + }; + if( X.Class._getClass( args[ 0 ] ) ){ + params.push( args.shift() ); + } else + if( superDef.privateClass ){ + params.push( superDef.privateClass ); + }; + params.push( args[ 0 ] ); /* props */ + Super.__new = null; + traits = new Super(); + Super.__new = C; + klass = X.Class.create.apply( X.Class, params ); + traits = null; + if( opt_super === true ){ + def = X.Class._getClassDef( klass ); + def.Super = Super.prototype; + def.SuperConstructor = superDef[ CONSTRUCTOR ]; + }; + return klass; + }; + + /* X.Class.create で作られたクラスのインスタンスが共通で備えるメソッド */ + var CommonProps = { + kill : function(){ + var instance = this, + klass = X.Class._getClass( instance ), + def = X.Class._getClassDef( klass ), + data, p, i; + if( def.isPrivate === true && killPrivateFlag === false ){ + throw new Error( 'PrivateInstance.kill() work in PrivateUser.kill().' ); + }; + killPrivateFlag = false; // onKill 内で PrivateInstance.kill() を防ぐため + X.Type.isFunction( instance.onKill ) === true && instance.onKill(); + for( p in instance ){ + if( instance.hasOwnProperty && !instance.hasOwnProperty( p ) ) continue; + delete instance[ p ]; + }; + if( def.pool ){ + def.live && def.live.splice( def.live.indexOf( instance ), 1 ); + def.pool[ def.pool.length ] = instance; + }; + if( def.privateClass ){ + i = def.userList.indexOf( instance ); + if( i !== -1 ){ + data = X.Class._getPrivate( instance ); + killPrivateFlag = true; + data.kill(); + def.dataList.splice( i, 1 ); + def.userList.splice( i, 1 ); + }; + }; + // myCallback の削除 + // myCallback を受け取った API への通知 + } + }; + + /* + * new の実体.コンストラクタの機能は instance.Constructor に書く. + * これにより pool された オブジェクト(破棄されたインスタンス) を再利用できる + */ + /* Constructor Real for GeneralClass */ + function C( args ){ + var klass = this, + def = X.Class._getClassDef( klass ), + dataUser = def._tempUser, + instance, + userDef; + if( def.Abstract === true ){ + throw new Error( 'AbstractClass!' ); + }; + if( def.isPrivate === true && dataUser === null ){ + throw new Error( 'use myClass.newPrivate( instance, ...args )!' ); + }; + klass.__new = null; + instance = def.pool && def.pool.length > 0 ? def.pool.pop() : new klass(); + klass.__new = C; + if( def.isPrivate === true ){ + userDef = X.Class._getClassDef( dataUser ); + userDef.dataList.push( instance ); + userDef.userList.push( dataUser ); + instance.User = dataUser; + def._tempUser = null; + } else { + def.live && def.live.push( instance ); + }; + if( def.Super ){ + instance.Super = def.Super; + instance.SuperConstructor = superConstructor; + }; + def[ CONSTRUCTOR ] && def[ CONSTRUCTOR ].apply( instance, args ); + return instance; + }; + + function superConstructor(){ + X.Class._getClassDef( this ).SuperConstructor.apply( this, arguments ); + }; + + return { + POOL_OBJECT : 1, + ABSTRACT : 2, + FINAL : 4, + SUPER_ACCESS : 8, + PRIVATE_DATA : 16, + create : function( /* displayName, classSetting, opt_PrivateClass, props */ ){ + var args = copyArray( arguments ), + displayName = args[ 0 ], + classSetting, + opt_pool, opt_abstract, opt_final, opt_private, + privateDef, + props, + klass, + classDef = {}; + if( X.Type.isString( displayName ) === true ){ + classDef.displayName = displayName; + args.shift(); + }; + classSetting = args[ 0 ]; + if( X.Type.isNumber( classSetting ) === true ){ + opt_pool = !!( classSetting & X.Class.POOL_OBJECT ); + opt_abstract = !!( classSetting & X.Class.ABSTRACT ); + opt_final = !!( classSetting & X.Class.FINAL ); + opt_private = !!( classSetting & X.Class.PRIVATE_DATA ); + if( opt_final === true && opt_abstract === true ){ + throw new Error( 'final & Abstract!' ); + }; + args.shift(); + }; + + if( PRIVATE_CLASS_LIST.indexOf( args[ 0 ] ) !== -1 ){ + privateDef = X.Class._getClassDef( args[ 0 ] ); + if( privateDef.isPrivate !== true ){ + throw new Error( 'PrivateClass not found! please, X.Class.create( X.Class.PRIVATE, {...} ).' ); + } else + if( privateDef.Abstract === true ){ + throw new Error( 'PrivateClass is Abstract!' ); + }; + classDef.privateClass = args.shift(); + }; + props = args[ 0 ]; + if( props === null || X.Type.isObject( props ) === false ){ + throw new Error( 'No Class Def!' ); + }; + + if( X.Type.isFunction( props[ CONSTRUCTOR ] ) === true ){ + classDef[ CONSTRUCTOR ] = props[ CONSTRUCTOR ]; + }; + + klass = new Function( 'var a=arguments,f=a.callee;if(f.__new)return f.__new(a)' ); + klass.__new = C; + klass.prototype = X.Class._override( X.Class._override( traits || klass.prototype, props, true ), CommonProps, false ); + klass.name = displayName; + + if( opt_abstract === true ){ + classDef.Abstract = true; + } else + if( opt_pool === true ){ + classDef.pool = []; + if( opt_private === false ) classDef.live = []; + }; + if( opt_final === true ){ + classDef.Final = true; + } else { + klass.inherits = inherits; + }; + if( opt_private === true ){ + if( classDef.privateClass ){ + throw new Error( 'Private Data Class has no PrivateClass!' ); + }; + classDef.isPrivate = true; + PRIVATE_CLASS_LIST.push( klass ); + PRIVATE_DEF_LIST.push( classDef ); + } else { + CLASS_LIST.push( klass ); + DEF_LIST.push( classDef ); + }; + return klass; + }, + sys_shutdown : function(){ + + }, + _getClass : function( instance ){ + var cList = CLASS_LIST, + i = cList.length, + klass; + for( ; i; ){ + klass = cList[ --i ]; + if( instance instanceof klass ) return klass; + }; + cList = PRIVATE_CLASS_LIST; + i = cList.length; + for( ; i; ){ + klass = cList[ --i ]; + if( instance instanceof klass ) return klass; + }; + + if( cList.indexOf( instance ) !== -1 ) return instance; + if( CLASS_LIST.indexOf( instance ) !== -1 ) return instance; + }, + _getClassDef : function( KlassOrInstance ){ + var i = CLASS_LIST.indexOf( KlassOrInstance ); + if( i === -1 ) i = CLASS_LIST.indexOf( X.Class._getClass( KlassOrInstance ) ); + if( i !== -1 ) return DEF_LIST[ i ]; + + i = PRIVATE_CLASS_LIST.indexOf( KlassOrInstance ); + if( i === -1 ) i = PRIVATE_CLASS_LIST.indexOf( X.Class._getClass( KlassOrInstance ) ); + if( i !== -1 ) return PRIVATE_DEF_LIST[ i ]; + + if( DEF_LIST.indexOf( KlassOrInstance ) !== -1 ) return KlassOrInstance; + if( PRIVATE_DEF_LIST.indexOf( KlassOrInstance ) !== -1 ) return KlassOrInstance; + }, + _newPrivate : function( /* instance, args */ ){ + var args = copyArray( arguments ), + user = args.shift(), + def = X.Class._getClassDef( user ), + privateClass = def.privateClass, + privateDef = X.Class._getClassDef( privateClass ), + i = -1; + if( def.userList ){ + i = def.userList.indexOf( user ); + } else { + def.userList = []; + def.dataList = []; + }; + if( i !== -1 ){ + throw new Error( 'PrivateData already exist!' ); + }; + if( privateDef._tempUser ){ + throw new Error( 'newPrivate を連続呼び出しされたところ破綻' ); + }; + privateDef._tempUser = user; + return privateClass.__new( args ); + }, + _getPrivate : function( instance ){ + var def = X.Class._getClassDef( instance ), + i = def.userList.indexOf( instance ); + if( i !== -1 ) return def.dataList[ i ]; + }, + /* over のプロパティを target にコピーする.ただし target の プロパティが優先, force で解除 */ + _override : function ( target, src, force ){ + for( var p in src ){ + if( p === 'Super' || p === 'SuperConstructor' ){ + throw new Error( 'Super & SuperConstructor is reserved!' ); + }; + if( force === true || target[ p ] === void 0 ){ + target[ p ] = src[ p ]; + }; + }; + return target; + } + }; +})(); \ No newline at end of file diff --git a/0.6.x/js/core/06_XTimer.js b/0.6.x/js/core/06_XTimer.js new file mode 100644 index 0000000..c8a2185 --- /dev/null +++ b/0.6.x/js/core/06_XTimer.js @@ -0,0 +1,113 @@ +/** + * use X.Callback + */ + +X.Timer = ( function(){ + var setTimeout = window.setTimeout; + var clearTimeout = window.clearTimeout; + var INTERVAL_TIME = 16; + var TICKET_LIST = []; + var timerId = -1; + var next = 0; + /* const */ + var INDEX_TIME = 0, + INDEX_LAST = 1, + INDEX_COUNT = 2, + INDEX_CALLBACK = 3; + + function loop(){ + var i = 0, + c = next, + list = TICKET_LIST, + queue, callback; + for( ; i < list.length; ){ + queue = list[ i ]; + if( 0 < ( queue[ INDEX_LAST ] -= c ) ){ + ++i; + continue; + }; + callback = queue[ INDEX_CALLBACK ]; + c = queue[ INDEX_COUNT ]; + if( callback() === false || c === 1 ){ + list.splice( i, 1 ); + callback.kill(); + queue.length = 0; + continue; + } else + if( 1 < c ){ + --queue[ INDEX_COUNT ]; + }; + ++i; + queue[ INDEX_LAST ] = queue[ INDEX_TIME ]; + }; + timerId = -1; + update(); + }; + function update(){ + var list = TICKET_LIST, + l = list.length, + n = 99999999, + last; + if( l === 0 ){ + timerId !== -1 && clearTimeout( timerId ); + timerId = -1; + return; + }; + for( ; l; ){ + last = list[ --l ][ INDEX_LAST ]; + if( last < n ) n = last; + }; + if( n < next || timerId === -1 ){ + timerId !== -1 && clearTimeout( timerId ); + timerId = setTimeout( loop, INTERVAL_TIME * n ); + next = n; + }; + }; + + return { + add : function( time, count, args1, args2, args3 ){ + if( time < INTERVAL_TIME ) time = INTERVAL_TIME; + time = Math.floor( time / INTERVAL_TIME ); + var callback, + list = TICKET_LIST, + l = list.length, + i = l, + queue, args; + if( typeof count !== 'number' || count < 0 ){ + count = 0; + }; + /* + for( ; i; ){ + queue = list[ --i ]; + if( queue[ INDEX_CALLBACK ].same( args1, args2 ) === true ){ + queue[ INDEX_TIME ] = queue[ INDEX_LAST ] = time; + queue[ INDEX_COUNT ] = count; + update(); + return; + }; + }; */ + + list[ l ] = [ time, time, count, X.Callback.create( args1, args2, args3 ) ]; + update(); + }, + once : function( time, args1, args2, args3 ){ + X.Timer.add( time, 1, args1, args2, args3 ); + }, + remove : function( args1, args2 ){ + var queue, + i = 0, + list = TICKET_LIST; + if( !callback ) return; + while( queue = list[ i ] ){ + if( queue[ INDEX_CALLBACK ].same( args1, args2 ) === true ){ + callback.kill(); + list.splice( i, 1 ); + break; + } else { + ++i; + }; + }; + update(); + } + }; +})(); \ No newline at end of file diff --git a/0.6.x/js/core/07_XEventDispatcher.js b/0.6.x/js/core/07_XEventDispatcher.js new file mode 100644 index 0000000..9bcd66b --- /dev/null +++ b/0.6.x/js/core/07_XEventDispatcher.js @@ -0,0 +1,84 @@ +X.EventDispatcher = ( function(){ + var LIST = [], TEMP = [], once; + + function getList( instance, type, create ){ + var i = LIST.indexOf( instance ), + data, list; + if( i === -1 ){ + if( !create ) return; + LIST[ LIST.length ] = instance; + TEMP[ TEMP.length ] = data = {}; + } else { + data = TEMP[ i ]; + }; + list = data[ type ]; + if( !create || list ) return list; + list = data[ type ] = []; + list.data = data; + return list; + }; + + function exist( list, arg1, arg2 ){ + for( var i = list.length; i; ){ + if( list[ --i ].same( arg1, arg2 ) === true ) return i; + }; + return -1; + }; + + return X.Class.create( + 'EventDispatcher', + { + listen : function( type, arg1, arg2 ){ + var list = getList( this, type, true ); + if( list.length && exist( list, arg1, arg2 ) !== -1 ) return; + list[ list.length ] = X.Callback[ once === true ? 'once' : 'create' ]( arg1, arg2 ); + }, + listenOnce : function( type, arg1, arg2 ){ + once = true; + this.listen( type, arg1, arg2 ); + once = false; + }, + unlisten : function( type, arg1, arg2 ){ + var list = getList( this, type ), + list, i; + if( !list ) return; + i = exist( list, arg1, arg2 ); + i !== -1 && list.splice( i, 1 ); + if( list.length === 0 ){ + list.data[ e.type ] = void 0; + delete list.data; + }; + }, + listening : function( type, arg1, arg2 ){ + var list = getList( this, type ); + if( !list ) return false; + return exist( list, arg1, arg2 ) !== -1; + }, + dispatch : function( e ){ + // dispatch 中の listen は? + // + + var list = getList( this, e.type ), + i, f; + if( !list ) return; + for( i = list.length; i; ){ + f = list[ --i ]; + // once の場合リストから削除してからファイア + f.once === true && list.splice( i, 1 ); + if( f( e ) === false ){ + + }; + if( list.length === 0 ){ + list.data[ e.type ] = void 0; + delete list.data; + }; + }; + return; + } + }//, onKillCallback( instance ) + ); +})(); + + + + diff --git a/0.6.x/js/core/10_XStyle.js b/0.6.x/js/core/10_XStyle.js new file mode 100644 index 0000000..e018963 --- /dev/null +++ b/0.6.x/js/core/10_XStyle.js @@ -0,0 +1,30 @@ +X.Style = { + /* font-size -> fontSize */ + camelize: function( cssProp ){ + var parts = cssProp.split( ' ' ).join( '' ).split( '-' ), + l = parts.length, + i, camelized; + if( l === 1 ) return parts[ 0 ]; + + camelized = cssProp.charAt(0) === '-' + ? parts[ 0 ].charAt( 0 ).toUpperCase() + parts[ 0 ].substring( 1 ) + : parts[ 0 ]; + + for( i = 1; i < l; ++i ){ + camelized += parts[ i ].charAt( 0 ).toUpperCase() + parts[ i ].substring( 1 ); + }; + return camelized; + }, + REG_LARGE : /[A-Z]/g, + /* fontSize -> font-size */ + uncamelize: function( str ){ + return str.split( ' ' ).join( '' ).replace( X.Style.REG_LARGE, '-$&' ).toLowerCase(); + }, + objToCssText : function( obj ){ + var css = [], uncamelize = X.Style.uncamelize, p; + for( p in obj ){ + css[ css.length ] = [ uncamelize( p ), obj[ p ] ].join( ':' ); + }; + return css.join( ';' ); + } +}; diff --git a/0.6.x/js/core/11_XDom.js b/0.6.x/js/core/11_XDom.js new file mode 100644 index 0000000..eb17831 --- /dev/null +++ b/0.6.x/js/core/11_XDom.js @@ -0,0 +1,190 @@ +/** + * use X.Callback + */ +var X = X || {}; + +X.Dom = { + getElementById : + document.getElementById ? + (function( id ){ + return document.getElementById( id ); + }) : + document.all ? + (function( id ){ + return document.all[ id ]; + }) : + (function(){}), + getElementsByTagName : + document.getElementsByTagName ? + (function( parent, tagName ){ + return parent.getElementsByTagName( tagName.toUpperCase() ); + }) : + document.all ? + (function( parent, tagName ){ + return parent.all.tags( tagName.toUpperCase() ); + }) : + (function(){}), + getElementsByClassName : + document.getElementsByClassName ? + (function( parent, className ){ + return parent.getElementsByClassName( className ); + }) : + document.getElementsByTagName ? + (function( parent, className ){ + var self = X.Dom, + live = parent.getElementsByTagName( '*' ), + nodes = [], + node; + for( var i = 0, l = live.length; i < l; ++i ){ + nodes[ i ] = live[ i ]; + }; + for( i = 0; i < nodes.length; ){ + node = nodes[ i ]; + if( node.nodeType !== 1 || self.hasClassName( node, className ) === false ){ + nodes.splice( i, 1 ); + } else { + ++i; + }; + }; + return nodes; + }) : + document.all ? + (function( parent, className ){ + var self = X.Dom, + live = parent.all, + nodes = [], + node; + for( var i = 0, l = live.length; i < l; ++i ){ + nodes[ i ] = live[ i ]; + }; + for( i = 0; i < nodes.length; ){ + node = nodes[ i ]; + if( !node.className || !node.className.length || self.hasClassName( node, className ) === false ){ + nodes.splice( i, 1 ); + } else { + ++i; + }; + }; + return nodes; + }) : + (function(){}), + hasClass : function( elm, className ){ + var cnames = ( elm.className || '' ).split( ' ' ), + _cnames = className.split( ' ' ), + cname, + i = _cnames.length; + for( ; i; ){ + cname = _cnames[ --i ]; + if( cname === '' ) continue; + if( cnames.indexOf( cname ) === -1 ) return false; + }; + return true; + }, + createElement : + document.createElement ? + (function( tagName ){ + return document.createElement( tagName ); + }) : + document.all ? + (function( tagName ){ + document.body.insertAdjacentHTML( 'BeforeEnd', '<' + tagName + '>gggg<\/' + tagName + '>' ); + var list = document.all.tags( tagName.toUpperCase() ), + ret = list[ list.length - 1 ]; + return list; + }) : + (function(){}), + appendChild : + document.appendChild ? + (function( target, elm ){ + return target.appendChild( elm ); + }) : + document.all ? + (function( target, elm ){ + return target.insertAdjacentHTML( 'BeforeEnd', elm.outerHTML || elm ); // elm の場合と string の場合がある + }) : + (function(){}), + removeChild : + document.removeChild ? + (function( parent, elm ){ + return target.removeChild( elm ); + }) : + document.all ? + (function( parent, elm ){ + var children = parent.children, + i = 0, + l = children.length, + html = [], + child, update; + if( i === 1 ){ + parent.innerHTML = ''; + return; + }; + for( ; i < l; ++i ){ + child = children[ i ]; + if( child !== elm ){ + html[ html.length ] = child.outerHTML; + } else { + update = true; + }; + }; + if( !update ) return; + parent.innerHTML = html.join(''); + }) : + (function(){}), + insertBefore : + document.insertBefore ? + (function( parent, elm, elmAfter ){ + return parent.insertBefore( elm, elmAfter ); + }) : + document.all ? + (function( parent, elm, elmAfter ){ + return elmAfter.insertAdjacentHTML( 'BeforeBegin', '<' + elm.tagName + ' class="list">' + elm.innerHTML + '<\/' + elm.tagName + '>' ); + }) : + (function(){}) +}; + +if( X.UA.IE && X.UA.IE < 5 ){ + /* + * ie4 に TextNode は存在しない。 Element.children にテキストノードは無視される。 + * そこでテキストノードを判定して控える操作が必要になる。 + */ + X.Dom.getChildNodes = function( elm ){ + var html = elm.innerHTML, + children = elm.children, + l = children.length - 1, + _ = '', + cr = X.Dom.getCRChars( html ), + i, j, child, outer, index, parts, ret, text; + if( l < 0 ){ + if( html.length ) return [ html ]; // new X.Dom.TextNode( html ); + return []; + }; + ret = []; + j = -1; + html = html.split( cr ).join( _ ); + for( i = 0; i <= l; ++i ){ + child = children[ i ]; + outer = child.outerHTML.split( cr ).join( _ ); + index = html.indexOf( outer ); + if( index === -1 ){ + alert( 'X.Dom.getChildNodes\n' + outer + '\n' + html.substr( 0, 100 ) ); + continue; + }; + if( 0 < index ){ + ret[ ++j ] = html.substr( 0, index ); // new X.Dom.TextNode( html ); + }; + ret[ ++j ] = child; + html = html.substr( index + outer.length ); + if( i === l && html.length ){ + ret[ ++j ] = html; // new X.Dom.TextNode( html ); + break; + }; + }; + return ret; + }; + X.Dom.getCRChars = function( src ){ + return 0 <= src.indexOf( '\r\n' ) ? '\r\n' : + 0 <= src.indexOf( '\n' ) ? '\n' : + 0 <= src.indexOf( '\r' ) ? '\r' : '\n'; + }; +}; \ No newline at end of file diff --git a/0.6.x/js/core/12_XDomEvent.js b/0.6.x/js/core/12_XDomEvent.js new file mode 100644 index 0000000..6585f47 --- /dev/null +++ b/0.6.x/js/core/12_XDomEvent.js @@ -0,0 +1,168 @@ +/** + * use X.Callback + */ +var X = X || {}; + +X.DomEvent = { + _load : false, + _ready : false, + _unload : false, + add : + document.addEventListener ? + (function( element, type, arg2, arg3, arg4 /* [ listener || ( context + function ) || function ][ arguments ] */ ){ + var callback; + if( typeof arg2 === 'function' ){ + callback = X.Callback.create( element, arg2, arg3 ); + } else { + callback = X.Callback.create( arg2, arg3, arg4 ); + }; + callback.c = X.DomEvent._callback; // override + element.addEventListener( type, callback, false ); + }) : + document.attachEvent ? + (function( element, type, arg2, arg3, arg4 /* [ listener || ( context + function ) || function ][ arguments ] */ ){ + var callback; + if( typeof arg2 === 'function' ){ + callback = X.Callback.create( element, arg2, arg3 ); + } else { + callback = X.Callback.create( arg2, arg3, arg4 ); + }; + callback.c = X.DomEvent._callback; // override + callback.e = element; + element.attachEvent( 'on' + type, callback ); + }) : + (function( element, type, arg2, arg3, arg4 /* [ listener || ( context + function ) || function ][ arguments ] */ ){ + var callback; + if( typeof arg2 === 'function' ){ + callback = X.Callback.create( element, arg2, arg3 ); + } else { + callback = X.Callback.create( arg2, arg3, arg4 ); + }; + if( X.DomEvent.helper( element, type, callback ) === false ){ + callback.c = X.DomEvent._callback; // override + return; + }; + helper = X.DomEvent.Dom0.find( element, type, callback ); + if( helper ){ + if( helper.list.indexOf( callback ) === -1 ) helper.list[ helper.list.length ] = callback; + } else { + new X.DomEvent.Dom0.Helper( element, type, callback ); + }; + }), + remove : + document.removeEventListener ? + (function( element, type, arg2, arg3 ){ + var callback = X.Callback.find( arg2, arg3 ); + if( callback ){ + element.removeEventListener( type, callback, false ); + X.Callback._correct( callback ); + }; + }) : + document.detachEvent ? + (function( element, type, arg2, arg3 ){ + var callback = X.Callback.find( arg2, arg3 ); + if( callback ){ + element.detachEvent( 'on' + type, callback ); + X.Callback._correct( callback ); + }; + }) : + (function( element, type, arg2, arg3 ){ + var t = X.DomEvent.Dom0.find( element, type ), + c = X.Callback.find( arg2, arg3 ), + i; + if( t && c ){ + i = t.list.indexOf( c ); + if( i !== -1 ){ + t.list.splice( i, 1 ); + X.Callback._correct( c ); + }; + if( t.list.length === 0 ){ + t.elm[ 'on' + t.type ] = X.DomEvent.Dom0.emptyFunc; + t.elm[ 'on' + t.type ] = ''; + c = X.Callback.find( t ); + X.Callback._correct( c ); + X.DomEvent.Dom0.LIST.splice( X.DomEvent.Dom0.LIST.indexOf( t ), 1 ); + delete t.elm; + delete t.type; + delete t.list; + }; + }; + }), + _callback : + window.addEventListener ? + (function( event ){ + var f = this, + r = f.callback.call( f.context, event ); + if( r !== false ) return r; + event.preventDefault(); + event.stopPropagation(); + return false; + }) : + (function(){ + var f = this, + e = window.event, + x = f.context, + r = f.callback.call( x, new X.DomEvent.xEvent( e, x.elm )); + if( r !== false ) return r; + e.cancelBubble = true; + e.returnValue = false; + return r; + }) +}; +if( !window.addEventListener ){ + X.DomEvent.xEvent = function( e, element ){ + this._event = e; + this.type = e.type; + this.target = e.srcElement; + this.currentTarget = element; + this.relatedTarget = e.formElement ? e.formElement : e.toElement; + this.eventPhase = e.srcElement === element ? 2: 3; + + this.clientX = e.clientX; + this.clientY = e.clientY; + this.screenX = e.screenX; + this.screenY = e.screenY; + + this.keyCode = e.keyCode; + this.altKey = e.altKey; + this.ctrlKey = e.ctrlKey; + this.shiftKey = e.shiftKey; + + this.wheelDelta = e.wheelDelta; + }; +}; +if( !document.addEventListener && !document.attachEvent ){ + X.DomEvent.Dom0 = { + LIST : [], + emptyFunc : new Function(), + find : function( element, type ){ + var list = X.DomEvent.Dom0.LIST, + i = list.length, + helper; + for( ; i < l; ){ + helper = list[ --i ]; + if( helper.elm === element && helper.type === type ) return helper; + }; + return null; + }, + Helper : function( elm, type, callback ){ + this.elm = elm; + this.type = type; + this.list = [ callback ]; + + var callback = elm[ 'on' + type ] = X.DomEvent.create( this ); + callback.c = X.DomEvent._callback; // override + X.DomEvent.Dom0.LIST[ X.DomEvent.Dom0.LIST.length ] = this; + } + }; + X.DomEvent.Dom0.Helper.prototype.handleEvent = function(e){ + //e = e.copy(); + var list = this.list, + i = list.length, + cancel; + for( ; i; ){ + if( list[ --i ]( e ) === false ) cancel = false; + }; + return cancel; + }; +}; \ No newline at end of file diff --git a/0.6.x/js/core/13_XViewEvent.js b/0.6.x/js/core/13_XViewEvent.js new file mode 100644 index 0000000..a71a1fa --- /dev/null +++ b/0.6.x/js/core/13_XViewEvent.js @@ -0,0 +1,18 @@ +X.ViewEvent = { + SYS_READY : 0, + INIT : 1, + ADDED : 2, + CREATION_COMPLETE : 3, + REMOVED : 4, + + VIEW_RESIZED : 7, // リサイズイベントのバブルアップは要素のレイアウトマネジャーでキャンセルされることも + IN_VIEW : 8, // 要素が視界に入った + OUT_VIEW : 9, + + _NO_BUBLEUP : 10 //-- ここ以上はノード上をバブルアップ + + // USER_CLICK + // USER_MOVE + // USER_KEYDOWN + // USER_KEYUP +}; diff --git a/0.6.x/js/core/14_XView.js b/0.6.x/js/core/14_XView.js new file mode 100644 index 0000000..4afe06a --- /dev/null +++ b/0.6.x/js/core/14_XView.js @@ -0,0 +1,113 @@ + +X.View = (function( window, document ){ + var view = X.UA.IE ? + ( document.compatMode !== "CSS1Compat" ? document.body : document.documentElement ) : window, + lock = 0, w = 0, h = 0, + resize, delayResize; + +/* ----------------------------------------------- + * Document Ready + * Dean Edwards/Matthias Miller/John Resig + */ + function init(){ + if( X.View.ready ) return; + X.View.ready = true; + X.View.dispatch( { type : X.ViewEvent.SYS_READY, w : w, h : h } ); + }; + /* for Mozilla/Opera9 */ + if( document.addEventListener ){ + document.addEventListener( "DOMContentLoaded", init, false ); + }; + if( 4 < X.UA.IE ){ + document.write( "