12 pettanr.log = ( function(){
18 pettanr.io = ( function(){
27 * お気に入り画像一覧 > tag:ペン次郎 > ペン次郎:笑う
28 * 最近アップロードされた画像 > images
30 * キャラクター画像庫 > アニマル系 > tag:ペン次郎 > ペン次郎:笑う
37 pettanr.file = ( function(){
38 var FILE_TYPE_IS_FOLDER = 1,
39 numFileType = FILE_TYPE_IS_FOLDER,
40 FILEDATA_RESITER = [], // store all of fileData( json object )
41 FILEDATA_ACCESS = [], // file operations for Kernel only ! hide from Out of pettanr.file
42 FILE_OBJECT_POOL = [],
43 EVENT_LISTENER_RESISTER = [],
45 TREE_ACCESS_ARRAY = [];
47 var REQUEST_CONTROLER = ( function(){
48 var REQUEST_TICKET_RESISTER = [],
49 DATA_TYPE_ARRAY = 'json,xml,html,text'.split( ','),
56 var RequestTicketClass = function( _type, _data, _url, _onLoad, _onError){
57 this.type = DATA_TYPE_ARRAY[ _type];
60 this.onLoad = _onLoad;
61 this.onError = _onError;
66 if( REQUEST_TICKET_RESISTER.length === 0) return;
67 var _ticket = REQUEST_TICKET_RESISTER.shift();
70 dataType: _ticket.type,
71 success: function( _data){
72 _ticket.onLoad( _ticket.data, _data);
76 _ticket.onError( _ticket.data);
82 getNumTask: function(){
83 return REQUEST_TICKET_RESISTER.length;
85 getNumError: function(){
88 getJson: function( _data, _url, _onLoad, _onError){
89 REQUEST_TICKET_RESISTER.push( new RequestTicketClass( DATA_IS_JSON, _data, _url, _onLoad, _onError));
97 var FILE_CONTROLER = {
98 createTree: function( _rootFileData){
99 var _tree = new TreeClass( _rootFileData);
101 TREE_ARRAY.push( _tree);
104 getFileDataAccess: function( UIDorFILEorFILEDATA){
105 var _uid, _data, _access;
107 if( typeof UIDorFILEorFILEDATA === 'number'){
108 _data = FILEDATA_RESITER[ UIDorFILEorFILEDATA] || null;
110 if( UIDorFILEorFILEDATA instanceof FileClass){
111 _uid = UIDorFILEorFILEDATA.getUID();
112 _data = FILEDATA_RESITER[ _uid] || null;
114 _data = UIDorFILEorFILEDATA || null;
117 if( _data === null || typeof _data !== 'object') return null;
118 for( var i=0, l = FILEDATA_ACCESS.length; i<l; ++i){
119 _access = FILEDATA_ACCESS[ i];
120 if( _access.DATA === _data) return _access;
124 getFileData: function( UIDorFILEorFILEDATA){
125 var _access = FILE_CONTROLER.getFileDataAccess( UIDorFILEorFILEDATA);
126 return _access !== null ? _access.DATA : null;
128 getChildren: function( UIDorFILEorFILEDATA){
129 var _data = FILE_CONTROLER.getFileData( UIDorFILEorFILEDATA);
130 return _data !== null ? _data.children || null : null;
132 getDriver: function( _file){
133 var _data = FILE_CONTROLER.getFileData( _file);
134 return _data !== null && _data.driver ? _data.driver : FileDriverBase;
136 getUpdateFlag: function( _file, _bit){
137 var _driver = FILE_CONTROLER.getDriver( _file ),
139 if( typeof _driver.getUpdatePolicy === 'function'){
140 _policy = _driver.getUpdatePolicy( _file );
143 if( typeof _policy !== 'number') {
144 _policy = FileDriverBase.getUpdatePolicy( _file )
146 return _policy % ( _bit * 2) >= _bit;
148 move: function( _prentUID, _targetfile, _newFolder, _newIndex, _opt_callback){
149 var _parentData = FILE_CONTROLER.getFileDataAccess( _prentUID),
150 _parentType = _parentData.TYPE,
151 _targetData = FILE_CONTROLER.getFileDataAccess( _targetfile),
152 _targetType = _targetData.TYPE;
154 replace: function( _uid, _file, _newIndex){
157 addEventListener: function( FILEorNULL, _eventType, _callback){
158 var _uid = FILEorNULL instanceof FileClass ? FILEorNULL.getUID() : FILEorNULL;
159 EVENT_LISTENER_RESISTER.push( new FileEventTicketClass( _uid, _eventType, _callback));
161 removeEventListener: function( FILEorNULL, _eventType, _callback){
162 var _uid = FILEorNULL instanceof FileClass ? FILEorNULL.getUID() : FILEorNULL,
164 for(var i=0, l = EVENT_LISTENER_RESISTER.length; i<l; ++i){
165 _ticket = EVENT_LISTENER_RESISTER[i];
166 if( _ticket.fileUID === _uid && _ticket.eventType === _eventType && _ticket.callBack === _callback){
167 EVENT_LISTENER_RESISTER.splice( i, 1);
172 fileEventRellay: function( _targetFile, _targetTree, _event){
173 var _uid = _targetTree.getUID(),
174 _access = TREE_ACCESS_ARRAY[ _uid ],
175 _data = FILE_CONTROLER.getFileData( _targetFile ),
177 _access && _access.dispatchFileEvent( _event );
178 for( var i=0, l = TREE_ARRAY.length; i<l; ++i){
180 _tree = TREE_ARRAY[ i ];
181 if( FILE_CONTROLER.getFileData( _tree.getCurrentFile() ) === _data ){
182 _access = TREE_ACCESS_ARRAY[ _tree.getUID() ];
183 _access && _access.dispatchFileEvent( _event);
190 var TreeClass = function( ROOTFILE_DATA){
191 var UID = TREE_ACCESS_ARRAY.length,
192 PARENT_FILE_RESITER = [],
194 dispatchFileEvent: dispatchFileEvent,
197 EVENT_LISTENER_ARRAY = [],
204 TREE_ACCESS_ARRAY.push( ACCESS);
206 function onDestroy(){
210 function dispatchFileEvent( e){
211 var _eventType = e.eventType,
212 _targetFile = e.targetFile,
213 _uid = _targetFile.getUID(),
214 _ticket, _type, _callback;
215 for(var i=0, l = EVENT_LISTENER_RESISTER.length; i<l; ++i){
216 _ticket = EVENT_LISTENER_RESISTER[i],
217 _type = _ticket.eventType,
218 _callback = _ticket.callBack;
219 if( _eventType === _type && _uid === _ticket.fileUID){
220 _callback( _eventType, _targetFile, e.key, e.value);
222 if( _type === pettanr.file.TREE_EVENT.UPDATE && _eventType === pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES){
223 _callback( _eventType, _targetFile);
231 currentFile = rootFile = new FileClass( this, null, ROOTFILE_DATA);
233 currentFile.getSeqentialFiles();
236 getUID: function(){ return UID},
237 getRootFile : function(){
240 getCurrentFile: function(){
243 hierarchy: function(){
244 return PARENT_FILE_RESITER.length;
246 getParentFileAt: function( _index){
247 var l = PARENT_FILE_RESITER.length;
248 if( typeof _index !== 'number' || _index < 0 || _index >= l) return null;
249 return PARENT_FILE_RESITER[ l -1 -_index];
251 down: function( _index){
252 if( typeof _index !== 'number' || _index < 0 || _index >= currentFile.getChildFileLength()) return;
253 PARENT_FILE_RESITER.unshift( currentFile);
254 currentFile = currentFile.getChildFileByIndex( _index);
255 currentFile.getSeqentialFiles();
258 up: function( _index){
259 var l = PARENT_FILE_RESITER.length;
260 if( l === 0) return null;
261 if( typeof _index === 'number'){
262 if( _index >= l) return null;
263 currentFile = this.getParentFileAt( _index);
264 PARENT_FILE_RESITER.splice( 0, l -_index);
266 currentFile = PARENT_FILE_RESITER.shift();
268 currentFile.getSeqentialFiles();
271 addTreeEventListener: function( _eventType, _callback){
272 FILE_CONTROLER.addEventListener( null, _eventType, _callback);
274 removeTreeEventListener: function( _eventType, _callback){
275 FILE_CONTROLER.removeEventListener( null, _eventType, _callback);
278 FILE_CONTROLER.destroyTree( UID);
283 var FileEventTicketClass = function( UID, _eventType, _callback){
285 this.eventType = _eventType;
286 this.callBack = _callback;
287 this.destroy = function(){
288 this.callBack = _callback = null;
292 var FileEventClass = function( eventType, file, key, value){
293 this.eventType = eventType;
294 this.targetFile = file;
295 this.updatedAttribute = key;
296 this.updatedValue = value;
300 * fileのdataはobjectで保持している。
301 * pettanr.file.の外からファイルをみるときは、FileClassを通して操作する。
302 * fileの変更、それに付随して追加されたイベントは、TreeClassで管理される。
303 * treeがdestryされると、fileのイベントリスナーも全て削除される。
304 * 他の tree も data の共通する currentFile に対してのみは、file の変更イベントを受け取って流す.
307 var FileClass = function( TREE, parentFile, data){
308 var uid = pettanr.util.getIndex( FILEDATA_RESITER, data ),
312 uid = FILEDATA_RESITER.length;
313 FILEDATA_RESITER.push( data );
316 FILEDATA_ACCESS.push(
319 updateParent: updateParent,
320 dispatchFileEvent: dispatchEvent
324 function updateParent( _parent){
325 parentFile = _parent;
327 function dispatchEvent( e){
328 FILE_CONTROLER.fileEventRellay( instance, TREE, e);
333 this.getUID = function(){
337 * ファイル構造は TRON のような ハイパーリンク方式 だが、文脈上の 親ファイルが存在する.その親ファイルを使う操作は.prototype に置く事ができない.
338 * 同様に TREE を使う操作も .prototype に置く事ができない.
340 this.getChildFileByIndex = function( _index){
341 var _children = FILE_CONTROLER.getChildren( instance );
342 if( typeof _index !== 'number' || _index < 0 || typeof _children.length !== 'number' || _index >= _children.length) return null;
343 var _file = new FileClass( TREE, this, _children[ _index]);
347 this.move = function( _newFolder, _newIndex, opt_callback){
348 TREE.move( parentFile, UID, _newFolder, _newIndex, opt_callback);
350 this.replace = function( _newIndex, opt_callback){
351 TREE.replace( parentFile, UID, _newIndex, opt_callback);
353 this.destroy = function(){
354 var _access = FILE_CONTROLER.getFileDataAccess( instance );
355 _index = getChildIndex( FILEDATA_ACCESS, _access );
356 if( _index === -1 || _access === null) return;
357 FILEDATA_ACCESS.splice( _index, 1);
358 TREE = parentFile = data = null;
359 delete _access.DATA, _access.updateParent, _access.dispatchFileEvent;
363 FileClass.prototype = {
364 isChildFile: function( _FILEorFILEDATA){
365 return this.getChildFileIndex( _FILEorFILEDATA) !== -1;
367 getSeqentialFiles: function(){
368 var _driver = FILE_CONTROLER.getDriver( this );
369 if( _driver !== null && typeof _driver.getSeqentialFiles === 'function'){
370 _driver.getSeqentialFiles( this );
373 addEventListener: function( _eventType, _callback){
374 FILE_CONTROLER.addEventListener( this, _eventType, _callback);
376 removeEventListener: function( _eventType, _callback){
377 FILE_CONTROLER.removeEventListener( this, _eventType, _callback);
379 getChildFileLength: function(){
380 var children = FILE_CONTROLER.getChildren( this);
381 return Type.isArray( children ) === true ? children.length : -1;
383 getChildFileIndex: function( _FILEorFILEDATA){
384 var children = FILE_CONTROLER.getChildren( this);
385 if( Type.isArray( children.length ) === false ) return -1;
386 var l = children.length,
387 _fileData = FILE_CONTROLER.getFileData( _FILEorFILEDATA);
388 if( _fileData === null) return -1;
389 for(var i=0; i<l; ++i){
390 if( children[ i] === _fileData) return i;
395 var driver = FILE_CONTROLER.getDriver( this );
396 if( typeof driver.getName === 'function'){
397 return driver.getName( this );
399 return FileDriverBase.getName( this);
401 getThumbnail: function(){
402 var driver = FILE_CONTROLER.getDriver( this);
403 if( typeof driver.getThumbnail === 'function'){
404 return driver.getThumbnail( this);
406 return FileDriverBase.getThumbnail( this);
409 var _data = FILE_CONTROLER.getFileData( this);
410 return typeof _data.type === 'number' ? _data.type : pettanr.file.FILE_TYPE.UNKNOWN;
412 getState: function(){
413 var _data = FILE_CONTROLER.getFileData( this);
414 return typeof _data.state === 'number' ? _data.state : pettanr.file.FILE_STATE.OK;
416 isWritable: function(){
417 return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.WRITE);
419 isSortable: function(){
420 return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.SORT);
422 isCreatable: function(){
423 return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.CREATE);
425 isRenamable: function(){
426 return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.RENAME);
432 write: function( _newName, _newData){
435 viwerApps: function(){
438 editorApps: function(){
450 onDelete: function(){
458 var FileDriverBase = {
459 getSeqentialFiles: function( _file){
461 getName: function( _file){
462 var _data = FILE_CONTROLER.getFileData( _file);
463 return _data.name || 'No Name';
465 getThumbnail: function( _file){
466 var _data = FILE_CONTROLER.getFileData( _file);
469 if( _type === pettanr.file.FILE_TYPE.FOLDER){
470 _className = 'folder';
472 if( _type === pettanr.file.FILE_TYPE.IMAGE){
475 if( _type === pettanr.file.FILE_TYPE.TEXT){
478 if( _type === pettanr.file.FILE_TYPE.HTML){
481 if( _type === pettanr.file.FILE_TYPE.CSV){
484 if( _type === pettanr.file.FILE_TYPE.JSON){
487 if( _type === pettanr.file.FILE_TYPE.XML){
492 className: ' file-type-' + _className
495 getUpdatePolicy: function( _file){
497 return pettanr.file.FILE_UPDATE_POLICY.SRWC;
502 write: function( _newName, _newData){
505 onCreate: function(){
514 onDelete: function(){
519 var ROOT_FILEDATA = {
521 type: FILE_TYPE_IS_FOLDER,
524 SYSTEM_TREE = FILE_CONTROLER.createTree( ROOT_FILEDATA),
525 ROOT_FILE = SYSTEM_TREE.getRootFile();
527 function createFolderUnderRoot( _fileData){
528 ROOT_FILEDATA.children.push( _fileData);
529 FILE_CONTROLER.getFileDataAccess( ROOT_FILE)
530 .dispatchFileEvent( new FileEventClass( pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES, ROOT_FILE, 'children', null));
532 function createFileEvent( _eventType, _file, _key, _value){
533 return new FileEventClass( _eventType, _file, _key, _value)
535 function createFileTypeID(){
536 return ++numFileType;
541 //REQUEST_CONTROLER.init();
542 //FILE_CONTROLER.init();
543 delete pettanr.file.init;
545 resisterDriver: function( _driver){
546 _driver.prototype = FileDriverBase;
551 createFolderUnderRoot: createFolderUnderRoot,
552 getFileDataAccess: FILE_CONTROLER.getFileDataAccess,
553 getFileData: FILE_CONTROLER.getFileData,
554 getJson: REQUEST_CONTROLER.getJson,
555 createFileEvent: createFileEvent,
556 createFileTypeID: createFileTypeID
559 createTree: function( _rootFile){
560 return FILE_CONTROLER.createTree( _rootFile);
562 isTreeInstance: function( _tree){
563 return _tree instanceof TreeClass;
565 isFileInstance: function( _file){
566 return _file instanceof FileClass;
570 FOLDER: FILE_TYPE_IS_FOLDER,
571 IMAGE: createFileTypeID(),
572 TEXT: createFileTypeID(),
573 HTML: createFileTypeID(),
574 CSV: createFileTypeID(),
575 JSON: createFileTypeID(),
576 XML: createFileTypeID()
585 FILE_UPDATE_POLICY: {
586 ____: parseInt( '0000', 2),
587 ___C: parseInt( '0001', 2), // hasCreateMenu
588 __W_: parseInt( '0010', 2), // isWritable
589 __WC: parseInt( '0011', 2), // isWritable
590 _R__: parseInt( '0000', 2), // isRenamable
591 _R_C: parseInt( '0101', 2), // hasCreateMenu
592 _RW_: parseInt( '0110', 2), // isWritable
593 _RWC: parseInt( '0111', 2), // isWritable
594 S___: parseInt( '1000', 2), // childrenIsSortable
595 S__C: parseInt( '1001', 2),
596 S_W_: parseInt( '1010', 2),
597 S_WC: parseInt( '1011', 2),
598 SR__: parseInt( '1000', 2),
599 SR_C: parseInt( '1101', 2),
600 SRW_: parseInt( '1110', 2),
601 SRWC: parseInt( '1111', 2),
608 UPDATE: 'onTreeUpdate'
611 UPDATE_ATTRIVUTE: 'onFileUpdate',
612 GET_SEQENTIAL_FILES:'gotSeqentilFiles'
614 FILE_DATA_PROPERTY_RESERVED: [
615 'children', 'driver', 'state', 'type'
620 pettanr.finder = ( function(){
621 var FINDER_ARRAY = [],
622 ELM_ORIGIN_FINDER_LOCATION_ITEM = pettanr.util.pullHtmlAsTemplete( 'templete-finder-location-item'),
623 ELM_ORIGIN_FINDER_ICON = pettanr.util.pullHtmlAsTemplete( 'templete-finder-icon'),
624 ELM_ORIGIN_CONTAINER = pettanr.util.pullHtmlAsTemplete( 'templete-finder-container'),
625 ICON_HEIGHT = pettanr.util.getElementSize( ELM_ORIGIN_FINDER_ICON).height,
626 ICON_CLASSNAME = ELM_ORIGIN_FINDER_ICON.getElementsByTagName( 'div')[0].className,
627 FINDER_ICON_POOL = [],
628 BREAD_OBJECT_POOL = [];
630 var FinderIconClass = function(){
632 ELM_WRAPPER = ELM_ORIGIN_FINDER_ICON.cloneNode( true),
633 ELM_THUMBNAIL = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-thumbnail', 'div')[0],
634 ELM_FILENAME = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-filename', 'div')[0],
635 file, w, index, style, instansce, callback;
637 ELM_WRAPPER.onclick = onClick;
643 var _thumb = file.getThumbnail();
645 ELM_THUMBNAIL.className = ICON_CLASSNAME + ' has-thumbnail';
646 ELM_THUMBNAIL.style.backgroundImage = [ 'url(', _thumb.image, ')'].join( '');
648 ELM_THUMBNAIL.className = ICON_CLASSNAME + ' ' +_thumb.className;
649 ELM_THUMBNAIL.style.backgroundImage = '';
651 ELM_FILENAME.innerHTML = file.getName();
654 ELM_WRAPPER.style.top = (index * ICON_HEIGHT) +'px';
656 function onCollect(){
657 elmContainer.removeChild( ELM_WRAPPER);
659 FINDER_ICON_POOL.push( instansce);
663 init: function( _file, _elmContainer, _w, _index, _style, _callback){
665 if( elmContainer !== _elmContainer){
666 _elmContainer.appendChild( ELM_WRAPPER);
667 elmContainer = _elmContainer;
673 if( index !== _index){
677 callback = _callback;
680 index: function( _index){
684 style: function( _style){
688 onResize: function( w){
692 elmContainer.removeChild( ELM_WRAPPER);
693 file = elmContainer = null;
694 FINDER_ICON_POOL.push( instansce);
698 function updateIconPosition( _style, _w, _index, _elm){
701 var BreadcrumbClass = function(){
703 ELM_WRAPPER = ELM_ORIGIN_FINDER_LOCATION_ITEM.cloneNode( true),
704 ELM_FILENAME = ELM_WRAPPER.getElementsByTagName( 'a')[0],
705 file, w, index, instansce,
707 ELM_WRAPPER.onclick = onClick;
709 ELM_FILENAME.className = 'file-icon-' +file.getType();
710 ELM_FILENAME.innerHTML = file.getName();
712 function resize( index){
713 ELM_WRAPPER.style.left = (index * 90) +'px';
721 init: function( _file, _elmContainer, _index, _callback){
723 if( elmContainer !== _elmContainer){
724 _elmContainer.appendChild( ELM_WRAPPER);
725 elmContainer = _elmContainer;
731 if( index !== _index){
735 callback = _callback;
738 index: function( _index){
742 onResize: function( w){
746 elmContainer.removeChild( ELM_WRAPPER);
747 file = elmContainer = null;
748 BREAD_OBJECT_POOL.push( this);
753 var FinderClass = function( ELM_CONTAINER, tree, detailSwitchEnabled, styleSwitchEnabled, actionSwitchEnabled){
756 elmContainer = ELM_ORIGIN_CONTAINER.cloneNode( true),
757 elmLocation = elmContainer.getElementsByTagName( 'ul')[0],
758 nodesDiv = elmContainer.getElementsByTagName( 'div'),
759 elmSidebarButton = nodesDiv[1],
760 elmStyleButton = nodesDiv[2],
761 elmActionButton = nodesDiv[3],
762 elmBody = nodesDiv[ nodesDiv.length -1],
763 //tree = pettanr.file.createTree( TREE_TYPE),
766 headH = pettanr.util.getElementSize( ELM_ORIGIN_FINDER_ICON).height,
770 size = pettanr.util.getElementSize( ELM_ORIGIN_FINDER_ICON),
776 tree.addTreeEventListener( pettanr.file.TREE_EVENT.UPDATE, draw);
779 var l = tree.hierarchy() +1,
780 m = BREAD_ARRAY.length,
782 for(var i=0; i<l; ++i){
783 _file = i !== l-1 ? tree.getParentFileAt( i) : tree.getCurrentFile();
785 BREAD_ARRAY[ i].init( _file, elmLocation, i, onHeadClick);
787 BREAD_ARRAY.push( getBreadcrumb( _file, elmLocation, i, onHeadClick));
790 while( l < BREAD_ARRAY.length){
791 BREAD_ARRAY.pop().destroy();
794 l = _file.getChildFileLength();
795 m = ICON_ARRAY.length;
799 ICON_ARRAY[ i].init( _file.getChildFileByIndex( i), elmBody, w, i, style, onBodyClick);
801 ICON_ARRAY.push( getFinderIcon( _file.getChildFileByIndex( i), elmBody, w, i, style, onBodyClick));
804 while( l < ICON_ARRAY.length){
805 ICON_ARRAY.pop().destroy();
808 function onHeadClick( i){
809 var l = BREAD_ARRAY.length -1;
811 var _file = tree.getParentFileAt( i);
818 function onBodyClick( i){
819 var l = ICON_ARRAY.length;
821 var _file = tree.getCurrentFile().getChildFileByIndex( i);
822 if( _file !== null && ( _file.getChildFileLength() !== -1 || _file.getType() === pettanr.file.FILE_TYPE.FOLDER)){
829 this.init = function(){
830 ELM_CONTAINER.appendChild( elmContainer);
831 //$( elmLocation).click( onHeadClick);
832 //$( elmContainer).click( onBodyClick);
833 var position = pettanr.util.getAbsolutePosition( elmLocation);
836 bodyY = pettanr.util.getAbsolutePosition( elmBody).y;
839 this.onOpen = function(){
840 this.init !== undefined && this.init();
843 this.onClose = function(){
846 this.onWindowResize = function( _w, _h){
850 function getFinderIcon( _file, _elmContainer, w, index, style, callback){
852 if( FINDER_ICON_POOL.length > 0){
853 _icon = FINDER_ICON_POOL.shift();
855 _icon = new FinderIconClass();
857 _icon.init( _file, _elmContainer, w, index, style, callback);
861 function getBreadcrumb( _file, _elmContainer, index, callback){
863 if( BREAD_OBJECT_POOL.length > 0){
864 _bread = BREAD_OBJECT_POOL.shift();
866 _bread = new BreadcrumbClass();
868 _bread.init( _file, _elmContainer, index, callback);
876 createFinder: function( _elmTarget, _tree, detailSwitchEnabled, styleSwitchEnabled, actionSwitchEnabled){
877 var _finder = new FinderClass( _elmTarget, _tree, detailSwitchEnabled, styleSwitchEnabled, actionSwitchEnabled);
878 FINDER_ARRAY.push( _finder);
881 createFinderHead: function(){
884 resisterFinderPane: function( _finderPane){
887 isFinderInstance: function( _finder){
888 return _finder instanceof FinderClass;
894 pettanr.driver = ( function(){
895 var MyAuthorID = 'current_author' in window ? current_author.id : 1,
896 MyArtistID = 'current_artist' in window ? current_artist.id : 1,
898 getSeqentialFiles: function( _file){
899 var _data = FileAPI.getFileData( _file),
900 _json = _data !== null ? _data.json : null;
901 if( _json === true && _data.type === pettanr.driver.FILE_TYPE.COMIC ){
902 _json = [ pettanr.CONST.PETTANR_ROOT_PATH, 'comics\/', _data.id, '.json\/play\/' ].join( '' );
904 if( typeof _json === 'string'){
905 FileAPI.getJson( _file, _json, onLoadJson, onErrorJson);
906 _data.state = pettanr.file.FILE_STATE.LOADING;
911 getName: function( _file){
912 var _data = FileAPI.getFileData( _file),
913 _type = _data !== null ? _data.type : null;
914 if( _type === pettanr.driver.FILE_TYPE.PICTURE ){
915 return [ _data.id, _data.ext ].join( '.');
917 if( _type === pettanr.driver.FILE_TYPE.PANEL ){
918 return [ _data.t, ':', _data.comic.title ].join( '');
920 if( _type === pettanr.driver.FILE_TYPE.COMIC ){
923 if( _type === pettanr.driver.FILE_TYPE.ARTIST ){
924 return [ _data.id , ':', _data.name, '画伯' ].join( '');
926 if( _type === pettanr.driver.FILE_TYPE.AUTHOR ){
927 return [ _data.id , ':', _data.name, '先生' ].join( '');
931 getThumbnail: function( _file){
932 var _data = FileAPI.getFileData( _file);
933 _type = _data !== null ? _data.type : null;
934 if( _type === pettanr.driver.FILE_TYPE.PICTURE){
935 return { image: [ pettanr.CONST.RESOURCE_PICTURE_PATH, 'thumbnail/', _data.id, '.', _data.ext ].join( '')};
937 if( _data === FILE_DATA_COMICS_ROOT){
938 return { className: 'file-type-cabinet'};
940 if( _type === pettanr.driver.FILE_TYPE.COMIC){
941 return { className: 'file-type-comic'};
943 if( _type === pettanr.driver.FILE_TYPE.PANEL){
944 return { className: 'file-type-panel'};
946 if( _type === pettanr.driver.FILE_TYPE.AUTHOR){
947 return { className: 'file-type-author'};
949 if( _type === pettanr.driver.FILE_TYPE.ARTIST){
950 return { className: 'file-type-artist'};
952 if( _type === pettanr.driver.FILE_TYPE.FOLDEER){
953 return { className: 'file-type-folder'};
955 return { className: 'file-type-folder'};
958 FileAPI = pettanr.file.resisterDriver( Driver),
959 FILE_DATA_SERVICE_ROOT = {
960 name: 'PettanR root',
961 type: pettanr.file.FILE_TYPE.FOLDER,
964 FILE_DATA_COMICS_ROOT = {
966 type: pettanr.file.FILE_TYPE.FOLDER,
969 json: pettanr.CONST.URL_COMICS_JSON
971 FILE_DATA_PANELS_ROOT = {
973 type: pettanr.file.FILE_TYPE.FOLDER,
976 json: pettanr.CONST.URL_PANELS_JSON
978 FILE_DATA_PICTURE_ROOT = {
980 type: pettanr.file.FILE_TYPE.FOLDER,
983 json: pettanr.CONST.URL_RESOURCE_PICTURES_JSON
985 FILE_DATA_MY_COMICS_ROOT = {
987 type: pettanr.file.FILE_TYPE.AUTHOR,
991 FILE_DATA_MY_PICTURES_ROOT = {
993 type: pettanr.file.FILE_TYPE.ARTIST,
996 json: pettanr.CONST.URL_ORIGINAL_PICTURES_JSON
998 FILE_DATA_AUTHOR_ROOT = {
1000 type: pettanr.file.FILE_TYPE.FOLDER,
1003 FILE_DATA_ARTIST_ROOT = {
1005 type: pettanr.file.FILE_TYPE.FOLDER,
1008 FILE_DATA_LISENCE_ROOT = {
1009 name: 'Original Lisences',
1010 type: pettanr.file.FILE_TYPE.FOLDER,
1013 FILE_DATA_BALLOON_ROOT = {
1014 name: 'Balloon templetes',
1015 type: pettanr.file.FILE_TYPE.FOLDER,
1022 RESOURCE_PICTURE_ARRAY = [],
1023 BALLOON_TEMPLETE_ARRAY = [],
1024 ORIGINAL_LICENSE_ARRAY = [],
1025 BASIC_LICENSES = 'cc_by,cc_nc,cc_nd,cc_sa,keep_aspect_ratio,no_convert,no_flip,no_resize'.split( ',');
1026 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);
1027 FILE_DATA_COMICS_ROOT.children.push( FILE_DATA_MY_COMICS_ROOT, FILE_DATA_AUTHOR_ROOT);
1028 FILE_DATA_PICTURE_ROOT.children.push( FILE_DATA_MY_PICTURES_ROOT, FILE_DATA_ARTIST_ROOT);
1030 FileAPI.createFolderUnderRoot( FILE_DATA_SERVICE_ROOT);
1032 function onLoadJson( _file, _json){
1033 var _access = FileAPI.getFileDataAccess( _file),
1034 _data = _access !== null ? _access.DATA : null,
1036 if( _data === null){
1037 onErrorJson( _file);
1040 _data.state = pettanr.file.FILE_STATE.OK;
1042 if( Type.isArray( _json ) === true ){
1043 var l = _json.length;
1044 if( l === 0) return;
1045 for( var i=0; i<l; ++i ){
1046 buildFileData( _json[ i], _data);
1050 buildFileData( _json, _data );
1052 _access.dispatchFileEvent( FileAPI.createFileEvent( pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES, _file, 'children', null));
1054 function onErrorJson( _file ){
1055 var _data = FileAPI.getFileData( _file);
1056 if( _data !== null){
1057 _data.state = pettanr.file.FILE_STATE.ERROR;
1060 function buildFileData( _data, _parent ){
1063 if( _parent === FILE_DATA_PANELS_ROOT ){
1064 _data.type = pettanr.driver.FILE_TYPE.PANEL;
1065 _array = PANEL_ARRAY;
1068 if( _parent === FILE_DATA_COMICS_ROOT ){
1069 _data.type = pettanr.driver.FILE_TYPE.COMIC;
1070 _array = COMIC_ARRAY;
1072 if( _parent.type === pettanr.driver.FILE_TYPE.COMIC ){
1073 _array = COMIC_ARRAY;
1076 if( _parent === FILE_DATA_LISENCE_ROOT ){
1077 _data.type = pettanr.driver.FILE_TYPE.LICENSE;
1078 _array = ORIGINAL_LICENSE_ARRAY;
1081 if( _parent === FILE_DATA_AUTHOR_ROOT ){
1082 _data.type = pettanr.driver.FILE_TYPE.AUTHOR;
1083 _array = AUTHOR_ARRAY;
1086 if( _parent === FILE_DATA_ARTIST_ROOT ){
1087 _data.type = pettanr.driver.FILE_TYPE.ARTIST;
1088 _array = ARTIST_ARRAY;
1091 if( _parent === FILE_DATA_PICTURE_ROOT || _parent === FILE_DATA_MY_PICTURES_ROOT ){
1092 _data.type = pettanr.driver.FILE_TYPE.PICTURE;
1093 _array = RESOURCE_PICTURE_ARRAY;
1094 // original_license を含まなければ、license object を削除して ビットデータ で保持
1095 // original_license なら ファイルを作る buildFileData( _license, FILE_DATA_LISENCE_ROOT)
1096 var _license = _data.license,
1097 _Math_pow = Math.pow,
1099 if( typeof _license === 'object'){
1100 for( i=0, l=BASIC_LICENSES.length; i<l; ++i){
1101 if( typeof _license[ BASIC_LICENSES[ i]] === 'number'){
1102 _bits += _Math_pow( 2, i);
1105 _data.license = _bits;
1111 _data.driver = Driver;
1113 // _array に _data を格納 または 上書き
1114 if( typeof _data.id === 'number' && _data.id > 0 ){
1115 var _id = _data.id - 1,
1116 __data = _array[ _id ],
1117 _reserved = pettanr.file.FILE_DATA_PROPERTY_RESERVED.join( ', ' );
1119 for( var key in _data){
1120 if( _reserved.indexOf( key ) === -1 ){
1121 __data[ key ] = _data[ key ];
1124 _data = __data; // このタイミングで参照が切れるので注意!!
1126 _array[ _id ] = _data;
1134 if( _parent === FILE_DATA_AUTHOR_ROOT || _parent === FILE_DATA_ARTIST_ROOT ){
1135 addChildData( _parent, _data );
1138 if( _parent.type === pettanr.driver.FILE_TYPE.COMIC || _parent === FILE_DATA_COMICS_ROOT ){
1139 var _panels = _data.panels,
1141 if( _panels && Type.isArray( _panels ) === true ){
1143 for( i=0, l=_panels.length; i<l; ++i){
1144 _panel = buildFileData( _panels[ i ], FILE_DATA_PANELS_ROOT );
1148 addChildData( _data, _panel );
1150 delete _data.panels;
1152 if( _data.json !== null ){
1155 if( Type.isArray( _data.children ) === false ){
1156 _data.children = [];
1159 var _author = _data.author || getResource( AUTHOR_ARRAY, _data.author_id );
1161 _data.author = _author = buildFileData( _author, FILE_DATA_AUTHOR_ROOT );
1162 addChildData( _author, _data );
1163 _author.id === MyAuthorID && addChildData( FILE_DATA_MY_COMICS_ROOT, _data );
1167 if( _parent === FILE_DATA_PANELS_ROOT ){
1168 _data.comic = getResource( COMIC_ARRAY, _data.comic_id ),
1169 _data.author = getResource( AUTHOR_ARRAY, _data.author_id );
1171 // picture data をファイルに取り出し
1172 if( Type.isArray( _data.panel_elements ) === true ){
1175 for( i=0, l=_elements.length; i<l; ++i){
1176 _elm = _elements[ i];
1177 if( _elm.resource_picture ){
1178 _elm.resource_picture = buildFileData( _elm.resource_picture, FILE_DATA_PICTURE_ROOT); // 上記参照切れに備えてここで上書き
1180 _elm.resource_picture = getResource( RESOURCE_PICTURE_ARRAY, _elm.resource_picture_id );
1186 if( _data.type = pettanr.driver.FILE_TYPE.PICTURE ){
1187 var _artist = _data.artist || getResource( ARTIST_ARRAY, _data.artist_id );
1189 _data.artist = _artist = buildFileData( _artist, FILE_DATA_ARTIST_ROOT );
1190 addChildData( _artist, _data );
1191 _artist.id === MyArtistID && addChildData( FILE_DATA_MY_PICTURES_ROOT, _data );
1196 function addChildData( _parent, _child ){
1197 if( Type.isArray( _parent.children ) === false){
1198 _parent.children = [];
1200 pettanr.util.getIndex( _parent.children, _child ) === -1 && _parent.children.push( _child );
1202 function getResource( _array, _id ){
1203 if( Type.isArray( _array ) === false || Type.isNumber( _id ) === false || _id < 1 ) return null;
1204 var _data = _array[ _id - 1 ];
1206 _data = _array[ _id - 1 ] = {};
1212 createComicTree: function(){
1213 return pettanr.file.createTree( FILE_DATA_SERVICE_ROOT); //FILE_DATA_COMICS_ROOT);
1215 createPictureTree: function(){
1216 return pettanr.file.createTree( FILE_DATA_PICTURE_ROOT);
1218 createServiceTree: function(){
1219 return pettanr.file.createTree( FILE_DATA_SERVICE_ROOT);
1221 isPettanrFileInstance: function( _file){
1222 if( pettanr.file.isPettanFileInstance( _file) === true){
1223 var _data = FileAPI.getFileData( _file);
1224 return _data !== null && _data.driver === Driver;
1229 COMIC: FileAPI.createFileTypeID(),
1230 PANEL: FileAPI.createFileTypeID(),
1231 PICTURE: FileAPI.createFileTypeID(),
1232 PANEL_PICTURE: FileAPI.createFileTypeID(),
1233 BALLOON: FileAPI.createFileTypeID(),
1234 AUTHOR: FileAPI.createFileTypeID(),
1235 ARTIST: FileAPI.createFileTypeID(),
1236 LICENSE: FileAPI.createFileTypeID()
1242 pettanr.gallery = ( function(){
1244 elmContainer = document.getElementById( 'gallery'),
1248 init: function( _option){
1250 delete pettanr.gallery.init;
1252 firstOpen: function(){
1253 finder = pettanr.finder.createFinder( elmContainer, pettanr.driver.createPictureTree());
1254 delete pettanr.gallery.firstOpen;
1257 pettanr.gallery.firstOpen !== undefined && pettanr.gallery.firstOpen();
1261 onClose: function(){
1264 onWindowResize: function( _w, _h){
1265 finder.onWindowResize( _w, _h);
1270 pettanr.cabinet = ( function(){
1272 elmContainer = document.getElementById( 'cabinet'),
1276 init: function( _option){
1278 delete pettanr.cabinet.init;
1280 firstOpen: function(){
1281 finder = pettanr.finder.createFinder( elmContainer, pettanr.driver.createComicTree());
1282 delete pettanr.cabinet.firstOpen;
1285 pettanr.cabinet.firstOpen !== undefined && pettanr.cabinet.firstOpen();
1289 onClose: function(){
1292 onWindowResize: function( _w, _h){
1293 finder.onWindowResize( _w, _h);
1302 pettanr.fn( pettanr.view);
1303 pettanr.fn( pettanr.overlay);
1304 pettanr.fn( pettanr.key);
1305 pettanr.fn( pettanr.balloon);
1307 pettanr.fn( pettanr.editor);
1308 pettanr.fn( pettanr.comicConsole);
1309 pettanr.fn( pettanr.uploadConsole);
1310 pettanr.fn( pettanr.panelConsole);
1311 pettanr.fn( pettanr.artistConsole);
1313 pettanr.fn( pettanr.file);
1314 pettanr.fn( pettanr.finder);
1315 pettanr.fn( pettanr.gallery);
1316 pettanr.fn( pettanr.cabinet);
1318 $(window).ready( pettanr.init);