13 * お気に入り画像一覧 > tag:ペン次郎 > ペン次郎:笑う
14 * 最近アップロードされた画像 > images
16 * キャラクター画像庫 > アニマル系 > tag:ペン次郎 > ペン次郎:笑う
23 pettanr.file = ( function(){
24 var FILE_TYPE_IS_FOLDER = 1,
25 numFileType = FILE_TYPE_IS_FOLDER,
26 FILEDATA_RESITER = [], // store all of fileData( json object )
27 FILEDATA_ACCESS = [], // file operations for Kernel only ! hide from Out of pettanr.file
28 FILE_OBJECT_POOL = [],
29 EVENT_LISTENER_REGISTER = [],
31 TREE_ACCESS_ARRAY = [];
33 var REQUEST_CONTROLER = ( function(){
34 var REQUEST_TICKET_RESISTER = [],
37 DATA_TYPE_ARRAY = 'json,xml,html,text'.split( ','),
44 var RequestTicketClass = function( _type, _data, _url, _onLoad, _onError){
45 this.type = DATA_TYPE_ARRAY[ _type];
48 this.onLoad = _onLoad;
49 this.onError = _onError;
54 if( currentTicket !== null ) return;
55 currentTicket = REQUEST_TICKET_RESISTER.shift();
57 url: currentTicket.url,
58 dataType: currentTicket.type,
63 function onSuccess( _data ){
65 window.setTimeout( asyncSuccess, 0 );
67 function asyncSuccess(){
68 currentTicket.onLoad( currentTicket.data, currentData );
69 currentTicket = currentData = null;
70 REQUEST_TICKET_RESISTER.length !== 0 && window.setTimeout( request, 0 );
75 window.setTimeout( asyncError, 0 );
77 function asyncError(){
78 currentTicket.onError( currentTicket.data );
80 REQUEST_TICKET_RESISTER.length !== 0 && window.setTimeout( request, 0 );
83 getNumTask: function(){
84 return REQUEST_TICKET_RESISTER.length;
86 getNumError: function(){
89 getJson: function( _data, _url, _onLoad, _onError ){
90 REQUEST_TICKET_RESISTER.push( new RequestTicketClass( DATA_IS_JSON, _data, _url, _onLoad, _onError));
91 currentTicket === null && request();
98 var FILE_CONTROLER = {
99 createTree: function( _rootFileData){
100 var _tree = new TreeClass( _rootFileData);
102 TREE_ARRAY.push( _tree);
105 getFileUID: function( FILEDATAorFILE ){
106 if( FILEDATAorFILE instanceof FileClass ){
107 return FILEDATAorFILE.getUID();
110 var uid = pettanr.util.getIndex( FILEDATA_RESITER, FILEDATAorFILE );
112 uid = FILEDATA_RESITER.length;
113 FILEDATA_RESITER.push( FILEDATAorFILE );
117 getFileDataAccess: function( UIDorFILEorFILEDATA){
118 var _uid, _data, _access;
120 if( typeof UIDorFILEorFILEDATA === 'number'){
121 _data = FILEDATA_RESITER[ UIDorFILEorFILEDATA ] || null;
123 if( UIDorFILEorFILEDATA instanceof FileClass){
124 _uid = UIDorFILEorFILEDATA.getUID();
125 _data = FILEDATA_RESITER[ _uid ] || null;
127 _data = UIDorFILEorFILEDATA || null;
130 if( _data === null || typeof _data !== 'object') return null;
131 for( var i=0, l = FILEDATA_ACCESS.length; i<l; ++i){
132 _access = FILEDATA_ACCESS[ i];
133 if( _access.DATA === _data) return _access;
137 getFileData: function( UIDorFILEorFILEDATA){
138 var _access = FILE_CONTROLER.getFileDataAccess( UIDorFILEorFILEDATA);
139 return _access !== null ? _access.DATA : null;
141 getChildren: function( UIDorFILEorFILEDATA){
142 var _data = FILE_CONTROLER.getFileData( UIDorFILEorFILEDATA);
143 return _data !== null ? _data.children || null : null;
145 getDriver: function( _file){
146 var _data = FILE_CONTROLER.getFileData( _file);
147 return _data !== null && _data.driver ? _data.driver : FileDriverBase;
149 getUpdateFlag: function( _file, _bit ){
150 var _driver = FILE_CONTROLER.getDriver( _file ),
152 if( typeof _driver.getUpdatePolicy === 'function'){
153 _policy = _driver.getUpdatePolicy( _file );
156 if( typeof _policy !== 'number') {
157 _policy = FileDriverBase.getUpdatePolicy( _file )
159 return _policy % ( _bit * 2) >= _bit;
161 move: function( _prentUID, _targetfile, _newFolder, _newIndex, _opt_callback){
162 var _parentData = FILE_CONTROLER.getFileDataAccess( _prentUID),
163 _parentType = _parentData.TYPE,
164 _targetData = FILE_CONTROLER.getFileDataAccess( _targetfile),
165 _targetType = _targetData.TYPE;
167 replace: function( _uid, _file, _newIndex){
170 addEventListener: function( FILEorNULL, _eventType, _callback ){
171 var _uid = FILEorNULL instanceof FileClass ? FILEorNULL.getUID() : FILEorNULL;
172 EVENT_LISTENER_REGISTER.push( new FileEventTicketClass( _uid, _eventType, _callback));
174 removeEventListener: function( FILEorNULL, _eventType, _callback ){
175 var _uid = FILEorNULL instanceof FileClass ? FILEorNULL.getUID() : FILEorNULL,
177 for(var i=0, l = EVENT_LISTENER_REGISTER.length; i<l; ++i ){
178 _ticket = EVENT_LISTENER_REGISTER[ i ];
179 if( _ticket.fileUID === _uid && _ticket.eventType === _eventType && _ticket.callBack === _callback ){
180 EVENT_LISTENER_REGISTER.splice( i, 1 );
185 getTreeAccess: function(){
188 fileEventRellay: function( _uid, _event ){
189 var _fileAccess = FILE_CONTROLER.getFileDataAccess( _uid );
190 if( _fileAccess === null ) return;
191 var _treeUID = _fileAccess.TREE.getUID(),
192 _treeAccess = TREE_ACCESS_ARRAY[ _treeUID ],
193 _data = _fileAccess.DATA,
195 if( !_treeAccess ) return;
196 _treeAccess.dispatchFileEvent( _event );
197 for( var i=0, l = TREE_ARRAY.length; i<l; ++i){
198 if( i !== _treeUID ){
199 _tree = TREE_ARRAY[ i ];
200 if( FILE_CONTROLER.getFileData( _tree.getCurrentFile() ) === _data ){
201 _treeAccess = TREE_ACCESS_ARRAY[ _tree.getUID() ];
202 _treeAccess && _treeAccess.dispatchFileEvent( _event );
209 var AsyncEventDispatcher = ( function(){
213 var _stack = STACK_LIST.shift();
214 _stack[ 0 ]( _stack[ 1 ], _stack[ 2 ], _stack[ 3 ], _stack[ 4 ] );
216 while( _stack.length > 0 ){
219 if( STACK_LIST.length !== 0 ){
220 window.setTimeout( dispatch, 0 );
224 addEvent: function( _callback, _eventType, _targetFile, _key, _value ){
225 if( STACK_LIST.length === 0 ){
226 window.setTimeout( dispatch, 0 );
228 STACK_LIST.push( [ _callback, _eventType, _targetFile, _key, _value ] );
233 var TreeClass = function( rootFileData ){
234 var PARENT_FILE_RESITER = [],
236 dispatchFileEvent: dispatchFileEvent
238 EVENT_LISTENER_ARRAY = [],
243 TREE_ACCESS_ARRAY.push( ACCESS );
245 function dispatchFileEvent( e ){
246 var _eventType = e.eventType,
247 _targetFile = e.targetFile,
248 _uid = _targetFile.getUID(),
249 _ticket, _type, _callback;
250 for( var i=0, l = EVENT_LISTENER_REGISTER.length; i<l; ++i ){
251 _ticket = EVENT_LISTENER_REGISTER[ i ];
252 _type = _ticket.eventType;
253 _callback = _ticket.callBack;
254 if( _eventType === _type && _uid === _ticket.fileUID ){
255 AsyncEventDispatcher.addEvent( _callback, _eventType, _targetFile, e.key, e.value );
257 if( _type === pettanr.file.TREE_EVENT.UPDATE && _eventType === pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES ){
258 AsyncEventDispatcher.addEvent( _callback, _eventType, _targetFile );
266 currentFile = rootFile = new FileClass( instance, null, rootFileData );
268 currentFile.getSeqentialFiles();
272 return pettanr.util.getIndex( TREE_ACCESS_ARRAY, ACCESS );
274 getRootFile : function(){
277 getCurrentFile: function(){
280 hierarchy: function(){
281 return PARENT_FILE_RESITER.length;
283 getParentFileAt: function( _index){
284 var l = PARENT_FILE_RESITER.length;
285 if( typeof _index !== 'number' || _index < 0 || _index >= l) return null;
286 return PARENT_FILE_RESITER[ l -1 -_index];
288 down: function( _index){
289 if( typeof _index !== 'number' || _index < 0 || _index >= currentFile.getChildFileLength()) return;
290 PARENT_FILE_RESITER.unshift( currentFile );
291 currentFile = currentFile.getChildFileByIndex( _index );
292 currentFile.getSeqentialFiles();
295 up: function( _index){
296 var l = PARENT_FILE_RESITER.length;
297 if( l === 0) return null;
300 var _currentFile = currentFile;
302 _currentFile.destroy();
304 if( typeof _index === 'number'){
305 if( _index >= l) return null;
306 currentFile = this.getParentFileAt( _index );
307 PARENT_FILE_RESITER.splice( 0, l -_index);
309 currentFile = PARENT_FILE_RESITER.shift();
311 currentFile.getSeqentialFiles();
314 addTreeEventListener: function( _eventType, _callback){
315 FILE_CONTROLER.addEventListener( null, _eventType, _callback);
317 removeTreeEventListener: function( _eventType, _callback){
318 FILE_CONTROLER.removeEventListener( null, _eventType, _callback);
321 FILE_CONTROLER.destroyTree( instance.getUID() );
323 var _currentFile = currentFile;
324 currentFile = rootFile = rootFileData = null;
325 // currentFile, rootFile を null にしないと .File.destroy() ができない.
326 _currentFile.destroy();
327 while( PARENT_FILE_RESITER.length > 0 ){
328 _currentFile = PARENT_FILE_RESITER.shift();
329 _currentFile.destroy();
336 var FileEventTicketClass = function( _uid, _eventType, _callback ){
338 this.eventType = _eventType;
339 this.callBack = _callback;
340 this.destroy = function(){
342 delete this.eventType;
344 delete this.callBack;
346 _uid = _eventType = _callback = undefined;
349 var FileEventClass = function( eventType, file, key, value){
350 this.eventType = eventType;
351 this.targetFile = file;
352 this.updatedAttribute = key;
353 this.updatedValue = value;
357 * fileのdataはobjectで保持している。
358 * pettanr.file.の外からファイルをみるときは、FileClassを通して操作する。
359 * fileの変更、それに付随して追加されたイベントは、TreeClassで管理される。
360 * treeがdestryされると、fileのイベントリスナーも全て削除される。
361 * 他の tree も data の共通する currentFile に対してのみは、file の変更イベントを受け取って流す.
366 var FileClass = function( tree, parentData, data ){
367 var uid = FILE_CONTROLER.getFileUID( data ),
370 FILEDATA_ACCESS.push(
373 parentData: parentData,
375 dispatchFileEvent: dispatchEvent
379 tree = parentData = data = null;
381 function dispatchEvent( e ){
382 FILE_CONTROLER.fileEventRellay( uid, e );
384 this.getUID = function(){
389 FileClass.prototype = {
390 isChildFile: function( _FILEorFILEDATA){
391 return this.getChildFileIndex( _FILEorFILEDATA) !== -1;
393 getSeqentialFiles: function(){
394 var _driver = FILE_CONTROLER.getDriver( this );
395 if( _driver !== null && typeof _driver.getSeqentialFiles === 'function' ){
396 _driver.getSeqentialFiles( this );
399 addEventListener: function( _eventType, _callback ){
400 FILE_CONTROLER.addEventListener( this, _eventType, _callback );
402 removeEventListener: function( _eventType, _callback ){
403 FILE_CONTROLER.removeEventListener( this, _eventType, _callback );
405 getChildFileLength: function(){
406 var children = FILE_CONTROLER.getChildren( this );
407 return Type.isArray( children ) === true ? children.length : -1;
409 getChildFileIndex: function( _FILEorFILEDATA ){
410 var children = FILE_CONTROLER.getChildren( this);
411 if( Type.isArray( children ) === false ) return -1;
412 var l = children.length,
413 _fileData = FILE_CONTROLER.getFileData( _FILEorFILEDATA );
414 if( _fileData === null ) return -1;
415 for( var i=0; i<l; ++i ){
416 if( children[ i ] === _fileData ) return i;
420 getChildFileByIndex: function( _index ){
421 var _access = FILE_CONTROLER.getFileDataAccess( this ),
422 _children = FILE_CONTROLER.getChildren( this );
423 if( typeof _index !== 'number' || _index < 0 || Type.isArray( _children ) === false || _index >= _children.length) return null;
424 var _file = new FileClass( _access.TREE, _access.DATA, _children[ _index ]);
429 var driver = FILE_CONTROLER.getDriver( this );
430 if( typeof driver.getName === 'function'){
431 return driver.getName( this );
433 return FileDriverBase.getName( this);
435 getThumbnail: function(){
436 var driver = FILE_CONTROLER.getDriver( this);
437 if( typeof driver.getThumbnail === 'function'){
438 return driver.getThumbnail( this);
440 return FileDriverBase.getThumbnail( this);
443 var _data = FILE_CONTROLER.getFileData( this);
444 return typeof _data.type === 'number' ? _data.type : pettanr.file.FILE_TYPE.UNKNOWN;
446 getState: function(){
447 var _data = FILE_CONTROLER.getFileData( this);
448 return typeof _data.state === 'number' ? _data.state : pettanr.file.FILE_STATE.OK;
450 getSummary: function(){
451 var driver = FILE_CONTROLER.getDriver( this );
452 if( typeof driver.getSummary === 'function'){
453 return driver.getSummary( this );
455 return FileDriverBase.getSummary( this);
457 isWritable: function(){
458 return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.WRITE );
460 isSortable: function(){
461 return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.SORT );
463 isCreatable: function(){
464 return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.CREATE );
466 isRenamable: function(){
467 return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.RENAME );
469 isDeletable: function(){
470 return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.DELETE );
474 var driver = FILE_CONTROLER.getDriver( this ),
476 if( typeof driver.read === 'function'){
477 data = driver.read( this );
479 return FileDriverBase.read( data || this );
481 write: function( _newData, _onUpdateFunction ){
482 var driver = FILE_CONTROLER.getDriver( this );
483 if( typeof driver.write === 'function'){
484 return driver.write( this, _newData, _onUpdateFunction );
486 return FileDriverBase.write( this, _newData, _onUpdateFunction );
488 viewerApplicationList: function(){
489 var driver = FILE_CONTROLER.getDriver( this );
490 if( typeof driver.viewerApplicationList === 'function'){
491 return driver.viewerApplicationList( this );
493 return FileDriverBase.viewerApplicationList( this );
495 editorApplicationList: function(){
496 var driver = FILE_CONTROLER.getDriver( this );
497 if( typeof driver.editorApplicationList === 'function'){
498 return driver.editorApplicationList( this );
500 return FileDriverBase.viwerApps( this );
511 onDelete: function(){
514 move: function( _newFolder, _newIndex, opt_callback ){
515 var _access = FILE_CONTROLER.getFileDataAccess( this );
516 _access.TREE.move( _access.parentData, this.getUID(), _newFolder, _newIndex, opt_callback );
518 replace: function( _newIndex, opt_callback ){
519 var _access = FILE_CONTROLER.getFileDataAccess( this );
520 _access.TREE.replace( _access.parentData, this.getUID(), _newIndex, opt_callback);
524 * 探しているファイルの属性と値を指定.一致する child の index を配列で返す.
526 search: function( obj, rule ){
527 var _children = FILE_CONTROLER.getChildren( this ),
530 for( var i=0, l=_children.length; i<l; ++i ){
531 _child = _children[ i ];
534 if( obj[ k ] !== _child[ k ] ){
539 c === true && ret.push( i );
544 var _access = FILE_CONTROLER.getFileDataAccess( this );
545 var TREE = _access.TREE;
546 if( TREE.getCurrentFile() === this ) return;
547 if( TREE.getRootFile() === this ) return;
548 for( var i=0, l = TREE.hierarchy(); i<l; ++i ){
549 if( TREE.getParentFileAt( i ) === this ){
553 var _index = pettanr.util.getIndex( FILEDATA_ACCESS, _access );
554 if( _index === -1 || _access === null ) return;
556 FILEDATA_ACCESS.splice( _index, 1 );
559 delete _access.parentData;
560 delete _access.dispatchFileEvent;
567 var FileDriverBase = {
568 getSeqentialFiles: function( _file){
570 getName: function( _file){
571 var _data = FILE_CONTROLER.getFileData( _file);
572 return _data.name || 'No Name';
574 getThumbnail: function( _file){
575 var _data = FILE_CONTROLER.getFileData( _file),
578 if( _type === pettanr.file.FILE_TYPE.FOLDER){
579 _className = 'folder';
581 if( _type === pettanr.file.FILE_TYPE.IMAGE){
584 if( _type === pettanr.file.FILE_TYPE.TEXT){
587 if( _type === pettanr.file.FILE_TYPE.HTML){
590 if( _type === pettanr.file.FILE_TYPE.CSV){
593 if( _type === pettanr.file.FILE_TYPE.JSON){
596 if( _type === pettanr.file.FILE_TYPE.XML){
601 className: ' file-type-' + _className
604 getSummary: function( _file ){
605 var _data = FILE_CONTROLER.getFileData( _file ),
607 if( _type === pettanr.file.FILE_TYPE.FOLDER){
610 if( _type === pettanr.file.FILE_TYPE.IMAGE){
613 if( _type === pettanr.file.FILE_TYPE.TEXT){
616 if( _type === pettanr.file.FILE_TYPE.HTML){
617 return 'html document file';
619 if( _type === pettanr.file.FILE_TYPE.CSV){
620 return 'csv daat file';
622 if( _type === pettanr.file.FILE_TYPE.JSON){
623 return 'json data file';
625 if( _type === pettanr.file.FILE_TYPE.XML){
626 return 'xml data file';
630 getUpdatePolicy: function( _file ){
632 return pettanr.file.FILE_UPDATE_POLICY.DSRWC;
634 read: function( _FILEorDATA ){
636 protects = pettanr.file.FILE_DATA_PROPERTY_RESERVED;
637 if( _FILEorDATA instanceof FileClass ){
638 data = FILE_CONTROLER.getFileData( _FILEorDATA )
643 function clone( src ) {
645 if( Type.isArray(src) === true ){
648 if( Type.isObject(src) === true ){
651 if( Type.isNumber(src) === true || Type.isString(src) === true || Type.isBoolean( src ) === true ){
656 for( var key in src ){
657 if( pettanr.util.getIndex( protects, key ) === -1 ){
659 ret[ key ] = clone( src[ key ]);
665 return clone( data );
667 write: function( _file, _newData, _onUpdateFunction ){
668 var _data = FILE_CONTROLER.getFileData( _file ),
672 viewerApplicationList: function(){
675 editorApplicationList: function(){
678 onCreate: function(){
687 onDelete: function(){
692 var ROOT_FILEDATA = {
694 type: FILE_TYPE_IS_FOLDER,
697 SYSTEM_TREE = FILE_CONTROLER.createTree( ROOT_FILEDATA),
698 ROOT_FILE = SYSTEM_TREE.getRootFile();
700 function createFolderUnderRoot( _fileData){
701 ROOT_FILEDATA.children.push( _fileData);
702 FILE_CONTROLER.getFileDataAccess( ROOT_FILE)
703 .dispatchFileEvent( new FileEventClass( pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES, ROOT_FILE, 'children', null));
705 function createFileEvent( _eventType, _file, _key, _value){
706 return new FileEventClass( _eventType, _file, _key, _value);
708 function createFileTypeID(){
709 return ++numFileType;
714 //REQUEST_CONTROLER.init();
715 //FILE_CONTROLER.init();
716 delete pettanr.file.init;
718 registerDriver: function( _driver ){
719 _driver.prototype = FileDriverBase;
724 createFolderUnderRoot: createFolderUnderRoot,
725 getFileDataAccess: FILE_CONTROLER.getFileDataAccess,
726 getFileData: FILE_CONTROLER.getFileData,
727 getJson: REQUEST_CONTROLER.getJson,
728 createFileEvent: createFileEvent,
729 createFileTypeID: createFileTypeID
732 createTree: function( _rootFile){
733 return FILE_CONTROLER.createTree( _rootFile);
735 isTreeInstance: function( _tree){
736 return _tree instanceof TreeClass;
738 isFileInstance: function( _file){
739 return _file instanceof FileClass;
743 FOLDER: FILE_TYPE_IS_FOLDER,
744 IMAGE: createFileTypeID(),
745 TEXT: createFileTypeID(),
746 HTML: createFileTypeID(),
747 CSV: createFileTypeID(),
748 JSON: createFileTypeID(),
749 XML: createFileTypeID()
758 FILE_UPDATE_POLICY: {
759 _____: parseInt( '00000', 2),
760 ____C: parseInt( '00001', 2), // hasCreateMenu
761 ___W_: parseInt( '00010', 2), // isWritable
762 ___WC: parseInt( '00011', 2), // isWritable
763 __R__: parseInt( '00100', 2), // isRenamable
764 __R_C: parseInt( '00101', 2), // hasCreateMenu
765 __RW_: parseInt( '00110', 2), // isWritable
766 __RWC: parseInt( '00111', 2), // isWritable
767 _S___: parseInt( '01000', 2), // childrenIsSortable
768 _S__C: parseInt( '01001', 2),
769 _S_W_: parseInt( '01010', 2),
770 _S_WC: parseInt( '01011', 2),
771 _SR__: parseInt( '01100', 2),
772 _SR_C: parseInt( '01101', 2),
773 _SRW_: parseInt( '01110', 2),
774 _SRWC: parseInt( '01111', 2),
775 D____: parseInt( '10000', 2),
776 D___C: parseInt( '10001', 2), // hasCreateMenu
777 D__W_: parseInt( '10010', 2), // isWritable
778 D__WC: parseInt( '10011', 2), // isWritable
779 D_R__: parseInt( '10100', 2), // isRenamable
780 D_R_C: parseInt( '10101', 2), // hasCreateMenu
781 D_RW_: parseInt( '10110', 2), // isWritable
782 D_RWC: parseInt( '10111', 2), // isWritable
783 DS___: parseInt( '11000', 2), // childrenIsSortable
784 DS__C: parseInt( '11001', 2),
785 DS_W_: parseInt( '11010', 2),
786 DS_WC: parseInt( '11011', 2),
787 DSR__: parseInt( '11100', 2),
788 DSR_C: parseInt( '11101', 2),
789 DSRW_: parseInt( '11110', 2),
790 DSRWC: parseInt( '11111', 2),
798 UPDATE: 'onTreeUpdate'
801 UPDATE_ATTRIVUTE: 'onFileUpdate',
802 GET_SEQENTIAL_FILES:'gotSeqentilFiles'
804 FILE_DATA_PROPERTY_RESERVED: [
805 'children', 'driver', 'state', 'type'
810 pettanr.finder = ( function(){
811 var FINDER_ARRAY = [],
812 ELM_ORIGIN_FINDER_LOCATION_ITEM = pettanr.util.pullHtmlAsTemplete( 'templete-finder-location-item'),
813 ELM_ORIGIN_FINDER_ICON = ( function(){
814 var forIE = pettanr.util.pullHtmlAsTemplete( 'templete-finder-icon-ie'),
815 modern = pettanr.util.pullHtmlAsTemplete( 'templete-finder-icon');
816 return pettanr.ua.isIE === true && pettanr.ua.ieVersion < 8 ? forIE : modern;
818 ELM_ORIGIN_CONTAINER = pettanr.util.pullHtmlAsTemplete( 'templete-finder-container'),
819 ICON_HEIGHT = pettanr.util.getElementSize( ELM_ORIGIN_FINDER_ICON).height,
820 ICON_CLASSNAME = 'finder-icon-thumbnail',
821 FINDER_ICON_POOL = [],
822 BREAD_OBJECT_POOL = [];
824 var FinderIconClass = function(){
826 ELM_WRAPPER = ELM_ORIGIN_FINDER_ICON.cloneNode( true),
827 ELM_THUMBNAIL = pettanr.util.getElementsByClassName( ELM_WRAPPER, ICON_CLASSNAME )[0],
828 ELM_FILENAME = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-filename' )[0],
829 ELM_DESCRIPTION = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-summary' )[0],
830 ELM_EDITOR_BUTTON = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-console-editor-apps' )[0],
831 ELM_VIEWER_BUTTON = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-console-viewer-apps' )[0],
832 ELM_ACTION_BUTTON = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-console-action' )[0],
833 file, w, index, style, instansce,
834 onDownCallback, onEditorCallback, onViewerCallback, onActionCallback,
835 viewerList, editorList;
837 ELM_WRAPPER.onclick = onDownClick;
838 function onDownClick(){
839 onDownCallback( index);
842 ELM_EDITOR_BUTTON.onclick = onEditorClick;
843 function onEditorClick(){
844 onEditorCallback( file, editorList[ 0 ] );
847 ELM_VIEWER_BUTTON.onclick = onViwerClick;
848 function onViwerClick(){
849 onViewerCallback( file, viewerList[ 0 ] );
852 ELM_ACTION_BUTTON.onclick = onActionClick;
853 function onActionClick(){
854 onActionCallback( file );
858 var _thumb = file.getThumbnail();
860 ELM_THUMBNAIL.className = ICON_CLASSNAME + ' has-thumbnail';
861 ELM_THUMBNAIL.style.backgroundImage = [ 'url(', _thumb.image, ')'].join( '');
863 ELM_THUMBNAIL.className = ICON_CLASSNAME + ' ' + _thumb.className;
864 ELM_THUMBNAIL.style.backgroundImage = '';
866 ELM_FILENAME.firstChild.data = file.getName();
867 ELM_DESCRIPTION.firstChild.data = file.getSummary();
869 if( Type.isArray( viewerList ) === true && viewerList.length > 0 ){
870 ELM_VIEWER_BUTTON.style.display = '';
872 ELM_VIEWER_BUTTON.style.display = 'none';
874 if( Type.isArray( editorList ) === true && editorList.length > 0 ){
875 ELM_EDITOR_BUTTON.style.display = '';
877 ELM_EDITOR_BUTTON.style.display = 'none';
881 // ELM_WRAPPER.style.top = (index * ICON_HEIGHT) +'px';
883 function onCollect(){
884 elmContainer.removeChild( ELM_WRAPPER );
886 FINDER_ICON_POOL.push( instansce );
890 init: function( _file, _elmContainer, _w, _index, _style, _onDownCallback, _onEditorCallback, _onViewerCallback, _onActionCallback ){
892 if( elmContainer !== _elmContainer){
893 _elmContainer.appendChild( ELM_WRAPPER);
894 elmContainer = _elmContainer;
897 file && file.destroy();
899 viewerList = file.viewerApplicationList();
900 editorList = file.editorApplicationList();
903 if( index !== _index){
907 onDownCallback = _onDownCallback;
908 onEditorCallback = _onEditorCallback;
909 onViewerCallback = _onViewerCallback;
910 onActionCallback = _onActionCallback;
913 index: function( _index){
917 style: function( _style){
921 onResize: function( w ){
925 elmContainer.removeChild( ELM_WRAPPER );
926 file && file.destroy();
927 file = elmContainer = onDownCallback = onEditorCallback = onViewerCallback = onActionCallback = viewerList = editorList = null;
928 FINDER_ICON_POOL.push( instansce);
932 function updateIconPosition( _style, _w, _index, _elm){
935 var BreadcrumbClass = function(){
937 ELM_WRAPPER = ELM_ORIGIN_FINDER_LOCATION_ITEM.cloneNode( true ),
938 ELM_FILENAME = ELM_WRAPPER.getElementsByTagName( 'a')[0],
939 file, w, index, instansce,
941 ELM_WRAPPER.onclick = onClick;
943 ELM_FILENAME.className = 'file-icon-' + file.getType();
944 ELM_FILENAME.innerHTML = file.getName();
946 function resize( index){
947 ELM_WRAPPER.style.left = (index * 90) +'px';
955 init: function( _file, _elmContainer, _index, _callback ){
957 if( elmContainer !== _elmContainer ){
958 _elmContainer.appendChild( ELM_WRAPPER);
959 elmContainer = _elmContainer;
965 if( index !== _index){
969 callback = _callback;
972 index: function( _index){
976 onResize: function( w){
980 elmContainer.removeChild( ELM_WRAPPER);
981 file = elmContainer = null;
982 BREAD_OBJECT_POOL.push( this );
987 var FinderClass = function( ELM_CONTAINER, tree, header, footer, onSelect, viewerOption, editorOption ){
990 elmContainer = ELM_ORIGIN_CONTAINER.cloneNode( true ),
991 elmLocation = elmContainer.getElementsByTagName( 'ul' )[0],
992 nodesDiv = elmContainer.getElementsByTagName( 'div' ),
993 elmSidebarButton = nodesDiv[1],
994 elmStyleButton = nodesDiv[2],
995 elmActionButton = nodesDiv[3],
996 elmBody = nodesDiv[ nodesDiv.length -1 ],
997 //tree = pettanr.file.createTree( TREE_TYPE),
1000 headH = pettanr.util.getElementSize( nodesDiv[0] ).height,
1004 size = pettanr.util.getElementSize( ELM_ORIGIN_FINDER_ICON ),
1006 iconH = size.height,
1011 tree.addTreeEventListener( pettanr.file.TREE_EVENT.UPDATE, draw );
1012 ELM_CONTAINER.appendChild( elmContainer );
1014 function draw( _w, _h ){
1015 w = Type.isFinite( _w ) === true ? _w : w;
1016 h = Type.isFinite( _h ) === true ? _h : h;
1018 var l = tree.hierarchy() +1,
1019 m = BREAD_ARRAY.length,
1021 for(var i=0; i<l; ++i){
1022 _file = i !== l-1 ? tree.getParentFileAt( i) : tree.getCurrentFile();
1024 BREAD_ARRAY[ i].init( _file, elmLocation, i, onHeadClick);
1026 BREAD_ARRAY.push( getBreadcrumb( _file, elmLocation, i, onHeadClick ));
1029 while( l < BREAD_ARRAY.length){
1030 BREAD_ARRAY.pop().destroy();
1033 l = _file.getChildFileLength();
1034 m = ICON_ARRAY.length;
1036 for( i=0; i<l; ++i){
1038 ICON_ARRAY[ i ].init( _file.getChildFileByIndex( i), elmBody, w, i, style, onDown, onEditor, onViwer, onAction );
1040 ICON_ARRAY.push( getFinderIcon( _file.getChildFileByIndex( i), elmBody, _w, i, style, onDown, onEditor, onViwer, onAction ));
1043 if( _file.getState() === pettanr.file.FILE_STATE.LOADING ){
1044 elmBody.className = 'finder-body loading';
1046 elmBody.className = 'finder-body';
1049 elmBody.style.height = bodyH + 'px';
1051 while( l < ICON_ARRAY.length){
1052 ICON_ARRAY.pop().destroy();
1056 function onHeadClick( i){
1057 var l = BREAD_ARRAY.length -1;
1059 var _file = tree.getParentFileAt( i);
1060 if( _file !== null){
1066 function onDown( i ){
1067 if( i < ICON_ARRAY.length ){
1068 var _file = tree.getCurrentFile().getChildFileByIndex( i );
1069 if( _file !== null && ( _file.getChildFileLength() !== -1 || _file.getType() === pettanr.file.FILE_TYPE.FOLDER)){
1073 Type.isFunction( onSelect ) === true && onSelect( _file );
1077 function onEditor( _file, _app, editorOption ){
1078 _app.boot( _file, editorOption );
1080 function onViwer( _file, _app ){
1081 _app.bootInOverlay( _file, viewerOption );
1083 function onAction( _file ){
1086 this.rootElement = elmContainer;
1087 this.parentElement = ELM_CONTAINER;
1088 this.displayName = 'finder';
1090 this.MIN_WIDTH = 240;
1091 this.MIN_HEIGHT = 240;
1092 this.init = function(){
1093 //$( elmLocation).click( onHeadClick);
1094 //$( elmContainer).click( onBodyClick);
1095 var position = pettanr.util.getAbsolutePosition( elmLocation );
1098 bodyY = pettanr.util.getAbsolutePosition( elmBody ).y;
1099 delete instance.init;
1101 this.onPaneResize = function( _w, _h ){
1102 instance.init && instance.init();
1107 elmBody.style.height = ( _h - headH ) + 'px';
1109 for(var i=0, l=ICON_ARRAY.length; i<l; ++i){
1110 ICON_ARRAY[ i].onResize( _w );
1114 FinderClass.prototype = pettanr.view._getAbstractApplication();
1116 function getFinderIcon( _file, _elmContainer, w, index, style, onDown, onEditor, onViwer, onAction){
1118 if( FINDER_ICON_POOL.length > 0){
1119 _icon = FINDER_ICON_POOL.shift();
1121 _icon = new FinderIconClass();
1123 _icon.init( _file, _elmContainer, w, index, style, onDown, onEditor, onViwer, onAction );
1127 function getBreadcrumb( _file, _elmContainer, index, callback){
1129 if( BREAD_OBJECT_POOL.length > 0){
1130 _bread = BREAD_OBJECT_POOL.shift();
1132 _bread = new BreadcrumbClass();
1134 _bread.init( _file, _elmContainer, index, callback);
1142 createFinder: function( _applicationReference, _elmTarget, _tree, _header, _footer, _onSelect, _viewerOption, _editorOption ){
1143 if( pettanr.view.isApplicationReference( _applicationReference ) === false ) return;
1145 var _finder = new FinderClass( _elmTarget, _tree, _header, _footer, _onSelect, _viewerOption, _editorOption );
1146 FINDER_ARRAY.push( _finder );
1149 registerFinderHead: function(){
1152 registerFinderPane: function( _finderPane){
1155 isFinderInstance: function( _finder){
1156 return _finder instanceof FinderClass;
1158 isFinderPaneInstance: function(){
1161 isFinderHeadInstance: function(){
1167 pettanr.driver = ( function(){
1168 var MyAuthorID = 'current_author' in window ? current_author.id : ( pettanr.CONST.SERVER_SUPPORT === false ? 1 : -1 ),
1169 MyArtistID = 'current_artist' in window ? current_artist.id : ( pettanr.CONST.SERVER_SUPPORT === false ? 1 : -1 ),
1171 getSeqentialFiles: function( _file){
1172 var _data = FileAPI.getFileData( _file),
1173 _json = _data !== null ? _data.json : null;
1174 if( _json === true && _data.type === pettanr.driver.FILE_TYPE.COMIC ){
1175 if( pettanr.CONST.SERVER_SUPPORT === false ){
1176 _json = [ 'json\/comics_', _data.id, '.json' ].join( '' );
1178 _json = [ pettanr.CONST.PETTANR_ROOT_PATH, 'comics\/', _data.id, '.json\/play\/' ].join( '' );
1181 if( typeof _json === 'string'){
1182 FileAPI.getJson( _file, _json, onLoadJson, onErrorJson);
1183 _data.state = pettanr.file.FILE_STATE.LOADING;
1188 getName: function( _file){
1189 var _data = FileAPI.getFileData( _file),
1190 _type = _data !== null ? _data.type : null;
1191 if( _type === pettanr.driver.FILE_TYPE.PICTURE ){
1192 return [ _data.id, _data.ext ].join( '.');
1194 if( _type === pettanr.driver.FILE_TYPE.PANEL ){
1195 return [ _data.t, ':', _data.comic.title ].join( '');
1197 if( _type === pettanr.driver.FILE_TYPE.COMIC ){
1200 if( _type === pettanr.driver.FILE_TYPE.ARTIST ){
1201 return [ _data.name, '画伯' ].join( '');
1203 if( _type === pettanr.driver.FILE_TYPE.AUTHOR ){
1204 return [ _data.name, '先生' ].join( '');
1208 getThumbnail: function( _file){
1209 var _data = FileAPI.getFileData( _file),
1210 _type = _data !== null ? _data.type : null;
1211 if( _type === pettanr.driver.FILE_TYPE.PICTURE){
1212 return { image: [ pettanr.CONST.RESOURCE_PICTURE_PATH, 'thumbnail/', _data.id, '.', _data.ext ].join( '')};
1214 if( _data === FILE_DATA_COMICS_ROOT){
1215 return { className: 'file-type-cabinet'};
1217 if( _type === pettanr.driver.FILE_TYPE.COMIC){
1218 return { className: 'file-type-comic'};
1220 if( _type === pettanr.driver.FILE_TYPE.PANEL){
1221 return { className: 'file-type-panel'};
1223 if( _type === pettanr.driver.FILE_TYPE.AUTHOR){
1224 return { className: 'file-type-author'};
1226 if( _type === pettanr.driver.FILE_TYPE.ARTIST){
1227 return { className: 'file-type-artist'};
1229 if( _type === pettanr.file.FILE_TYPE.FOLDER){
1230 return { className: 'file-type-folder'};
1232 return { className: 'file-type-broken'};
1234 getSummary: function( _file ){
1235 var _data = FileAPI.getFileData( _file ),
1236 _type = _data !== null ? _data.type : null;
1237 if( _type === pettanr.driver.FILE_TYPE.PICTURE){
1238 return [ _data.width, 'x', _data.height, ', filesize:', _data.filesize, ', lisence:', _data.license ].join( '' );
1240 if( _data === FILE_DATA_COMICS_ROOT){
1241 return 'cabinet file';
1243 if( _type === pettanr.driver.FILE_TYPE.COMIC){
1244 return 'comic file, id:' + _data.id;
1246 if( _type === pettanr.driver.FILE_TYPE.PANEL){
1247 return [ _data.width, 'x', _data.height ].join( '' );
1249 if( _type === pettanr.driver.FILE_TYPE.AUTHOR){
1250 return 'author file, id:' + _data.id;
1252 if( _type === pettanr.driver.FILE_TYPE.ARTIST){
1253 return [ 'id:', _data.id, ' Email:', _data.email || 'empty' , ', HP:', _data.homepage_url || 'empty' ].join( '' );
1255 if( _type === pettanr.file.FILE_TYPE.FOLDER){
1256 return 'pettanR folder';
1258 return 'pettanR unknown file';
1260 read: function( _file ){
1261 var _data = FileAPI.getFileData( _file ),
1262 _type = _data !== null ? _data.type : null,
1264 if( _type === pettanr.driver.FILE_TYPE.COMIC ){
1265 // children を panels に deepcopy
1267 for( var key in _data ){
1268 ret[ key ] = _data[ key ]
1270 ret.panels = _data.children;
1273 if( _type === pettanr.driver.FILE_TYPE.PANEL ){
1275 if( _type === pettanr.driver.FILE_TYPE.PANEL_PICTURE ){
1278 if( _type === pettanr.driver.FILE_TYPE.BALLOON ){
1280 if( _type === pettanr.driver.FILE_TYPE.PICTURE ){
1283 write: function( _file, _newData, _onUpdateFunction ){
1284 var _data = FileAPI.getFileData( _file ),
1285 _type = _data !== null ? _data.type : null;
1286 if( _type === pettanr.driver.FILE_TYPE.COMIC ){
1288 if( _type === pettanr.driver.FILE_TYPE.PANEL ){
1290 if( _type === pettanr.driver.FILE_TYPE.PANEL_PICTURE ){
1293 if( _type === pettanr.driver.FILE_TYPE.BALLOON ){
1295 if( _type === pettanr.driver.FILE_TYPE.PICTURE ){
1298 viewerApplicationList: function( _file ){
1299 var _data = FileAPI.getFileData( _file ),
1300 _type = _data !== null ? _data.type : null;
1301 if( _type === pettanr.driver.FILE_TYPE.PANEL ){
1302 return [ pettanr.reader ];
1304 if( _type === pettanr.driver.FILE_TYPE.COMIC ){
1305 return [ pettanr.reader ];
1307 if( _data === FILE_DATA_MY_PICTURES_ROOT ){
1308 return [ pettanr.premiumSatge ];
1310 if( _type === pettanr.driver.FILE_TYPE.ARTIST ){
1311 return [ pettanr.premiumSatge ];
1315 editorApplicationList: function( _file ){
1316 var _data = FileAPI.getFileData( _file ),
1317 _type = _data !== null ? _data.type : null;
1318 if( _type === pettanr.driver.FILE_TYPE.PANEL ){
1319 return [ pettanr.editor ];
1321 if( _type === pettanr.driver.FILE_TYPE.COMIC ){
1322 return [ pettanr.editor, pettanr.comicConsole ];
1327 FileAPI = pettanr.file.registerDriver( Driver ),
1328 FILE_DATA_SERVICE_ROOT = {
1329 name: 'PettanR root',
1330 type: pettanr.file.FILE_TYPE.FOLDER,
1333 FILE_DATA_COMICS_ROOT = {
1335 type: pettanr.file.FILE_TYPE.FOLDER,
1338 json: pettanr.CONST.URL_COMICS_JSON
1340 FILE_DATA_PANELS_ROOT = {
1342 type: pettanr.file.FILE_TYPE.FOLDER,
1345 json: pettanr.CONST.URL_PANELS_JSON
1347 FILE_DATA_PICTURE_ROOT = {
1349 type: pettanr.file.FILE_TYPE.FOLDER,
1352 json: pettanr.CONST.URL_RESOURCE_PICTURES_JSON
1354 FILE_DATA_MY_COMICS_ROOT = {
1356 type: pettanr.file.FILE_TYPE.FOLDER,
1361 FILE_DATA_LATEST_COMICS = {
1362 name: 'Latest Comics',
1363 type: pettanr.file.FILE_TYPE.FOLDER,
1366 FILE_DATA_MY_PICTURES_ROOT = {
1367 name: 'My Pictures',
1368 type: pettanr.file.FILE_TYPE.FOLDER,
1371 json: pettanr.CONST.URL_ORIGINAL_PICTURES_JSON,
1374 FILE_DATA_AUTHOR_ROOT = {
1376 type: pettanr.file.FILE_TYPE.FOLDER,
1379 FILE_DATA_ARTIST_ROOT = {
1381 type: pettanr.file.FILE_TYPE.FOLDER,
1384 FILE_DATA_LISENCE_ROOT = {
1385 name: 'Original Lisences',
1386 type: pettanr.file.FILE_TYPE.FOLDER,
1389 FILE_DATA_BALLOON_ROOT = {
1390 name: 'Balloon templetes',
1391 type: pettanr.file.FILE_TYPE.FOLDER,
1398 RESOURCE_PICTURE_ARRAY = [],
1399 BALLOON_TEMPLETE_ARRAY = [],
1400 ORIGINAL_LICENSE_ARRAY = [],
1401 BASIC_LICENSES = 'cc_by,cc_nc,cc_nd,cc_sa,keep_aspect_ratio,no_convert,no_flip,no_resize'.split( ',');
1402 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);
1403 FILE_DATA_COMICS_ROOT.children.push( FILE_DATA_MY_COMICS_ROOT, FILE_DATA_LATEST_COMICS, FILE_DATA_AUTHOR_ROOT);
1404 FILE_DATA_PICTURE_ROOT.children.push( FILE_DATA_MY_PICTURES_ROOT, FILE_DATA_ARTIST_ROOT);
1406 FileAPI.createFolderUnderRoot( FILE_DATA_SERVICE_ROOT);
1408 function onLoadJson( _file, _json ){
1409 var _access = FileAPI.getFileDataAccess( _file),
1410 _data = _access !== null ? _access.DATA : null,
1412 if( _data === null){
1413 onErrorJson( _file);
1416 _data.state = pettanr.file.FILE_STATE.OK;
1418 if( Type.isArray( _json ) === true ){
1420 if( l === 0) return;
1421 for( var i=0; i<l; ++i ){
1422 buildFileData( _json[ i], _data);
1426 buildFileData( _json, _data );
1428 _access.dispatchFileEvent( FileAPI.createFileEvent( pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES, _file, 'children', null));
1430 function onErrorJson( _file ){
1431 var _data = FileAPI.getFileData( _file);
1432 if( _data !== null){
1433 _data.state = pettanr.file.FILE_STATE.ERROR;
1436 function buildFileData( _data, _parent ){
1439 if( _parent === FILE_DATA_PANELS_ROOT ){
1440 _data.type = pettanr.driver.FILE_TYPE.PANEL;
1441 _array = PANEL_ARRAY;
1444 if( _parent === FILE_DATA_COMICS_ROOT ){
1445 _data.type = pettanr.driver.FILE_TYPE.COMIC;
1446 _array = COMIC_ARRAY;
1448 if( _parent.type === pettanr.driver.FILE_TYPE.COMIC ){
1449 _array = COMIC_ARRAY;
1452 if( _parent === FILE_DATA_LISENCE_ROOT ){
1453 _data.type = pettanr.driver.FILE_TYPE.LICENSE;
1454 _array = ORIGINAL_LICENSE_ARRAY;
1457 if( _parent === FILE_DATA_AUTHOR_ROOT ){
1458 _data.type = pettanr.driver.FILE_TYPE.AUTHOR;
1459 _array = AUTHOR_ARRAY;
1462 if( _parent === FILE_DATA_ARTIST_ROOT ){
1463 _data.type = pettanr.driver.FILE_TYPE.ARTIST;
1464 _array = ARTIST_ARRAY;
1467 if( _parent === FILE_DATA_PICTURE_ROOT || _parent === FILE_DATA_MY_PICTURES_ROOT ){
1468 _data.type = pettanr.driver.FILE_TYPE.PICTURE;
1469 _array = RESOURCE_PICTURE_ARRAY;
1470 // original_license を含まなければ、license object を削除して ビットデータ で保持
1471 // original_license なら ファイルを作る buildFileData( _license, FILE_DATA_LISENCE_ROOT)
1472 var _license = _data.license,
1474 _Math_pow = Math.pow,
1476 if( typeof _license === 'object'){
1477 for( i=0, l=BASIC_LICENSES.length; i<l; ++i){
1478 _rule = _license[ BASIC_LICENSES[ i]]
1479 if( typeof _rule === 'number' && _rule === 1 ){
1480 _bits += _Math_pow( 2, i);
1483 _data.license = _bits;
1489 _data.driver = Driver;
1491 // _array に _data を格納 または 上書き
1492 if( typeof _data.id === 'number' && _data.id > 0 ){
1493 var _id = _data.id - 1,
1494 __data = _array[ _id ],
1495 _reserved = pettanr.file.FILE_DATA_PROPERTY_RESERVED.join( ', ' );
1497 for( var key in _data){
1498 if( _reserved.indexOf( key ) === -1 ){
1499 __data[ key ] = _data[ key ];
1502 _data = __data; // このタイミングで参照が切れるので注意!!
1504 _array[ _id ] = _data;
1512 if( _parent === FILE_DATA_AUTHOR_ROOT || _parent === FILE_DATA_ARTIST_ROOT ){
1513 addChildData( _parent, _data );
1516 if( _parent.type === pettanr.driver.FILE_TYPE.COMIC || _parent === FILE_DATA_COMICS_ROOT ){
1517 var _panels = _data.panels,
1519 if( _panels && Type.isArray( _panels ) === true ){
1521 for( i=0, l=_panels.length; i<l; ++i){
1522 _panel = buildFileData( _panels[ i ], FILE_DATA_PANELS_ROOT );
1526 addChildData( _data, _panel );
1528 delete _data.panels;
1530 if( _data.json !== null ){
1533 if( Type.isArray( _data.children ) === false ){
1534 _data.children = [];
1537 var _author = _data.author || getResource( AUTHOR_ARRAY, _data.author_id );
1539 _data.author = _author = buildFileData( _author, FILE_DATA_AUTHOR_ROOT );
1540 addChildData( _author, _data );
1541 _author.id === MyAuthorID && addChildData( FILE_DATA_MY_COMICS_ROOT, _data );
1543 if( _parent === FILE_DATA_COMICS_ROOT ){
1544 addChildData( FILE_DATA_LATEST_COMICS, _data);
1548 if( _parent === FILE_DATA_PANELS_ROOT ){
1549 _data.comic = getResource( COMIC_ARRAY, _data.comic_id );
1550 _data.author = getResource( AUTHOR_ARRAY, _data.author_id );
1552 // picture data をファイルに取り出し
1553 var _elements = _data.panel_elements,
1555 if( Type.isArray( _elements ) === true ){
1556 for( i=0, l=_elements.length; i<l; ++i){
1557 _elm = _elements[ i];
1558 if( _elm.resource_picture ){
1559 _elm.resource_picture = buildFileData( _elm.resource_picture, FILE_DATA_PICTURE_ROOT ); // 上記参照切れに備えてここで上書き
1561 _elm.resource_picture = getResource( RESOURCE_PICTURE_ARRAY, _elm.resource_picture_id );
1567 if( _data.type == pettanr.driver.FILE_TYPE.PICTURE ){
1568 var _artist = _data.artist || getResource( ARTIST_ARRAY, _data.artist_id );
1570 _data.artist = _artist = buildFileData( _artist, FILE_DATA_ARTIST_ROOT );
1571 addChildData( _artist, _data );
1572 if( _artist.id === MyArtistID ){
1573 addChildData( FILE_DATA_MY_PICTURES_ROOT, _data );
1574 //FILE_DATA_MY_PICTURES_ROOT.type = pettanr.driver.FILE_TYPE.ARTIST;
1575 //FILE_DATA_MY_PICTURES_ROOT.id = MyArtistID;
1581 function addChildData( _parent, _child ){
1582 if( Type.isArray( _parent.children ) === false){
1583 _parent.children = [];
1585 pettanr.util.getIndex( _parent.children, _child ) === -1 && _parent.children.push( _child );
1587 function getResource( _array, _id ){
1588 if( Type.isArray( _array ) === false || Type.isNumber( _id ) === false || _id < 1 ) return null;
1589 var _data = _array[ _id - 1 ];
1591 _data = _array[ _id - 1 ] = {};
1597 createComicTree: function(){
1598 return pettanr.file.createTree( FILE_DATA_SERVICE_ROOT ); //FILE_DATA_COMICS_ROOT);
1600 createPictureTree: function(){
1601 var _tree = pettanr.file.createTree( FILE_DATA_PICTURE_ROOT );
1602 _root = _tree.getRootFile();
1603 _myPic = _root.getChildFileByIndex( 0 );
1604 _pic = _root.getChildFileByIndex( 1 );
1605 _myPic.getSeqentialFiles();
1606 _pic.getSeqentialFiles();
1611 createArtistTree: function(){
1612 return pettanr.file.createTree( FILE_DATA_ARTIST_ROOT );
1614 createServiceTree: function(){
1615 return pettanr.file.createTree( FILE_DATA_SERVICE_ROOT );
1617 isPettanrFileInstance: function( _file ){
1618 if( pettanr.file.isFileInstance( _file ) === true){
1619 var _data = FileAPI.getFileData( _file);
1620 return _data !== null && _data.driver === Driver;
1624 _getAPI: function(){
1627 _getPictureRootData: function(){
1628 return FILE_DATA_PICTURE_ROOT;
1630 _getMyPicturesData: function(){
1631 return FILE_DATA_MY_PICTURES_ROOT;
1634 COMIC: FileAPI.createFileTypeID(),
1635 PANEL: FileAPI.createFileTypeID(),
1636 PICTURE: FileAPI.createFileTypeID(),
1637 PANEL_PICTURE: FileAPI.createFileTypeID(),
1638 BALLOON: FileAPI.createFileTypeID(),
1639 AUTHOR: FileAPI.createFileTypeID(),
1640 ARTIST: FileAPI.createFileTypeID(),
1641 LICENSE: FileAPI.createFileTypeID()
1646 pettanr.entrance = pettanr.view.registerApplication( function(){
1647 var wrap = document.getElementById('inner-wrapper'),
1648 pageHeaderH = pettanr.util.getElementSize( document.getElementById( 'header' ) ).height,
1650 this.displayName = 'Home';
1652 this.rootElement = document.getElementById('entrance');
1653 this.onOpen = function( _w, _h, _option ){
1654 wrap.style.display = '';
1655 wrap.style.height = ( _h - pageHeaderH ) + 'px';
1657 this.onClose = function(){
1658 wrap.style.display = 'none';
1660 this.onPaneResize = function( _w, _h){
1661 instance.onOpen( _w, _h );
1664 pettanr.entrance.addToLancher();
1666 pettanr.cabinet = pettanr.view.registerApplication( function(){
1668 elmContainer = document.getElementById( 'cabinet'),
1670 pageHeaderH = pettanr.util.getElementSize( document.getElementById( 'header' ) ).height;
1672 this.displayName = 'Comic list';
1673 this.ID = 'Comiclist';
1674 this.rootElement = elmContainer;
1675 this.onOpen = function( _w, _h ){
1676 finder = finder || pettanr.finder.createFinder( pettanr.cabinet, elmContainer, pettanr.driver.createComicTree() );
1677 finder.resize( _w, _h - pageHeaderH );
1679 this.onClose = function(){
1682 this.onPaneResize = function( _w, _h){
1683 finder.resize( _w, _h - pageHeaderH );
1686 pettanr.cabinet.addToLancher();
1688 pettanr.gallery = pettanr.view.registerApplication( function(){
1690 elmContainer = document.getElementById( 'gallery' ),
1692 pageHeaderH = pettanr.util.getElementSize( document.getElementById( 'header' ) ).height;
1694 this.displayName = 'Pictures';
1695 this.ID = 'pictures';
1696 this.rootElement = elmContainer;
1697 this.onOpen = function( _w, _h ){
1698 finder = finder || pettanr.finder.createFinder( pettanr.gallery, elmContainer, pettanr.driver.createPictureTree() );
1699 finder.resize( _w, _h - pageHeaderH );
1701 this.onClose = function(){
1704 this.onPaneResize = function( _w, _h){
1705 finder.resize( _w, _h - pageHeaderH );
1708 pettanr.gallery.addToLancher();
1710 pettanr.backyard = pettanr.view.registerApplication( function(){
1711 this.displayName = 'Settings';
1712 this.ID = 'Settinds';
1713 this.rootElement = document.getElementById( 'backyard' );
1714 this.onOpen = function( _w, _h, _option ){
1716 this.onClose = function(){
1718 this.onPaneResize = function( _w, _h){
1721 pettanr.backyard.addToLancher();
1723 if( pettanr.DEBUG === true){
1724 pettanr.debug = pettanr.view.registerApplication( function(){
1725 var elmDl = document.getElementById( 'useragent'),
1728 pettanR: pettanr.version,
1729 ua: navigator.userAgent,
1730 platform: navigator.platform,
1731 appVersion: navigator.appVersion,
1732 appCodeName:navigator.appCodeName,
1733 appName: navigator.appName,
1734 language: navigator.browserLanguage || navigator.language,
1735 ActiveX: pettanr.ua.ACTIVEX
1739 //data.ua = 'Internet Explorer';
1740 data.version = ua.IE;
1741 if( ua.ieVersion >= 8) data.RenderingVersion = ua.ieRenderingVersion;
1742 data.browserType = ua.STANDALONE === true ? 'Standalone' : 'bundle';
1743 if( ua.ieVersion < 9) {
1749 data.RenderingMode = ua.isStanderdMode === true ? 'Standerd' : 'Quirks';
1751 for( var key in data){
1752 elmDt = document.createElement( 'dt');
1753 elmDt.innerHTML = key;
1754 elmDd = document.createElement( 'dd');
1755 elmDd.innerHTML = '' + data[ key];
1756 if( !data[ key]) elmDd.style.color = 'red';
1757 elmDl.appendChild( elmDt);
1758 elmDl.appendChild( elmDd);
1761 var wrap = document.getElementById('inner-wrapper'),
1762 pageHeaderH = pettanr.util.getElementSize( document.getElementById( 'header' )).height,
1765 this.displayName = 'Debug';
1767 this.rootElement = document.getElementById( 'debug' );
1768 this.onOpen = function( _w, _h, _option ){
1769 wrap.style.display = '';
1770 wrap.style.height = ( _h - pageHeaderH ) + 'px';
1772 this.onClose = function(){
1773 wrap.style.display = 'none';
1775 this.onPaneResize = function( _w, _h ){
1776 instance.onOpen( _w, _h );
1779 pettanr.debug.addToLancher();
1782 var _debug = document.getElementById( 'debug');
1784 pettanr.util.removeAllChildren( _debug);
1785 _debug.parentNode.removeChild( _debug);
1790 /* ----------------------------------------
1791 * Image Group Exproler
1794 pettanr.premiumSatge = pettanr.view.registerApplication( function(){
1795 var ICON_ARRAY = [],
1797 ARTIST_TREE = pettanr.driver.createArtistTree(),
1798 ARTIST_ROOT_FILE = ARTIST_TREE.getRootFile(),
1802 elmWrap = document.getElementById( 'image-group-wrapper' ),
1803 elmContainer = document.getElementById( 'image-group-icon-container' ),
1805 containerH = pettanr.util.getElementSize( elmContainer ).height,
1806 elmIconOrigin = ( function(){
1807 var ret = document.createElement( 'div' ),
1808 data = document.createElement( 'div' );
1809 ret.appendChild( data );
1810 ret.className = 'image-group-item';
1811 data.className = 'image-group-item-title';
1815 size = pettanr.util.getElementSize( elmIconOrigin ),
1817 itemH = size.height,
1818 elmName = document.getElementById( 'image-group-name' ),
1819 elmButton = document.getElementById( 'image-group-button' ),
1820 buttonW = pettanr.util.getElementSize( elmButton ).width,
1822 onUpdateFunction = null,
1823 onUpdateData = null,
1825 onEnterInterval = null;
1827 elmButton.onclick = clickOK;
1829 var BASE_PATH = pettanr.CONST.RESOURCE_PICTURE_PATH,
1830 THUMB_PATH = BASE_PATH, // + 'thumbnail/',
1831 LIMIT_FILESIZE = 1024 * 10; // 10KB
1833 var ImageGroupIconClass = function( INDEX, data ){
1834 var elmIconWrap = elmIconOrigin.cloneNode( true ),
1835 elmIconTitle = pettanr.util.getElementsByClassName( elmIconWrap, 'image-group-item-title' )[ 0 ],
1836 SRC = [ BASE_PATH, data.id, '.', data.ext ].join( ''),
1837 LOW_SRC = data.filesize && data.filesize > LIMIT_FILESIZE ? [ THUMB_PATH, data.id, '.', data.ext ].join( '') : null,
1838 reversibleImage = null,
1840 onEnterFlag = false,
1842 elmContainer.appendChild( elmIconWrap );
1843 elmIconWrap.style.left = ( INDEX * itemW ) + 'px';
1844 elmIconTitle.appendChild( document.createTextNode( data.filesize + 'bytes' ) );
1846 function onImageLoad( url, _imgW, _imgH ){
1847 data.width = _imgW = _imgW || data.width || 64;
1848 data.height = _imgH = _imgH || data.height || 64;
1849 elmIconTitle.firstChild.data = _imgW + 'x' + _imgH;
1850 var zoom = 128 /( _imgW > _imgH ? _imgW : _imgH ),
1851 MATH_FLOOR = Math.floor,
1852 h = MATH_FLOOR( _imgH * zoom ),
1853 w = MATH_FLOOR( _imgW * zoom );
1854 reversibleImage.elm.style.cssText = [
1856 'height:', h, 'px;',
1857 'margin:', MATH_FLOOR( itemH / 2 - h / 2 ), 'px ', MATH_FLOOR( itemW / 2 - w / 2 ), 'px 0'
1859 reversibleImage.resize( w, h );
1860 elmIconWrap.onclick = onClick;
1864 onUpdateData = data;
1865 pettanr.premiumSatge.shutdown();
1868 function asyncDraw(){
1869 reversibleImage = pettanr.image.createReversibleImage( LOW_SRC || SRC, itemW, itemH, onImageLoad );
1870 elmIconWrap.appendChild( reversibleImage.elm );
1875 this.onEnter = function( delay ){
1876 timer = window.setTimeout( asyncDraw, delay );
1877 delete instance.onEnter;
1879 this.destroy = function(){
1880 delete instance.destroy;
1881 timer && window.clearTimeout( timer );
1882 reversibleImage && reversibleImage.destroy();
1883 pettanr.util.removeAllChildren( elmIconWrap );
1884 elmContainer.removeChild( elmIconWrap );
1885 elmIconWrap.onclick = '';
1886 reversibleImage = elmIconWrap = elmIconTitle = data = timer = null;
1890 function onEnterShowImage(){
1891 var l = ICON_ARRAY.length,
1892 _start = -wrapX /itemW -1,
1893 _end = _start + winW /itemW +1,
1895 for( var i=0, c = 0; i<l; ++i){
1896 _icon = ICON_ARRAY[ i ];
1897 if( _start < i && i < _end && _icon.onEnter ){
1898 _icon.onEnter( c * 100 );
1902 onEnterInterval !== null && window.clearTimeout( onEnterInterval );
1903 onEnterInterval = null;
1906 pettanr.premiumSatge.shutdown();
1908 function onMouseWheel( e, delta ){
1909 if( winW < containerW){
1910 wrapX += delta * WHEEL_DELTA;
1911 wrapX = wrapX > 0 ? 0 : wrapX < winW -containerW ? winW -containerW : wrapX;
1912 jqContainer.css( { left: wrapX});
1914 onEnterInterval !== null && window.clearTimeout( onEnterInterval );
1915 onEnterInterval = window.setTimeout( onEnterShowImage, 500 );
1917 //e.stopPropagation();
1921 function drawIcons(){
1922 while( ICON_ARRAY.length > 0 ){
1923 ICON_ARRAY.shift().destroy();
1926 var _index = ARTIST_ROOT_FILE.search( {
1928 type: pettanr.driver.FILE_TYPE.ARTIST
1930 _artistFile = ARTIST_ROOT_FILE.getChildFileByIndex( _index ),
1932 if( _artistFile !== null ){
1933 for(var i=0, l=_artistFile.getChildFileLength(); i<l; ++i ){
1934 _file = _artistFile.getChildFileByIndex( i );
1935 ICON_ARRAY.push( new ImageGroupIconClass( i, pettanr.driver._getAPI().getFileData( _file ) ));
1938 elmName.firstChild.data = _artistFile.getName();
1939 _artistFile.destroy();
1943 function onFadeout(){
1944 while( ICON_ARRAY.length > 0 ){
1945 ICON_ARRAY.shift().destroy();
1947 onUpdateFunction !== null && onUpdateData !== null && onUpdateFunction( onUpdateData );
1948 onUpdateFunction = onUpdateData = null;
1952 // this.rootElement = elmWrap;
1953 this.displayName = 'premiumStage';
1954 this.ID = 'premiumStage';
1955 this.rootElement = elmWrap;
1956 this.MIN_WIDTH = 320;
1957 this.MIN_HEIGHT = 320;
1958 this.init = function(){
1959 jqContainer = $( elmContainer ).mousewheel( onMouseWheel );
1962 //var tree = pettanr.driver.createPictureTree();
1963 //tree.addTreeEventListener( pettanr.file.TREE_EVENT.UPDATE, drawIcons );
1964 // pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES
1965 delete instance.init;
1967 this.onOpen = function( _windowW, _windowH, _ARTISTIDorFILE, _onUpdateFunction ){
1968 instance.init && instance.init();
1970 if( pettanr.driver.isPettanrFileInstance( _ARTISTIDorFILE ) === true ){
1971 var _data = pettanr.driver._getAPI().getFileData( _ARTISTIDorFILE );
1972 if( _ARTISTIDorFILE.getType() === pettanr.driver.FILE_TYPE.ARTIST || pettanr.driver._getMyPicturesData() === _data ){
1973 artistID = _data.id || -1;
1976 if( Type.isNumber( _ARTISTIDorFILE ) === true ){
1977 artistID = _ARTISTIDorFILE;
1980 onUpdateFunction = _onUpdateFunction || null;
1981 onUpdateData = null;
1986 containerW = ICON_ARRAY.length * itemW;
1990 var w = winW > containerW ? winW : containerW,
1991 h = _windowH > containerH ? containerH : _windowH,
1992 MATH_FLOOR = Math.floor;
1998 top: MATH_FLOOR( _windowH /2)
1999 }).stop().animate( {
2001 top: MATH_FLOOR( _windowH /2 -h /2)
2002 }, onEnterShowImage );
2004 elmButton.style.cssText = [
2005 'left:', MATH_FLOOR( winW /2 - buttonW /2), 'px;',
2006 'top:', MATH_FLOOR( _windowH /2 + containerH /2 +10), 'px'
2009 this.onPaneResize = function( _windowW, _windowH ){
2010 var w = _windowW > containerW ? _windowW : containerW,
2011 h = _windowH > containerH ? containerH : _windowH,
2012 MATH_FLOOR = Math.floor,
2013 offsetW = MATH_FLOOR( _windowW /2 -winW /2);
2017 if( offsetW <= 0){ // smaller
2023 top: MATH_FLOOR( _windowH /2 -h /2)
2026 jqContainer.css( { // bigger
2029 borderLeftWidth: offsetW
2031 top: MATH_FLOOR( _windowH /2 -h /2),
2035 elmButton.style.cssText = [
2036 'left:', MATH_FLOOR( _windowW /2 -buttonW /2), 'px;',
2037 'top:', MATH_FLOOR( _windowH /2 +containerH /2 +10), 'px'
2041 this.onClose = function(){
2042 jqContainer.stop().animate( {
2044 top: Math.floor( winH /2 )
2046 onEnterInterval !== null && window.clearTimeout( onEnterInterval );
2047 onEnterInterval = null;
2052 /* ----------------------------------------
2056 pettanr.textEditor = pettanr.view.registerApplication( function(){
2057 var jqWrap, jqTextarea, jqButton,
2058 textElement, onUpdateFunction,
2062 //pettanr.key.addKeyDownEvent( ID, 69, false, false, clickOK);
2065 textElement && textElement.text( jqTextarea.val() );
2066 window.setTimeout( asyncCallback, 0 );
2069 function asyncCallback(){
2070 onUpdateFunction && onUpdateFunction( textElement );
2071 onUpdateFunction = textElement = null;
2072 pettanr.textEditor.shutdown();
2075 function keyCancel( e ){
2076 if( e.keyCode === 69 && e.shiftKey === false && e.ctrlKey === true){
2080 e.cancelBubble = true;
2081 e.returnValue = false;
2085 function textareaFitHeight(){
2087 while( jqTextarea.height() < textElement.h ){
2089 jqTextarea.attr( 'rows', rows );
2091 rows > 1 && jqTextarea.attr( 'rows', --rows );
2095 // this.rootElement = elmWrap;
2096 this.displayName = 'textEditor';
2097 this.ID = 'textEditor';
2098 this.rootElement = document.getElementById( 'speach-editor-wrapper' );
2099 this.MIN_WIDTH = 320;
2100 this.MIN_HEIGHT = 320;
2101 this.init = function(){
2102 jqWrap = $( '#speach-editor-wrapper' ).hide();
2103 jqTextarea = $( '#speach-editor' ).keydown( keyCancel );
2104 jqButton = $( '#speach-edit-complete-button').click( clickOK );
2105 delete instance.init;
2107 this.onOpen = function( _w, _h, _panelX, _panelY, _textElement, _onUpdateFunction ){
2108 instance.init && instance.init();
2112 textElement = _textElement;
2113 onUpdateFunction = _onUpdateFunction || null;
2116 instance.onPaneResize( _w, _h );
2117 jqTextarea.val( _textElement.text() ).focus();
2120 * ie6,7は、textarea { width:100%}でも高さが変わらない。rowsを設定。
2122 pettanr.ua.isIE === true && pettanr.ua.ieVersion <= 7 && setTimeout( textareaFitHeight, 0);
2124 this.onPaneResize = function( _w, _h ){
2126 left: textElement.x + panelX,
2127 top: textElement.y + panelY,
2128 width: textElement.w,
2129 height: textElement.h
2132 this.onClose = function(){
2138 pettanr.reader = pettanr.view.registerApplication( function(){
2139 var jqWrap, jqPanelContainer,
2141 headerH = pettanr.util.getElementSize( document.getElementById( 'comic-reader-header' ) ).height,
2142 consoleH = pettanr.util.getElementSize( document.getElementById( 'comic-reader-console' ) ).height,
2144 elmContainer = document.getElementById( 'comic-reader-panel-container' ),
2145 elmTitle = document.getElementById( 'comic-reader-title' ).firstChild,
2146 elmAuthor = document.getElementById( 'comic-reader-author' ).firstChild,
2147 elmBackButton = document.getElementById( 'comic-reader-back-button' ),
2148 elmNextButton = document.getElementById( 'comic-reader-forward-button' ),
2153 currentPanel = null,
2158 function onBackClick(){
2159 currentIndex -= ( currentIndex > 0 ? 1 : 0 );
2163 function onNextClick(){
2164 currentIndex += ( currentIndex < numPanel - 1 ? 1 : 0 );
2169 var elm = elmContainer.childNodes[ currentIndex ],
2170 h = windowH - headerH - consoleH,
2173 top = headerH - elm.offsetTop + Math.floor( ( h - elm.offsetHeight ) / 2 );
2176 jqPanelContainer.stop().animate( {
2180 function getCurrentTopPosition(){
2184 var fileData, title, author;
2186 if( pettanr.driver.isPettanrFileInstance( currentFile ) === true ){
2187 if( currentFile.getType() === pettanr.driver.FILE_TYPE.COMIC ){
2188 fileData = currentFile.read();
2189 title = fileData.title;
2190 author = fileData.author.name;
2191 comicData = fileData;
2192 numPanel = currentFile.getChildFileLength();
2194 if( currentFile.getType() === pettanr.driver.FILE_TYPE.PANEL ){
2195 fileData = currentFile.read();
2196 title = fileData.comic.title;
2197 author = fileData.comic.author.name;
2198 comicData = fileData;
2205 if( comicData !== null ){
2206 elmTitle.data = title;
2207 elmAuthor.data = author;
2208 bindWorker.json( comicData );
2209 window.setTimeout( asyncResize, 0 );
2212 function asyncResize(){
2213 instance.onPaneResize( windowW, windowH );
2217 // this.rootElement = elmWrap;
2218 this.displayName = ID;
2220 this.rootElement = document.getElementById( 'comic-reader-wrapper' );
2221 this.MIN_WIDTH = 320;
2222 this.MIN_HEIGHT = 320;
2223 this.init = function(){
2224 jqWrap = $( instance.rootElement );
2225 jqPanelContainer = $( elmContainer );
2227 elmBackButton.onclick = onBackClick;
2228 elmNextButton.onclick = onNextClick;
2230 bindWorker = pettanr.bind.createBindWorker( elmContainer, null, false, false );
2232 delete instance.init;
2234 this.onOpen = function( _w, _h, _file ){
2235 instance.init && instance.init();
2236 numPanel = currentIndex = 0;
2239 jqPanelContainer.css({
2245 if( pettanr.file.isFileInstance( _file ) === true ){
2246 currentFile = _file;
2247 _file.addEventListener( pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES, draw );
2251 this.onPaneResize = function( _windowW, _windowH ){
2254 var panelH = elmContainer.offsetHeight,
2255 panelW = elmContainer.offsetWidth,
2256 h = _windowH - headerH - consoleH;
2257 jqPanelContainer.stop().animate(
2259 left: Math.floor( ( _windowW - panelW ) / 2 ),
2260 top: headerH + ( panelH < h ? Math.floor( ( h - panelH ) / 2 ) : 0 )
2264 this.onClose = function(){
2266 currentFile.addEventListener( pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES, draw );
2267 currentFile = comicData = currentPanel = null;
2275 pettanr.fn( pettanr.view);
2276 pettanr.fn( pettanr.overlay);
2277 pettanr.fn( pettanr.key);
2278 pettanr.fn( pettanr.balloon);
2280 pettanr.fn( pettanr.editor);
2282 pettanr.fn( pettanr.file);
2283 pettanr.fn( pettanr.finder);
2284 pettanr.fn( pettanr.gallery);
2285 pettanr.fn( pettanr.cabinet);
2287 $(window).ready( pettanr.init);