Created
November 9, 2012 03:01
-
-
Save zrod/246c2165e673572d7bd9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* st/filemanager.js | |
* FileManager | |
* | |
* Dependencies: | |
* - jQuery | |
* - StoryTroop (st/storytroop) | |
* - StoryTroop.ui (st/ui) | |
* - Mustache (lib/mustache-wp) | |
*/ | |
define( function( require ) { | |
var $ = require( 'jquery' ), | |
storytroop = require( 'st/storytroop' ), | |
ui = require( 'st/ui' ), | |
Mustache = require( 'lib/mustache-wp' ); | |
var proto, | |
FM_URI = '/imagefilemanager/list'; | |
function FileManager() { | |
this.collection = {}; | |
this.settings = {}; | |
if ( arguments[0] ) { | |
this.context = ( arguments[0] instanceof jQuery ) ? arguments[0] : $( arguments[0] ); | |
if ( arguments[1] && typeof( arguments[1] ) === 'object' ) { | |
this.setSettings( arguments[1] ); | |
} | |
watchEvents.call( this ); | |
} | |
} | |
proto = FileManager.prototype; | |
/** | |
* setSettings | |
* - | |
* @param opt Object | |
*/ | |
proto.setSettings = function( opt ) { | |
var defaultSettings = { | |
selectCmd: '[data-filemanager-cmd="select"]', | |
removeCmd: '[data-filemanager-cmd="remove"]', | |
templates: { | |
collection: '<ul class="thumbnails">{{#items}}<li class="alignCenter" data-filemanager-type="{{type}}" data-filemanager-path="{{path}}">{{#file}}<a href="/imagefilemanager/delete?path={{path}}" data-filemanager-cmd="remove"><i class="icon-remove"></i></a>{{/file}}<a href="/imagefilemanager/list?path={{path}}" class="thumbnail" title="{{name}}" data-filemanager-obj="item"><div class="img"><img src="{{preview}}" alt="{{name}}" /></div> {{name}} </a> </li>{{/items}}</ul>' | |
}, | |
i18n: { | |
remove: 'Are you sure you want to remove this file?' | |
} | |
}; | |
this.settings = $.extend( {}, defaultSettings, opt ); | |
}; | |
/** | |
* init | |
*/ | |
proto.init = function() { | |
if ( Object.size( this.collection ) === 0 ) { | |
this.fetchCollection(); | |
} | |
}; | |
/** | |
* fetchCollection | |
* - | |
* @param path String | |
*/ | |
proto.fetchCollection = function( path ) { | |
var that = this, | |
path = path ? path : '', | |
cacheIndex,// = getCacheEntryKey.call( that, path ), | |
colUrl = FM_URI + ( path && typeof( path ) === 'string' ? '?path=' + encodeURIComponent( path ) : '' ), | |
loadingEl, | |
loadingCallback; | |
if ( cacheIndex ) { | |
// Read from cache | |
console.warn('present in cache'); | |
renderCollection.call( that, that.collection[cacheIndex][1] ); | |
that.context.data( 'activePath', path ); | |
} else { | |
// Fetch from server | |
loadingEl = that.context.find( '[data-filemanager-obj="loading"]' ); | |
ui.loading( 'show', { el: loadingEl, cursor: true } ); | |
$.ajax({ | |
url: colUrl | |
}).done( function( col ) { | |
if ( col && typeof( col ) === 'object' ) { | |
if ( Object.size( col ) > 0 ) { | |
renderCollection.call( that, col ); | |
that.context.data( 'activePath', path ); | |
// Store object in cache | |
path = path === '' ? '/' : path; | |
//that.collection.push( [path, col] ); | |
cacheItem.apply( that, [path, col] ); | |
} else { | |
// Empty | |
loadingCallback = function() { | |
that.context.find( '[data-filemanager-status="empty"]' ).show(); | |
}; | |
} | |
} else { | |
loadingCallback = function() { | |
that.context.find( '[data-filemanager-status="error"]' ).show(); | |
}; | |
} | |
}).fail( function() { | |
loadingCallback = function() { | |
that.context.find( '[data-filemanager-status="error"]' ).show(); | |
}; | |
}).always( function() { | |
ui.loading( 'hide', { el: loadingEl, callback: loadingCallback } ); | |
}); | |
} | |
}; | |
/** | |
* addItem | |
* - | |
* @param obj Object | |
*/ | |
proto.addItem = function( obj ) { | |
if ( obj && typeof( obj ) === 'Object' ) { | |
updateCollection( obj ); | |
} | |
}; | |
function cacheItem() { | |
var path = arguments[0], | |
obj = arguments[1], | |
o, | |
key = getCacheEntryKey.call( this, path ), | |
keyLen, | |
keyPath = '', | |
i = 0; | |
if ( key && key instanceof Array ) { | |
keyLen = key.length; | |
keyPath = this.collection; | |
for ( ; i < keyLen; i++ ) { | |
keyPath = keyPath[key[i]]; | |
} | |
// store item in 'data' and its child's path in 'child.path' --> {/path = data, child.path} | |
for ( o in obj ) { | |
//this.collection[key][path][o] = {}; | |
//this.collection[key][path].data = obj[o]; | |
keyPath[path][o] = {}; | |
keyPath[path].data = obj[o]; // !!! | |
} | |
console.log( keyPath ); | |
} else { | |
// Store in root | |
this.collection[path] = {}; | |
for ( o in obj ) { | |
this.collection[path][o] = {}; | |
this.collection[path].data = obj[o]; | |
} | |
} | |
console.log( this.collection ); | |
} | |
/** | |
* getCacheEntryKey | |
* - | |
* @return Int | |
*/ | |
function getCacheEntryKey() { | |
var key, | |
path = arguments[0], | |
c = arguments[1] ? arguments[1] : this.collection, | |
tree = arguments[2] ? arguments[2] : []; | |
if ( typeof( c ) === 'object' && Object.size( c ) > 0 ) { | |
for ( key in c ) { | |
if ( key === path ) { | |
//console.log( 'found a match', key ); | |
//tree.push( key ); | |
return tree; | |
} else { | |
tree.push( key ); | |
return getCacheEntryKey.apply( this, [path, c[key], tree] ); | |
} | |
} | |
} | |
return null; | |
} | |
/** | |
* renderCollection | |
* - | |
* @param col Object | |
*/ | |
function renderCollection( col ) { | |
var container = this.context.find( '[data-filemanager-obj="container"]' ), | |
path, | |
outputObj = { items: [] }, | |
output; | |
if ( container[0] && this.settings.templates.collection ) { | |
for ( path in col ) { | |
outputObj.items.push({ | |
type: col[path]['File Type'], | |
preview: col[path]['Preview'], | |
name: col[path]['Filename'], | |
path: col[path]['Path'], | |
file: ( col[path]['File Type'] === 'STANDARD' ? true : false ) | |
}); | |
} | |
output = Mustache.render( this.settings.templates.collection, outputObj ); | |
container[0].innerHTML = output; | |
//console.warn( 'current path: ' + this.context.data( 'activePath' ) ); | |
} | |
} | |
/** | |
* updateCollection | |
* Update local cache with added / deleted images | |
* Or just populate the collection cache obj, considering this is the first request | |
* - | |
* @param items Object | |
*/ | |
function updateCollection( items ) { | |
/*if ( this.collection && Object.size( this.collection ) > 0 ) { | |
console.log( this.collection ); | |
console.log( items ); | |
} else {*/ | |
// Collection was empty, populating for the first time | |
this.collection = items; | |
//} | |
} | |
/** | |
* history | |
* - | |
* @param dir String | |
*/ | |
function history( dir ) { | |
var that = this, | |
current = that.context.data( 'activePath' ), | |
cIndex, | |
nIndex, | |
next, | |
total = that.collection.length, | |
removeBtn = that.settings.removeCmd ? $( that.settings.removeCmd ) : null; | |
if ( current && total > 1 ) { | |
cIndex = getCacheEntryKey.call( that, current ); | |
if ( cIndex !== -1 ) { | |
total = total - 1; | |
switch ( dir ) { | |
case 'down': | |
if ( cIndex + 1 <= total ) { | |
nIndex = cIndex + 1; | |
} | |
break; | |
default: | |
if ( cIndex - 1 !== -1 ) { | |
nIndex = cIndex - 1; | |
} | |
} | |
} | |
} | |
if ( typeof( nIndex ) === 'number' ) { | |
next = that.collection[nIndex][1]; | |
that.context.data( 'activePath', that.collection[nIndex][0] ); | |
renderCollection.call( that, next ); | |
// Disable removeBtn | |
if ( removeBtn ) { | |
removeBtn.addClass( 'disabled' ); | |
} | |
} | |
} | |
/** | |
* watchEvents | |
*/ | |
function watchEvents() { | |
var that = this, | |
removeBtn = that.settings.removeCmd ? $( that.settings.removeCmd ) : null, | |
selectedItems = []; | |
/* | |
* Either go a directory down or select image/file | |
*/ | |
that.context.on( 'click', 'a[data-filemanager-obj="item"]', function( e ) { | |
var $this = $( this ), | |
mType = $this.parent().data( 'filemanager-type' ), | |
path = $this.parent().data( 'filemanager-path' ), | |
pathIndex; | |
if ( path && typeof( path ) === 'string' ) { | |
switch ( mType ) { | |
case 'STANDARD': | |
if ( $this.attr( 'data-filemanager-selected' ) ) { | |
pathIndex = selectedItems.indexOf( path ); | |
if ( pathIndex !== -1 ) { | |
selectedItems.splice( pathIndex, 1 ); | |
$this.removeAttr( 'data-filemanager-selected' ); | |
} | |
} else { | |
selectedItems.unshift( path ); | |
$this.attr( 'data-filemanager-selected', 'selected' ); | |
} | |
break; | |
default: | |
// Render next directory | |
that.fetchCollection( path ); | |
} | |
} | |
e.preventDefault(); | |
}); | |
/* | |
* Insert selected image(s) | |
*/ | |
$( that.settings.selectCmd ).click( function( e ) { | |
var sILen = selectedItems.length, | |
item; | |
if ( sILen > 0 && that.settings.selectCallback && typeof( that.settings.selectCallback ) === 'function' ) { | |
while ( sILen-- ) { | |
item = selectedItems.pop(); | |
if ( item ) { | |
that.settings.selectCallback.call( this, item ); | |
} | |
} | |
// Restore default state (filemanager-selected may have been used to style the element) | |
that.context.find( 'a[data-filemanager-selected]' ).removeAttr( 'data-filemanager-selected' ); | |
} | |
}); | |
/* | |
* Browse through collection | |
*/ | |
that.context.on( 'click', '[data-filemanager-nav="up"]', function( e ) { | |
history.call( that, 'up' ); | |
selectedItems = []; | |
e.preventDefault(); | |
}); | |
that.context.on( 'click', '[data-filemanager-nav="down"]', function( e ) { | |
history.call( that, 'down' ); | |
selectedItems = []; | |
e.preventDefault(); | |
}); | |
/* | |
* Remove an item | |
*/ | |
$( document ).on( 'click', that.settings.removeCmd, function( e ) { | |
var $this = $( this ), | |
ok = confirm( that.settings.i18n.remove ), | |
act, | |
cacheIndex, | |
path, | |
pathIndex; | |
if ( ok ) { | |
path = $this.parent().data( 'filemanager-path' ); | |
act = $this.attr( 'href' ); | |
ui.loading( 'show', { cursor: true } ); | |
$.ajax({ | |
url: act | |
}).done( function( r ) { | |
// If the current item had been selected, remove it from selectedItems array | |
pathIndex = selectedItems.indexOf( path ); | |
if ( pathIndex !== -1 ) { | |
selectedItems.splice( pathIndex, 1 ); | |
} | |
// Remove from cache !!! | |
cacheIndex = getCacheEntryKey.call( that, path ); | |
that.collection = []; // INVALDATING CACHE - As soon as the bug with cache's tree is fixed, remove parent node of current cacheIndex | |
// RE-RENDER !!! on next modal show(), render previous pointer | |
//that.fetchCollection( that.context.data( 'activePath' ) ); | |
$this.parent().remove(); | |
}).always( function() { | |
ui.loading( 'hide' ); | |
// Callback?! | |
if ( that.settings.removeCallback && typeof( that.settings.removeCallback ) === 'function' ) { | |
that.settings.removeCallback.call( this ); | |
} | |
}); | |
} | |
e.preventDefault(); | |
}); | |
// User must select a file before hitting 'upload' | |
/*that.context.find( '[data-filemanager-obj="form"]' ).submit( function( e ) { | |
var frm = $( this ), | |
file = frm.find( 'input[type="file"]' ), | |
errMsg; | |
if ( !file || !file.val() ) { | |
errMsg = frm.find( 'input[type="submit"]' ).data( 'filemanager-error-nofile' ); | |
if ( errMsg ) { | |
ui.notify( errMsg, { type: 'error' } ); | |
} | |
e.preventDefault(); | |
return false; // IE | |
} | |
});*/ | |
} | |
return FileManager; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment