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_REGISTER = [],
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_REGISTER.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_REGISTER.length; i<l; ++i){
165 _ticket = EVENT_LISTENER_REGISTER[i];
166 if( _ticket.fileUID === _uid && _ticket.eventType === _eventType && _ticket.callBack === _callback){
167 EVENT_LISTENER_REGISTER.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_REGISTER.length; i<l; ++i){
216 _ticket = EVENT_LISTENER_REGISTER[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;
360 delete _access.updateParent;
361 delete _access.dispatchFileEvent;
365 FileClass.prototype = {
366 isChildFile: function( _FILEorFILEDATA){
367 return this.getChildFileIndex( _FILEorFILEDATA) !== -1;
369 getSeqentialFiles: function(){
370 var _driver = FILE_CONTROLER.getDriver( this );
371 if( _driver !== null && typeof _driver.getSeqentialFiles === 'function'){
372 _driver.getSeqentialFiles( this );
375 addEventListener: function( _eventType, _callback){
376 FILE_CONTROLER.addEventListener( this, _eventType, _callback);
378 removeEventListener: function( _eventType, _callback){
379 FILE_CONTROLER.removeEventListener( this, _eventType, _callback);
381 getChildFileLength: function(){
382 var children = FILE_CONTROLER.getChildren( this);
383 return Type.isArray( children ) === true ? children.length : -1;
385 getChildFileIndex: function( _FILEorFILEDATA){
386 var children = FILE_CONTROLER.getChildren( this);
387 if( Type.isArray( children.length ) === false ) return -1;
388 var l = children.length,
389 _fileData = FILE_CONTROLER.getFileData( _FILEorFILEDATA);
390 if( _fileData === null) return -1;
391 for(var i=0; i<l; ++i){
392 if( children[ i] === _fileData) return i;
397 var driver = FILE_CONTROLER.getDriver( this );
398 if( typeof driver.getName === 'function'){
399 return driver.getName( this );
401 return FileDriverBase.getName( this);
403 getThumbnail: function(){
404 var driver = FILE_CONTROLER.getDriver( this);
405 if( typeof driver.getThumbnail === 'function'){
406 return driver.getThumbnail( this);
408 return FileDriverBase.getThumbnail( this);
411 var _data = FILE_CONTROLER.getFileData( this);
412 return typeof _data.type === 'number' ? _data.type : pettanr.file.FILE_TYPE.UNKNOWN;
414 getState: function(){
415 var _data = FILE_CONTROLER.getFileData( this);
416 return typeof _data.state === 'number' ? _data.state : pettanr.file.FILE_STATE.OK;
418 getSummary: function(){
419 var driver = FILE_CONTROLER.getDriver( this );
420 if( typeof driver.getSummary === 'function'){
421 return driver.getSummary( this );
423 return FileDriverBase.getSummary( this);
425 isWritable: function(){
426 return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.WRITE);
428 isSortable: function(){
429 return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.SORT);
431 isCreatable: function(){
432 return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.CREATE);
434 isRenamable: function(){
435 return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.RENAME);
441 write: function( _newName, _newData){
444 viwerApplicationList: function(){
445 var driver = FILE_CONTROLER.getDriver( this );
446 if( typeof driver.viwerApplicationList === 'function'){
447 return driver.viwerApplicationList( this );
449 return FileDriverBase.viwerApplicationList( this );
451 editorApplicationList: function(){
452 var driver = FILE_CONTROLER.editorApplicationList( this );
453 if( typeof driver.editorApplicationList === 'function'){
454 return driver.editorApplicationList( this );
456 return FileDriverBase.viwerApps( this );
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 getSummary: function( _file ){
513 var _data = FILE_CONTROLER.getFileData( _file ),
515 if( _type === pettanr.file.FILE_TYPE.FOLDER){
518 if( _type === pettanr.file.FILE_TYPE.IMAGE){
521 if( _type === pettanr.file.FILE_TYPE.TEXT){
524 if( _type === pettanr.file.FILE_TYPE.HTML){
525 return 'html document file';
527 if( _type === pettanr.file.FILE_TYPE.CSV){
528 return 'csv daat file';
530 if( _type === pettanr.file.FILE_TYPE.JSON){
531 return 'json data file';
533 if( _type === pettanr.file.FILE_TYPE.XML){
534 return 'xml data file';
538 getUpdatePolicy: function( _file){
540 return pettanr.file.FILE_UPDATE_POLICY.SRWC;
545 write: function( _newName, _newData){
548 viwerApplicationList: function(){
551 editorApplicationList: function(){
554 onCreate: function(){
563 onDelete: function(){
568 var ROOT_FILEDATA = {
570 type: FILE_TYPE_IS_FOLDER,
573 SYSTEM_TREE = FILE_CONTROLER.createTree( ROOT_FILEDATA),
574 ROOT_FILE = SYSTEM_TREE.getRootFile();
576 function createFolderUnderRoot( _fileData){
577 ROOT_FILEDATA.children.push( _fileData);
578 FILE_CONTROLER.getFileDataAccess( ROOT_FILE)
579 .dispatchFileEvent( new FileEventClass( pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES, ROOT_FILE, 'children', null));
581 function createFileEvent( _eventType, _file, _key, _value){
582 return new FileEventClass( _eventType, _file, _key, _value);
584 function createFileTypeID(){
585 return ++numFileType;
590 //REQUEST_CONTROLER.init();
591 //FILE_CONTROLER.init();
592 delete pettanr.file.init;
594 registerDriver: function( _driver){
595 _driver.prototype = FileDriverBase;
600 createFolderUnderRoot: createFolderUnderRoot,
601 getFileDataAccess: FILE_CONTROLER.getFileDataAccess,
602 getFileData: FILE_CONTROLER.getFileData,
603 getJson: REQUEST_CONTROLER.getJson,
604 createFileEvent: createFileEvent,
605 createFileTypeID: createFileTypeID
608 createTree: function( _rootFile){
609 return FILE_CONTROLER.createTree( _rootFile);
611 isTreeInstance: function( _tree){
612 return _tree instanceof TreeClass;
614 isFileInstance: function( _file){
615 return _file instanceof FileClass;
619 FOLDER: FILE_TYPE_IS_FOLDER,
620 IMAGE: createFileTypeID(),
621 TEXT: createFileTypeID(),
622 HTML: createFileTypeID(),
623 CSV: createFileTypeID(),
624 JSON: createFileTypeID(),
625 XML: createFileTypeID()
634 FILE_UPDATE_POLICY: {
635 ____: parseInt( '0000', 2),
636 ___C: parseInt( '0001', 2), // hasCreateMenu
637 __W_: parseInt( '0010', 2), // isWritable
638 __WC: parseInt( '0011', 2), // isWritable
639 _R__: parseInt( '0000', 2), // isRenamable
640 _R_C: parseInt( '0101', 2), // hasCreateMenu
641 _RW_: parseInt( '0110', 2), // isWritable
642 _RWC: parseInt( '0111', 2), // isWritable
643 S___: parseInt( '1000', 2), // childrenIsSortable
644 S__C: parseInt( '1001', 2),
645 S_W_: parseInt( '1010', 2),
646 S_WC: parseInt( '1011', 2),
647 SR__: parseInt( '1000', 2),
648 SR_C: parseInt( '1101', 2),
649 SRW_: parseInt( '1110', 2),
650 SRWC: parseInt( '1111', 2),
657 UPDATE: 'onTreeUpdate'
660 UPDATE_ATTRIVUTE: 'onFileUpdate',
661 GET_SEQENTIAL_FILES:'gotSeqentilFiles'
663 FILE_DATA_PROPERTY_RESERVED: [
664 'children', 'driver', 'state', 'type'
669 pettanr.finder = ( function(){
670 var FINDER_ARRAY = [],
671 ELM_ORIGIN_FINDER_LOCATION_ITEM = pettanr.util.pullHtmlAsTemplete( 'templete-finder-location-item'),
672 ELM_ORIGIN_FINDER_ICON = pettanr.util.pullHtmlAsTemplete( 'templete-finder-icon'),
673 ELM_ORIGIN_CONTAINER = pettanr.util.pullHtmlAsTemplete( 'templete-finder-container'),
674 ICON_HEIGHT = pettanr.util.getElementSize( ELM_ORIGIN_FINDER_ICON).height,
675 ICON_CLASSNAME = 'finder-icon-thumbnail',
676 FINDER_ICON_POOL = [],
677 BREAD_OBJECT_POOL = [];
679 var FinderIconClass = function(){
681 ELM_WRAPPER = ELM_ORIGIN_FINDER_ICON.cloneNode( true),
682 ELM_THUMBNAIL = pettanr.util.getElementsByClassName( ELM_WRAPPER, ICON_CLASSNAME )[0],
683 ELM_FILENAME = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-filename' )[0],
684 ELM_DESCRIPTION = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-summary' )[0],
685 file, w, index, style, instansce, callback;
687 ELM_WRAPPER.onclick = onClick;
693 var _thumb = file.getThumbnail();
695 ELM_THUMBNAIL.className = ICON_CLASSNAME + ' has-thumbnail';
696 ELM_THUMBNAIL.style.backgroundImage = [ 'url(', _thumb.image, ')'].join( '');
698 ELM_THUMBNAIL.className = ICON_CLASSNAME + ' ' +_thumb.className;
699 ELM_THUMBNAIL.style.backgroundImage = '';
701 ELM_FILENAME.innerHTML = file.getName();
702 ELM_DESCRIPTION.innerHTML = file.getSummary();
705 ELM_WRAPPER.style.top = (index * ICON_HEIGHT) +'px';
707 function onCollect(){
708 elmContainer.removeChild( ELM_WRAPPER);
710 FINDER_ICON_POOL.push( instansce);
714 init: function( _file, _elmContainer, _w, _index, _style, _callback){
716 if( elmContainer !== _elmContainer){
717 _elmContainer.appendChild( ELM_WRAPPER);
718 elmContainer = _elmContainer;
724 if( index !== _index){
728 callback = _callback;
731 index: function( _index){
735 style: function( _style){
739 onResize: function( w){
743 elmContainer.removeChild( ELM_WRAPPER);
744 file = elmContainer = null;
745 FINDER_ICON_POOL.push( instansce);
749 function updateIconPosition( _style, _w, _index, _elm){
752 var BreadcrumbClass = function(){
754 ELM_WRAPPER = ELM_ORIGIN_FINDER_LOCATION_ITEM.cloneNode( true),
755 ELM_FILENAME = ELM_WRAPPER.getElementsByTagName( 'a')[0],
756 file, w, index, instansce,
758 ELM_WRAPPER.onclick = onClick;
760 ELM_FILENAME.className = 'file-icon-' +file.getType();
761 ELM_FILENAME.innerHTML = file.getName();
763 function resize( index){
764 ELM_WRAPPER.style.left = (index * 90) +'px';
772 init: function( _file, _elmContainer, _index, _callback){
774 if( elmContainer !== _elmContainer){
775 _elmContainer.appendChild( ELM_WRAPPER);
776 elmContainer = _elmContainer;
782 if( index !== _index){
786 callback = _callback;
789 index: function( _index){
793 onResize: function( w){
797 elmContainer.removeChild( ELM_WRAPPER);
798 file = elmContainer = null;
799 BREAD_OBJECT_POOL.push( this);
804 var FinderClass = function( ELM_CONTAINER, tree, header, footer ){
807 elmContainer = ELM_ORIGIN_CONTAINER.cloneNode( true),
808 elmLocation = elmContainer.getElementsByTagName( 'ul')[0],
809 nodesDiv = elmContainer.getElementsByTagName( 'div'),
810 elmSidebarButton = nodesDiv[1],
811 elmStyleButton = nodesDiv[2],
812 elmActionButton = nodesDiv[3],
813 elmBody = nodesDiv[ nodesDiv.length -1 ],
814 //tree = pettanr.file.createTree( TREE_TYPE),
817 headH = pettanr.util.getElementSize( nodesDiv[0] ).height,
821 size = pettanr.util.getElementSize( ELM_ORIGIN_FINDER_ICON ),
827 tree.addTreeEventListener( pettanr.file.TREE_EVENT.UPDATE, draw);
829 function draw( _w, _h ){
830 w = Type.isFinite( _w ) === true ? _w : w;
831 h = Type.isFinite( _h ) === true ? _h : h;
833 var l = tree.hierarchy() +1,
834 m = BREAD_ARRAY.length,
836 for(var i=0; i<l; ++i){
837 _file = i !== l-1 ? tree.getParentFileAt( i) : tree.getCurrentFile();
839 BREAD_ARRAY[ i].init( _file, elmLocation, i, onHeadClick);
841 BREAD_ARRAY.push( getBreadcrumb( _file, elmLocation, i, onHeadClick));
844 while( l < BREAD_ARRAY.length){
845 BREAD_ARRAY.pop().destroy();
848 l = _file.getChildFileLength();
849 m = ICON_ARRAY.length;
853 ICON_ARRAY[ i].init( _file.getChildFileByIndex( i), elmBody, w, i, style, onBodyClick);
855 ICON_ARRAY.push( getFinderIcon( _file.getChildFileByIndex( i), elmBody, _w, i, style, onBodyClick));
858 if( _file.getState() === pettanr.file.FILE_STATE.LOADING ){
859 elmBody.className = 'finder-body loading';
861 elmBody.className = 'finder-body';
863 elmBody.style.height = bodyH + 'px';
865 while( l < ICON_ARRAY.length){
866 ICON_ARRAY.pop().destroy();
870 function onHeadClick( i){
871 var l = BREAD_ARRAY.length -1;
873 var _file = tree.getParentFileAt( i);
880 function onBodyClick( i){
881 var l = ICON_ARRAY.length;
883 var _file = tree.getCurrentFile().getChildFileByIndex( i);
884 if( _file !== null && ( _file.getChildFileLength() !== -1 || _file.getType() === pettanr.file.FILE_TYPE.FOLDER)){
891 this.init = function(){
892 ELM_CONTAINER.appendChild( elmContainer);
893 //$( elmLocation).click( onHeadClick);
894 //$( elmContainer).click( onBodyClick);
895 var position = pettanr.util.getAbsolutePosition( elmLocation);
898 bodyY = pettanr.util.getAbsolutePosition( elmBody).y;
901 this.onOpen = function( _w, _h, _option ){
902 this.init !== undefined && this.init();
905 this.onClose = function(){
908 this.onPaneResize = function( _w, _h){
911 elmBody.style.height = ( _h - headH ) + 'px';
913 for(var i=0, l=ICON_ARRAY.length; i<l; ++i){
914 ICON_ARRAY[ i].onResize( _w );
917 this.MIN_WIDTH = 240;
918 this.MIN_HEIGHT = 240;
921 pettanr.view.registerAsBasicPane( FinderClass );
923 function getFinderIcon( _file, _elmContainer, w, index, style, callback){
925 if( FINDER_ICON_POOL.length > 0){
926 _icon = FINDER_ICON_POOL.shift();
928 _icon = new FinderIconClass();
930 _icon.init( _file, _elmContainer, w, index, style, callback);
934 function getBreadcrumb( _file, _elmContainer, index, callback){
936 if( BREAD_OBJECT_POOL.length > 0){
937 _bread = BREAD_OBJECT_POOL.shift();
939 _bread = new BreadcrumbClass();
941 _bread.init( _file, _elmContainer, index, callback);
949 createFinder: function( _elmTarget, _tree, _header, _footer ){
950 var _finder = new FinderClass( _elmTarget, _tree, _header, _footer );
951 FINDER_ARRAY.push( _finder);
954 registerFinderHead: function(){
957 registerFinderPane: function( _finderPane){
960 isFinderInstance: function( _finder){
961 return _finder instanceof FinderClass;
963 isFinderPaneInstance: function(){
966 isFinderHeadInstance: function(){
972 pettanr.driver = ( function(){
973 var MyAuthorID = 'current_author' in window ? current_author.id : ( pettanr.DEBUG ? 1 : -1 ),
974 MyArtistID = 'current_artist' in window ? current_artist.id : ( pettanr.DEBUG ? 1 : -1 ),
976 getSeqentialFiles: function( _file){
977 var _data = FileAPI.getFileData( _file),
978 _json = _data !== null ? _data.json : null;
979 if( _json === true && _data.type === pettanr.driver.FILE_TYPE.COMIC ){
980 _json = [ pettanr.CONST.PETTANR_ROOT_PATH, 'comics\/', _data.id, '.json\/play\/' ].join( '' );
982 if( typeof _json === 'string'){
983 FileAPI.getJson( _file, _json, onLoadJson, onErrorJson);
984 _data.state = pettanr.file.FILE_STATE.LOADING;
989 getName: function( _file){
990 var _data = FileAPI.getFileData( _file),
991 _type = _data !== null ? _data.type : null;
992 if( _type === pettanr.driver.FILE_TYPE.PICTURE ){
993 return [ _data.id, _data.ext ].join( '.');
995 if( _type === pettanr.driver.FILE_TYPE.PANEL ){
996 return [ _data.t, ':', _data.comic.title ].join( '');
998 if( _type === pettanr.driver.FILE_TYPE.COMIC ){
1001 if( _type === pettanr.driver.FILE_TYPE.ARTIST ){
1002 return [ _data.id , ':', _data.name, '画伯' ].join( '');
1004 if( _type === pettanr.driver.FILE_TYPE.AUTHOR ){
1005 return [ _data.id , ':', _data.name, '先生' ].join( '');
1007 return _data.name + _data.type;
1009 getThumbnail: function( _file){
1010 var _data = FileAPI.getFileData( _file),
1011 _type = _data !== null ? _data.type : null;
1012 if( _type === pettanr.driver.FILE_TYPE.PICTURE){
1013 return { image: [ pettanr.CONST.RESOURCE_PICTURE_PATH, 'thumbnail/', _data.id, '.', _data.ext ].join( '')};
1015 if( _data === FILE_DATA_COMICS_ROOT){
1016 return { className: 'file-type-cabinet'};
1018 if( _type === pettanr.driver.FILE_TYPE.COMIC){
1019 return { className: 'file-type-comic'};
1021 if( _type === pettanr.driver.FILE_TYPE.PANEL){
1022 return { className: 'file-type-panel'};
1024 if( _type === pettanr.driver.FILE_TYPE.AUTHOR){
1025 return { className: 'file-type-author'};
1027 if( _type === pettanr.driver.FILE_TYPE.ARTIST){
1028 return { className: 'file-type-artist'};
1030 if( _type === pettanr.file.FILE_TYPE.FOLDER){
1031 return { className: 'file-type-folder'};
1033 return { className: 'file-type-broken'};
1035 getSummary: function( _file ){
1036 var _data = FileAPI.getFileData( _file),
1037 _type = _data !== null ? _data.type : null;
1038 if( _type === pettanr.driver.FILE_TYPE.PICTURE){
1039 return [ _data.width, 'x', _data.height, ', filesize:', _data.filesize, ', lisence:', _data.license ].join( '' );
1041 if( _data === FILE_DATA_COMICS_ROOT){
1042 return 'cabinet file';
1044 if( _type === pettanr.driver.FILE_TYPE.COMIC){
1045 return 'comic file';
1047 if( _type === pettanr.driver.FILE_TYPE.PANEL){
1048 return [ _data.width, 'x', _data.height ].join( '' );
1050 if( _type === pettanr.driver.FILE_TYPE.AUTHOR){
1051 return 'author file';
1053 if( _type === pettanr.driver.FILE_TYPE.ARTIST){
1054 return [ 'Email:', _data.email || 'empty' , ', HP:', _data.homepage_url || 'empty' ].join( '' );
1056 if( _type === pettanr.file.FILE_TYPE.FOLDER){
1057 return 'pettanR folder';
1059 return 'pettanR unknown file';
1061 viwerApplicationList: function( _file ){
1062 var _data = FileAPI.getFileData( _file ),
1063 _type = _data !== null ? _data.type : null;
1066 editorApplicationList: function( _file ){
1067 var _data = FileAPI.getFileData( _file ),
1068 _type = _data !== null ? _data.type : null;
1072 FileAPI = pettanr.file.registerDriver( Driver),
1073 FILE_DATA_SERVICE_ROOT = {
1074 name: 'PettanR root',
1075 type: pettanr.file.FILE_TYPE.FOLDER,
1078 FILE_DATA_COMICS_ROOT = {
1080 type: pettanr.file.FILE_TYPE.FOLDER,
1083 json: pettanr.CONST.URL_COMICS_JSON
1085 FILE_DATA_PANELS_ROOT = {
1087 type: pettanr.file.FILE_TYPE.FOLDER,
1090 json: pettanr.CONST.URL_PANELS_JSON
1092 FILE_DATA_PICTURE_ROOT = {
1094 type: pettanr.file.FILE_TYPE.FOLDER,
1097 json: pettanr.CONST.URL_RESOURCE_PICTURES_JSON
1099 FILE_DATA_MY_COMICS_ROOT = {
1101 type: pettanr.file.FILE_TYPE.FOLDER,
1105 FILE_DATA_LATEST_COMICS = {
1106 name: 'Latest Comics',
1107 type: pettanr.file.FILE_TYPE.FOLDER,
1110 FILE_DATA_MY_PICTURES_ROOT = {
1111 name: 'My Pictures',
1112 type: pettanr.file.FILE_TYPE.FOLDER,
1115 json: pettanr.CONST.URL_ORIGINAL_PICTURES_JSON
1117 FILE_DATA_AUTHOR_ROOT = {
1119 type: pettanr.file.FILE_TYPE.FOLDER,
1122 FILE_DATA_ARTIST_ROOT = {
1124 type: pettanr.file.FILE_TYPE.FOLDER,
1127 FILE_DATA_LISENCE_ROOT = {
1128 name: 'Original Lisences',
1129 type: pettanr.file.FILE_TYPE.FOLDER,
1132 FILE_DATA_BALLOON_ROOT = {
1133 name: 'Balloon templetes',
1134 type: pettanr.file.FILE_TYPE.FOLDER,
1141 RESOURCE_PICTURE_ARRAY = [],
1142 BALLOON_TEMPLETE_ARRAY = [],
1143 ORIGINAL_LICENSE_ARRAY = [],
1144 BASIC_LICENSES = 'cc_by,cc_nc,cc_nd,cc_sa,keep_aspect_ratio,no_convert,no_flip,no_resize'.split( ',');
1145 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);
1146 FILE_DATA_COMICS_ROOT.children.push( FILE_DATA_MY_COMICS_ROOT, FILE_DATA_LATEST_COMICS, FILE_DATA_AUTHOR_ROOT);
1147 FILE_DATA_PICTURE_ROOT.children.push( FILE_DATA_MY_PICTURES_ROOT, FILE_DATA_ARTIST_ROOT);
1149 FileAPI.createFolderUnderRoot( FILE_DATA_SERVICE_ROOT);
1151 function onLoadJson( _file, _json){
1152 var _access = FileAPI.getFileDataAccess( _file),
1153 _data = _access !== null ? _access.DATA : null,
1155 if( _data === null){
1156 onErrorJson( _file);
1159 _data.state = pettanr.file.FILE_STATE.OK;
1161 if( Type.isArray( _json ) === true ){
1163 if( l === 0) return;
1164 for( var i=0; i<l; ++i ){
1165 buildFileData( _json[ i], _data);
1169 buildFileData( _json, _data );
1171 _access.dispatchFileEvent( FileAPI.createFileEvent( pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES, _file, 'children', null));
1173 function onErrorJson( _file ){
1174 var _data = FileAPI.getFileData( _file);
1175 if( _data !== null){
1176 _data.state = pettanr.file.FILE_STATE.ERROR;
1179 function buildFileData( _data, _parent ){
1182 if( _parent === FILE_DATA_PANELS_ROOT ){
1183 _data.type = pettanr.driver.FILE_TYPE.PANEL;
1184 _array = PANEL_ARRAY;
1187 if( _parent === FILE_DATA_COMICS_ROOT ){
1188 _data.type = pettanr.driver.FILE_TYPE.COMIC;
1189 _array = COMIC_ARRAY;
1191 if( _parent.type === pettanr.driver.FILE_TYPE.COMIC ){
1192 _array = COMIC_ARRAY;
1195 if( _parent === FILE_DATA_LISENCE_ROOT ){
1196 _data.type = pettanr.driver.FILE_TYPE.LICENSE;
1197 _array = ORIGINAL_LICENSE_ARRAY;
1200 if( _parent === FILE_DATA_AUTHOR_ROOT ){
1201 _data.type = pettanr.driver.FILE_TYPE.AUTHOR;
1202 _array = AUTHOR_ARRAY;
1205 if( _parent === FILE_DATA_ARTIST_ROOT ){
1206 _data.type = pettanr.driver.FILE_TYPE.ARTIST;
1207 _array = ARTIST_ARRAY;
1210 if( _parent === FILE_DATA_PICTURE_ROOT || _parent === FILE_DATA_MY_PICTURES_ROOT ){
1211 _data.type = pettanr.driver.FILE_TYPE.PICTURE;
1212 _array = RESOURCE_PICTURE_ARRAY;
1213 // original_license を含まなければ、license object を削除して ビットデータ で保持
1214 // original_license なら ファイルを作る buildFileData( _license, FILE_DATA_LISENCE_ROOT)
1215 var _license = _data.license,
1217 _Math_pow = Math.pow,
1219 if( typeof _license === 'object'){
1220 for( i=0, l=BASIC_LICENSES.length; i<l; ++i){
1221 _rule = _license[ BASIC_LICENSES[ i]]
1222 if( typeof _rule === 'number' && _rule === 1 ){
1223 _bits += _Math_pow( 2, i);
1226 _data.license = _bits;
1232 _data.driver = Driver;
1234 // _array に _data を格納 または 上書き
1235 if( typeof _data.id === 'number' && _data.id > 0 ){
1236 var _id = _data.id - 1,
1237 __data = _array[ _id ],
1238 _reserved = pettanr.file.FILE_DATA_PROPERTY_RESERVED.join( ', ' );
1240 for( var key in _data){
1241 if( _reserved.indexOf( key ) === -1 ){
1242 __data[ key ] = _data[ key ];
1245 _data = __data; // このタイミングで参照が切れるので注意!!
1247 _array[ _id ] = _data;
1255 if( _parent === FILE_DATA_AUTHOR_ROOT || _parent === FILE_DATA_ARTIST_ROOT ){
1256 addChildData( _parent, _data );
1259 if( _parent.type === pettanr.driver.FILE_TYPE.COMIC || _parent === FILE_DATA_COMICS_ROOT ){
1260 var _panels = _data.panels,
1262 if( _panels && Type.isArray( _panels ) === true ){
1264 for( i=0, l=_panels.length; i<l; ++i){
1265 _panel = buildFileData( _panels[ i ], FILE_DATA_PANELS_ROOT );
1269 addChildData( _data, _panel );
1271 delete _data.panels;
1273 if( _data.json !== null ){
1276 if( Type.isArray( _data.children ) === false ){
1277 _data.children = [];
1280 var _author = _data.author || getResource( AUTHOR_ARRAY, _data.author_id );
1282 _data.author = _author = buildFileData( _author, FILE_DATA_AUTHOR_ROOT );
1283 addChildData( _author, _data );
1284 _author.id === MyAuthorID && addChildData( FILE_DATA_MY_COMICS_ROOT, _data );
1286 if( _parent === FILE_DATA_COMICS_ROOT ){
1287 addChildData( FILE_DATA_LATEST_COMICS, _data);
1291 if( _parent === FILE_DATA_PANELS_ROOT ){
1292 _data.comic = getResource( COMIC_ARRAY, _data.comic_id );
1293 _data.author = getResource( AUTHOR_ARRAY, _data.author_id );
1295 // picture data をファイルに取り出し
1296 if( Type.isArray( _data.panel_elements ) === true ){
1299 for( i=0, l=_elements.length; i<l; ++i){
1300 _elm = _elements[ i];
1301 if( _elm.resource_picture ){
1302 _elm.resource_picture = buildFileData( _elm.resource_picture, FILE_DATA_PICTURE_ROOT); // 上記参照切れに備えてここで上書き
1304 _elm.resource_picture = getResource( RESOURCE_PICTURE_ARRAY, _elm.resource_picture_id );
1310 if( _data.type == pettanr.driver.FILE_TYPE.PICTURE ){
1311 var _artist = _data.artist || getResource( ARTIST_ARRAY, _data.artist_id );
1313 _data.artist = _artist = buildFileData( _artist, FILE_DATA_ARTIST_ROOT );
1314 addChildData( _artist, _data );
1315 _artist.id === MyArtistID && addChildData( FILE_DATA_MY_PICTURES_ROOT, _data );
1320 function addChildData( _parent, _child ){
1321 if( Type.isArray( _parent.children ) === false){
1322 _parent.children = [];
1324 pettanr.util.getIndex( _parent.children, _child ) === -1 && _parent.children.push( _child );
1326 function getResource( _array, _id ){
1327 if( Type.isArray( _array ) === false || Type.isNumber( _id ) === false || _id < 1 ) return null;
1328 var _data = _array[ _id - 1 ];
1330 _data = _array[ _id - 1 ] = {};
1336 createComicTree: function(){
1337 return pettanr.file.createTree( FILE_DATA_SERVICE_ROOT); //FILE_DATA_COMICS_ROOT);
1339 createPictureTree: function(){
1340 return pettanr.file.createTree( FILE_DATA_PICTURE_ROOT);
1342 createServiceTree: function(){
1343 return pettanr.file.createTree( FILE_DATA_SERVICE_ROOT);
1345 isPettanrFileInstance: function( _file){
1346 if( pettanr.file.isPettanFileInstance( _file) === true){
1347 var _data = FileAPI.getFileData( _file);
1348 return _data !== null && _data.driver === Driver;
1353 COMIC: FileAPI.createFileTypeID(),
1354 PANEL: FileAPI.createFileTypeID(),
1355 PICTURE: FileAPI.createFileTypeID(),
1356 PANEL_PICTURE: FileAPI.createFileTypeID(),
1357 BALLOON: FileAPI.createFileTypeID(),
1358 AUTHOR: FileAPI.createFileTypeID(),
1359 ARTIST: FileAPI.createFileTypeID(),
1360 LICENSE: FileAPI.createFileTypeID()
1366 pettanr.gallery = ( function(){
1368 elmContainer = document.getElementById( 'gallery'),
1370 pageHeaderH = pettanr.util.getElementSize( document.getElementById('header') ).height;
1372 init: function( _option){
1374 delete pettanr.gallery.init;
1376 firstOpen: function(){
1377 finder = pettanr.finder.createFinder( elmContainer, pettanr.driver.createPictureTree());
1378 delete pettanr.gallery.firstOpen;
1380 onOpen: function( _w, _h, _option ){
1381 pettanr.gallery.firstOpen !== undefined && pettanr.gallery.firstOpen();
1382 finder.onOpen( _w, _h - pageHeaderH, _option );
1385 onClose: function(){
1388 onWindowResize: function( _w, _h){
1389 finder.resize( _w, _h - pageHeaderH );
1394 pettanr.cabinet = ( function(){
1396 elmContainer = document.getElementById( 'cabinet'),
1398 pageHeaderH = pettanr.util.getElementSize( document.getElementById('header') ).height;
1401 init: function( _option){
1403 delete pettanr.cabinet.init;
1405 firstOpen: function(){
1406 finder = pettanr.finder.createFinder( elmContainer, pettanr.driver.createComicTree());
1407 delete pettanr.cabinet.firstOpen;
1409 onOpen: function( _w, _h, _option ){
1410 pettanr.cabinet.firstOpen !== undefined && pettanr.cabinet.firstOpen();
1411 finder.onOpen( _w, _h - pageHeaderH, _option );
1414 onClose: function(){
1417 onWindowResize: function( _w, _h){
1418 finder.resize( _w, _h - pageHeaderH);
1427 pettanr.fn( pettanr.view);
1428 pettanr.fn( pettanr.overlay);
1429 pettanr.fn( pettanr.key);
1430 pettanr.fn( pettanr.balloon);
1432 pettanr.fn( pettanr.editor);
1433 pettanr.fn( pettanr.comicConsole);
1434 pettanr.fn( pettanr.uploadConsole);
1435 pettanr.fn( pettanr.panelConsole);
1436 pettanr.fn( pettanr.artistConsole);
1438 pettanr.fn( pettanr.file);
1439 pettanr.fn( pettanr.finder);
1440 pettanr.fn( pettanr.gallery);
1441 pettanr.fn( pettanr.cabinet);
1443 $(window).ready( pettanr.init);