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;
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 viwerApplicationList: function(){
436 var driver = FILE_CONTROLER.getDriver( this );
437 if( typeof driver.viwerApplicationList === 'function'){
438 return driver.viwerApplicationList( this );
440 return FileDriverBase.viwerApplicationList( this );
442 editorApplicationList: function(){
443 var driver = FILE_CONTROLER.editorApplicationList( this );
444 if( typeof driver.editorApplicationList === 'function'){
445 return driver.editorApplicationList( this );
447 return FileDriverBase.viwerApps( this );
458 onDelete: function(){
466 var FileDriverBase = {
467 getSeqentialFiles: function( _file){
469 getName: function( _file){
470 var _data = FILE_CONTROLER.getFileData( _file);
471 return _data.name || 'No Name';
473 getThumbnail: function( _file){
474 var _data = FILE_CONTROLER.getFileData( _file);
477 if( _type === pettanr.file.FILE_TYPE.FOLDER){
478 _className = 'folder';
480 if( _type === pettanr.file.FILE_TYPE.IMAGE){
483 if( _type === pettanr.file.FILE_TYPE.TEXT){
486 if( _type === pettanr.file.FILE_TYPE.HTML){
489 if( _type === pettanr.file.FILE_TYPE.CSV){
492 if( _type === pettanr.file.FILE_TYPE.JSON){
495 if( _type === pettanr.file.FILE_TYPE.XML){
500 className: ' file-type-' + _className
503 getUpdatePolicy: function( _file){
505 return pettanr.file.FILE_UPDATE_POLICY.SRWC;
510 write: function( _newName, _newData){
513 viwerApplicationList: function(){
516 editorApplicationList: function(){
519 onCreate: function(){
528 onDelete: function(){
533 var ROOT_FILEDATA = {
535 type: FILE_TYPE_IS_FOLDER,
538 SYSTEM_TREE = FILE_CONTROLER.createTree( ROOT_FILEDATA),
539 ROOT_FILE = SYSTEM_TREE.getRootFile();
541 function createFolderUnderRoot( _fileData){
542 ROOT_FILEDATA.children.push( _fileData);
543 FILE_CONTROLER.getFileDataAccess( ROOT_FILE)
544 .dispatchFileEvent( new FileEventClass( pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES, ROOT_FILE, 'children', null));
546 function createFileEvent( _eventType, _file, _key, _value){
547 return new FileEventClass( _eventType, _file, _key, _value)
549 function createFileTypeID(){
550 return ++numFileType;
555 //REQUEST_CONTROLER.init();
556 //FILE_CONTROLER.init();
557 delete pettanr.file.init;
559 registerDriver: function( _driver){
560 _driver.prototype = FileDriverBase;
565 createFolderUnderRoot: createFolderUnderRoot,
566 getFileDataAccess: FILE_CONTROLER.getFileDataAccess,
567 getFileData: FILE_CONTROLER.getFileData,
568 getJson: REQUEST_CONTROLER.getJson,
569 createFileEvent: createFileEvent,
570 createFileTypeID: createFileTypeID
573 createTree: function( _rootFile){
574 return FILE_CONTROLER.createTree( _rootFile);
576 isTreeInstance: function( _tree){
577 return _tree instanceof TreeClass;
579 isFileInstance: function( _file){
580 return _file instanceof FileClass;
584 FOLDER: FILE_TYPE_IS_FOLDER,
585 IMAGE: createFileTypeID(),
586 TEXT: createFileTypeID(),
587 HTML: createFileTypeID(),
588 CSV: createFileTypeID(),
589 JSON: createFileTypeID(),
590 XML: createFileTypeID()
599 FILE_UPDATE_POLICY: {
600 ____: parseInt( '0000', 2),
601 ___C: parseInt( '0001', 2), // hasCreateMenu
602 __W_: parseInt( '0010', 2), // isWritable
603 __WC: parseInt( '0011', 2), // isWritable
604 _R__: parseInt( '0000', 2), // isRenamable
605 _R_C: parseInt( '0101', 2), // hasCreateMenu
606 _RW_: parseInt( '0110', 2), // isWritable
607 _RWC: parseInt( '0111', 2), // isWritable
608 S___: parseInt( '1000', 2), // childrenIsSortable
609 S__C: parseInt( '1001', 2),
610 S_W_: parseInt( '1010', 2),
611 S_WC: parseInt( '1011', 2),
612 SR__: parseInt( '1000', 2),
613 SR_C: parseInt( '1101', 2),
614 SRW_: parseInt( '1110', 2),
615 SRWC: parseInt( '1111', 2),
622 UPDATE: 'onTreeUpdate'
625 UPDATE_ATTRIVUTE: 'onFileUpdate',
626 GET_SEQENTIAL_FILES:'gotSeqentilFiles'
628 FILE_DATA_PROPERTY_RESERVED: [
629 'children', 'driver', 'state', 'type'
634 pettanr.finder = ( function(){
635 var FINDER_ARRAY = [],
636 ELM_ORIGIN_FINDER_LOCATION_ITEM = pettanr.util.pullHtmlAsTemplete( 'templete-finder-location-item'),
637 ELM_ORIGIN_FINDER_ICON = pettanr.util.pullHtmlAsTemplete( 'templete-finder-icon'),
638 ELM_ORIGIN_CONTAINER = pettanr.util.pullHtmlAsTemplete( 'templete-finder-container'),
639 ICON_HEIGHT = pettanr.util.getElementSize( ELM_ORIGIN_FINDER_ICON).height,
640 ICON_CLASSNAME = ELM_ORIGIN_FINDER_ICON.getElementsByTagName( 'div')[0].className,
641 FINDER_ICON_POOL = [],
642 BREAD_OBJECT_POOL = [];
644 var FinderIconClass = function(){
646 ELM_WRAPPER = ELM_ORIGIN_FINDER_ICON.cloneNode( true),
647 ELM_THUMBNAIL = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-thumbnail', 'div')[0],
648 ELM_FILENAME = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-filename', 'div')[0],
649 file, w, index, style, instansce, callback;
651 ELM_WRAPPER.onclick = onClick;
657 var _thumb = file.getThumbnail();
659 ELM_THUMBNAIL.className = ICON_CLASSNAME + ' has-thumbnail';
660 ELM_THUMBNAIL.style.backgroundImage = [ 'url(', _thumb.image, ')'].join( '');
662 ELM_THUMBNAIL.className = ICON_CLASSNAME + ' ' +_thumb.className;
663 ELM_THUMBNAIL.style.backgroundImage = '';
665 ELM_FILENAME.innerHTML = file.getName();
668 ELM_WRAPPER.style.top = (index * ICON_HEIGHT) +'px';
670 function onCollect(){
671 elmContainer.removeChild( ELM_WRAPPER);
673 FINDER_ICON_POOL.push( instansce);
677 init: function( _file, _elmContainer, _w, _index, _style, _callback){
679 if( elmContainer !== _elmContainer){
680 _elmContainer.appendChild( ELM_WRAPPER);
681 elmContainer = _elmContainer;
687 if( index !== _index){
691 callback = _callback;
694 index: function( _index){
698 style: function( _style){
702 onResize: function( w){
706 elmContainer.removeChild( ELM_WRAPPER);
707 file = elmContainer = null;
708 FINDER_ICON_POOL.push( instansce);
712 function updateIconPosition( _style, _w, _index, _elm){
715 var BreadcrumbClass = function(){
717 ELM_WRAPPER = ELM_ORIGIN_FINDER_LOCATION_ITEM.cloneNode( true),
718 ELM_FILENAME = ELM_WRAPPER.getElementsByTagName( 'a')[0],
719 file, w, index, instansce,
721 ELM_WRAPPER.onclick = onClick;
723 ELM_FILENAME.className = 'file-icon-' +file.getType();
724 ELM_FILENAME.innerHTML = file.getName();
726 function resize( index){
727 ELM_WRAPPER.style.left = (index * 90) +'px';
735 init: function( _file, _elmContainer, _index, _callback){
737 if( elmContainer !== _elmContainer){
738 _elmContainer.appendChild( ELM_WRAPPER);
739 elmContainer = _elmContainer;
745 if( index !== _index){
749 callback = _callback;
752 index: function( _index){
756 onResize: function( w){
760 elmContainer.removeChild( ELM_WRAPPER);
761 file = elmContainer = null;
762 BREAD_OBJECT_POOL.push( this);
767 var FinderClass = function( ELM_CONTAINER, tree, header, footer ){
770 elmContainer = ELM_ORIGIN_CONTAINER.cloneNode( true),
771 elmLocation = elmContainer.getElementsByTagName( 'ul')[0],
772 nodesDiv = elmContainer.getElementsByTagName( 'div'),
773 elmSidebarButton = nodesDiv[1],
774 elmStyleButton = nodesDiv[2],
775 elmActionButton = nodesDiv[3],
776 elmBody = nodesDiv[ nodesDiv.length -1 ],
777 //tree = pettanr.file.createTree( TREE_TYPE),
780 headH = pettanr.util.getElementSize( nodesDiv[0] ).height,
784 size = pettanr.util.getElementSize( ELM_ORIGIN_FINDER_ICON ),
790 tree.addTreeEventListener( pettanr.file.TREE_EVENT.UPDATE, draw);
792 function draw( _w, _h ){
796 var l = tree.hierarchy() +1,
797 m = BREAD_ARRAY.length,
799 for(var i=0; i<l; ++i){
800 _file = i !== l-1 ? tree.getParentFileAt( i) : tree.getCurrentFile();
802 BREAD_ARRAY[ i].init( _file, elmLocation, i, onHeadClick);
804 BREAD_ARRAY.push( getBreadcrumb( _file, elmLocation, i, onHeadClick));
807 while( l < BREAD_ARRAY.length){
808 BREAD_ARRAY.pop().destroy();
811 l = _file.getChildFileLength();
812 m = ICON_ARRAY.length;
816 ICON_ARRAY[ i].init( _file.getChildFileByIndex( i), elmBody, w, i, style, onBodyClick);
818 ICON_ARRAY.push( getFinderIcon( _file.getChildFileByIndex( i), elmBody, _w, i, style, onBodyClick));
821 if( _file.getState() === pettanr.file.FILE_STATE.LOADING ){
822 elmBody.className = 'finder-body loading';
824 elmBody.className = 'finder-body';
826 elmBody.style.height = bodyH + 'px';
828 while( l < ICON_ARRAY.length){
829 ICON_ARRAY.pop().destroy();
833 function onHeadClick( i){
834 var l = BREAD_ARRAY.length -1;
836 var _file = tree.getParentFileAt( i);
843 function onBodyClick( i){
844 var l = ICON_ARRAY.length;
846 var _file = tree.getCurrentFile().getChildFileByIndex( i);
847 if( _file !== null && ( _file.getChildFileLength() !== -1 || _file.getType() === pettanr.file.FILE_TYPE.FOLDER)){
854 this.init = function(){
855 ELM_CONTAINER.appendChild( elmContainer);
856 //$( elmLocation).click( onHeadClick);
857 //$( elmContainer).click( onBodyClick);
858 var position = pettanr.util.getAbsolutePosition( elmLocation);
861 bodyY = pettanr.util.getAbsolutePosition( elmBody).y;
864 this.onOpen = function( _w, _h, _option ){
865 this.init !== undefined && this.init();
868 this.onClose = function(){
871 this.onPaneResize = function( _w, _h){
874 elmBody.style.height = ( _h - headH ) + 'px';
876 for(var i=0, l=ICON_ARRAY.length; i<l; ++i){
877 ICON_ARRAY[ i].onResize( _w );
880 this.MIN_WIDTH = 240;
881 this.MIN_HEIGHT = 240;
884 pettanr.view.registerAsBasicPane( FinderClass );
886 function getFinderIcon( _file, _elmContainer, w, index, style, callback){
888 if( FINDER_ICON_POOL.length > 0){
889 _icon = FINDER_ICON_POOL.shift();
891 _icon = new FinderIconClass();
893 _icon.init( _file, _elmContainer, w, index, style, callback);
897 function getBreadcrumb( _file, _elmContainer, index, callback){
899 if( BREAD_OBJECT_POOL.length > 0){
900 _bread = BREAD_OBJECT_POOL.shift();
902 _bread = new BreadcrumbClass();
904 _bread.init( _file, _elmContainer, index, callback);
912 createFinder: function( _elmTarget, _tree, _header, _footer ){
913 var _finder = new FinderClass( _elmTarget, _tree, _header, _footer );
914 FINDER_ARRAY.push( _finder);
917 registerFinderHead: function(){
920 registerFinderPane: function( _finderPane){
923 isFinderInstance: function( _finder){
924 return _finder instanceof FinderClass;
926 isFinderPaneInstance: function(){
929 isFinderHeadInstance: function(){
935 pettanr.driver = ( function(){
936 var MyAuthorID = 'current_author' in window ? current_author.id : ( pettanr.DEBUG ? 1 : -1 ),
937 MyArtistID = 'current_artist' in window ? current_artist.id : ( pettanr.DEBUG ? 1 : -1 ),
939 getSeqentialFiles: function( _file){
940 var _data = FileAPI.getFileData( _file),
941 _json = _data !== null ? _data.json : null;
942 if( _json === true && _data.type === pettanr.driver.FILE_TYPE.COMIC ){
943 _json = [ pettanr.CONST.PETTANR_ROOT_PATH, 'comics\/', _data.id, '.json\/play\/' ].join( '' );
945 if( typeof _json === 'string'){
946 FileAPI.getJson( _file, _json, onLoadJson, onErrorJson);
947 _data.state = pettanr.file.FILE_STATE.LOADING;
952 getName: function( _file){
953 var _data = FileAPI.getFileData( _file),
954 _type = _data !== null ? _data.type : null;
955 if( _type === pettanr.driver.FILE_TYPE.PICTURE ){
956 return [ _data.id, _data.ext ].join( '.');
958 if( _type === pettanr.driver.FILE_TYPE.PANEL ){
959 return [ _data.t, ':', _data.comic.title ].join( '');
961 if( _type === pettanr.driver.FILE_TYPE.COMIC ){
964 if( _type === pettanr.driver.FILE_TYPE.ARTIST ){
965 return [ _data.id , ':', _data.name, '画伯' ].join( '');
967 if( _type === pettanr.driver.FILE_TYPE.AUTHOR ){
968 return [ _data.id , ':', _data.name, '先生' ].join( '');
970 return _data.name + _data.type;
972 getThumbnail: function( _file){
973 var _data = FileAPI.getFileData( _file),
974 _type = _data !== null ? _data.type : null;
975 if( _type === pettanr.driver.FILE_TYPE.PICTURE){
976 return { image: [ pettanr.CONST.RESOURCE_PICTURE_PATH, 'thumbnail/', _data.id, '.', _data.ext ].join( '')};
978 if( _data === FILE_DATA_COMICS_ROOT){
979 return { className: 'file-type-cabinet'};
981 if( _type === pettanr.driver.FILE_TYPE.COMIC){
982 return { className: 'file-type-comic'};
984 if( _type === pettanr.driver.FILE_TYPE.PANEL){
985 return { className: 'file-type-panel'};
987 if( _type === pettanr.driver.FILE_TYPE.AUTHOR){
988 return { className: 'file-type-author'};
990 if( _type === pettanr.driver.FILE_TYPE.ARTIST){
991 return { className: 'file-type-artist'};
993 if( _type === pettanr.file.FILE_TYPE.FOLDER){
994 return { className: 'file-type-folder'};
996 return { className: 'file-type-broken'};
998 viwerApplicationList: function( _file ){
999 var _data = FileAPI.getFileData( _file ),
1000 _type = _data !== null ? _data.type : null;
1003 editorApplicationList: function( _file ){
1004 var _data = FileAPI.getFileData( _file ),
1005 _type = _data !== null ? _data.type : null;
1009 FileAPI = pettanr.file.registerDriver( Driver),
1010 FILE_DATA_SERVICE_ROOT = {
1011 name: 'PettanR root',
1012 type: pettanr.file.FILE_TYPE.FOLDER,
1015 FILE_DATA_COMICS_ROOT = {
1017 type: pettanr.file.FILE_TYPE.FOLDER,
1020 json: pettanr.CONST.URL_COMICS_JSON
1022 FILE_DATA_PANELS_ROOT = {
1024 type: pettanr.file.FILE_TYPE.FOLDER,
1027 json: pettanr.CONST.URL_PANELS_JSON
1029 FILE_DATA_PICTURE_ROOT = {
1031 type: pettanr.file.FILE_TYPE.FOLDER,
1034 json: pettanr.CONST.URL_RESOURCE_PICTURES_JSON
1036 FILE_DATA_MY_COMICS_ROOT = {
1038 type: pettanr.file.FILE_TYPE.FOLDER,
1042 FILE_DATA_LATEST_COMICS = {
1043 name: 'Latest Comics',
1044 type: pettanr.file.FILE_TYPE.FOLDER,
1047 FILE_DATA_MY_PICTURES_ROOT = {
1048 name: 'My Pictures',
1049 type: pettanr.file.FILE_TYPE.FOLDER,
1052 json: pettanr.CONST.URL_ORIGINAL_PICTURES_JSON
1054 FILE_DATA_AUTHOR_ROOT = {
1056 type: pettanr.file.FILE_TYPE.FOLDER,
1059 FILE_DATA_ARTIST_ROOT = {
1061 type: pettanr.file.FILE_TYPE.FOLDER,
1064 FILE_DATA_LISENCE_ROOT = {
1065 name: 'Original Lisences',
1066 type: pettanr.file.FILE_TYPE.FOLDER,
1069 FILE_DATA_BALLOON_ROOT = {
1070 name: 'Balloon templetes',
1071 type: pettanr.file.FILE_TYPE.FOLDER,
1078 RESOURCE_PICTURE_ARRAY = [],
1079 BALLOON_TEMPLETE_ARRAY = [],
1080 ORIGINAL_LICENSE_ARRAY = [],
1081 BASIC_LICENSES = 'cc_by,cc_nc,cc_nd,cc_sa,keep_aspect_ratio,no_convert,no_flip,no_resize'.split( ',');
1082 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);
1083 FILE_DATA_COMICS_ROOT.children.push( FILE_DATA_MY_COMICS_ROOT, FILE_DATA_LATEST_COMICS, FILE_DATA_AUTHOR_ROOT);
1084 FILE_DATA_PICTURE_ROOT.children.push( FILE_DATA_MY_PICTURES_ROOT, FILE_DATA_ARTIST_ROOT);
1086 FileAPI.createFolderUnderRoot( FILE_DATA_SERVICE_ROOT);
1088 function onLoadJson( _file, _json){
1089 var _access = FileAPI.getFileDataAccess( _file),
1090 _data = _access !== null ? _access.DATA : null,
1092 if( _data === null){
1093 onErrorJson( _file);
1096 _data.state = pettanr.file.FILE_STATE.OK;
1098 if( Type.isArray( _json ) === true ){
1099 var l = _json.length;
1100 if( l === 0) return;
1101 for( var i=0; i<l; ++i ){
1102 buildFileData( _json[ i], _data);
1106 buildFileData( _json, _data );
1108 _access.dispatchFileEvent( FileAPI.createFileEvent( pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES, _file, 'children', null));
1110 function onErrorJson( _file ){
1111 var _data = FileAPI.getFileData( _file);
1112 if( _data !== null){
1113 _data.state = pettanr.file.FILE_STATE.ERROR;
1116 function buildFileData( _data, _parent ){
1119 if( _parent === FILE_DATA_PANELS_ROOT ){
1120 _data.type = pettanr.driver.FILE_TYPE.PANEL;
1121 _array = PANEL_ARRAY;
1124 if( _parent === FILE_DATA_COMICS_ROOT ){
1125 _data.type = pettanr.driver.FILE_TYPE.COMIC;
1126 _array = COMIC_ARRAY;
1128 if( _parent.type === pettanr.driver.FILE_TYPE.COMIC ){
1129 _array = COMIC_ARRAY;
1132 if( _parent === FILE_DATA_LISENCE_ROOT ){
1133 _data.type = pettanr.driver.FILE_TYPE.LICENSE;
1134 _array = ORIGINAL_LICENSE_ARRAY;
1137 if( _parent === FILE_DATA_AUTHOR_ROOT ){
1138 _data.type = pettanr.driver.FILE_TYPE.AUTHOR;
1139 _array = AUTHOR_ARRAY;
1142 if( _parent === FILE_DATA_ARTIST_ROOT ){
1143 _data.type = pettanr.driver.FILE_TYPE.ARTIST;
1144 _array = ARTIST_ARRAY;
1147 if( _parent === FILE_DATA_PICTURE_ROOT || _parent === FILE_DATA_MY_PICTURES_ROOT ){
1148 _data.type = pettanr.driver.FILE_TYPE.PICTURE;
1149 _array = RESOURCE_PICTURE_ARRAY;
1150 // original_license を含まなければ、license object を削除して ビットデータ で保持
1151 // original_license なら ファイルを作る buildFileData( _license, FILE_DATA_LISENCE_ROOT)
1152 var _license = _data.license,
1153 _Math_pow = Math.pow,
1155 if( typeof _license === 'object'){
1156 for( i=0, l=BASIC_LICENSES.length; i<l; ++i){
1157 if( typeof _license[ BASIC_LICENSES[ i]] === 'number'){
1158 _bits += _Math_pow( 2, i);
1161 _data.license = _bits;
1167 _data.driver = Driver;
1169 // _array に _data を格納 または 上書き
1170 if( typeof _data.id === 'number' && _data.id > 0 ){
1171 var _id = _data.id - 1,
1172 __data = _array[ _id ],
1173 _reserved = pettanr.file.FILE_DATA_PROPERTY_RESERVED.join( ', ' );
1175 for( var key in _data){
1176 if( _reserved.indexOf( key ) === -1 ){
1177 __data[ key ] = _data[ key ];
1180 _data = __data; // このタイミングで参照が切れるので注意!!
1182 _array[ _id ] = _data;
1190 if( _parent === FILE_DATA_AUTHOR_ROOT || _parent === FILE_DATA_ARTIST_ROOT ){
1191 addChildData( _parent, _data );
1194 if( _parent.type === pettanr.driver.FILE_TYPE.COMIC || _parent === FILE_DATA_COMICS_ROOT ){
1195 var _panels = _data.panels,
1197 if( _panels && Type.isArray( _panels ) === true ){
1199 for( i=0, l=_panels.length; i<l; ++i){
1200 _panel = buildFileData( _panels[ i ], FILE_DATA_PANELS_ROOT );
1204 addChildData( _data, _panel );
1206 delete _data.panels;
1208 if( _data.json !== null ){
1211 if( Type.isArray( _data.children ) === false ){
1212 _data.children = [];
1215 var _author = _data.author || getResource( AUTHOR_ARRAY, _data.author_id );
1217 _data.author = _author = buildFileData( _author, FILE_DATA_AUTHOR_ROOT );
1218 addChildData( _author, _data );
1219 _author.id === MyAuthorID && addChildData( FILE_DATA_MY_COMICS_ROOT, _data );
1221 if( _parent === FILE_DATA_COMICS_ROOT ){
1222 addChildData( FILE_DATA_LATEST_COMICS, _data);
1226 if( _parent === FILE_DATA_PANELS_ROOT ){
1227 _data.comic = getResource( COMIC_ARRAY, _data.comic_id ),
1228 _data.author = getResource( AUTHOR_ARRAY, _data.author_id );
1230 // picture data をファイルに取り出し
1231 if( Type.isArray( _data.panel_elements ) === true ){
1234 for( i=0, l=_elements.length; i<l; ++i){
1235 _elm = _elements[ i];
1236 if( _elm.resource_picture ){
1237 _elm.resource_picture = buildFileData( _elm.resource_picture, FILE_DATA_PICTURE_ROOT); // 上記参照切れに備えてここで上書き
1239 _elm.resource_picture = getResource( RESOURCE_PICTURE_ARRAY, _elm.resource_picture_id );
1245 if( _data.type = pettanr.driver.FILE_TYPE.PICTURE ){
1246 var _artist = _data.artist || getResource( ARTIST_ARRAY, _data.artist_id );
1248 _data.artist = _artist = buildFileData( _artist, FILE_DATA_ARTIST_ROOT );
1249 addChildData( _artist, _data );
1250 _artist.id === MyArtistID && addChildData( FILE_DATA_MY_PICTURES_ROOT, _data );
1255 function addChildData( _parent, _child ){
1256 if( Type.isArray( _parent.children ) === false){
1257 _parent.children = [];
1259 pettanr.util.getIndex( _parent.children, _child ) === -1 && _parent.children.push( _child );
1261 function getResource( _array, _id ){
1262 if( Type.isArray( _array ) === false || Type.isNumber( _id ) === false || _id < 1 ) return null;
1263 var _data = _array[ _id - 1 ];
1265 _data = _array[ _id - 1 ] = {};
1271 createComicTree: function(){
1272 return pettanr.file.createTree( FILE_DATA_SERVICE_ROOT); //FILE_DATA_COMICS_ROOT);
1274 createPictureTree: function(){
1275 return pettanr.file.createTree( FILE_DATA_PICTURE_ROOT);
1277 createServiceTree: function(){
1278 return pettanr.file.createTree( FILE_DATA_SERVICE_ROOT);
1280 isPettanrFileInstance: function( _file){
1281 if( pettanr.file.isPettanFileInstance( _file) === true){
1282 var _data = FileAPI.getFileData( _file);
1283 return _data !== null && _data.driver === Driver;
1288 COMIC: FileAPI.createFileTypeID(),
1289 PANEL: FileAPI.createFileTypeID(),
1290 PICTURE: FileAPI.createFileTypeID(),
1291 PANEL_PICTURE: FileAPI.createFileTypeID(),
1292 BALLOON: FileAPI.createFileTypeID(),
1293 AUTHOR: FileAPI.createFileTypeID(),
1294 ARTIST: FileAPI.createFileTypeID(),
1295 LICENSE: FileAPI.createFileTypeID()
1301 pettanr.gallery = ( function(){
1303 elmContainer = document.getElementById( 'gallery'),
1305 pageHeaderH = pettanr.util.getElementSize( document.getElementById('header') ).height;
1307 init: function( _option){
1309 delete pettanr.gallery.init;
1311 firstOpen: function(){
1312 finder = pettanr.finder.createFinder( elmContainer, pettanr.driver.createPictureTree());
1313 delete pettanr.gallery.firstOpen;
1315 onOpen: function( _w, _h, _option ){
1316 pettanr.gallery.firstOpen !== undefined && pettanr.gallery.firstOpen();
1317 finder.onOpen( _w, _h - pageHeaderH, _option );
1320 onClose: function(){
1323 onWindowResize: function( _w, _h){
1324 finder.resize( _w, _h - pageHeaderH );
1329 pettanr.cabinet = ( function(){
1331 elmContainer = document.getElementById( 'cabinet'),
1333 pageHeaderH = pettanr.util.getElementSize( document.getElementById('header') ).height;
1336 init: function( _option){
1338 delete pettanr.cabinet.init;
1340 firstOpen: function(){
1341 finder = pettanr.finder.createFinder( elmContainer, pettanr.driver.createComicTree());
1342 delete pettanr.cabinet.firstOpen;
1344 onOpen: function( _w, _h, _option ){
1345 pettanr.cabinet.firstOpen !== undefined && pettanr.cabinet.firstOpen();
1346 finder.onOpen( _w, _h - pageHeaderH, _option );
1349 onClose: function(){
1352 onWindowResize: function( _w, _h){
1353 finder.resize( _w, _h - pageHeaderH);
1362 pettanr.fn( pettanr.view);
1363 pettanr.fn( pettanr.overlay);
1364 pettanr.fn( pettanr.key);
1365 pettanr.fn( pettanr.balloon);
1367 pettanr.fn( pettanr.editor);
1368 pettanr.fn( pettanr.comicConsole);
1369 pettanr.fn( pettanr.uploadConsole);
1370 pettanr.fn( pettanr.panelConsole);
1371 pettanr.fn( pettanr.artistConsole);
1373 pettanr.fn( pettanr.file);
1374 pettanr.fn( pettanr.finder);
1375 pettanr.fn( pettanr.gallery);
1376 pettanr.fn( pettanr.cabinet);
1378 $(window).ready( pettanr.init);