13 * お気に入り画像一覧 > tag:ペン次郎 > ペン次郎:笑う
14 * 最近アップロードされた画像 > images
16 * キャラクター画像庫 > アニマル系 > tag:ペン次郎 > ペン次郎:笑う
23 pettanr.file = ( function(){
24 var FILE_TYPE_IS_FOLDER = 1,
25 numFileType = FILE_TYPE_IS_FOLDER,
26 FILEDATA_RESITER = [], // store all of fileData( json object )
27 FILEDATA_ACCESS = [], // file operations for Kernel only ! hide from Out of pettanr.file
28 FILE_OBJECT_POOL = [],
29 EVENT_LISTENER_REGISTER = [],
31 TREE_ACCESS_ARRAY = [];
33 var REQUEST_CONTROLER = ( function(){
34 var REQUEST_TICKET_RESISTER = [],
37 DATA_TYPE_ARRAY = 'json,xml,html,text'.split( ','),
44 var RequestTicketClass = function( _type, _data, _url, _onLoad, _onError){
45 this.type = DATA_TYPE_ARRAY[ _type];
48 this.onLoad = _onLoad;
49 this.onError = _onError;
54 if( currentTicket !== null ) return;
55 currentTicket = REQUEST_TICKET_RESISTER.shift();
57 url: currentTicket.url,
58 dataType: currentTicket.type,
63 function onSuccess( _data ){
65 window.setTimeout( asyncSuccess, 0 );
67 function asyncSuccess(){
68 currentTicket.onLoad( currentTicket.data, currentData );
69 currentTicket = currentData = null;
70 REQUEST_TICKET_RESISTER.length !== 0 && window.setTimeout( request, 0 );
75 window.setTimeout( asyncError, 0 );
77 function asyncError(){
78 currentTicket.onError( currentTicket.data );
80 REQUEST_TICKET_RESISTER.length !== 0 && window.setTimeout( request, 0 );
83 getNumTask: function(){
84 return REQUEST_TICKET_RESISTER.length;
86 getNumError: function(){
89 getJson: function( _data, _url, _onLoad, _onError ){
90 REQUEST_TICKET_RESISTER.push( new RequestTicketClass( DATA_IS_JSON, _data, _url, _onLoad, _onError));
91 currentTicket === null && request();
98 var FILE_CONTROLER = {
99 createTree: function( _rootFileData){
100 var _tree = new TreeClass( _rootFileData);
102 TREE_ARRAY.push( _tree);
105 getFileUID: function( FILEDATAorFILE ){
106 if( FILEDATAorFILE instanceof FileClass ){
107 return FILEDATAorFILE.getUID();
110 var uid = pettanr.util.getIndex( FILEDATA_RESITER, FILEDATAorFILE );
112 uid = FILEDATA_RESITER.length;
113 FILEDATA_RESITER.push( FILEDATAorFILE );
117 getFileDataAccess: function( UIDorFILEorFILEDATA){
118 var _uid, _data, _access;
120 if( typeof UIDorFILEorFILEDATA === 'number'){
121 _data = FILEDATA_RESITER[ UIDorFILEorFILEDATA] || null;
123 if( UIDorFILEorFILEDATA instanceof FileClass){
124 _uid = UIDorFILEorFILEDATA.getUID();
125 _data = FILEDATA_RESITER[ _uid ] || null;
127 _data = UIDorFILEorFILEDATA || null;
130 if( _data === null || typeof _data !== 'object') return null;
131 for( var i=0, l = FILEDATA_ACCESS.length; i<l; ++i){
132 _access = FILEDATA_ACCESS[ i];
133 if( _access.DATA === _data) return _access;
137 getFileData: function( UIDorFILEorFILEDATA){
138 var _access = FILE_CONTROLER.getFileDataAccess( UIDorFILEorFILEDATA);
139 return _access !== null ? _access.DATA : null;
141 getChildren: function( UIDorFILEorFILEDATA){
142 var _data = FILE_CONTROLER.getFileData( UIDorFILEorFILEDATA);
143 return _data !== null ? _data.children || null : null;
145 getDriver: function( _file){
146 var _data = FILE_CONTROLER.getFileData( _file);
147 return _data !== null && _data.driver ? _data.driver : FileDriverBase;
149 getUpdateFlag: function( _file, _bit){
150 var _driver = FILE_CONTROLER.getDriver( _file ),
152 if( typeof _driver.getUpdatePolicy === 'function'){
153 _policy = _driver.getUpdatePolicy( _file );
156 if( typeof _policy !== 'number') {
157 _policy = FileDriverBase.getUpdatePolicy( _file )
159 return _policy % ( _bit * 2) >= _bit;
161 move: function( _prentUID, _targetfile, _newFolder, _newIndex, _opt_callback){
162 var _parentData = FILE_CONTROLER.getFileDataAccess( _prentUID),
163 _parentType = _parentData.TYPE,
164 _targetData = FILE_CONTROLER.getFileDataAccess( _targetfile),
165 _targetType = _targetData.TYPE;
167 replace: function( _uid, _file, _newIndex){
170 addEventListener: function( FILEorNULL, _eventType, _callback ){
171 var _uid = FILEorNULL instanceof FileClass ? FILEorNULL.getUID() : FILEorNULL;
172 EVENT_LISTENER_REGISTER.push( new FileEventTicketClass( _uid, _eventType, _callback));
174 removeEventListener: function( FILEorNULL, _eventType, _callback ){
175 var _uid = FILEorNULL instanceof FileClass ? FILEorNULL.getUID() : FILEorNULL,
177 for(var i=0, l = EVENT_LISTENER_REGISTER.length; i<l; ++i){
178 _ticket = EVENT_LISTENER_REGISTER[i];
179 if( _ticket.fileUID === _uid && _ticket.eventType === _eventType && _ticket.callBack === _callback){
180 EVENT_LISTENER_REGISTER.splice( i, 1);
185 getTreeAccess: function(){
188 fileEventRellay: function( _uid, _event ){
189 var _fileAccess = FILE_CONTROLER.getFileDataAccess( _uid );
190 if( _fileAccess === null ) return;
191 var _treeUID = _fileAccess.TREE.getUID(),
192 _treeAccess = TREE_ACCESS_ARRAY[ _treeUID ],
193 _data = _fileAccess.DATA,
195 if( !_treeAccess ) return;
196 _treeAccess.dispatchFileEvent( _event );
197 for( var i=0, l = TREE_ARRAY.length; i<l; ++i){
198 if( i !== _treeUID ){
199 _tree = TREE_ARRAY[ i ];
200 if( FILE_CONTROLER.getFileData( _tree.getCurrentFile() ) === _data ){
201 _treeAccess = TREE_ACCESS_ARRAY[ _tree.getUID() ];
202 _treeAccess && _treeAccess.dispatchFileEvent( _event );
209 var AsyncEventDispatcher = ( function(){
213 var _stack = STACK_LIST.shift();
214 _stack[ 0 ]( _stack[ 1 ], _stack[ 2 ], _stack[ 3 ], _stack[ 4 ] );
216 while( _stack.length > 0 ){
219 if( STACK_LIST.length !== 0 ){
220 window.setTimeout( dispatch, 0 );
224 addEvent: function( _callback, _eventType, _targetFile, _key, _value ){
225 if( STACK_LIST.length === 0 ){
226 window.setTimeout( dispatch, 0 );
228 STACK_LIST.push( [ _callback, _eventType, _targetFile, _key, _value ] );
233 var TreeClass = function( rootFileData ){
234 var PARENT_FILE_RESITER = [],
236 dispatchFileEvent: dispatchFileEvent
238 EVENT_LISTENER_ARRAY = [],
243 TREE_ACCESS_ARRAY.push( ACCESS );
245 function dispatchFileEvent( e ){
246 var _eventType = e.eventType,
247 _targetFile = e.targetFile,
248 _uid = _targetFile.getUID(),
249 _ticket, _type, _callback;
250 for( var i=0, l = EVENT_LISTENER_REGISTER.length; i<l; ++i ){
251 _ticket = EVENT_LISTENER_REGISTER[ i ];
252 _type = _ticket.eventType;
253 _callback = _ticket.callBack;
254 if( _eventType === _type && _uid === _ticket.fileUID ){
255 AsyncEventDispatcher.addEvent( _callback, _eventType, _targetFile, e.key, e.value );
257 if( _type === pettanr.file.TREE_EVENT.UPDATE && _eventType === pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES ){
258 AsyncEventDispatcher.addEvent( _callback, _eventType, _targetFile );
266 currentFile = rootFile = new FileClass( instance, null, rootFileData );
268 currentFile.getSeqentialFiles();
272 return pettanr.util.getIndex( TREE_ACCESS_ARRAY, ACCESS );
274 getRootFile : function(){
277 getCurrentFile: function(){
280 hierarchy: function(){
281 return PARENT_FILE_RESITER.length;
283 getParentFileAt: function( _index){
284 var l = PARENT_FILE_RESITER.length;
285 if( typeof _index !== 'number' || _index < 0 || _index >= l) return null;
286 return PARENT_FILE_RESITER[ l -1 -_index];
288 down: function( _index){
289 if( typeof _index !== 'number' || _index < 0 || _index >= currentFile.getChildFileLength()) return;
290 PARENT_FILE_RESITER.unshift( currentFile );
291 currentFile = currentFile.getChildFileByIndex( _index );
292 currentFile.getSeqentialFiles();
295 up: function( _index){
296 var l = PARENT_FILE_RESITER.length;
297 if( l === 0) return null;
300 var _currentFile = currentFile;
302 _currentFile.destroy();
304 if( typeof _index === 'number'){
305 if( _index >= l) return null;
306 currentFile = this.getParentFileAt( _index );
307 PARENT_FILE_RESITER.splice( 0, l -_index);
309 currentFile = PARENT_FILE_RESITER.shift();
311 currentFile.getSeqentialFiles();
314 addTreeEventListener: function( _eventType, _callback){
315 FILE_CONTROLER.addEventListener( null, _eventType, _callback);
317 removeTreeEventListener: function( _eventType, _callback){
318 FILE_CONTROLER.removeEventListener( null, _eventType, _callback);
321 FILE_CONTROLER.destroyTree( instance.getUID() );
323 var _currentFile = currentFile;
324 currentFile = rootFile = rootFileData = null;
325 // currentFile, rootFile を null にしないと .File.destroy() ができない.
326 _currentFile.destroy();
327 while( PARENT_FILE_RESITER.length > 0 ){
328 _currentFile = PARENT_FILE_RESITER.shift();
329 _currentFile.destroy();
336 var FileEventTicketClass = function( UID, _eventType, _callback){
338 this.eventType = _eventType;
339 this.callBack = _callback;
340 this.destroy = function(){
341 this.callBack = _callback = null;
345 var FileEventClass = function( eventType, file, key, value){
346 this.eventType = eventType;
347 this.targetFile = file;
348 this.updatedAttribute = key;
349 this.updatedValue = value;
353 * fileのdataはobjectで保持している。
354 * pettanr.file.の外からファイルをみるときは、FileClassを通して操作する。
355 * fileの変更、それに付随して追加されたイベントは、TreeClassで管理される。
356 * treeがdestryされると、fileのイベントリスナーも全て削除される。
357 * 他の tree も data の共通する currentFile に対してのみは、file の変更イベントを受け取って流す.
362 var FileClass = function( tree, parentData, data ){
363 var uid = FILE_CONTROLER.getFileUID( data ),
366 FILEDATA_ACCESS.push(
369 parentData: parentData,
371 dispatchFileEvent: dispatchEvent
375 tree = parentData = data = null;
377 function dispatchEvent( e ){
378 FILE_CONTROLER.fileEventRellay( uid, e );
380 this.getUID = function(){
385 FileClass.prototype = {
386 isChildFile: function( _FILEorFILEDATA){
387 return this.getChildFileIndex( _FILEorFILEDATA) !== -1;
389 getSeqentialFiles: function(){
390 var _driver = FILE_CONTROLER.getDriver( this );
391 if( _driver !== null && typeof _driver.getSeqentialFiles === 'function' ){
392 _driver.getSeqentialFiles( this );
395 addEventListener: function( _eventType, _callback ){
396 FILE_CONTROLER.addEventListener( this, _eventType, _callback );
398 removeEventListener: function( _eventType, _callback ){
399 FILE_CONTROLER.removeEventListener( this, _eventType, _callback );
401 getChildFileLength: function(){
402 var children = FILE_CONTROLER.getChildren( this );
403 return Type.isArray( children ) === true ? children.length : -1;
405 getChildFileIndex: function( _FILEorFILEDATA ){
406 var children = FILE_CONTROLER.getChildren( this);
407 if( Type.isArray( children ) === false ) return -1;
408 var l = children.length,
409 _fileData = FILE_CONTROLER.getFileData( _FILEorFILEDATA );
410 if( _fileData === null ) return -1;
411 for( var i=0; i<l; ++i ){
412 if( children[ i ] === _fileData ) return i;
416 getChildFileByIndex: function( _index ){
417 var _access = FILE_CONTROLER.getFileDataAccess( this ),
418 _children = FILE_CONTROLER.getChildren( this );
419 if( typeof _index !== 'number' || _index < 0 || Type.isArray( _children ) === false || _index >= _children.length) return null;
420 var _file = new FileClass( _access.TREE, _access.DATA, _children[ _index ]);
425 var driver = FILE_CONTROLER.getDriver( this );
426 if( typeof driver.getName === 'function'){
427 return driver.getName( this );
429 return FileDriverBase.getName( this);
431 getThumbnail: function(){
432 var driver = FILE_CONTROLER.getDriver( this);
433 if( typeof driver.getThumbnail === 'function'){
434 return driver.getThumbnail( this);
436 return FileDriverBase.getThumbnail( this);
439 var _data = FILE_CONTROLER.getFileData( this);
440 return typeof _data.type === 'number' ? _data.type : pettanr.file.FILE_TYPE.UNKNOWN;
442 getState: function(){
443 var _data = FILE_CONTROLER.getFileData( this);
444 return typeof _data.state === 'number' ? _data.state : pettanr.file.FILE_STATE.OK;
446 getSummary: function(){
447 var driver = FILE_CONTROLER.getDriver( this );
448 if( typeof driver.getSummary === 'function'){
449 return driver.getSummary( this );
451 return FileDriverBase.getSummary( this);
453 isWritable: function(){
454 return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.WRITE );
456 isSortable: function(){
457 return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.SORT );
459 isCreatable: function(){
460 return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.CREATE );
462 isRenamable: function(){
463 return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.RENAME );
465 isDeletable: function(){
466 return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.DELETE );
470 var driver = FILE_CONTROLER.getDriver( this );
471 if( typeof driver.read === 'function'){
472 return driver.read( this );
474 return FileDriverBase.read( this );
476 write: function( _newData, _onUpdateFunction ){
477 var driver = FILE_CONTROLER.getDriver( this );
478 if( typeof driver.write === 'function'){
479 return driver.write( this, _newData, _onUpdateFunction );
481 return FileDriverBase.write( this, _newData, _onUpdateFunction );
483 viewerApplicationList: function(){
484 var driver = FILE_CONTROLER.getDriver( this );
485 if( typeof driver.viewerApplicationList === 'function'){
486 return driver.viewerApplicationList( this );
488 return FileDriverBase.viewerApplicationList( this );
490 editorApplicationList: function(){
491 var driver = FILE_CONTROLER.getDriver( this );
492 if( typeof driver.editorApplicationList === 'function'){
493 return driver.editorApplicationList( this );
495 return FileDriverBase.viwerApps( this );
506 onDelete: function(){
509 move: function( _newFolder, _newIndex, opt_callback ){
510 var _access = FILE_CONTROLER.getFileDataAccess( this );
511 _access.TREE.move( _access.parentData, this.getUID(), _newFolder, _newIndex, opt_callback );
513 replace: function( _newIndex, opt_callback ){
514 var _access = FILE_CONTROLER.getFileDataAccess( this );
515 _access.TREE.replace( _access.parentData, this.getUID(), _newIndex, opt_callback);
519 * 探しているファイルの属性と値を指定.一致する child の index を配列で返す.
521 search: function( obj, rule ){
522 var _children = FILE_CONTROLER.getChildren( this ),
525 for( var i=0, l=_children.length; i<l; ++i ){
526 _child = _children[ i ];
529 if( obj[ k ] !== _child[ k ] ){
534 c === true && ret.push( i );
539 var _access = FILE_CONTROLER.getFileDataAccess( this );
540 var TREE = _access.TREE;
541 if( TREE.getCurrentFile() === this ) return;
542 if( TREE.getRootFile() === this ) return;
543 for( var i=0, l = TREE.hierarchy(); i<l; ++i ){
544 if( TREE.getParentFileAt( i ) === this ){
548 var _index = pettanr.util.getIndex( FILEDATA_ACCESS, _access );
549 if( _index === -1 || _access === null ) return;
551 FILEDATA_ACCESS.splice( _index, 1 );
554 delete _access.parentData;
555 delete _access.dispatchFileEvent;
562 var FileDriverBase = {
563 getSeqentialFiles: function( _file){
565 getName: function( _file){
566 var _data = FILE_CONTROLER.getFileData( _file);
567 return _data.name || 'No Name';
569 getThumbnail: function( _file){
570 var _data = FILE_CONTROLER.getFileData( _file),
573 if( _type === pettanr.file.FILE_TYPE.FOLDER){
574 _className = 'folder';
576 if( _type === pettanr.file.FILE_TYPE.IMAGE){
579 if( _type === pettanr.file.FILE_TYPE.TEXT){
582 if( _type === pettanr.file.FILE_TYPE.HTML){
585 if( _type === pettanr.file.FILE_TYPE.CSV){
588 if( _type === pettanr.file.FILE_TYPE.JSON){
591 if( _type === pettanr.file.FILE_TYPE.XML){
596 className: ' file-type-' + _className
599 getSummary: function( _file ){
600 var _data = FILE_CONTROLER.getFileData( _file ),
602 if( _type === pettanr.file.FILE_TYPE.FOLDER){
605 if( _type === pettanr.file.FILE_TYPE.IMAGE){
608 if( _type === pettanr.file.FILE_TYPE.TEXT){
611 if( _type === pettanr.file.FILE_TYPE.HTML){
612 return 'html document file';
614 if( _type === pettanr.file.FILE_TYPE.CSV){
615 return 'csv daat file';
617 if( _type === pettanr.file.FILE_TYPE.JSON){
618 return 'json data file';
620 if( _type === pettanr.file.FILE_TYPE.XML){
621 return 'xml data file';
625 getUpdatePolicy: function( _file ){
627 return pettanr.file.FILE_UPDATE_POLICY.DSRWC;
629 read: function( _file ){
630 var data = FILE_CONTROLER.getFileData( _file ),
631 protects = pettanr.file.FILE_DATA_PROPERTY_RESERVED;
633 function clone( src ) {
635 if( Type.isArray(src) === true ){
638 if( Type.isObject(src) === true ){
641 if( Type.isNumber(src) === true || Type.isString(src) === true || Type.isBoolean( src ) === true ){
646 for( var key in src ){
647 if( pettanr.util.getIndex( protects, key ) === -1 ){
649 ret[ key ] = clone( src[ key ]);
655 return clone( data );
657 write: function( _file, _newData, _onUpdateFunction ){
658 var _data = FILE_CONTROLER.getFileData( _file ),
662 viewerApplicationList: function(){
665 editorApplicationList: function(){
668 onCreate: function(){
677 onDelete: function(){
682 var ROOT_FILEDATA = {
684 type: FILE_TYPE_IS_FOLDER,
687 SYSTEM_TREE = FILE_CONTROLER.createTree( ROOT_FILEDATA),
688 ROOT_FILE = SYSTEM_TREE.getRootFile();
690 function createFolderUnderRoot( _fileData){
691 ROOT_FILEDATA.children.push( _fileData);
692 FILE_CONTROLER.getFileDataAccess( ROOT_FILE)
693 .dispatchFileEvent( new FileEventClass( pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES, ROOT_FILE, 'children', null));
695 function createFileEvent( _eventType, _file, _key, _value){
696 return new FileEventClass( _eventType, _file, _key, _value);
698 function createFileTypeID(){
699 return ++numFileType;
704 //REQUEST_CONTROLER.init();
705 //FILE_CONTROLER.init();
706 delete pettanr.file.init;
708 registerDriver: function( _driver ){
709 _driver.prototype = FileDriverBase;
714 createFolderUnderRoot: createFolderUnderRoot,
715 getFileDataAccess: FILE_CONTROLER.getFileDataAccess,
716 getFileData: FILE_CONTROLER.getFileData,
717 getJson: REQUEST_CONTROLER.getJson,
718 createFileEvent: createFileEvent,
719 createFileTypeID: createFileTypeID
722 createTree: function( _rootFile){
723 return FILE_CONTROLER.createTree( _rootFile);
725 isTreeInstance: function( _tree){
726 return _tree instanceof TreeClass;
728 isFileInstance: function( _file){
729 return _file instanceof FileClass;
733 FOLDER: FILE_TYPE_IS_FOLDER,
734 IMAGE: createFileTypeID(),
735 TEXT: createFileTypeID(),
736 HTML: createFileTypeID(),
737 CSV: createFileTypeID(),
738 JSON: createFileTypeID(),
739 XML: createFileTypeID()
748 FILE_UPDATE_POLICY: {
749 _____: parseInt( '00000', 2),
750 ____C: parseInt( '00001', 2), // hasCreateMenu
751 ___W_: parseInt( '00010', 2), // isWritable
752 ___WC: parseInt( '00011', 2), // isWritable
753 __R__: parseInt( '00100', 2), // isRenamable
754 __R_C: parseInt( '00101', 2), // hasCreateMenu
755 __RW_: parseInt( '00110', 2), // isWritable
756 __RWC: parseInt( '00111', 2), // isWritable
757 _S___: parseInt( '01000', 2), // childrenIsSortable
758 _S__C: parseInt( '01001', 2),
759 _S_W_: parseInt( '01010', 2),
760 _S_WC: parseInt( '01011', 2),
761 _SR__: parseInt( '01100', 2),
762 _SR_C: parseInt( '01101', 2),
763 _SRW_: parseInt( '01110', 2),
764 _SRWC: parseInt( '01111', 2),
765 D____: parseInt( '10000', 2),
766 D___C: parseInt( '10001', 2), // hasCreateMenu
767 D__W_: parseInt( '10010', 2), // isWritable
768 D__WC: parseInt( '10011', 2), // isWritable
769 D_R__: parseInt( '10100', 2), // isRenamable
770 D_R_C: parseInt( '10101', 2), // hasCreateMenu
771 D_RW_: parseInt( '10110', 2), // isWritable
772 D_RWC: parseInt( '10111', 2), // isWritable
773 DS___: parseInt( '11000', 2), // childrenIsSortable
774 DS__C: parseInt( '11001', 2),
775 DS_W_: parseInt( '11010', 2),
776 DS_WC: parseInt( '11011', 2),
777 DSR__: parseInt( '11100', 2),
778 DSR_C: parseInt( '11101', 2),
779 DSRW_: parseInt( '11110', 2),
780 DSRWC: parseInt( '11111', 2),
788 UPDATE: 'onTreeUpdate'
791 UPDATE_ATTRIVUTE: 'onFileUpdate',
792 GET_SEQENTIAL_FILES:'gotSeqentilFiles'
794 FILE_DATA_PROPERTY_RESERVED: [
795 'children', 'driver', 'state', 'type'
800 pettanr.finder = ( function(){
801 var FINDER_ARRAY = [],
802 ELM_ORIGIN_FINDER_LOCATION_ITEM = pettanr.util.pullHtmlAsTemplete( 'templete-finder-location-item'),
803 ELM_ORIGIN_FINDER_ICON = ( function(){
804 var forIE = pettanr.util.pullHtmlAsTemplete( 'templete-finder-icon-ie'),
805 modern = pettanr.util.pullHtmlAsTemplete( 'templete-finder-icon');
806 return pettanr.ua.isIE === true && pettanr.ua.ieVersion < 8 ? forIE : modern;
808 ELM_ORIGIN_CONTAINER = pettanr.util.pullHtmlAsTemplete( 'templete-finder-container'),
809 ICON_HEIGHT = pettanr.util.getElementSize( ELM_ORIGIN_FINDER_ICON).height,
810 ICON_CLASSNAME = 'finder-icon-thumbnail',
811 FINDER_ICON_POOL = [],
812 BREAD_OBJECT_POOL = [];
814 var FinderIconClass = function(){
816 ELM_WRAPPER = ELM_ORIGIN_FINDER_ICON.cloneNode( true),
817 ELM_THUMBNAIL = pettanr.util.getElementsByClassName( ELM_WRAPPER, ICON_CLASSNAME )[0],
818 ELM_FILENAME = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-filename' )[0],
819 ELM_DESCRIPTION = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-summary' )[0],
820 ELM_EDITOR_BUTTON = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-console-editor-apps' )[0],
821 ELM_VIEWER_BUTTON = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-console-viewer-apps' )[0],
822 ELM_ACTION_BUTTON = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-console-action' )[0],
823 file, w, index, style, instansce,
824 onDownCallback, onEditorCallback, onViewerCallback, onActionCallback,
825 viewerList, editorList;
827 ELM_WRAPPER.onclick = onDownClick;
828 function onDownClick(){
829 onDownCallback( index);
832 ELM_EDITOR_BUTTON.onclick = onEditorClick;
833 function onEditorClick(){
834 onEditorCallback( file, editorList[ 0 ] );
837 ELM_VIEWER_BUTTON.onclick = onViwerClick;
838 function onViwerClick(){
839 onViewerCallback( file, viewerList[ 0 ] );
842 ELM_ACTION_BUTTON.onclick = onActionClick;
843 function onActionClick(){
844 onActionCallback( file );
848 var _thumb = file.getThumbnail();
850 ELM_THUMBNAIL.className = ICON_CLASSNAME + ' has-thumbnail';
851 ELM_THUMBNAIL.style.backgroundImage = [ 'url(', _thumb.image, ')'].join( '');
853 ELM_THUMBNAIL.className = ICON_CLASSNAME + ' ' + _thumb.className;
854 ELM_THUMBNAIL.style.backgroundImage = '';
856 ELM_FILENAME.firstChild.data = file.getName();
857 ELM_DESCRIPTION.firstChild.data = file.getSummary();
859 if( Type.isArray( viewerList ) === true && viewerList.length > 0 ){
860 ELM_VIEWER_BUTTON.style.display = '';
862 ELM_VIEWER_BUTTON.style.display = 'none';
864 if( Type.isArray( editorList ) === true && editorList.length > 0 ){
865 ELM_EDITOR_BUTTON.style.display = '';
867 ELM_EDITOR_BUTTON.style.display = 'none';
871 // ELM_WRAPPER.style.top = (index * ICON_HEIGHT) +'px';
873 function onCollect(){
874 elmContainer.removeChild( ELM_WRAPPER );
876 FINDER_ICON_POOL.push( instansce );
880 init: function( _file, _elmContainer, _w, _index, _style, _onDownCallback, _onEditorCallback, _onViewerCallback, _onActionCallback ){
882 if( elmContainer !== _elmContainer){
883 _elmContainer.appendChild( ELM_WRAPPER);
884 elmContainer = _elmContainer;
887 file && file.destroy();
889 viewerList = file.viewerApplicationList();
890 editorList = file.editorApplicationList();
893 if( index !== _index){
897 onDownCallback = _onDownCallback;
898 onEditorCallback = _onEditorCallback;
899 onViewerCallback = _onViewerCallback;
900 onActionCallback = _onActionCallback;
903 index: function( _index){
907 style: function( _style){
911 onResize: function( w ){
915 elmContainer.removeChild( ELM_WRAPPER );
916 file && file.destroy();
917 file = elmContainer = onDownCallback = onEditorCallback = onViewerCallback = onActionCallback = viewerList = editorList = null;
918 FINDER_ICON_POOL.push( instansce);
922 function updateIconPosition( _style, _w, _index, _elm){
925 var BreadcrumbClass = function(){
927 ELM_WRAPPER = ELM_ORIGIN_FINDER_LOCATION_ITEM.cloneNode( true),
928 ELM_FILENAME = ELM_WRAPPER.getElementsByTagName( 'a')[0],
929 file, w, index, instansce,
931 ELM_WRAPPER.onclick = onClick;
933 ELM_FILENAME.className = 'file-icon-' +file.getType();
934 ELM_FILENAME.innerHTML = file.getName();
936 function resize( index){
937 ELM_WRAPPER.style.left = (index * 90) +'px';
945 init: function( _file, _elmContainer, _index, _callback ){
947 if( elmContainer !== _elmContainer ){
948 _elmContainer.appendChild( ELM_WRAPPER);
949 elmContainer = _elmContainer;
955 if( index !== _index){
959 callback = _callback;
962 index: function( _index){
966 onResize: function( w){
970 elmContainer.removeChild( ELM_WRAPPER);
971 file = elmContainer = null;
972 BREAD_OBJECT_POOL.push( this );
977 var FinderClass = function( ELM_CONTAINER, tree, header, footer ){
980 elmContainer = ELM_ORIGIN_CONTAINER.cloneNode( true ),
981 elmLocation = elmContainer.getElementsByTagName( 'ul' )[0],
982 nodesDiv = elmContainer.getElementsByTagName( 'div' ),
983 elmSidebarButton = nodesDiv[1],
984 elmStyleButton = nodesDiv[2],
985 elmActionButton = nodesDiv[3],
986 elmBody = nodesDiv[ nodesDiv.length -1 ],
987 //tree = pettanr.file.createTree( TREE_TYPE),
990 headH = pettanr.util.getElementSize( nodesDiv[0] ).height,
994 size = pettanr.util.getElementSize( ELM_ORIGIN_FINDER_ICON ),
1001 tree.addTreeEventListener( pettanr.file.TREE_EVENT.UPDATE, draw );
1002 ELM_CONTAINER.appendChild( elmContainer );
1004 function draw( _w, _h ){
1005 w = Type.isFinite( _w ) === true ? _w : w;
1006 h = Type.isFinite( _h ) === true ? _h : h;
1008 var l = tree.hierarchy() +1,
1009 m = BREAD_ARRAY.length,
1011 for(var i=0; i<l; ++i){
1012 _file = i !== l-1 ? tree.getParentFileAt( i) : tree.getCurrentFile();
1014 BREAD_ARRAY[ i].init( _file, elmLocation, i, onHeadClick);
1016 BREAD_ARRAY.push( getBreadcrumb( _file, elmLocation, i, onHeadClick ));
1019 while( l < BREAD_ARRAY.length){
1020 BREAD_ARRAY.pop().destroy();
1023 l = _file.getChildFileLength();
1024 m = ICON_ARRAY.length;
1026 for( i=0; i<l; ++i){
1028 ICON_ARRAY[ i ].init( _file.getChildFileByIndex( i), elmBody, w, i, style, onDown, onEditor, onViwer, onAction );
1030 ICON_ARRAY.push( getFinderIcon( _file.getChildFileByIndex( i), elmBody, _w, i, style, onDown, onEditor, onViwer, onAction ));
1033 if( _file.getState() === pettanr.file.FILE_STATE.LOADING ){
1034 elmBody.className = 'finder-body loading';
1036 elmBody.className = 'finder-body';
1039 elmBody.style.height = bodyH + 'px';
1041 while( l < ICON_ARRAY.length){
1042 ICON_ARRAY.pop().destroy();
1046 function onHeadClick( i){
1047 var l = BREAD_ARRAY.length -1;
1049 var _file = tree.getParentFileAt( i);
1050 if( _file !== null){
1056 function onDown( i ){
1057 if( i < ICON_ARRAY.length ){
1058 var _file = tree.getCurrentFile().getChildFileByIndex( i );
1059 if( _file !== null && ( _file.getChildFileLength() !== -1 || _file.getType() === pettanr.file.FILE_TYPE.FOLDER)){
1065 function onEditor( _file, _app ){
1068 function onViwer( _file, _app ){
1069 _app.bootInOverlay( _file );
1071 function onAction( _file ){
1074 this.rootElement = elmContainer;
1075 this.parentElement = ELM_CONTAINER;
1076 this.displayName = 'finder';
1078 this.MIN_WIDTH = 240;
1079 this.MIN_HEIGHT = 240;
1080 this.init = function(){
1081 //$( elmLocation).click( onHeadClick);
1082 //$( elmContainer).click( onBodyClick);
1083 var position = pettanr.util.getAbsolutePosition( elmLocation );
1086 bodyY = pettanr.util.getAbsolutePosition( elmBody ).y;
1087 delete instance.init;
1089 this.onPaneResize = function( _w, _h ){
1090 instance.init && instance.init();
1095 elmBody.style.height = ( _h - headH ) + 'px';
1097 for(var i=0, l=ICON_ARRAY.length; i<l; ++i){
1098 ICON_ARRAY[ i].onResize( _w );
1102 FinderClass.prototype = pettanr.view._getAbstractApplication();
1104 function getFinderIcon( _file, _elmContainer, w, index, style, onDown, onEditor, onViwer, onAction){
1106 if( FINDER_ICON_POOL.length > 0){
1107 _icon = FINDER_ICON_POOL.shift();
1109 _icon = new FinderIconClass();
1111 _icon.init( _file, _elmContainer, w, index, style, onDown, onEditor, onViwer, onAction );
1115 function getBreadcrumb( _file, _elmContainer, index, callback){
1117 if( BREAD_OBJECT_POOL.length > 0){
1118 _bread = BREAD_OBJECT_POOL.shift();
1120 _bread = new BreadcrumbClass();
1122 _bread.init( _file, _elmContainer, index, callback);
1130 createFinder: function( _applicationReference, _elmTarget, _tree, _header, _footer ){
1131 if( pettanr.view.isApplicationReference( _applicationReference ) === false ) return;
1133 var _finder = new FinderClass( _elmTarget, _tree, _header, _footer );
1134 FINDER_ARRAY.push( _finder );
1137 registerFinderHead: function(){
1140 registerFinderPane: function( _finderPane){
1143 isFinderInstance: function( _finder){
1144 return _finder instanceof FinderClass;
1146 isFinderPaneInstance: function(){
1149 isFinderHeadInstance: function(){
1155 pettanr.driver = ( function(){
1156 var MyAuthorID = 'current_author' in window ? current_author.id : ( pettanr.DEBUG ? 1 : -1 ),
1157 MyArtistID = 'current_artist' in window ? current_artist.id : ( pettanr.DEBUG ? 1 : -1 ),
1159 getSeqentialFiles: function( _file){
1160 var _data = FileAPI.getFileData( _file),
1161 _json = _data !== null ? _data.json : null;
1162 if( _json === true && _data.type === pettanr.driver.FILE_TYPE.COMIC ){
1163 if( pettanr.LOCAL === true ){
1164 _json = [ 'json\/comics_', _data.id, '.json' ].join( '' );
1166 _json = [ pettanr.CONST.PETTANR_ROOT_PATH, 'comics\/', _data.id, '.json\/play\/' ].join( '' );
1169 if( typeof _json === 'string'){
1170 FileAPI.getJson( _file, _json, onLoadJson, onErrorJson);
1171 _data.state = pettanr.file.FILE_STATE.LOADING;
1176 getName: function( _file){
1177 var _data = FileAPI.getFileData( _file),
1178 _type = _data !== null ? _data.type : null;
1179 if( _type === pettanr.driver.FILE_TYPE.PICTURE ){
1180 return [ _data.id, _data.ext ].join( '.');
1182 if( _type === pettanr.driver.FILE_TYPE.PANEL ){
1183 return [ _data.t, ':', _data.comic.title ].join( '');
1185 if( _type === pettanr.driver.FILE_TYPE.COMIC ){
1188 if( _type === pettanr.driver.FILE_TYPE.ARTIST ){
1189 return [ _data.name, '画伯' ].join( '');
1191 if( _type === pettanr.driver.FILE_TYPE.AUTHOR ){
1192 return [ _data.name, '先生' ].join( '');
1196 getThumbnail: function( _file){
1197 var _data = FileAPI.getFileData( _file),
1198 _type = _data !== null ? _data.type : null;
1199 if( _type === pettanr.driver.FILE_TYPE.PICTURE){
1200 return { image: [ pettanr.CONST.RESOURCE_PICTURE_PATH, 'thumbnail/', _data.id, '.', _data.ext ].join( '')};
1202 if( _data === FILE_DATA_COMICS_ROOT){
1203 return { className: 'file-type-cabinet'};
1205 if( _type === pettanr.driver.FILE_TYPE.COMIC){
1206 return { className: 'file-type-comic'};
1208 if( _type === pettanr.driver.FILE_TYPE.PANEL){
1209 return { className: 'file-type-panel'};
1211 if( _type === pettanr.driver.FILE_TYPE.AUTHOR){
1212 return { className: 'file-type-author'};
1214 if( _type === pettanr.driver.FILE_TYPE.ARTIST){
1215 return { className: 'file-type-artist'};
1217 if( _type === pettanr.file.FILE_TYPE.FOLDER){
1218 return { className: 'file-type-folder'};
1220 return { className: 'file-type-broken'};
1222 getSummary: function( _file ){
1223 var _data = FileAPI.getFileData( _file),
1224 _type = _data !== null ? _data.type : null;
1225 if( _type === pettanr.driver.FILE_TYPE.PICTURE){
1226 return [ _data.width, 'x', _data.height, ', filesize:', _data.filesize, ', lisence:', _data.license ].join( '' );
1228 if( _data === FILE_DATA_COMICS_ROOT){
1229 return 'cabinet file';
1231 if( _type === pettanr.driver.FILE_TYPE.COMIC){
1232 return 'comic file, id:' + _data.id;
1234 if( _type === pettanr.driver.FILE_TYPE.PANEL){
1235 return [ _data.width, 'x', _data.height ].join( '' );
1237 if( _type === pettanr.driver.FILE_TYPE.AUTHOR){
1238 return 'author file, id:' + _data.id;
1240 if( _type === pettanr.driver.FILE_TYPE.ARTIST){
1241 return [ 'id:', _data.id, ' Email:', _data.email || 'empty' , ', HP:', _data.homepage_url || 'empty' ].join( '' );
1243 if( _type === pettanr.file.FILE_TYPE.FOLDER){
1244 return 'pettanR folder';
1246 return 'pettanR unknown file';
1248 write: function( _file, _newData, _onUpdateFunction ){
1249 var _data = FileAPI.getFileData( _file ),
1250 _type = _data !== null ? _data.type : null;
1251 if( _type === pettanr.driver.FILE_TYPE.COMIC ){
1253 if( _type === pettanr.driver.FILE_TYPE.PANEL ){
1255 if( _type === pettanr.driver.FILE_TYPE.PANEL_PICTURE ){
1258 if( _type === pettanr.driver.FILE_TYPE.BALLOON ){
1260 if( _type === pettanr.driver.FILE_TYPE.PICTURE ){
1263 viewerApplicationList: function( _file ){
1264 var _data = FileAPI.getFileData( _file ),
1265 _type = _data !== null ? _data.type : null;
1267 if( _data === FILE_DATA_MY_PICTURES_ROOT ){
1268 return [ pettanr.premiumSatge ];
1270 if( _type === pettanr.driver.FILE_TYPE.ARTIST ){
1271 return [ pettanr.premiumSatge ];
1275 editorApplicationList: function( _file ){
1276 var _data = FileAPI.getFileData( _file ),
1277 _type = _data !== null ? _data.type : null;
1278 if( _type === pettanr.driver.FILE_TYPE.PANEL ){
1279 return [ pettanr.editor ];
1281 if( _type === pettanr.driver.FILE_TYPE.COMIC ){
1282 return [ pettanr.editor, pettanr.comicConsole ];
1287 FileAPI = pettanr.file.registerDriver( Driver ),
1288 FILE_DATA_SERVICE_ROOT = {
1289 name: 'PettanR root',
1290 type: pettanr.file.FILE_TYPE.FOLDER,
1293 FILE_DATA_COMICS_ROOT = {
1295 type: pettanr.file.FILE_TYPE.FOLDER,
1298 json: pettanr.CONST.URL_COMICS_JSON
1300 FILE_DATA_PANELS_ROOT = {
1302 type: pettanr.file.FILE_TYPE.FOLDER,
1305 json: pettanr.CONST.URL_PANELS_JSON
1307 FILE_DATA_PICTURE_ROOT = {
1309 type: pettanr.file.FILE_TYPE.FOLDER,
1312 json: pettanr.CONST.URL_RESOURCE_PICTURES_JSON
1314 FILE_DATA_MY_COMICS_ROOT = {
1316 type: pettanr.file.FILE_TYPE.FOLDER,
1321 FILE_DATA_LATEST_COMICS = {
1322 name: 'Latest Comics',
1323 type: pettanr.file.FILE_TYPE.FOLDER,
1326 FILE_DATA_MY_PICTURES_ROOT = {
1327 name: 'My Pictures',
1328 type: pettanr.file.FILE_TYPE.FOLDER,
1331 json: pettanr.CONST.URL_ORIGINAL_PICTURES_JSON,
1334 FILE_DATA_AUTHOR_ROOT = {
1336 type: pettanr.file.FILE_TYPE.FOLDER,
1339 FILE_DATA_ARTIST_ROOT = {
1341 type: pettanr.file.FILE_TYPE.FOLDER,
1344 FILE_DATA_LISENCE_ROOT = {
1345 name: 'Original Lisences',
1346 type: pettanr.file.FILE_TYPE.FOLDER,
1349 FILE_DATA_BALLOON_ROOT = {
1350 name: 'Balloon templetes',
1351 type: pettanr.file.FILE_TYPE.FOLDER,
1358 RESOURCE_PICTURE_ARRAY = [],
1359 BALLOON_TEMPLETE_ARRAY = [],
1360 ORIGINAL_LICENSE_ARRAY = [],
1361 BASIC_LICENSES = 'cc_by,cc_nc,cc_nd,cc_sa,keep_aspect_ratio,no_convert,no_flip,no_resize'.split( ',');
1362 FILE_DATA_SERVICE_ROOT.children.push( FILE_DATA_COMICS_ROOT, FILE_DATA_PICTURE_ROOT, FILE_DATA_PANELS_ROOT, FILE_DATA_LISENCE_ROOT, FILE_DATA_BALLOON_ROOT);
1363 FILE_DATA_COMICS_ROOT.children.push( FILE_DATA_MY_COMICS_ROOT, FILE_DATA_LATEST_COMICS, FILE_DATA_AUTHOR_ROOT);
1364 FILE_DATA_PICTURE_ROOT.children.push( FILE_DATA_MY_PICTURES_ROOT, FILE_DATA_ARTIST_ROOT);
1366 FileAPI.createFolderUnderRoot( FILE_DATA_SERVICE_ROOT);
1368 function onLoadJson( _file, _json ){
1369 var _access = FileAPI.getFileDataAccess( _file),
1370 _data = _access !== null ? _access.DATA : null,
1372 if( _data === null){
1373 onErrorJson( _file);
1376 _data.state = pettanr.file.FILE_STATE.OK;
1378 if( Type.isArray( _json ) === true ){
1380 if( l === 0) return;
1381 for( var i=0; i<l; ++i ){
1382 buildFileData( _json[ i], _data);
1386 buildFileData( _json, _data );
1388 _access.dispatchFileEvent( FileAPI.createFileEvent( pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES, _file, 'children', null));
1390 function onErrorJson( _file ){
1391 var _data = FileAPI.getFileData( _file);
1392 if( _data !== null){
1393 _data.state = pettanr.file.FILE_STATE.ERROR;
1396 function buildFileData( _data, _parent ){
1399 if( _parent === FILE_DATA_PANELS_ROOT ){
1400 _data.type = pettanr.driver.FILE_TYPE.PANEL;
1401 _array = PANEL_ARRAY;
1404 if( _parent === FILE_DATA_COMICS_ROOT ){
1405 _data.type = pettanr.driver.FILE_TYPE.COMIC;
1406 _array = COMIC_ARRAY;
1408 if( _parent.type === pettanr.driver.FILE_TYPE.COMIC ){
1409 _array = COMIC_ARRAY;
1412 if( _parent === FILE_DATA_LISENCE_ROOT ){
1413 _data.type = pettanr.driver.FILE_TYPE.LICENSE;
1414 _array = ORIGINAL_LICENSE_ARRAY;
1417 if( _parent === FILE_DATA_AUTHOR_ROOT ){
1418 _data.type = pettanr.driver.FILE_TYPE.AUTHOR;
1419 _array = AUTHOR_ARRAY;
1422 if( _parent === FILE_DATA_ARTIST_ROOT ){
1423 _data.type = pettanr.driver.FILE_TYPE.ARTIST;
1424 _array = ARTIST_ARRAY;
1427 if( _parent === FILE_DATA_PICTURE_ROOT || _parent === FILE_DATA_MY_PICTURES_ROOT ){
1428 _data.type = pettanr.driver.FILE_TYPE.PICTURE;
1429 _array = RESOURCE_PICTURE_ARRAY;
1430 // original_license を含まなければ、license object を削除して ビットデータ で保持
1431 // original_license なら ファイルを作る buildFileData( _license, FILE_DATA_LISENCE_ROOT)
1432 var _license = _data.license,
1434 _Math_pow = Math.pow,
1436 if( typeof _license === 'object'){
1437 for( i=0, l=BASIC_LICENSES.length; i<l; ++i){
1438 _rule = _license[ BASIC_LICENSES[ i]]
1439 if( typeof _rule === 'number' && _rule === 1 ){
1440 _bits += _Math_pow( 2, i);
1443 _data.license = _bits;
1449 _data.driver = Driver;
1451 // _array に _data を格納 または 上書き
1452 if( typeof _data.id === 'number' && _data.id > 0 ){
1453 var _id = _data.id - 1,
1454 __data = _array[ _id ],
1455 _reserved = pettanr.file.FILE_DATA_PROPERTY_RESERVED.join( ', ' );
1457 for( var key in _data){
1458 if( _reserved.indexOf( key ) === -1 ){
1459 __data[ key ] = _data[ key ];
1462 _data = __data; // このタイミングで参照が切れるので注意!!
1464 _array[ _id ] = _data;
1472 if( _parent === FILE_DATA_AUTHOR_ROOT || _parent === FILE_DATA_ARTIST_ROOT ){
1473 addChildData( _parent, _data );
1476 if( _parent.type === pettanr.driver.FILE_TYPE.COMIC || _parent === FILE_DATA_COMICS_ROOT ){
1477 var _panels = _data.panels,
1479 if( _panels && Type.isArray( _panels ) === true ){
1481 for( i=0, l=_panels.length; i<l; ++i){
1482 _panel = buildFileData( _panels[ i ], FILE_DATA_PANELS_ROOT );
1486 addChildData( _data, _panel );
1488 delete _data.panels;
1490 if( _data.json !== null ){
1493 if( Type.isArray( _data.children ) === false ){
1494 _data.children = [];
1497 var _author = _data.author || getResource( AUTHOR_ARRAY, _data.author_id );
1499 _data.author = _author = buildFileData( _author, FILE_DATA_AUTHOR_ROOT );
1500 addChildData( _author, _data );
1501 _author.id === MyAuthorID && addChildData( FILE_DATA_MY_COMICS_ROOT, _data );
1503 if( _parent === FILE_DATA_COMICS_ROOT ){
1504 addChildData( FILE_DATA_LATEST_COMICS, _data);
1508 if( _parent === FILE_DATA_PANELS_ROOT ){
1509 _data.comic = getResource( COMIC_ARRAY, _data.comic_id );
1510 _data.author = getResource( AUTHOR_ARRAY, _data.author_id );
1512 // picture data をファイルに取り出し
1513 var _elements = _data.panel_elements,
1515 if( Type.isArray( _elements ) === true ){
1516 for( i=0, l=_elements.length; i<l; ++i){
1517 _elm = _elements[ i];
1518 if( _elm.resource_picture ){
1519 _elm.resource_picture = buildFileData( _elm.resource_picture, FILE_DATA_PICTURE_ROOT ); // 上記参照切れに備えてここで上書き
1521 _elm.resource_picture = getResource( RESOURCE_PICTURE_ARRAY, _elm.resource_picture_id );
1527 if( _data.type == pettanr.driver.FILE_TYPE.PICTURE ){
1528 var _artist = _data.artist || getResource( ARTIST_ARRAY, _data.artist_id );
1530 _data.artist = _artist = buildFileData( _artist, FILE_DATA_ARTIST_ROOT );
1531 addChildData( _artist, _data );
1532 if( _artist.id === MyArtistID ){
1533 addChildData( FILE_DATA_MY_PICTURES_ROOT, _data );
1534 //FILE_DATA_MY_PICTURES_ROOT.type = pettanr.driver.FILE_TYPE.ARTIST;
1535 //FILE_DATA_MY_PICTURES_ROOT.id = MyArtistID;
1541 function addChildData( _parent, _child ){
1542 if( Type.isArray( _parent.children ) === false){
1543 _parent.children = [];
1545 pettanr.util.getIndex( _parent.children, _child ) === -1 && _parent.children.push( _child );
1547 function getResource( _array, _id ){
1548 if( Type.isArray( _array ) === false || Type.isNumber( _id ) === false || _id < 1 ) return null;
1549 var _data = _array[ _id - 1 ];
1551 _data = _array[ _id - 1 ] = {};
1557 createComicTree: function(){
1558 return pettanr.file.createTree( FILE_DATA_SERVICE_ROOT ); //FILE_DATA_COMICS_ROOT);
1560 createPictureTree: function(){
1561 return pettanr.file.createTree( FILE_DATA_PICTURE_ROOT );
1563 createArtistTree: function(){
1564 return pettanr.file.createTree( FILE_DATA_ARTIST_ROOT );
1566 createServiceTree: function(){
1567 return pettanr.file.createTree( FILE_DATA_SERVICE_ROOT );
1569 isPettanrFileInstance: function( _file ){
1570 if( pettanr.file.isFileInstance( _file ) === true){
1571 var _data = FileAPI.getFileData( _file);
1572 return _data !== null && _data.driver === Driver;
1576 _getAPI: function(){
1579 _getPictureRootData: function(){
1580 return FILE_DATA_PICTURE_ROOT;
1582 _getMyPicturesData: function(){
1583 return FILE_DATA_MY_PICTURES_ROOT;
1586 COMIC: FileAPI.createFileTypeID(),
1587 PANEL: FileAPI.createFileTypeID(),
1588 PICTURE: FileAPI.createFileTypeID(),
1589 PANEL_PICTURE: FileAPI.createFileTypeID(),
1590 BALLOON: FileAPI.createFileTypeID(),
1591 AUTHOR: FileAPI.createFileTypeID(),
1592 ARTIST: FileAPI.createFileTypeID(),
1593 LICENSE: FileAPI.createFileTypeID()
1598 pettanr.entrance = pettanr.view.registerApplication( function(){
1599 var wrap = document.getElementById('inner-wrapper'),
1600 pageHeaderH = pettanr.util.getElementSize( document.getElementById( 'header' ) ).height,
1602 this.displayName = 'Home';
1604 this.rootElement = document.getElementById('entrance');
1605 this.onOpen = function( _w, _h, _option ){
1606 wrap.style.display = '';
1607 wrap.style.height = ( _h - pageHeaderH ) + 'px';
1609 this.onClose = function(){
1610 wrap.style.display = 'none';
1612 this.onPaneResize = function( _w, _h){
1613 instance.onOpen( _w, _h );
1616 pettanr.entrance.addToLancher();
1618 pettanr.cabinet = pettanr.view.registerApplication( function(){
1620 elmContainer = document.getElementById( 'cabinet'),
1622 pageHeaderH = pettanr.util.getElementSize( document.getElementById( 'header' ) ).height;
1624 this.displayName = 'Comic list';
1625 this.ID = 'Comiclist';
1626 this.rootElement = elmContainer;
1627 this.onOpen = function( _w, _h ){
1628 finder = finder || pettanr.finder.createFinder( pettanr.cabinet, elmContainer, pettanr.driver.createComicTree() );
1629 finder.resize( _w, _h - pageHeaderH );
1631 this.onClose = function(){
1634 this.onPaneResize = function( _w, _h){
1635 finder.resize( _w, _h - pageHeaderH );
1638 pettanr.cabinet.addToLancher();
1640 pettanr.gallery = pettanr.view.registerApplication( function(){
1642 elmContainer = document.getElementById( 'gallery' ),
1644 pageHeaderH = pettanr.util.getElementSize( document.getElementById( 'header' ) ).height;
1646 this.displayName = 'Pictures';
1647 this.ID = 'pictures';
1648 this.rootElement = elmContainer;
1649 this.onOpen = function( _w, _h ){
1650 finder = finder || pettanr.finder.createFinder( pettanr.gallery, elmContainer, pettanr.driver.createPictureTree() );
1651 finder.resize( _w, _h - pageHeaderH );
1653 this.onClose = function(){
1656 this.onPaneResize = function( _w, _h){
1657 finder.resize( _w, _h - pageHeaderH );
1660 pettanr.gallery.addToLancher();
1662 pettanr.backyard = pettanr.view.registerApplication( function(){
1663 this.displayName = 'Settings';
1664 this.ID = 'Settinds';
1665 this.rootElement = document.getElementById( 'backyard' );
1666 this.onOpen = function( _w, _h, _option ){
1668 this.onClose = function(){
1670 this.onPaneResize = function( _w, _h){
1673 pettanr.backyard.addToLancher();
1675 if( pettanr.DEBUG === true){
1676 pettanr.debug = pettanr.view.registerApplication( function(){
1677 var elmDl = document.getElementById( 'useragent'),
1680 pettanR: pettanr.version,
1681 ua: navigator.userAgent,
1682 platform: navigator.platform,
1683 appVersion: navigator.appVersion,
1684 appCodeName:navigator.appCodeName,
1685 appName: navigator.appName,
1686 language: navigator.browserLanguage || navigator.language,
1687 ActiveX: pettanr.ua.ACTIVEX
1691 //data.ua = 'Internet Explorer';
1692 data.version = ua.IE;
1693 if( ua.ieVersion >= 8) data.RenderingVersion = ua.ieRenderingVersion;
1694 data.browserType = ua.STANDALONE === true ? 'Standalone' : 'bundle';
1695 if( ua.ieVersion < 9) {
1701 data.RenderingMode = ua.isStanderdMode === true ? 'Standerd' : 'Quirks';
1703 for( var key in data){
1704 elmDt = document.createElement( 'dt');
1705 elmDt.innerHTML = key;
1706 elmDd = document.createElement( 'dd');
1707 elmDd.innerHTML = '' + data[ key];
1708 if( !data[ key]) elmDd.style.color = 'red';
1709 elmDl.appendChild( elmDt);
1710 elmDl.appendChild( elmDd);
1713 var wrap = document.getElementById('inner-wrapper'),
1714 pageHeaderH = pettanr.util.getElementSize( document.getElementById( 'header' )).height,
1717 this.displayName = 'Debug';
1719 this.rootElement = document.getElementById( 'debug' );
1720 this.onOpen = function( _w, _h, _option ){
1721 wrap.style.display = '';
1722 wrap.style.height = ( _h - pageHeaderH ) + 'px';
1724 this.onClose = function(){
1725 wrap.style.display = 'none';
1727 this.onPaneResize = function( _w, _h ){
1728 instance.onOpen( _w, _h );
1731 pettanr.debug.addToLancher();
1734 var _debug = document.getElementById( 'debug');
1736 pettanr.util.removeAllChildren( _debug);
1737 _debug.parentNode.removeChild( _debug);
1742 /* ----------------------------------------
1743 * Image Group Exproler
1746 pettanr.premiumSatge = pettanr.view.registerApplication( function(){
1747 var ICON_ARRAY = [],
1749 ARTIST_TREE = pettanr.driver.createArtistTree(),
1750 ARTIST_ROOT_FILE = ARTIST_TREE.getRootFile(),
1754 elmWrap = document.getElementById( 'image-group-wrapper' ),
1755 elmContainer = document.getElementById( 'image-group-icon-container' ),
1757 containerH = pettanr.util.getElementSize( elmContainer ).height,
1758 elmIconOrigin = ( function(){
1759 var ret = document.createElement( 'div' ),
1760 data = document.createElement( 'div' );
1761 ret.appendChild( data );
1762 ret.className = 'image-group-item';
1763 data.className = 'image-group-item-title';
1767 size = pettanr.util.getElementSize( elmIconOrigin ),
1769 itemH = size.height,
1770 elmName = document.getElementById( 'image-group-name' ),
1771 elmButton = document.getElementById( 'image-group-button' ),
1772 buttonW = pettanr.util.getElementSize( elmButton ).width,
1774 onUpdateFunction = null,
1775 onUpdateData = null,
1777 onEnterInterval = null;
1779 elmButton.onclick = clickOK;
1781 var BASE_PATH = pettanr.LOCAL === true ? 'resource_pictures\/' : pettanr.CONST.PETTANR_ROOT_PATH + 'resource_pictures\/',
1782 THUMB_PATH = BASE_PATH, // + 'thumbnail/',
1783 LIMIT_FILESIZE = 1024 * 10; // 10KB
1785 var ImageGroupIconClass = function( INDEX, data ){
1786 var elmIconWrap = elmIconOrigin.cloneNode( true ),
1787 elmIconTitle = pettanr.util.getElementsByClassName( elmIconWrap, 'image-group-item-title' )[ 0 ],
1788 SRC = [ BASE_PATH, data.id, '.', data.ext ].join( ''),
1789 LOW_SRC = data.filesize && data.filesize > LIMIT_FILESIZE ? [ THUMB_PATH, data.id, '.', data.ext ].join( '') : null,
1790 reversibleImage = null,
1792 onEnterFlag = false,
1794 elmContainer.appendChild( elmIconWrap );
1795 elmIconWrap.style.left = ( INDEX * itemW ) + 'px';
1796 elmIconTitle.appendChild( document.createTextNode( data.filesize + 'bytes' ) );
1798 function onImageLoad( url, _imgW, _imgH ){
1799 data.width = _imgW = _imgW || data.width || 64;
1800 data.height = _imgH = _imgH || data.height || 64;
1801 elmIconTitle.firstChild.data = _imgW + 'x' + _imgH;
1802 var zoom = 128 /( _imgW > _imgH ? _imgW : _imgH ),
1803 MATH_FLOOR = Math.floor,
1804 h = MATH_FLOOR( _imgH * zoom ),
1805 w = MATH_FLOOR( _imgW * zoom );
1806 reversibleImage.elm.style.cssText = [
1808 'height:', h, 'px;',
1809 'margin:', MATH_FLOOR( itemH / 2 - h / 2 ), 'px ', MATH_FLOOR( itemW / 2 - w / 2 ), 'px 0'
1811 reversibleImage.resize( w, h );
1812 elmIconWrap.onclick = onClick;
1816 onUpdateData = data;
1817 pettanr.premiumSatge.shutdown();
1820 function asyncDraw(){
1821 reversibleImage = pettanr.image.createReversibleImage( LOW_SRC || SRC, itemW, itemH, onImageLoad );
1822 elmIconWrap.appendChild( reversibleImage.elm );
1827 this.onEnter = function( delay ){
1828 timer = window.setTimeout( asyncDraw, delay );
1829 delete instance.onEnter;
1831 this.destroy = function(){
1832 delete instance.destroy;
1833 timer && window.clearTimeout( timer );
1834 reversibleImage && reversibleImage.destroy();
1835 pettanr.util.removeAllChildren( elmIconWrap );
1836 elmContainer.removeChild( elmIconWrap );
1837 elmIconWrap.onclick = '';
1838 reversibleImage = elmIconWrap = elmIconTitle = data = timer = null;
1842 function onEnterShowImage(){
1843 var l = ICON_ARRAY.length,
1844 _start = -wrapX /itemW -1,
1845 _end = _start + winW /itemW +1,
1847 for( var i=0, c = 0; i<l; ++i){
1848 _icon = ICON_ARRAY[ i ];
1849 if( _start < i && i < _end && _icon.onEnter ){
1850 _icon.onEnter( c * 100 );
1854 onEnterInterval !== null && window.clearTimeout( onEnterInterval );
1855 onEnterInterval = null;
1858 pettanr.premiumSatge.shutdown();
1860 function onMouseWheel( e, delta ){
1861 if( winW < containerW){
1862 wrapX += delta * WHEEL_DELTA;
1863 wrapX = wrapX > 0 ? 0 : wrapX < winW -containerW ? winW -containerW : wrapX;
1864 jqContainer.css( { left: wrapX});
1866 onEnterInterval !== null && window.clearTimeout( onEnterInterval );
1867 onEnterInterval = window.setTimeout( onEnterShowImage, 500 );
1869 //e.stopPropagation();
1873 function drawIcons(){
1874 while( ICON_ARRAY.length > 0 ){
1875 ICON_ARRAY.shift().destroy();
1878 var _index = ARTIST_ROOT_FILE.search( {
1880 type: pettanr.driver.FILE_TYPE.ARTIST
1882 _artistFile = ARTIST_ROOT_FILE.getChildFileByIndex( _index ),
1884 if( _artistFile !== null ){
1885 for(var i=0, l=_artistFile.getChildFileLength(); i<l; ++i ){
1886 _file = _artistFile.getChildFileByIndex( i );
1887 ICON_ARRAY.push( new ImageGroupIconClass( i, pettanr.driver._getAPI().getFileData( _file ) ));
1890 elmName.firstChild.data = _artistFile.getName();
1891 _artistFile.destroy();
1895 function onFadeout(){
1896 while( ICON_ARRAY.length > 0 ){
1897 ICON_ARRAY.shift().destroy();
1899 onUpdateFunction !== null && onUpdateData !== null && onUpdateFunction( onUpdateData );
1900 onUpdateFunction = onUpdateData = null;
1904 // this.rootElement = elmWrap;
1905 this.displayName = 'premiumStage';
1906 this.ID = 'premiumStage';
1907 this.rootElement = elmWrap;
1908 this.MIN_WIDTH = 320;
1909 this.MIN_HEIGHT = 320;
1910 this.init = function(){
1911 jqContainer = $( elmContainer ).mousewheel( onMouseWheel );
1914 //var tree = pettanr.driver.createPictureTree();
1915 //tree.addTreeEventListener( pettanr.file.TREE_EVENT.UPDATE, drawIcons );
1917 delete instance.init;
1919 this.onOpen = function( _windowW, _windowH, _ARTISTIDorFILE, _onUpdateFunction ){
1920 instance.init && instance.init();
1922 if( pettanr.driver.isPettanrFileInstance( _ARTISTIDorFILE ) === true ){
1923 var _data = pettanr.driver._getAPI().getFileData( _ARTISTIDorFILE );
1924 if( _ARTISTIDorFILE.getType() === pettanr.driver.FILE_TYPE.ARTIST || pettanr.driver._getMyPicturesData() === _data ){
1925 artistID = _data.id || -1;
1928 if( Type.isNumber( _ARTISTIDorFILE ) === true ){
1929 artistID = _ARTISTIDorFILE;
1932 onUpdateFunction = _onUpdateFunction || null;
1933 onUpdateData = null;
1938 containerW = ICON_ARRAY.length * itemW;
1942 var w = winW > containerW ? winW : containerW,
1943 h = _windowH > containerH ? containerH : _windowH,
1944 MATH_FLOOR = Math.floor;
1950 top: MATH_FLOOR( _windowH /2)
1951 }).stop().animate( {
1953 top: MATH_FLOOR( _windowH /2 -h /2)
1954 }, onEnterShowImage );
1956 elmButton.style.cssText = [
1957 'left:', MATH_FLOOR( winW /2 - buttonW /2), 'px;',
1958 'top:', MATH_FLOOR( _windowH /2 + containerH /2 +10), 'px'
1961 this.onPaneResize = function( _windowW, _windowH ){
1962 var w = _windowW > containerW ? _windowW : containerW,
1963 h = _windowH > containerH ? containerH : _windowH,
1964 MATH_FLOOR = Math.floor,
1965 offsetW = MATH_FLOOR( _windowW /2 -winW /2);
1969 if( offsetW <= 0){ // smaller
1975 top: MATH_FLOOR( _windowH /2 -h /2)
1978 jqContainer.css( { // bigger
1981 borderLeftWidth: offsetW
1983 top: MATH_FLOOR( _windowH /2 -h /2),
1987 elmButton.style.cssText = [
1988 'left:', MATH_FLOOR( _windowW /2 -buttonW /2), 'px;',
1989 'top:', MATH_FLOOR( _windowH /2 +containerH /2 +10), 'px'
1993 this.onClose = function(){
1994 jqContainer.stop().animate( {
1996 top: Math.floor( winH /2 )
1998 onEnterInterval !== null && window.clearTimeout( onEnterInterval );
1999 onEnterInterval = null;
2004 /* ----------------------------------------
2008 pettanr.textEditor = pettanr.view.registerApplication( function(){
2009 var jqWrap, jqTextarea, jqButton,
2010 textElement, onUpdateFunction,
2014 //pettanr.key.addKeyDownEvent( ID, 69, false, false, clickOK);
2017 textElement && textElement.text( jqTextarea.val() );
2018 onUpdateFunction ? window.setTimeout( asyncCallback, 50 ) : pettanr.textEditor.shutdown();
2021 function asyncCallback(){
2022 onUpdateFunction( textElement );
2023 pettanr.textEditor.shutdown();
2026 function keyCancel( e ){
2027 if( e.keyCode === 69 && e.shiftKey === false && e.ctrlKey === true){
2031 e.cancelBubble = true;
2032 e.returnValue = false;
2036 function textareaFitHeight(){
2038 while( jqTextarea.height() < textElement.h ){
2040 jqTextarea.attr( 'rows', rows );
2042 rows > 1 && jqTextarea.attr( 'rows', --rows );
2046 // this.rootElement = elmWrap;
2047 this.displayName = 'textEditor';
2048 this.ID = 'textEditor';
2049 this.rootElement = document.getElementById( 'speach-editor-wrapper' );
2050 this.MIN_WIDTH = 320;
2051 this.MIN_HEIGHT = 320;
2052 this.init = function(){
2053 jqWrap = $( '#speach-editor-wrapper' ).hide();
2054 jqTextarea = $( '#speach-editor' ).keydown( keyCancel );
2055 jqButton = $( '#speach-edit-complete-button').click( clickOK );
2056 delete instance.init;
2058 this.onOpen = function( _w, _h, _panelX, _panelY, _textElement, _onUpdateFunction ){
2059 instance.init && instance.init();
2063 textElement = _textElement;
2064 onUpdateFunction = _onUpdateFunction || null;
2067 instance.onPaneResize( _w, _h );
2068 jqTextarea.val( _textElement.text() ).focus();
2071 * ie6,7は、textarea { width:100%}でも高さが変わらない。rowsを設定。
2073 pettanr.ua.isIE === true && pettanr.ua.ieVersion <= 7 && setTimeout( textareaFitHeight, 0);
2075 this.onPaneResize = function( _w, _h ){
2077 left: textElement.x + panelX,
2078 top: textElement.y + panelY,
2079 width: textElement.w,
2080 height: textElement.h
2083 this.onClose = function(){
2085 textElement = onUpdateFunction = null;
2093 pettanr.fn( pettanr.view);
2094 pettanr.fn( pettanr.overlay);
2095 pettanr.fn( pettanr.key);
2096 pettanr.fn( pettanr.balloon);
2098 pettanr.fn( pettanr.editor);
2100 pettanr.fn( pettanr.file);
2101 pettanr.fn( pettanr.finder);
2102 pettanr.fn( pettanr.gallery);
2103 pettanr.fn( pettanr.cabinet);
2105 $(window).ready( pettanr.init);