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 getFileData: function( UIDorFILEorFILEDATA){
105 var _access = FILE_CONTROLER.getFileDataAccess( UIDorFILEorFILEDATA);
106 return _access !== null ? _access.DATA : null;
108 getChildren: function( UIDorFILEorFILEDATA){
109 var _data = FILE_CONTROLER.getFileData( UIDorFILEorFILEDATA);
110 return _data !== null ? _data.children || null : null;
112 getFileDataAccess: function( UIDorFILEorFILEDATA){
113 var _uid, _data, _access;
115 if( typeof UIDorFILEorFILEDATA === 'number'){
116 _data = FILEDATA_RESITER[ UIDorFILEorFILEDATA] || null;
118 if( UIDorFILEorFILEDATA instanceof FileClass){
119 _uid = UIDorFILEorFILEDATA.getUID();
120 _data = FILEDATA_RESITER[ _uid] || null;
122 _data = UIDorFILEorFILEDATA || null;
125 if( _data === null || typeof _data !== 'object') return null;
126 for( var i=0, l = FILEDATA_ACCESS.length; i<l; ++i){
127 _access = FILEDATA_ACCESS[ i];
128 if( _access.DATA === _data) return _access;
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.getFileData( _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 getUID: function ( _filedata){
149 var l = FILEDATA_RESITER.length;
150 for( var i=0; i<l; ++i){
151 if( FILEDATA_RESITER[ i] === _filedata) return i;
155 getSeqentialFiles: function( _file){
156 var _driver = FILE_CONTROLER.getDriver( _file);
157 if( _driver !== null && typeof _driver.getSeqentialFiles === 'function'){
158 _driver.getSeqentialFiles( _file);
161 updateFileAttribute: function( _uid, key, _value, _opt_callback){
162 var _data = FILE_CONTROLER.getFileDataAccess( _uid),
166 getFileAttribute: function( _uid, KEYorKEYARRAY){
167 var _fileData = FILE_CONTROLER.getFileDataAccess( _uid),
168 _type = _fileData.TYPE;
170 move: function( _prentUID, _targetfile, _newFolder, _newIndex, _opt_callback){
171 var _parentData = FILE_CONTROLER.getFileDataAccess( _prentUID),
172 _parentType = _parentData.TYPE,
173 _targetData = FILE_CONTROLER.getFileDataAccess( _targetfile),
174 _targetType = _targetData.TYPE;
176 replace: function( _uid, _file, _newIndex){
179 addEventListener: function( FILEorNULL, _eventType, _callback){
180 var _uid = FILEorNULL instanceof FileClass ? FILEorNULL.getUID() : FILEorNULL;
181 EVENT_LISTENER_RESISTER.push( new FileEventTicketClass( _uid, _eventType, _callback));
183 removeEventListener: function( FILEorNULL, _eventType, _callback){
184 var _uid = FILEorNULL instanceof FileClass ? FILEorNULL.getUID() : FILEorNULL,
186 for(var i=0, l = EVENT_LISTENER_RESISTER.length; i<l; ++i){
187 _ticket = EVENT_LISTENER_RESISTER[i];
188 if( _ticket.fileUID === _uid && _ticket.eventType === _eventType && _ticket.callBack === _callback){
189 EVENT_LISTENER_RESISTER.splice( i, 1);
194 fileEventRellay: function( _targetFile, _targetTree, _event){
195 var _uid = _targetTree.getUID(),
196 _access = TREE_ACCESS_ARRAY[ _uid],
197 l = TREE_ARRAY.length,
199 _access !== undefined && _access.dispatchFileEvent( _event);
200 for(var i=0; i<l; ++i){
202 _tree = TREE_ARRAY[i];
203 _currentFile = _tree.getCurrentFile();
204 if( FILE_CONTROLER.getFileData( _currentFile) === _access.DATA){
205 TREE_ACCESS_ARRAY[ _tree.getUID()].dispatchFileEvent( _event);
212 var TreeClass = function( ROOTFILE_DATA){
213 var UID = TREE_ACCESS_ARRAY.length,
214 PARENT_FILE_RESITER = [],
216 dispatchFileEvent: dispatchFileEvent,
219 EVENT_LISTENER_ARRAY = [],
226 TREE_ACCESS_ARRAY.push( ACCESS);
228 function onDestroy(){
232 function dispatchFileEvent( e){
233 var _eventType = e.eventType,
234 _targetFile = e.targetFile,
235 _uid = _targetFile.getUID(),
236 _ticket, _type, _callback;
237 for(var i=0, l = EVENT_LISTENER_RESISTER.length; i<l; ++i){
238 _ticket = EVENT_LISTENER_RESISTER[i],
239 _type = _ticket.eventType,
240 _callback = _ticket.callBack;
241 if( _eventType === _type && _uid === _ticket.fileUID){
242 _callback( _eventType, _targetFile, e.key, e.value);
244 if( _type === pettanr.file.TREE_EVENT.UPDATE && _eventType === pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES){
245 _callback( _eventType, _targetFile);
253 currentFile = rootFile = new FileClass( this, null, ROOTFILE_DATA);
255 FILE_CONTROLER.getSeqentialFiles( currentFile);
258 getUID: function(){ return UID},
259 getRootFile : function(){
262 getCurrentFile: function(){
265 hierarchy: function(){
266 return PARENT_FILE_RESITER.length;
268 getParentFileAt: function( _index){
269 var l = PARENT_FILE_RESITER.length;
270 if( typeof _index !== 'number' || _index < 0 || _index >= l) return null;
271 return PARENT_FILE_RESITER[ l -1 -_index];
273 down: function( _index){
274 if( typeof _index !== 'number' || _index < 0 || _index >= currentFile.getChildFileLength()) return;
275 PARENT_FILE_RESITER.unshift( currentFile);
276 currentFile = currentFile.getChildFileByIndex( _index);
277 FILE_CONTROLER.getSeqentialFiles( currentFile);
280 up: function( _index){
281 var l = PARENT_FILE_RESITER.length;
282 if( l === 0) return null;
283 if( typeof _index === 'number'){
284 if( _index >= l) return null;
285 currentFile = this.getParentFileAt( _index);
286 PARENT_FILE_RESITER.splice( 0, l -_index);
288 currentFile = PARENT_FILE_RESITER.shift();
290 FILE_CONTROLER.getSeqentialFiles( currentFile);
293 addTreeEventListener: function( _eventType, _callback){
294 FILE_CONTROLER.addEventListener( null, _eventType, _callback);
296 removeTreeEventListener: function( _eventType, _callback){
297 FILE_CONTROLER.removeEventListener( null, _eventType, _callback);
300 FILE_CONTROLER.destroyTree( UID);
305 var FileEventTicketClass = function( UID, _eventType, _callback){
307 this.eventType = _eventType;
308 this.callBack = _callback;
309 this.destroy = function(){
310 this.callBack = _callback = null;
314 var FileEventClass = function( eventType, file, key, value){
315 this.eventType = eventType;
316 this.targetFile = file;
317 this.updatedAttribute = key;
318 this.updatedValue = value;
322 * fileのdataはobjectで保持している。
323 * pettanr.file.の外からファイルをみるときは、FileClassを通して操作する。
324 * fileの変更、それに付随して追加されたイベントは、TreeClassで管理される。
325 * treeがdestryされると、fileのイベントリスナーも全て削除される。
326 * 他の tree も data の共通する currentFile に対してのみは、file の変更イベントを受け取って流す.
329 var FileClass = function( TREE, parentFile, data){
333 var uid = FILE_CONTROLER.getUID( data),
337 uid = FILEDATA_RESITER.length;
338 FILEDATA_RESITER.push( data);
341 FILEDATA_ACCESS.push(
344 updateParent: updateParent,
345 dispatchFileEvent: dispatchEvent
349 function updateParent( _parent){
350 parentFile = _parent;
352 function dispatchEvent( e){
353 FILE_CONTROLER.fileEventRellay( instance, TREE, e);
357 this.init = function(){
360 this.getUID = function(){
364 * ファイル構造は TRON のような ハイパーリンク方式 だが、文脈上の 親ファイルが存在する場合がある.
366 this.getChildFileByIndex = function( _index){
367 var _children = FILE_CONTROLER.getChildren( instance );
368 if( typeof _index !== 'number' || _index < 0 || typeof _children.length !== 'number' || _index >= _children.length) return null;
369 var _file = new FileClass( TREE, this, _children[ _index]);
373 this.move = function( _newFolder, _newIndex, opt_callback){
374 TREE.move( parentFile, UID, _newFolder, _newIndex, opt_callback);
376 this.replace = function( _newIndex, opt_callback){
377 TREE.replace( parentFile, UID, _newIndex, opt_callback);
379 this.destroy = function(){
380 var _access = FILE_CONTROLER.getFileDataAccess( instance );
381 _index = getChildIndex( FILEDATA_ACCESS, _access );
382 if( _index === -1 || _access === null) return;
383 FILEDATA_ACCESS.splice( _index, 1);
384 TREE = parentFile = data = null;
385 delete _access.DATA, _access.updateParent, _access.dispatchFileEvent;
388 FileClass.prototype = {
389 isChildFile: function( _FILEorFILEDATA){
390 return this.getChildFileIndex( _FILEorFILEDATA) !== -1;
392 getSeqentialFiles: function(){
393 FILE_CONTROLER.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 children !== null && typeof children.length === 'number' ? children.length : 0;
405 getChildFileIndex: function( _FILEorFILEDATA){
406 var children = FILE_CONTROLER.getChildren( this);
408 if( children === null || typeof children.length !== 'number') return -1;
409 var l = children.length,
410 _fileData = FILE_CONTROLER.getFileData( _FILEorFILEDATA);
411 if( _fileData === null) return -1;
412 for(var i=0; i<l; ++i){
413 if( children[ i] === _fileData) return i;
418 var driver = FILE_CONTROLER.getDriver( this );
419 if( typeof driver.getName === 'function'){
420 return driver.getName( this );
422 return FileDriverBase.getName( this);
424 getThumbnail: function(){
425 var driver = FILE_CONTROLER.getDriver( this);
426 if( typeof driver.getThumbnail === 'function'){
427 return driver.getThumbnail( this);
429 return FileDriverBase.getThumbnail( this);
432 var _data = FILE_CONTROLER.getFileData( this);
433 return typeof _data.type === 'number' ? _data.type : pettanr.file.FILE_TYPE.UNKNOWN;
435 getState: function(){
436 var _data = FILE_CONTROLER.getFileData( this);
437 return typeof _data.state === 'number' ? _data.state : pettanr.file.FILE_STATE.OK;
439 isWritable: function(){
440 return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.WRITE);
442 isSortable: function(){
443 return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.SORT);
445 isCreatable: function(){
446 return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.CREATE);
448 isRenamable: function(){
449 return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.RENAME);
455 write: function( _newName, _newData){
467 onDelete: function(){
475 var FileDriverBase = {
476 getSeqentialFiles: function( _file){
478 getName: function( _file){
479 var _data = FILE_CONTROLER.getFileData( _file);
480 return _data.name || 'No Name';
482 getThumbnail: function( _file){
483 var _data = FILE_CONTROLER.getFileData( _file);
486 if( _type === pettanr.file.FILE_TYPE.FOLDER){
487 _className = 'folder';
489 if( _type === pettanr.file.FILE_TYPE.IMAGE){
492 if( _type === pettanr.file.FILE_TYPE.TEXT){
495 if( _type === pettanr.file.FILE_TYPE.HTML){
498 if( _type === pettanr.file.FILE_TYPE.CSV){
501 if( _type === pettanr.file.FILE_TYPE.JSON){
504 if( _type === pettanr.file.FILE_TYPE.XML){
509 className: ' file-type-' + _className
512 getUpdatePolicy: function( _file){
514 return pettanr.file.FILE_UPDATE_POLICY.SRWC;
519 write: function( _newName, _newData){
522 onCreate: function(){
531 onDelete: function(){
536 function getFileObject( TREE, parentFile, data){
537 var _file = FILE_OBJECT_POOL.length > 0 ? FILE_OBJECT_POOL.shift() : new FileClass();
538 _file.init( TREE, parentFile, data);
542 var ROOT_FILEDATA = {
544 type: FILE_TYPE_IS_FOLDER,
547 SYSTEM_TREE = FILE_CONTROLER.createTree( ROOT_FILEDATA),
548 ROOT_FILE = SYSTEM_TREE.getRootFile();
550 function createFolderUnderRoot( _fileData){
551 ROOT_FILEDATA.children.push( _fileData);
552 FILE_CONTROLER.getFileDataAccess( ROOT_FILE)
553 .dispatchFileEvent( new FileEventClass( pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES, ROOT_FILE, 'children', null));
555 function createFileEvent( _eventType, _file, _key, _value){
556 return new FileEventClass( _eventType, _file, _key, _value)
558 function createFileTypeID(){
559 return ++numFileType;
564 //REQUEST_CONTROLER.init();
565 //FILE_CONTROLER.init();
566 delete pettanr.file.init;
568 resisterDriver: function( _driver){
569 _driver.prototype = FileDriverBase;
574 createFolderUnderRoot: createFolderUnderRoot,
575 getFileDataAccess: FILE_CONTROLER.getFileDataAccess,
576 getFileData: FILE_CONTROLER.getFileData,
577 getJson: REQUEST_CONTROLER.getJson,
578 createFileEvent: createFileEvent,
579 createFileTypeID: createFileTypeID
582 createTree: function( _rootFile){
583 return FILE_CONTROLER.createTree( _rootFile);
585 isTreeInstance: function( _tree){
586 return _tree instanceof TreeClass;
588 isFileInstance: function( _file){
589 return _file instanceof FileClass;
593 FOLDER: FILE_TYPE_IS_FOLDER,
594 IMAGE: createFileTypeID(),
595 TEXT: createFileTypeID(),
596 HTML: createFileTypeID(),
597 CSV: createFileTypeID(),
598 JSON: createFileTypeID(),
599 XML: createFileTypeID()
608 FILE_UPDATE_POLICY: {
609 ____: parseInt( '0000', 2),
610 ___C: parseInt( '0001', 2), // hasCreateMenu
611 __W_: parseInt( '0010', 2), // isWritable
612 __WC: parseInt( '0011', 2), // isWritable
613 _R__: parseInt( '0000', 2), // isRenamable
614 _R_C: parseInt( '0101', 2), // hasCreateMenu
615 _RW_: parseInt( '0110', 2), // isWritable
616 _RWC: parseInt( '0111', 2), // isWritable
617 S___: parseInt( '1000', 2), // childrenIsSortable
618 S__C: parseInt( '1001', 2),
619 S_W_: parseInt( '1010', 2),
620 S_WC: parseInt( '1011', 2),
621 SR__: parseInt( '1000', 2),
622 SR_C: parseInt( '1101', 2),
623 SRW_: parseInt( '1110', 2),
624 SRWC: parseInt( '1111', 2),
631 UPDATE: 'onTreeUpdate'
634 UPDATE_ATTRIVUTE: 'onFileUpdate',
635 GET_SEQENTIAL_FILES:'gotSeqentilFiles'
637 FILE_DATA_PROPERTY_RESERVED: [
638 'children', 'driver', 'state', 'type', 'name'
643 pettanr.finder = ( function(){
644 var FINDER_ARRAY = [],
645 ELM_ORIGIN_FINDER_LOCATION_ITEM = pettanr.util.pullHtmlAsTemplete( 'templete-finder-location-item'),
646 ELM_ORIGIN_FINDER_ICON = pettanr.util.pullHtmlAsTemplete( 'templete-finder-icon'),
647 ELM_ORIGIN_CONTAINER = pettanr.util.pullHtmlAsTemplete( 'templete-finder-container'),
648 ICON_HEIGHT = pettanr.util.getElementSize( ELM_ORIGIN_FINDER_ICON).height,
649 ICON_CLASSNAME = ELM_ORIGIN_FINDER_ICON.getElementsByTagName( 'div')[0].className,
650 FINDER_ICON_POOL = [],
651 BREAD_OBJECT_POOL = [];
653 var FinderIconClass = function(){
655 ELM_WRAPPER = ELM_ORIGIN_FINDER_ICON.cloneNode( true),
656 ELM_THUMBNAIL = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-thumbnail', 'div')[0],
657 ELM_FILENAME = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-filename', 'div')[0],
658 file, w, index, style, instansce, callback;
660 ELM_WRAPPER.onclick = onClick;
666 var _thumb = file.getThumbnail();
668 ELM_THUMBNAIL.className = ICON_CLASSNAME + ' has-thumbnail';
669 ELM_THUMBNAIL.style.backgroundImage = [ 'url(', _thumb.image, ')'].join( '');
671 ELM_THUMBNAIL.className = ICON_CLASSNAME + ' ' +_thumb.className;
672 ELM_THUMBNAIL.style.backgroundImage = '';
674 ELM_FILENAME.innerHTML = file.getName();
677 ELM_WRAPPER.style.top = (index * ICON_HEIGHT) +'px';
679 function onCollect(){
680 elmContainer.removeChild( ELM_WRAPPER);
682 FINDER_ICON_POOL.push( instansce);
686 init: function( _file, _elmContainer, _w, _index, _style, _callback){
688 if( elmContainer !== _elmContainer){
689 _elmContainer.appendChild( ELM_WRAPPER);
690 elmContainer = _elmContainer;
696 if( index !== _index){
700 callback = _callback;
703 index: function( _index){
707 style: function( _style){
711 onResize: function( w){
715 elmContainer.removeChild( ELM_WRAPPER);
716 file = elmContainer = null;
717 FINDER_ICON_POOL.push( instansce);
721 function updateIconPosition( _style, _w, _index, _elm){
724 var BreadcrumbClass = function(){
726 ELM_WRAPPER = ELM_ORIGIN_FINDER_LOCATION_ITEM.cloneNode( true),
727 ELM_FILENAME = ELM_WRAPPER.getElementsByTagName( 'a')[0],
728 file, w, index, instansce,
730 ELM_WRAPPER.onclick = onClick;
732 ELM_FILENAME.className = 'file-icon-' +file.getType();
733 ELM_FILENAME.innerHTML = file.getName();
735 function resize( index){
736 ELM_WRAPPER.style.left = (index * 90) +'px';
744 init: function( _file, _elmContainer, _index, _callback){
746 if( elmContainer !== _elmContainer){
747 _elmContainer.appendChild( ELM_WRAPPER);
748 elmContainer = _elmContainer;
754 if( index !== _index){
758 callback = _callback;
761 index: function( _index){
765 onResize: function( w){
769 elmContainer.removeChild( ELM_WRAPPER);
770 file = elmContainer = null;
771 BREAD_OBJECT_POOL.push( this);
776 var FinderClass = function( ELM_CONTAINER, tree, detailSwitchEnabled, styleSwitchEnabled, actionSwitchEnabled){
779 elmContainer = ELM_ORIGIN_CONTAINER.cloneNode( true),
780 elmLocation = elmContainer.getElementsByTagName( 'ul')[0],
781 nodesDiv = elmContainer.getElementsByTagName( 'div'),
782 elmSidebarButton = nodesDiv[1],
783 elmStyleButton = nodesDiv[2],
784 elmActionButton = nodesDiv[3],
785 elmBody = nodesDiv[ nodesDiv.length -1],
786 //tree = pettanr.file.createTree( TREE_TYPE),
789 headH = pettanr.util.getElementSize( ELM_ORIGIN_FINDER_ICON).height,
793 size = pettanr.util.getElementSize( ELM_ORIGIN_FINDER_ICON),
799 tree.addTreeEventListener( pettanr.file.TREE_EVENT.UPDATE, draw);
802 var l = tree.hierarchy() +1,
803 m = BREAD_ARRAY.length,
805 for(var i=0; i<l; ++i){
806 _file = i !== l-1 ? tree.getParentFileAt( i) : tree.getCurrentFile();
808 BREAD_ARRAY[ i].init( _file, elmLocation, i, onHeadClick);
810 BREAD_ARRAY.push( getBreadcrumb( _file, elmLocation, i, onHeadClick));
813 while( l < BREAD_ARRAY.length){
814 BREAD_ARRAY.pop().destroy();
817 l = _file.getChildFileLength();
818 m = ICON_ARRAY.length;
822 ICON_ARRAY[ i].init( _file.getChildFileByIndex( i), elmBody, w, i, style, onBodyClick);
824 ICON_ARRAY.push( getFinderIcon( _file.getChildFileByIndex( i), elmBody, w, i, style, onBodyClick));
827 while( l < ICON_ARRAY.length){
828 ICON_ARRAY.pop().destroy();
831 function onHeadClick( i){
832 var l = BREAD_ARRAY.length -1;
834 var _file = tree.getParentFileAt( i);
841 function onBodyClick( i){
842 var l = ICON_ARRAY.length;
844 var _file = tree.getCurrentFile().getChildFileByIndex( i);
845 if( _file !== null && ( _file.getChildFileLength() > 0 || _file.getType() === pettanr.file.FILE_TYPE.FOLDER)){
852 this.init = function(){
853 ELM_CONTAINER.appendChild( elmContainer);
854 //$( elmLocation).click( onHeadClick);
855 //$( elmContainer).click( onBodyClick);
856 var position = pettanr.util.getAbsolutePosition( elmLocation);
859 bodyY = pettanr.util.getAbsolutePosition( elmBody).y;
862 this.onOpen = function(){
863 this.init !== undefined && this.init();
866 this.onClose = function(){
869 this.onWindowResize = function( _w, _h){
873 function getFinderIcon( _file, _elmContainer, w, index, style, callback){
875 if( FINDER_ICON_POOL.length > 0){
876 _icon = FINDER_ICON_POOL.shift();
878 _icon = new FinderIconClass();
880 _icon.init( _file, _elmContainer, w, index, style, callback);
884 function getBreadcrumb( _file, _elmContainer, index, callback){
886 if( BREAD_OBJECT_POOL.length > 0){
887 _bread = BREAD_OBJECT_POOL.shift();
889 _bread = new BreadcrumbClass();
891 _bread.init( _file, _elmContainer, index, callback);
899 createFinder: function( _elmTarget, _tree, detailSwitchEnabled, styleSwitchEnabled, actionSwitchEnabled){
900 var _finder = new FinderClass( _elmTarget, _tree, detailSwitchEnabled, styleSwitchEnabled, actionSwitchEnabled);
901 FINDER_ARRAY.push( _finder);
904 createFinderHead: function(){
907 resisterFinderPane: function( _finderPane){
910 isFinderInstance: function( _finder){
911 return _finder instanceof FinderClass;
917 pettanr.driver = ( function(){
918 var MyAuthorID = 'current_author' in window ? current_author.id : 1,
919 MyArtistID = 'current_artist' in window ? current_artist.id : 1,
921 getSeqentialFiles: function( _file){
922 var _data = FileAPI.getFileData( _file),
923 _json = _data !== null ? _data.json : null;
924 if( typeof _json === 'string'){
925 FileAPI.getJson( _file, _json, onLoadJson, onErrorJson);
926 _data.state = pettanr.file.FILE_STATE.LOADING;
930 getName: function( _file){
931 var _data = FileAPI.getFileData( _file),
932 _type = _data !== null ? _data.type : null;
933 if( _type === pettanr.driver.FILE_TYPE.PICTURE){
934 return [ _data.id, _data.ext ].join( '.');
936 if( _type === pettanr.driver.FILE_TYPE.PANEL){
937 return [ _data.t, ':', _data.comic.name || _data.comic.title ].join( '');
939 if( _type === pettanr.driver.FILE_TYPE.ARTIST){
940 return [ _data.id , ':', _data.name, '画伯' ].join( '');
942 if( _type === pettanr.driver.FILE_TYPE.AUTHOR){
943 return [ _data.id , ':', _data.name, '先生' ].join( '');
945 return _data.name || _data.title;
947 getThumbnail: function( _file){
948 var _data = FileAPI.getFileData( _file);
949 _type = _data !== null ? _data.type : null;
950 if( _type === pettanr.driver.FILE_TYPE.PICTURE){
951 return { image: [ pettanr.CONST.RESOURCE_PICTURE_PATH, 'thumbnail/', _data.id, '.', _data.ext ].join( '')};
953 if( _data === FILE_DATA_COMIC_ROOT){
954 return { className: 'file-type-cabinet'};
956 if( _type === pettanr.driver.FILE_TYPE.COMIC){
957 return { className: 'file-type-comic'};
959 if( _type === pettanr.driver.FILE_TYPE.PANEL){
960 return { className: 'file-type-panel'};
962 if( _type === pettanr.driver.FILE_TYPE.AUTHOR){
963 return { className: 'file-type-author'};
965 if( _type === pettanr.driver.FILE_TYPE.ARTIST){
966 return { className: 'file-type-artist'};
968 if( _type === pettanr.driver.FILE_TYPE.FOLDEER){
969 return { className: 'file-type-folder'};
971 return { className: 'file-type-folder'};
974 FileAPI = pettanr.file.resisterDriver( Driver),
975 FILE_DATA_SERVICE_ROOT = {
976 name: 'PettanR root',
977 type: pettanr.file.FILE_TYPE.FOLDER,
980 FILE_DATA_COMIC_ROOT = {
982 type: pettanr.file.FILE_TYPE.FOLDER,
985 json: pettanr.CONST.URL_PANELS_JSON
987 FILE_DATA_PICTURE_ROOT = {
989 type: pettanr.file.FILE_TYPE.FOLDER,
992 json: pettanr.CONST.URL_ORIGINAL_PICTURES_JSON
994 FILE_DATA_MY_COMICS_ROOT = {
996 type: pettanr.file.FILE_TYPE.FOLDER,
999 FILE_DATA_MY_PICTURES_ROOT = {
1000 name: 'My Pictures',
1001 type: pettanr.file.FILE_TYPE.FOLDER,
1004 FILE_DATA_AUTHOR_ROOT = {
1006 type: pettanr.file.FILE_TYPE.FOLDER,
1009 FILE_DATA_ARTIST_ROOT = {
1011 type: pettanr.file.FILE_TYPE.FOLDER,
1014 FILE_DATA_LICENSE_ROOT = {
1015 name: 'Original Licenses',
1016 type: pettanr.file.FILE_TYPE.FOLDER,
1019 FILE_DATA_BALLOON_ROOT = {
1020 name: 'Balloon templetes',
1021 type: pettanr.file.FILE_TYPE.FOLDER,
1028 RESOURCE_PICTURE_ARRAY = [],
1029 BALLOON_TEMPLETE_ARRAY = [],
1030 ORIGINAL_LICENSE_ARRAY = [],
1031 BASIC_LICENSES = 'cc_by,cc_nc,cc_nd,cc_sa,keep_aspect_ratio,no_convert,no_flip,no_resize'.split( ',');
1032 FILE_DATA_SERVICE_ROOT.children.push( FILE_DATA_COMIC_ROOT, FILE_DATA_PICTURE_ROOT, FILE_DATA_LICENSE_ROOT, FILE_DATA_BALLOON_ROOT);
1033 FILE_DATA_COMIC_ROOT.children.push( FILE_DATA_MY_COMICS_ROOT, FILE_DATA_AUTHOR_ROOT);
1034 FILE_DATA_PICTURE_ROOT.children.push( FILE_DATA_MY_PICTURES_ROOT, FILE_DATA_ARTIST_ROOT);
1036 FileAPI.createFolderUnderRoot( FILE_DATA_SERVICE_ROOT);
1038 function onLoadJson( _file, _json){
1039 var _access = FileAPI.getFileDataAccess( _file),
1040 _data = _access !== null ? _access.DATA : null,
1042 if( _data === null){
1043 onErrorJson( _file);
1046 _data.state = pettanr.file.FILE_STATE.OK;
1047 if( l === 0) return;
1048 for(var i=0; i<l; ++i){
1049 buildFileData( _json[ i], _data);
1051 _access.dispatchFileEvent( FileAPI.createFileEvent( pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES, _file, 'children', null));
1053 function onErrorJson( _file){
1054 var _data = FileAPI.getFileData( _file);
1055 if( _data !== null){
1056 _data.state = pettanr.file.FILE_STATE.ERROR;
1059 function buildFileData( _data, _parent){
1063 if( _parent === FILE_DATA_COMIC_ROOT){
1064 _data.type = pettanr.driver.FILE_TYPE.PANEL;
1065 _array = PANEL_ARRAY;
1067 if( _parent === FILE_DATA_PICTURE_ROOT){
1068 _data.type = pettanr.driver.FILE_TYPE.PICTURE;
1069 _array = RESOURCE_PICTURE_ARRAY;
1071 // original_license を含まなければ、license object を削除して ビットデータ で保持
1072 // original_license なら ファイルを作る buildFileData( _license, FILE_DATA_LICENSE_ROOT)
1073 var _license = _data.license,
1074 _Math_pow = Math.pow,
1076 if( typeof _license === 'object'){
1077 for( i=0, l=BASIC_LICENSES.length; i<l; ++i){
1078 if( typeof _license[ BASIC_LICENSES[ i]] === 'number'){
1079 _bits += _Math_pow( 2, i);
1082 _data.license = _bits;
1085 if( _parent === FILE_DATA_LICENSE_ROOT){
1086 _data.type = pettanr.driver.FILE_TYPE.LICENSE;
1087 _array = ORIGINAL_LICENSE_ARRAY;
1090 _data.driver = Driver;
1092 // _array に _data を格納 または 上書き
1093 if( typeof _id === 'number'){
1094 var __data = _array[ _id];
1096 for( var key in _data){
1097 __data[ key ] = _data[ key ];
1099 _data = __data; // このタイミングで参照が切れるので注意!!
1101 _array[ _id] = _data;
1105 if( _parent === FILE_DATA_COMIC_ROOT){
1106 if( _data.comic && _data.author){
1107 var _comic = getFolderData( _data, 'comic', FILE_DATA_COMIC_ROOT),
1108 _comicList = getFolderData( _data, 'author', FILE_DATA_AUTHOR_ROOT);
1109 _comic.children.push( _data);
1110 pettanr.util.getIndex( _comicList.children, _comic) === -1 && _comicList.children.push( _comic);
1111 _comicList.id === MyAuthorID && pettanr.util.getIndex( FILE_DATA_MY_COMICS_ROOT.children, _comic) === -1 && FILE_DATA_MY_COMICS_ROOT.children.push( _comic);
1113 // picture data をファイルに取り出し
1114 var _elements = _data.panel_elements || [],
1116 for(var i=0, l=_elements.length; i<l; ++i){
1117 _elm = _elements[ i];
1118 if( _elm.resource_picture){
1119 _elm.resource_picture = buildFileData( _elm.resource_picture, FILE_DATA_PICTURE_ROOT); // 上記参照切れに備えてここで上書き
1121 if( _elm.resource_picture_id && RESOURCE_PICTURE_ARRAY[ _elm.resource_picture_id]){
1122 _elm.resource_picture = RESOURCE_PICTURE_ARRAY[ _elm.resource_picture_id];
1126 if( _parent === FILE_DATA_PICTURE_ROOT){
1128 var _pictureList = getFolderData( _data, 'artist', FILE_DATA_ARTIST_ROOT);
1129 pettanr.util.getIndex( _pictureList.children, _data) === -1 && _pictureList.children.push( _data);
1130 _pictureList.id === MyArtistID && pettanr.util.getIndex( FILE_DATA_MY_PICTURES_ROOT.children, _data) === -1 && FILE_DATA_MY_PICTURES_ROOT.children.push( _data);
1137 * folder には Artist, Author, Comic,
1139 function getFolderData( _data, _key, _parentData){
1140 if( typeof _data[ _key ] !== 'object') return {children:[]};
1142 _id = _data[ _key ].id,
1144 if( typeof _id !== 'number') return {children:[]};
1146 _array = _parentData === FILE_DATA_ARTIST_ROOT ? ARTIST_ARRAY :
1147 _parentData === FILE_DATA_AUTHOR_ROOT ? AUTHOR_ARRAY :
1148 _parentData === FILE_DATA_COMIC_ROOT ? COMIC_ARRAY : []
1150 if( typeof _array[ _id] === 'object'){
1151 var __data = _array[ _id];
1152 for( var i in _data[ _key ]){
1153 __data[ i ] = _data[ _key ][ i ];
1155 return _data[ _key ] = __data;// このタイミングで参照が切れるので注意!!
1157 // 以下は folder がなく 新規に作られる場合.
1158 _ret = _array[ _id ] = _data[ _key ];
1160 _ret.name = _ret.title;
1164 _ret.driver = Driver;
1166 if( _parentData === FILE_DATA_AUTHOR_ROOT){
1167 _ret.type = pettanr.driver.FILE_TYPE.AUTHOR;
1169 if( _parentData === FILE_DATA_ARTIST_ROOT){
1170 _ret.type = pettanr.driver.FILE_TYPE.ARTIST;
1172 if( _parentData === FILE_DATA_COMIC_ROOT){
1173 _ret.type = pettanr.driver.FILE_TYPE.COMIC;
1176 _ret.type = pettanr.file.FILE_TYPE.FOLDER;
1179 _parentData.children.push( _ret);
1185 createComicTree: function(){
1186 return pettanr.file.createTree( FILE_DATA_SERVICE_ROOT); //FILE_DATA_COMIC_ROOT);
1188 createPictureTree: function(){
1189 return pettanr.file.createTree( FILE_DATA_PICTURE_ROOT);
1191 createServiceTree: function(){
1192 return pettanr.file.createTree( FILE_DATA_SERVICE_ROOT);
1194 isPettanrFileInstance: function( _file){
1195 if( pettanr.file.isPettanFileInstance( _file) === true){
1196 var _data = FileAPI.getFileData( _file);
1197 return _data !== null && _data.driver === Driver;
1202 COMIC: FileAPI.createFileTypeID(),
1203 PANEL: FileAPI.createFileTypeID(),
1204 PICTURE: FileAPI.createFileTypeID(),
1205 PANEL_PICTURE: FileAPI.createFileTypeID(),
1206 BALLOON: FileAPI.createFileTypeID(),
1207 AUTHOR: FileAPI.createFileTypeID(),
1208 ARTIST: FileAPI.createFileTypeID(),
1209 LICENSE: FileAPI.createFileTypeID()
1215 pettanr.gallery = ( function(){
1217 elmContainer = document.getElementById( 'gallery'),
1221 init: function( _option){
1223 delete pettanr.gallery.init;
1225 firstOpen: function(){
1226 finder = pettanr.finder.createFinder( elmContainer, pettanr.driver.createPictureTree());
1227 delete pettanr.gallery.firstOpen;
1230 pettanr.gallery.firstOpen !== undefined && pettanr.gallery.firstOpen();
1234 onClose: function(){
1237 onWindowResize: function( _w, _h){
1238 finder.onWindowResize( _w, _h);
1243 pettanr.cabinet = ( function(){
1245 elmContainer = document.getElementById( 'cabinet'),
1249 init: function( _option){
1251 delete pettanr.cabinet.init;
1253 firstOpen: function(){
1254 finder = pettanr.finder.createFinder( elmContainer, pettanr.driver.createComicTree());
1255 delete pettanr.cabinet.firstOpen;
1258 pettanr.cabinet.firstOpen !== undefined && pettanr.cabinet.firstOpen();
1262 onClose: function(){
1265 onWindowResize: function( _w, _h){
1266 finder.onWindowResize( _w, _h);
1275 pettanr.fn( pettanr.view);
1276 pettanr.fn( pettanr.overlay);
1277 pettanr.fn( pettanr.key);
1278 pettanr.fn( pettanr.balloon);
1280 pettanr.fn( pettanr.editor);
1281 pettanr.fn( pettanr.comicConsole);
1282 pettanr.fn( pettanr.uploadConsole);
1284 pettanr.fn( pettanr.file);
1285 pettanr.fn( pettanr.finder);
1286 pettanr.fn( pettanr.gallery);
1287 pettanr.fn( pettanr.cabinet);
1289 $(window).ready( pettanr.init);