mkfile.js 0000644 00000003213 15073226546 0006362 0 ustar 00 /**
* @class elFinder command "mkfile"
* Create new empty file
*
* @author Dmitry (dio) Levashov
**/
elFinder.prototype.commands.mkfile = function() {
"use strict";
var self = this;
this.disableOnSearch = true;
this.updateOnSelect = false;
this.mime = 'text/plain';
this.prefix = 'untitled file.txt';
this.variants = [];
this.getTypeName = function(mime, type) {
var fm = self.fm,
name;
if (name = fm.messages['kind' + fm.kinds[mime]]) {
name = fm.i18n(['extentiontype', type.toUpperCase(), name]);
} else {
name = fm.i18n(['extentionfile', type.toUpperCase()]);
}
return name;
};
this.fm.bind('open reload canMakeEmptyFile', function() {
var fm = self.fm,
hides = fm.getCommand('edit').getMkfileHides();
self.variants = [];
if (fm.mimesCanMakeEmpty) {
jQuery.each(fm.mimesCanMakeEmpty, function(mime, type) {
type && !hides[mime] && fm.uploadMimeCheck(mime) && self.variants.push([mime, self.getTypeName(mime, type)]);
});
}
self.change();
});
this.getstate = function() {
return this.fm.cwd().write ? 0 : -1;
};
this.exec = function(_dum, mime) {
var fm = self.fm,
type, err;
if (type = fm.mimesCanMakeEmpty[mime]) {
if (fm.uploadMimeCheck(mime)) {
this.mime = mime;
this.prefix = fm.i18n(['untitled file', type]);
var prefix_val = this.prefix;
if(prefix_val.includes("untitled file")){
prefix_val.replace("untitled file", "NewFile");
this.prefix = prefix_val;
}
return jQuery.proxy(fm.res('mixin', 'make'), self)();
}
err = ['errMkfile', self.getTypeName(mime, type)];
}
return jQuery.Deferred().reject(err);
};
};
copy.js 0000644 00000001732 15073226546 0006071 0 ustar 00 /**
* @class elFinder command "copy".
* Put files in filemanager clipboard.
*
* @type elFinder.command
* @author Dmitry (dio) Levashov
*/
elFinder.prototype.commands.copy = function() {
"use strict";
this.shortcuts = [{
pattern : 'ctrl+c ctrl+insert'
}];
this.getstate = function(select) {
var sel = this.files(select),
cnt = sel.length,
filter = function(files) {
var fres = true;
return jQuery.grep(files, function(f) {
fres = fres && f.read ? true : false;
return fres;
});
};
return cnt && filter(sel).length == cnt ? 0 : -1;
};
this.exec = function(hashes) {
var fm = this.fm,
dfrd = jQuery.Deferred()
.fail(function(error) {
fm.error(error);
});
jQuery.each(this.files(hashes), function(i, file) {
if (! file.read) {
return !dfrd.reject(['errCopy', file.name, 'errPerm']);
}
});
return dfrd.state() == 'rejected' ? dfrd : dfrd.resolve(fm.clipboard(this.hashes(hashes)));
};
};
empty.js 0000644 00000006503 15073226546 0006256 0 ustar 00 /**
* @class elFinder command "empty".
* Empty the folder
*
* @type elFinder.command
* @author Naoki Sawada
*/
elFinder.prototype.commands.empty = function() {
"use strict";
var self, fm,
selFiles = function(select) {
var sel = self.files(select);
if (!sel.length) {
sel = [ fm.cwd() ];
}
return sel;
};
this.linkedCmds = ['rm'];
this.init = function() {
// lazy assign to make possible to become superclass
self = this;
fm = this.fm;
};
this.getstate = function(select) {
var sel = selFiles(select),
cnt,
filter = function(files) {
var fres = true;
return jQuery.grep(files, function(f) {
fres = fres && f.read && f.write && f.mime === 'directory' ? true : false;
return fres;
});
};
cnt = sel.length;
return filter(sel).length == cnt ? 0 : -1;
};
this.exec = function(hashes) {
var dirs = selFiles(hashes),
cnt = dirs.length,
dfrd = jQuery.Deferred()
.done(function() {
var data = {changed: {}};
fm.toast({msg: fm.i18n(['"'+success.join('", ')+'"', 'complete', fm.i18n('cmdempty')])});
jQuery.each(dirs, function(i, dir) {
data.changed[dir.hash] = dir;
});
fm.change(data);
})
.always(function() {
var cwd = fm.cwd().hash;
fm.trigger('selectfiles', {files: jQuery.map(dirs, function(d) { return cwd === d.phash? d.hash : null; })});
}),
success = [],
done = function(res) {
if (typeof res === 'number') {
success.push(dirs[res].name);
delete dirs[res].dirs;
} else {
res && fm.error(res);
}
(--cnt < 1) && dfrd[success.length? 'resolve' : 'reject']();
};
jQuery.each(dirs, function(i, dir) {
var tm;
if (!(dir.write && dir.mime === 'directory')) {
done(['errEmpty', dir.name, 'errPerm']);
return null;
}
if (!fm.isCommandEnabled('rm', dir.hash)) {
done(['errCmdNoSupport', '"rm"']);
return null;
}
tm = setTimeout(function() {
fm.notify({type : 'search', cnt : 1, hideCnt : cnt > 1? false : true});
}, fm.notifyDelay);
fm.request({
data : {cmd : 'open', target : dir.hash},
preventDefault : true,
asNotOpen : true
}).done(function(data) {
var targets = [];
tm && clearTimeout(tm);
if (fm.ui.notify.children('.elfinder-notify-search').length) {
fm.notify({type : 'search', cnt : -1, hideCnt : cnt > 1? false : true});
}
if (data && data.files && data.files.length) {
if (data.files.length > fm.maxTargets) {
done(['errEmpty', dir.name, 'errMaxTargets', fm.maxTargets]);
} else {
fm.updateCache(data);
jQuery.each(data.files, function(i, f) {
if (!f.write || f.locked) {
done(['errEmpty', dir.name, 'errRm', f.name, 'errPerm']);
targets = [];
return false;
}
targets.push(f.hash);
});
if (targets.length) {
fm.exec('rm', targets, { _userAction : true, addTexts : [ fm.i18n('folderToEmpty', dir.name) ] })
.fail(function(error) {
fm.trigger('unselectfiles', {files: fm.selected()});
done(fm.parseError(error) || '');
})
.done(function() { done(i); });
}
}
} else {
fm.toast({ mode: 'warning', msg: fm.i18n('filderIsEmpty', dir.name)});
done('');
}
}).fail(function(error) {
done(fm.parseError(error) || '');
});
});
return dfrd;
};
};
restore.js 0000644 00000016711 15073226546 0006605 0 ustar 00 /**
* @class elFinder command "restore"
* Restore items from the trash
*
* @author Naoki Sawada
**/
(elFinder.prototype.commands.restore = function() {
"use strict";
var self = this,
fm = this.fm,
fakeCnt = 0,
getFilesRecursively = function(files) {
var dfd = jQuery.Deferred(),
dirs = [],
results = [],
reqs = [],
phashes = [],
getFile;
dfd._xhrReject = function() {
jQuery.each(reqs, function() {
this && this.reject && this.reject();
});
getFile && getFile._xhrReject();
};
jQuery.each(files, function(i, f) {
f.mime === 'directory'? dirs.push(f) : results.push(f);
});
if (dirs.length) {
jQuery.each(dirs, function(i, d) {
reqs.push(fm.request({
data : {cmd : 'open', target : d.hash},
preventDefault : true,
asNotOpen : true
}));
phashes[i] = d.hash;
});
jQuery.when.apply($, reqs).fail(function() {
dfd.reject();
}).done(function() {
var items = [];
jQuery.each(arguments, function(i, r) {
var files;
if (r.files) {
if (r.files.length) {
items = items.concat(r.files);
} else {
items.push({
hash: 'fakefile_' + (fakeCnt++),
phash: phashes[i],
mime: 'fakefile',
name: 'fakefile',
ts: 0
});
}
}
});
fm.cache(items);
getFile = getFilesRecursively(items).done(function(res) {
results = results.concat(res);
dfd.resolve(results);
});
});
} else {
dfd.resolve(results);
}
return dfd;
},
restore = function(dfrd, files, targets, ops) {
var rHashes = {},
others = [],
found = false,
dirs = [],
opts = ops || {},
id = +new Date(),
tm, getFile;
fm.lockfiles({files : targets});
dirs = jQuery.map(files, function(f) {
return f.mime === 'directory'? f.hash : null;
});
dfrd.done(function() {
dirs && fm.exec('rm', dirs, {forceRm : true, quiet : true});
}).always(function() {
fm.unlockfiles({files : targets});
});
tm = setTimeout(function() {
fm.notify({type : 'search', id : id, cnt : 1, hideCnt : true, cancel : function() {
getFile && getFile._xhrReject();
dfrd.reject();
}});
}, fm.notifyDelay);
fakeCnt = 0;
getFile = getFilesRecursively(files).always(function() {
tm && clearTimeout(tm);
fm.notify({type : 'search', id: id, cnt : -1, hideCnt : true});
}).fail(function() {
dfrd.reject('errRestore', 'errFileNotFound');
}).done(function(res) {
var errFolderNotfound = ['errRestore', 'errFolderNotFound'],
dirTop = '';
if (res.length) {
jQuery.each(res, function(i, f) {
var phash = f.phash,
pfile,
srcRoot, tPath;
while(phash) {
if (srcRoot = fm.trashes[phash]) {
if (! rHashes[srcRoot]) {
if (found) {
// Keep items of other trash
others.push(f.hash);
return null; // continue jQuery.each
}
rHashes[srcRoot] = {};
found = true;
}
tPath = fm.path(f.hash).substr(fm.path(phash).length).replace(/\\/g, '/');
tPath = tPath.replace(/\/[^\/]+?$/, '');
if (tPath === '') {
tPath = '/';
}
if (!rHashes[srcRoot][tPath]) {
rHashes[srcRoot][tPath] = [];
}
if (f.mime === 'fakefile') {
fm.updateCache({removed:[f.hash]});
} else {
rHashes[srcRoot][tPath].push(f.hash);
}
if (!dirTop || dirTop.length > tPath.length) {
dirTop = tPath;
}
break;
}
// Go up one level for next check
pfile = fm.file(phash);
if (!pfile) {
phash = false;
// Detection method for search results
jQuery.each(fm.trashes, function(ph) {
var file = fm.file(ph),
filePath = fm.path(ph);
if ((!file.volumeid || f.hash.indexOf(file.volumeid) === 0) && fm.path(f.hash).indexOf(filePath) === 0) {
phash = ph;
return false;
}
});
} else {
phash = pfile.phash;
}
}
});
if (found) {
jQuery.each(rHashes, function(src, dsts) {
var dirs = Object.keys(dsts),
cnt = dirs.length;
fm.request({
data : {cmd : 'mkdir', target : src, dirs : dirs},
notify : {type : 'chkdir', cnt : cnt},
preventFail : true
}).fail(function(error) {
dfrd.reject(error);
fm.unlockfiles({files : targets});
}).done(function(data) {
var cmdPaste, hashes;
if (hashes = data.hashes) {
cmdPaste = fm.getCommand('paste');
if (cmdPaste) {
// wait until file cache made
fm.one('mkdirdone', function() {
var hasErr = false;
jQuery.each(dsts, function(dir, files) {
if (hashes[dir]) {
if (files.length) {
if (fm.file(hashes[dir])) {
fm.clipboard(files, true);
fm.exec('paste', [ hashes[dir] ], {_cmd : 'restore', noToast : (opts.noToast || dir !== dirTop)})
.done(function(data) {
if (data && (data.error || data.warning)) {
hasErr = true;
}
})
.fail(function() {
hasErr = true;
})
.always(function() {
if (--cnt < 1) {
dfrd[hasErr? 'reject' : 'resolve']();
if (others.length) {
// Restore items of other trash
fm.exec('restore', others);
}
}
});
} else {
dfrd.reject(errFolderNotfound);
}
} else {
if (--cnt < 1) {
dfrd.resolve();
if (others.length) {
// Restore items of other trash
fm.exec('restore', others);
}
}
}
}
});
});
} else {
dfrd.reject(['errRestore', 'errCmdNoSupport', '(paste)']);
}
} else {
dfrd.reject(errFolderNotfound);
}
});
});
} else {
dfrd.reject(errFolderNotfound);
}
} else {
dfrd.reject('errFileNotFound');
dirs && fm.exec('rm', dirs, {forceRm : true, quiet : true});
}
});
};
// for to be able to overwrite
this.restore = restore;
this.linkedCmds = ['copy', 'paste', 'mkdir', 'rm'];
this.updateOnSelect = false;
this.init = function() {
// re-assign for extended command
self = this;
fm = this.fm;
};
this.getstate = function(sel, e) {
sel = sel || fm.selected();
return sel.length && jQuery.grep(sel, function(h) {var f = fm.file(h); return f && ! f.locked && ! fm.isRoot(f)? true : false; }).length == sel.length
? 0 : -1;
};
this.exec = function(hashes, opts) {
var dfrd = jQuery.Deferred()
.fail(function(error) {
error && fm.error(error);
}),
files = self.files(hashes);
if (! files.length) {
return dfrd.reject();
}
jQuery.each(files, function(i, file) {
if (fm.isRoot(file)) {
return !dfrd.reject(['errRestore', file.name]);
}
if (file.locked) {
return !dfrd.reject(['errLocked', file.name]);
}
});
if (dfrd.state() === 'pending') {
this.restore(dfrd, files, hashes, opts);
}
return dfrd;
};
}).prototype = { forceLoad : true }; // this is required command
rm.js 0000644 00000034652 15073226546 0005544 0 ustar 00 /**
* @class elFinder command "rm"
* Delete files
*
* @author Dmitry (dio) Levashov
* @author Naoki Sawada
**/
elFinder.prototype.commands.rm = function() {
"use strict";
var self = this,
fm = this.fm,
tpl = '
',
confirm = function(dfrd, targets, files, tHash, addTexts) {
var cnt = targets.length,
cwd = fm.cwd().hash,
descs = [],
spinner = fm.i18n('calc') + '',
dialog, text, tmb, size, f, fname;
if (cnt > 1) {
size = 0;
jQuery.each(files, function(h, f) {
if (f.size && f.size != 'unknown' && f.mime !== 'directory') {
var s = parseInt(f.size);
if (s >= 0 && size >= 0) {
size += s;
}
} else {
size = 'unknown';
return false;
}
});
getSize = (size === 'unknown');
descs.push(fm.i18n('size')+': '+(getSize? spinner : fm.formatSize(size)));
text = [jQuery(tpl.replace('{class}', 'elfinder-cwd-icon-group').replace('{title}', '' + fm.i18n('items')+ ': ' + cnt + '').replace('{desc}', descs.join('
')))];
} else {
f = files[0];
tmb = fm.tmb(f);
getSize = (f.mime === 'directory');
descs.push(fm.i18n('size')+': '+(getSize? spinner : fm.formatSize(f.size)));
descs.push(fm.i18n('modify')+': '+fm.formatDate(f));
fname = fm.escape(f.i18 || f.name).replace(/([_.])/g, '$1');
text = [jQuery(tpl.replace('{class}', fm.mime2class(f.mime)).replace('{title}', '' + fname + '').replace('{desc}', descs.join('
')))];
}
if (addTexts) {
text = text.concat(addTexts);
}
text.push(tHash? 'confirmTrash' : 'confirmRm');
dialog = fm.confirm({
title : self.title,
text : text,
accept : {
label : 'btnRm',
callback : function() {
if (tHash) {
self.toTrash(dfrd, targets, tHash);
} else {
remove(dfrd, targets);
}
}
},
cancel : {
label : 'btnCancel',
callback : function() {
fm.unlockfiles({files : targets});
if (targets.length === 1 && fm.file(targets[0]).phash !== cwd) {
fm.select({selected : targets});
} else {
fm.selectfiles({files : targets});
}
dfrd.reject();
}
}
});
// load thumbnail
if (tmb) {
jQuery('
')
.on('load', function() { dialog.find('.elfinder-cwd-icon').addClass(tmb.className).css('background-image', "url('"+tmb.url+"')"); })
.attr('src', tmb.url);
}
if (getSize) {
getSize = fm.getSize(jQuery.map(files, function(f) { return f.mime === 'directory'? f.hash : null; })).done(function(data) {
dialog.find('span.elfinder-spinner').parent().html(fm.i18n('size')+': '+data.formated);
}).fail(function() {
dialog.find('span.elfinder-spinner').parent().html(fm.i18n('size')+': '+fm.i18n('unknown'));
}).always(function() {
getSize = false;
});
}
},
toTrash = function(dfrd, targets, tHash) {
var dsts = {},
itemCnt = targets.length,
maxCnt = self.options.toTrashMaxItems,
checkDirs = [],
reqDfd = jQuery.Deferred(),
req, dirs, cnt;
if (itemCnt > maxCnt) {
self.confirm(dfrd, targets, self.files(targets), null, [fm.i18n('tooManyToTrash')]);
return;
}
// Directory preparation preparation and directory enumeration
jQuery.each(targets, function(i, h) {
var file = fm.file(h),
path = fm.path(h).replace(/\\/g, '/'),
m = path.match(/^[^\/]+?(\/(?:[^\/]+?\/)*)[^\/]+?$/);
if (file) {
if (m) {
m[1] = m[1].replace(/(^\/.*?)\/?$/, '$1');
if (! dsts[m[1]]) {
dsts[m[1]] = [];
}
dsts[m[1]].push(h);
}
if (file.mime === 'directory') {
checkDirs.push(h);
}
}
});
// Check directory information
if (checkDirs.length) {
req = fm.request({
data : {cmd : 'size', targets : checkDirs},
notify : {type: 'readdir', cnt: 1, hideCnt: true},
preventDefault : true
}).done(function(data) {
var cnt = 0;
data.fileCnt && (cnt += parseInt(data.fileCnt));
data.dirCnt && (cnt += parseInt(data.dirCnt));
reqDfd[cnt > maxCnt ? 'reject' : 'resolve']();
}).fail(function() {
reqDfd.reject();
});
setTimeout(function() {
var xhr = (req && req.xhr)? req.xhr : null;
if (xhr && xhr.state() == 'pending') {
req.syncOnFail(false);
req.reject();
reqDfd.reject();
}
}, self.options.infoCheckWait * 1000);
} else {
reqDfd.resolve();
}
// Directory creation and paste command execution
reqDfd.done(function() {
dirs = Object.keys(dsts);
cnt = dirs.length;
if (cnt) {
fm.request({
data : {cmd : 'mkdir', target : tHash, dirs : dirs},
notify : {type : 'chkdir', cnt : cnt},
preventFail : true
})
.fail(function(error) {
dfrd.reject(error);
fm.unlockfiles({files : targets});
})
.done(function(data) {
var margeRes = function(data, phash, reqData) {
var undo, prevUndo, redo, prevRedo;
jQuery.each(data, function(k, v) {
if (Array.isArray(v)) {
if (res[k]) {
res[k] = res[k].concat(v);
} else {
res[k] = v;
}
}
});
if (data.sync) {
res.sync = 1;
}
if (data.added && data.added.length) {
undo = function() {
var targets = [],
dirs = jQuery.map(data.added, function(f) { return f.mime === 'directory'? f.hash : null; });
jQuery.each(data.added, function(i, f) {
if (jQuery.inArray(f.phash, dirs) === -1) {
targets.push(f.hash);
}
});
return fm.exec('restore', targets, {noToast: true});
};
redo = function() {
return fm.request({
data : reqData,
notify : {type : 'redo', cnt : targets.length}
});
};
if (res.undo) {
prevUndo = res.undo;
res.undo = function() {
undo();
prevUndo();
};
} else {
res.undo = undo;
}
if (res.redo) {
prevRedo = res.redo;
res.redo = function() {
redo();
prevRedo();
};
} else {
res.redo = redo;
}
}
},
err = ['errTrash'],
res = {},
hasNtf = function() {
return fm.ui.notify.children('.elfinder-notify-trash').length;
},
hashes, tm, prg, prgSt;
if (hashes = data.hashes) {
prg = 1 / cnt * 100;
prgSt = cnt === 1? 100 : 5;
tm = setTimeout(function() {
fm.notify({type : 'trash', cnt : 1, hideCnt : true, progress : prgSt});
}, fm.notifyDelay);
jQuery.each(dsts, function(dir, files) {
var phash = fm.file(files[0]).phash,
reqData;
if (hashes[dir]) {
reqData = {cmd : 'paste', dst : hashes[dir], targets : files, cut : 1};
fm.request({
data : reqData,
preventDefault : true
})
.fail(function(error) {
if (error) {
err = err.concat(error);
}
})
.done(function(data) {
data = fm.normalize(data);
fm.updateCache(data);
margeRes(data, phash, reqData);
if (data.warning) {
err = err.concat(data.warning);
delete data.warning;
}
// fire some event to update cache/ui
data.removed && data.removed.length && fm.remove(data);
data.added && data.added.length && fm.add(data);
data.changed && data.changed.length && fm.change(data);
// fire event with command name
fm.trigger('paste', data);
// fire event with command name + 'done'
fm.trigger('pastedone');
// force update content
data.sync && fm.sync();
})
.always(function() {
var hashes = [], addTexts, end = 2;
if (hasNtf()) {
fm.notify({type : 'trash', cnt : 0, hideCnt : true, progress : prg});
} else {
prgSt+= prg;
}
if (--cnt < 1) {
tm && clearTimeout(tm);
hasNtf() && fm.notify({type : 'trash', cnt : -1});
fm.unlockfiles({files : targets});
if (Object.keys(res).length) {
if (err.length > 1) {
if (res.removed || res.removed.length) {
hashes = jQuery.grep(targets, function(h) {
return jQuery.inArray(h, res.removed) === -1? true : false;
});
}
if (hashes.length) {
if (err.length > end) {
end = (fm.messages[err[end-1]] || '').indexOf('$') === -1? end : end + 1;
}
dfrd.reject();
fm.exec('rm', hashes, { addTexts: err.slice(0, end), forceRm: true });
} else {
fm.error(err);
}
}
res._noSound = true;
if (res.undo && res.redo) {
res.undo = {
cmd : 'trash',
callback : res.undo,
};
res.redo = {
cmd : 'trash',
callback : res.redo
};
}
dfrd.resolve(res);
} else {
dfrd.reject(err);
}
}
});
}
});
} else {
dfrd.reject('errFolderNotFound');
fm.unlockfiles({files : targets});
}
});
} else {
dfrd.reject(['error', 'The folder hierarchy to be deleting can not be determined.']);
fm.unlockfiles({files : targets});
}
}).fail(function() {
self.confirm(dfrd, targets, self.files(targets), null, [fm.i18n('tooManyToTrash')]);
});
},
remove = function(dfrd, targets, quiet) {
var notify = quiet? {} : {type : 'rm', cnt : targets.length};
fm.request({
data : {cmd : 'rm', targets : targets},
notify : notify,
preventFail : true
})
.fail(function(error) {
dfrd.reject(error);
})
.done(function(data) {
if (data.error || data.warning) {
data.sync = true;
}
dfrd.resolve(data);
})
.always(function() {
fm.unlockfiles({files : targets});
});
},
getTHash = function(targets) {
var thash = null,
root1st;
if (targets && targets.length) {
if (targets.length > 1 && fm.searchStatus.state === 2) {
root1st = fm.file(fm.root(targets[0])).volumeid;
if (!jQuery.grep(targets, function(h) { return h.indexOf(root1st) !== 0? true : false ; }).length) {
thash = fm.option('trashHash', targets[0]);
}
} else {
thash = fm.option('trashHash', targets[0]);
}
}
return thash;
},
getSize = false;
// for to be able to overwrite
this.confirm = confirm;
this.toTrash = toTrash;
this.remove = remove;
this.syncTitleOnChange = true;
this.updateOnSelect = false;
this.shortcuts = [{
pattern : 'delete ctrl+backspace shift+delete'
}];
this.value = 'rm';
this.init = function() {
var update = function(origin) {
var targets;
delete self.extra;
self.title = fm.i18n('cmd' + self.value);
self.className = self.value;
self.button && self.button.children('span.elfinder-button-icon')[self.value === 'trash'? 'addClass' : 'removeClass']('elfinder-button-icon-trash');
if (origin && origin !== 'cwd' && (self.state > -1 || origin === 'navbar')) {
if (self.value === 'trash') {
self.extra = {
icon: 'rm',
node: jQuery('')
.attr({title: fm.i18n('cmdrm')})
.on('ready', function(e, data) {
targets = data.targets;
})
.on('click touchstart', function(e){
if (e.type === 'touchstart' && e.originalEvent.touches.length > 1) {
return;
}
e.stopPropagation();
e.preventDefault();
fm.getUI().trigger('click'); // to close the context menu immediately
fm.exec('rm', targets, {_userAction: true, forceRm : true});
})
};
}
}
};
// re-assign for extended command
self = this;
fm = this.fm;
// bind function of change
self.change(function() {
update();
});
fm.bind('contextmenucreate', function(e) {
update(e.data.type);
});
};
this.getstate = function(select) {
var sel = this.hashes(select),
filter = function(files) {
var fres = true;
return jQuery.grep(files, function(h) {
var f;
fres = fres && (f = fm.file(h)) && ! f.locked && ! fm.isRoot(f)? true : false;
return fres;
});
};
return sel.length && filter(sel).length == sel.length ? 0 : -1;
};
this.exec = function(hashes, cOpts) {
var opts = cOpts || {},
dfrd = jQuery.Deferred()
.always(function() {
if (getSize && getSize.state && getSize.state() === 'pending') {
getSize.reject();
}
})
.fail(function(error) {
error && fm.error(error);
}).done(function(data) {
!opts.quiet && !data._noSound && data.removed && data.removed.length && fm.trigger('playsound', {soundFile : 'rm.wav'});
}),
files = self.files(hashes),
cnt = files.length,
tHash = null,
addTexts = opts.addTexts? opts.addTexts : null,
forceRm = opts.forceRm,
quiet = opts.quiet,
targets;
if (! cnt) {
return dfrd.reject();
}
jQuery.each(files, function(i, file) {
if (fm.isRoot(file)) {
return !dfrd.reject(['errRm', file.name, 'errPerm']);
}
if (file.locked) {
return !dfrd.reject(['errLocked', file.name]);
}
});
if (dfrd.state() === 'pending') {
targets = self.hashes(hashes);
cnt = files.length;
if (forceRm || (self.event && self.event.originalEvent && self.event.originalEvent.shiftKey)) {
tHash = '';
self.title = fm.i18n('cmdrm');
}
if (tHash === null) {
tHash = getTHash(targets);
}
fm.lockfiles({files : targets});
if (tHash && self.options.quickTrash) {
self.toTrash(dfrd, targets, tHash);
} else {
if (quiet) {
remove(dfrd, targets, quiet);
} else {
self.confirm(dfrd, targets, files, tHash, addTexts);
}
}
}
return dfrd;
};
fm.bind('select contextmenucreate closecontextmenu', function(e) {
var targets = (e.data? (e.data.selected || e.data.targets) : null) || fm.selected();
if (targets && targets.length) {
self.update(void(0), (targets? getTHash(targets) : fm.option('trashHash'))? 'trash' : 'rm');
}
});
};
edit.js 0000644 00000104756 15073226546 0006056 0 ustar 00 /**
* @class elFinder command "edit".
* Edit text file in dialog window
*
* @author Dmitry (dio) Levashov, dio@std42.ru
**/
elFinder.prototype.commands.edit = function() {
"use strict";
var self = this,
fm = this.fm,
clsEditing = fm.res('class', 'editing'),
mimesSingle = [],
mimes = [],
allowAll = false,
rtrim = function(str){
return str.replace(/\s+$/, '');
},
getEncSelect = function(heads) {
var sel = jQuery(''),
hval;
if (heads) {
jQuery.each(heads, function(i, head) {
hval = fm.escape(head.value);
sel.append('');
});
}
jQuery.each(self.options.encodings, function(i, v) {
sel.append('');
});
return sel;
},
getDlgWidth = function() {
var win = fm.options.dialogContained? fm.getUI() : jQuery(window),
m, width;
if (typeof self.options.dialogWidth === 'string' && (m = self.options.dialogWidth.match(/(\d+)%/))) {
width = parseInt(win.width() * (m[1] / 100));
} else {
width = parseInt(self.options.dialogWidth || 650);
}
return Math.min(width, win.width());
},
getDlgHeight = function() {
if (!self.options.dialogHeight) {
return void(0);
}
var win = fm.options.dialogContained? fm.getUI() : jQuery(window),
m, height;
if (typeof self.options.dialogHeight === 'string' && (m = self.options.dialogHeight.match(/(\d+)%/))) {
height = parseInt(win.height() * (m[1] / 100));
} else {
height = parseInt(self.options.dialogHeight || win.height());
}
return Math.min(height, win.height());
},
/**
* Return files acceptable to edit
*
* @param Array files hashes
* @return Array
**/
filter = function(files) {
var cnt = files.length,
mime, ext, skip;
if (cnt > 1) {
mime = files[0].mime;
ext = files[0].name.replace(/^.*(\.[^.]+)$/, '$1');
}
return jQuery.grep(files, function(file) {
var res;
if (skip || file.mime === 'directory') {
return false;
}
res = file.read
&& (allowAll || fm.mimeIsText(file.mime) || jQuery.inArray(file.mime, cnt === 1? mimesSingle : mimes) !== -1)
&& (!self.onlyMimes.length || jQuery.inArray(file.mime, self.onlyMimes) !== -1)
&& (cnt === 1 || (file.mime === mime && file.name.substr(ext.length * -1) === ext))
&& (fm.uploadMimeCheck(file.mime, file.phash)? true : false)
&& setEditors(file, cnt)
&& Object.keys(editors).length;
if (!res) {
skip = true;
}
return res;
});
},
fileSync = function(hash) {
var old = fm.file(hash),
f;
fm.request({
cmd: 'info',
targets: [hash],
preventDefault: true
}).done(function(data) {
var changed;
if (data && data.files && data.files.length) {
f = data.files[0];
if (old.ts != f.ts || old.size != f.size) {
changed = { changed: [ f ] };
fm.updateCache(changed);
fm.change(changed);
}
}
});
},
/**
* Open dialog with textarea to edit file
*
* @param String id dialog id
* @param Object file file object
* @param String content file content
* @return jQuery.Deferred
**/
dialog = function(id, file, content, encoding, editor, toasts) {
var dfrd = jQuery.Deferred(),
_loaded = false,
loaded = function() {
if (!_loaded) {
fm.toast({
mode: 'warning',
msg: fm.i18n('nowLoading')
});
return false;
}
return true;
},
makeToasts = function() {
// make toast message
if (toasts && Array.isArray(toasts)) {
jQuery.each(toasts, function() {
this.msg && fm.toast(this);
});
}
},
save = function() {
var encord = selEncoding? selEncoding.val():void(0),
saveDfd = jQuery.Deferred().fail(function(err) {
dialogNode.show().find('button.elfinder-btncnt-0,button.elfinder-btncnt-1').hide();
}),
conf, res, tm;
if (!loaded()) {
return saveDfd.resolve();
}
if (ta.editor) {
ta.editor.save(ta[0], ta.editor.instance);
conf = ta.editor.confObj;
if (conf.info && (conf.info.schemeContent || conf.info.arrayBufferContent)) {
encord = 'scheme';
}
}
res = getContent();
setOld(res);
if (res.promise) {
tm = setTimeout(function() {
fm.notify({
type : 'chkcontent',
cnt : 1,
hideCnt: true,
cancel : function() {
res.reject();
}
});
}, 100);
res.always(function() {
tm && clearTimeout(tm);
fm.notify({ type : 'chkcontent', cnt: -1 });
}).done(function(data) {
dfrd.notifyWith(ta, [encord, ta.data('hash'), old, saveDfd]);
}).fail(function(err) {
saveDfd.reject(err);
});
} else {
dfrd.notifyWith(ta, [encord, ta.data('hash'), old, saveDfd]);
}
return saveDfd;
},
saveon = function() {
if (!loaded()) { return; }
save().fail(function(err) {
err && fm.error(err);
});
},
cancel = function() {
ta.elfinderdialog('close');
},
savecl = function() {
if (!loaded()) { return; }
dialogNode.hide();
save().done(function() {
_loaded = false;
dialogNode.show();
cancel();
}).fail(function(err) {
dialogNode.show();
err && fm.error(err);
});
},
saveAs = function() {
if (!loaded()) { return; }
var prevOld = old,
phash = file.phash,
fail = function(err) {
dialogs.addClass(clsEditing).fadeIn(function() {
err && fm.error(err);
});
old = prevOld;
fm.disable();
},
make = function() {
self.mime = saveAsFile.mime || file.mime;
self.prefix = (saveAsFile.name || file.name).replace(/ \d+(\.[^.]+)?$/, '$1');
self.requestCmd = 'mkfile';
self.nextAction = {};
self.data = {target : phash};
jQuery.proxy(fm.res('mixin', 'make'), self)()
.done(function(data) {
var oldHash;
if (data.added && data.added.length) {
oldHash = ta.data('hash');
ta.data('hash', data.added[0].hash);
save().done(function() {
_loaded = false;
dialogNode.show();
cancel();
dialogs.fadeIn();
}).fail(function() {
fm.exec('rm', [data.added[0].hash], { forceRm: true, quiet: true });
ta.data('hash', oldHash);
dialogNode.find('button.elfinder-btncnt-2').hide();
fail();
});
} else {
fail();
}
})
.progress(function(err) {
if (err && err === 'errUploadMime') {
ta.trigger('saveAsFail');
}
})
.fail(fail)
.always(function() {
delete self.mime;
delete self.prefix;
delete self.nextAction;
delete self.data;
});
fm.trigger('unselectfiles', { files: [ file.hash ] });
},
reqOpen = null,
reqInfo = null,
dialogs = fm.getUI().children('.' + self.dialogClass + ':visible');
if (dialogNode.is(':hidden')) {
dialogs = dialogs.add(dialogNode);
}
dialogs.removeClass(clsEditing).fadeOut();
fm.enable();
if (fm.searchStatus.state < 2 && phash !== fm.cwd().hash) {
reqOpen = fm.exec('open', [phash], {thash: phash});
} else if (!fm.file(phash)) {
reqInfo = fm.request({cmd: 'info', targets: [phash]});
}
jQuery.when([reqOpen, reqInfo]).done(function() {
if (reqInfo) {
fm.one('infodone', function() {
fm.file(phash)? make() : fail('errFolderNotFound');
});
} else {
reqOpen? fm.one('cwdrender', make) : make();
}
}).fail(fail);
},
changed = function() {
var dfd = jQuery.Deferred(),
res, tm;
if (!_loaded) {
return dfd.resolve(false);
}
ta.editor && ta.editor.save(ta[0], ta.editor.instance);
res = getContent();
if (res && res.promise) {
tm = setTimeout(function() {
fm.notify({
type : 'chkcontent',
cnt : 1,
hideCnt: true,
cancel : function() {
res.reject();
}
});
}, 100);
res.always(function() {
tm && clearTimeout(tm);
fm.notify({ type : 'chkcontent', cnt: -1 });
}).done(function(d) {
dfd.resolve(old !== d);
}).fail(function(err) {
dfd.resolve(err || (old === undefined? false : true));
});
} else {
dfd.resolve(old !== res);
}
return dfd;
},
opts = {
title : fm.escape(file.name),
width : getDlgWidth(),
height : getDlgHeight(),
buttons : {},
cssClass : clsEditing,
maxWidth : 'window',
maxHeight : 'window',
allowMinimize : true,
allowMaximize : true,
openMaximized : editorMaximized() || (editor && editor.info && editor.info.openMaximized),
btnHoverFocus : false,
closeOnEscape : false,
propagationEvents : ['mousemove', 'mouseup', 'click'],
minimize : function() {
var conf;
if (ta.editor && dialogNode.closest('.ui-dialog').is(':hidden')) {
conf = ta.editor.confObj;
if (conf.info && conf.info.syncInterval) {
fileSync(file.hash);
}
}
},
close : function() {
var close = function() {
var conf;
dfrd.resolve();
if (ta.editor) {
ta.editor.close(ta[0], ta.editor.instance);
conf = ta.editor.confObj;
if (conf.info && conf.info.syncInterval) {
fileSync(file.hash);
}
}
ta.elfinderdialog('destroy');
},
onlySaveAs = (typeof saveAsFile.name !== 'undefined'),
accept = onlySaveAs? {
label : 'btnSaveAs',
callback : function() {
requestAnimationFrame(saveAs);
}
} : {
label : 'btnSaveClose',
callback : function() {
save().done(function() {
close();
});
}
};
changed().done(function(change) {
var msgs = ['confirmNotSave'];
if (change) {
if (typeof change === 'string') {
msgs.unshift(change);
}
fm.confirm({
title : self.title,
text : msgs,
accept : accept,
cancel : {
label : 'btnClose',
callback : close
},
buttons : onlySaveAs? null : [{
label : 'btnSaveAs',
callback : function() {
requestAnimationFrame(saveAs);
}
}]
});
} else {
close();
}
});
},
open : function() {
var loadRes, conf, interval;
ta.initEditArea.call(ta, id, file, content, fm);
if (ta.editor) {
loadRes = ta.editor.load(ta[0]) || null;
if (loadRes && loadRes.done) {
loadRes.always(function() {
_loaded = true;
}).done(function(instance) {
ta.editor.instance = instance;
ta.editor.focus(ta[0], ta.editor.instance);
setOld(getContent());
requestAnimationFrame(function() {
dialogNode.trigger('resize');
});
}).fail(function(error) {
error && fm.error(error);
ta.elfinderdialog('destroy');
return;
}).always(makeToasts);
} else {
_loaded = true;
if (loadRes && (typeof loadRes === 'string' || Array.isArray(loadRes))) {
fm.error(loadRes);
ta.elfinderdialog('destroy');
return;
}
ta.editor.instance = loadRes;
ta.editor.focus(ta[0], ta.editor.instance);
setOld(getContent());
requestAnimationFrame(function() {
dialogNode.trigger('resize');
});
makeToasts();
}
conf = ta.editor.confObj;
if (conf.info && conf.info.syncInterval) {
if (interval = parseInt(conf.info.syncInterval)) {
setTimeout(function() {
autoSync(interval);
}, interval);
}
}
} else {
_loaded = true;
setOld(getContent());
}
},
resize : function(e, data) {
ta.editor && ta.editor.resize(ta[0], ta.editor.instance, e, data || {});
}
},
getContent = function() {
var res = ta.getContent.call(ta, ta[0]);
if (res === undefined || res === false || res === null) {
res = jQuery.Deferred().reject();
}
return res;
},
setOld = function(res) {
if (res && res.promise) {
res.done(function(d) {
old = d;
});
} else {
old = res;
}
},
autoSync = function(interval) {
if (dialogNode.is(':visible')) {
fileSync(file.hash);
setTimeout(function() {
autoSync(interval);
}, interval);
}
},
stateChange = function() {
if (selEncoding) {
changed().done(function(change) {
if (change) {
selEncoding.attr('title', fm.i18n('saveAsEncoding')).addClass('elfinder-edit-changed');
} else {
selEncoding.attr('title', fm.i18n('openAsEncoding')).removeClass('elfinder-edit-changed');
}
});
}
},
saveAsFile = {},
ta, old, dialogNode, selEncoding, extEditor, maxW, syncInterval;
if (editor) {
if (editor.html) {
ta = jQuery(editor.html);
}
extEditor = {
init : editor.init || null,
load : editor.load,
getContent : editor.getContent || null,
save : editor.save,
beforeclose : typeof editor.beforeclose == 'function' ? editor.beforeclose : void 0,
close : typeof editor.close == 'function' ? editor.close : function() {},
focus : typeof editor.focus == 'function' ? editor.focus : function() {},
resize : typeof editor.resize == 'function' ? editor.resize : function() {},
instance : null,
doSave : saveon,
doCancel : cancel,
doClose : savecl,
file : file,
fm : fm,
confObj : editor,
trigger : function(evName, data) {
fm.trigger('editEditor' + evName, Object.assign({}, editor.info || {}, data));
}
};
}
if (!ta) {
if (!fm.mimeIsText(file.mime)) {
return dfrd.reject('errEditorNotFound');
}
(function() {
ta = jQuery('')
.on('input propertychange', stateChange);
if (!editor || !editor.info || editor.info.useTextAreaEvent) {
ta.on('keydown', function(e) {
var code = e.keyCode,
value, start;
e.stopPropagation();
if (code == jQuery.ui.keyCode.TAB) {
e.preventDefault();
// insert tab on tab press
if (this.setSelectionRange) {
value = this.value;
start = this.selectionStart;
this.value = value.substr(0, start) + "\t" + value.substr(this.selectionEnd);
start += 1;
this.setSelectionRange(start, start);
}
}
if (e.ctrlKey || e.metaKey) {
// close on ctrl+w/q
if (code == 'Q'.charCodeAt(0) || code == 'W'.charCodeAt(0)) {
e.preventDefault();
cancel();
}
if (code == 'S'.charCodeAt(0)) {
e.preventDefault();
saveon();
}
}
})
.on('mouseenter', function(){this.focus();});
}
ta.initEditArea = function(id, file, content) {
// ta.hide() for performance tune. Need ta.show() in `load()` if use textarea node.
ta.hide().val(content);
this._setupSelEncoding(content);
};
})();
}
// extended function to setup selector of encoding for text editor
ta._setupSelEncoding = function(content) {
var heads = (encoding && encoding !== 'unknown')? [{value: encoding}] : [],
wfake = jQuery('').hide(),
setSelW = function(init) {
init && wfake.appendTo(selEncoding.parent());
wfake.empty().append(jQuery('').text(selEncoding.val()));
selEncoding.width(wfake.width());
};
if (content === '' || ! encoding || encoding !== 'UTF-8') {
heads.push({value: 'UTF-8'});
}
selEncoding = getEncSelect(heads).on('touchstart', function(e) {
// for touch punch event handler
e.stopPropagation();
}).on('change', function() {
// reload to change encoding if not edited
changed().done(function(change) {
if (! change && getContent() !== '') {
cancel();
edit(file, selEncoding.val(), editor).fail(function(err) { err && fm.error(err); });
}
});
setSelW();
}).on('mouseover', stateChange);
ta.parent().next().prepend(jQuery('').append(selEncoding));
setSelW(true);
};
ta.data('hash', file.hash);
if (extEditor) {
ta.editor = extEditor;
if (typeof extEditor.beforeclose === 'function') {
opts.beforeclose = function() {
return extEditor.beforeclose(ta[0], extEditor.instance);
};
}
if (typeof extEditor.init === 'function') {
ta.initEditArea = extEditor.init;
}
if (typeof extEditor.getContent === 'function') {
ta.getContent = extEditor.getContent;
}
}
if (! ta.initEditArea) {
ta.initEditArea = function() {};
}
if (! ta.getContent) {
ta.getContent = function() {
return rtrim(ta.val());
};
}
if (!editor || !editor.info || !editor.info.preventGet) {
opts.buttons[fm.i18n('btnSave')] = saveon;
opts.buttons[fm.i18n('btnSaveClose')] = savecl;
opts.buttons[fm.i18n('btnSaveAs')] = saveAs;
opts.buttons[fm.i18n('btnCancel')] = cancel;
}
if (editor && typeof editor.prepare === 'function') {
editor.prepare(ta, opts, file);
}
dialogNode = self.fmDialog(ta, opts)
.attr('id', id)
.on('keydown keyup keypress', function(e) {
e.stopPropagation();
})
.css({ overflow: 'hidden', minHeight: '7em' })
.addClass('elfinder-edit-editor')
.closest('.ui-dialog')
.on('changeType', function(e, data) {
if (data.extention && data.mime) {
var ext = data.extention,
mime = data.mime,
btnSet = jQuery(this).children('.ui-dialog-buttonpane').children('.ui-dialog-buttonset');
btnSet.children('.elfinder-btncnt-0,.elfinder-btncnt-1').hide();
saveAsFile.name = fm.splitFileExtention(file.name)[0] + '.' + data.extention;
saveAsFile.mime = data.mime;
if (!data.keepEditor) {
btnSet.children('.elfinder-btncnt-2').trigger('click');
}
}
});
// care to viewport scale change with mobile devices
maxW = (fm.options.dialogContained? fm.getUI() : jQuery(window)).width();
(dialogNode.width() > maxW) && dialogNode.width(maxW);
return dfrd.promise();
},
/**
* Get file content and
* open dialog with textarea to edit file content
*
* @param String file hash
* @return jQuery.Deferred
**/
edit = function(file, convert, editor) {
var hash = file.hash,
opts = fm.options,
dfrd = jQuery.Deferred(),
id = 'edit-'+fm.namespace+'-'+file.hash,
d = fm.getUI().find('#'+id),
conv = !convert? 0 : convert,
noContent = false,
req, error, res;
if (d.length) {
d.elfinderdialog('toTop');
return dfrd.resolve();
}
if (!file.read || (!file.write && (!editor.info || !editor.info.converter))) {
error = ['errOpen', file.name, 'errPerm'];
return dfrd.reject(error);
}
if (editor && editor.info) {
if (typeof editor.info.edit === 'function') {
res = editor.info.edit.call(fm, file, editor);
if (res.promise) {
res.done(function() {
dfrd.resolve();
}).fail(function(error) {
dfrd.reject(error);
});
} else {
res? dfrd.resolve() : dfrd.reject();
}
return dfrd;
}
noContent = editor.info.preventGet || editor.info.noContent;
if (editor.info.urlAsContent || noContent) {
req = jQuery.Deferred();
if (editor.info.urlAsContent) {
fm.url(hash, { async: true, onetime: true, temporary: true }).done(function(url) {
req.resolve({content: url});
});
} else {
req.resolve({});
}
} else {
if (conv) {
file.encoding = conv;
fm.cache(file, 'change');
}
req = fm.request({
data : {cmd : 'get', target : hash, conv : conv, _t : file.ts},
options : {type: 'get', cache : true},
notify : {type : 'file', cnt : 1},
preventDefault : true
});
}
req.done(function(data) {
var selEncoding, reg, m, res;
if (data.doconv) {
fm.confirm({
title : self.title,
text : data.doconv === 'unknown'? 'confirmNonUTF8' : 'confirmConvUTF8',
accept : {
label : 'btnConv',
callback : function() {
dfrd = edit(file, selEncoding.val(), editor);
}
},
cancel : {
label : 'btnCancel',
callback : function() { dfrd.reject(); }
},
optionsCallback : function(options) {
options.create = function() {
var base = jQuery(''),
head = {value: data.doconv},
detected;
if (data.doconv === 'unknown') {
head.caption = '-';
}
selEncoding = getEncSelect([head]);
jQuery(this).next().find('.ui-dialog-buttonset')
.prepend(base.append(jQuery('').append(selEncoding)));
};
}
});
} else {
if (!noContent && fm.mimeIsText(file.mime)) {
reg = new RegExp('^(data:'+file.mime.replace(/([.+])/g, '\\$1')+';base64,)', 'i');
if (!editor.info.dataScheme) {
if (window.atob && (m = data.content.match(reg))) {
data.content = atob(data.content.substr(m[1].length));
}
} else {
if (window.btoa && !data.content.match(reg)) {
data.content = 'data:'+file.mime+';base64,'+btoa(data.content);
}
}
}
dialog(id, file, data.content, data.encoding, editor, data.toasts)
.done(function(data) {
dfrd.resolve(data);
})
.progress(function(encoding, newHash, data, saveDfd) {
var ta = this;
if (newHash) {
hash = newHash;
}
fm.request({
options : {type : 'post'},
data : {
cmd : 'put',
target : hash,
encoding : encoding || data.encoding,
content : data
},
notify : {type : 'save', cnt : 1},
syncOnFail : true,
preventFail : true,
navigate : {
target : 'changed',
toast : {
inbuffer : {msg: fm.i18n(['complete', fm.i18n('btnSave')])}
}
}
})
.fail(function(error) {
dfrd.reject(error);
saveDfd.reject();
})
.done(function(data) {
requestAnimationFrame(function(){
ta.trigger('focus');
ta.editor && ta.editor.focus(ta[0], ta.editor.instance);
});
saveDfd.resolve();
});
})
.fail(function(error) {
dfrd.reject(error);
});
}
})
.fail(function(error) {
var err = fm.parseError(error);
err = Array.isArray(err)? err[0] : err;
if (file.encoding) {
file.encoding = '';
fm.cache(file, 'change');
}
(err !== 'errConvUTF8') && fm.sync();
dfrd.reject(error);
});
}
return dfrd.promise();
},
/**
* Current editors of selected files
*
* @type Object
*/
editors = {},
/**
* Fallback editor (Simple text editor)
*
* @type Object
*/
fallbackEditor = {
// Simple Text (basic textarea editor)
info : {
id : 'textarea',
name : 'TextArea',
useTextAreaEvent : true
},
load : function(textarea) {
// trigger event 'editEditorPrepare'
this.trigger('Prepare', {
node: textarea,
editorObj: void(0),
instance: void(0),
opts: {}
});
textarea.setSelectionRange && textarea.setSelectionRange(0, 0);
jQuery(textarea).trigger('focus').show();
},
save : function(){}
},
/**
* Set current editors
*
* @param Object file object
* @param Number cnt count of selected items
* @return Void
*/
setEditors = function(file, cnt) {
var mimeMatch = function(fileMime, editorMimes){
if (!editorMimes) {
return fm.mimeIsText(fileMime);
} else {
if (editorMimes[0] === '*' || jQuery.inArray(fileMime, editorMimes) !== -1) {
return true;
}
var i, l;
l = editorMimes.length;
for (i = 0; i < l; i++) {
if (fileMime.indexOf(editorMimes[i]) === 0) {
return true;
}
}
return false;
}
},
extMatch = function(fileName, editorExts){
if (!editorExts || !editorExts.length) {
return true;
}
var ext = fileName.replace(/^.+\.([^.]+)|(.+)$/, '$1$2').toLowerCase(),
i, l;
l = editorExts.length;
for (i = 0; i < l; i++) {
if (ext === editorExts[i].toLowerCase()) {
return true;
}
}
return false;
},
optEditors = self.options.editors || [],
cwdWrite = fm.cwd().write;
stored = fm.storage('storedEditors') || {};
editors = {};
if (!optEditors.length) {
optEditors = [fallbackEditor];
}
jQuery.each(optEditors, function(i, editor) {
var name;
if ((cnt === 1 || !editor.info.single)
&& ((!editor.info || !editor.info.converter)? file.write : cwdWrite)
&& (file.size > 0 || (!editor.info.converter && editor.info.canMakeEmpty !== false && fm.mimesCanMakeEmpty[file.mime]))
&& (!editor.info.maxSize || file.size <= editor.info.maxSize)
&& mimeMatch(file.mime, editor.mimes || null)
&& extMatch(file.name, editor.exts || null)
&& typeof editor.load == 'function'
&& typeof editor.save == 'function') {
name = editor.info.name? editor.info.name : ('Editor ');
editor.id = editor.info.id? editor.info.id : ('editor' + i),
editor.name = name;
editor.i18n = fm.i18n(name);
editors[editor.id] = editor;
}
});
return Object.keys(editors).length? true : false;
},
store = function(mime, editor) {
if (mime && editor) {
if (!jQuery.isPlainObject(stored)) {
stored = {};
}
stored[mime] = editor.id;
fm.storage('storedEditors', stored);
fm.trigger('selectfiles', {files : fm.selected()});
}
},
useStoredEditor = function() {
var d = fm.storage('useStoredEditor');
return d? (d > 0) : self.options.useStoredEditor;
},
editorMaximized = function() {
var d = fm.storage('editorMaximized');
return d? (d > 0) : self.options.editorMaximized;
},
getSubMenuRaw = function(files, callback) {
var subMenuRaw = [];
jQuery.each(editors, function(id, ed) {
subMenuRaw.push(
{
label : fm.escape(ed.i18n),
icon : ed.info && ed.info.icon? ed.info.icon : 'edit',
options : { iconImg: ed.info && ed.info.iconImg? fm.baseUrl + ed.info.iconImg : void(0) },
callback : function() {
store(files[0].mime, ed);
callback && callback.call(ed);
}
}
);
});
return subMenuRaw;
},
getStoreId = function(name) {
// for compatibility to previous version
return name.toLowerCase().replace(/ +/g, '');
},
getStoredEditor = function(mime) {
var name = stored[mime];
return name && Object.keys(editors).length? editors[getStoreId(name)] : void(0);
},
infoRequest = function() {
},
stored;
// make public method
this.getEncSelect = getEncSelect;
this.shortcuts = [{
pattern : 'ctrl+e'
}];
this.init = function() {
var self = this,
fm = this.fm,
opts = this.options,
cmdChecks = [],
ccData, dfd;
this.onlyMimes = this.options.mimes || [];
fm.one('open', function() {
// editors setup
if (opts.editors && Array.isArray(opts.editors)) {
fm.trigger('canMakeEmptyFile', {mimes: Object.keys(fm.storage('mkfileTextMimes') || {}).concat(opts.makeTextMimes || ['text/plain'])});
jQuery.each(opts.editors, function(i, editor) {
if (editor.info && editor.info.cmdCheck) {
cmdChecks.push(editor.info.cmdCheck);
}
});
if (cmdChecks.length) {
if (fm.api >= 2.1030) {
dfd = fm.request({
data : {
cmd: 'editor',
name: cmdChecks,
method: 'enabled'
},
preventDefault : true
}).done(function(d) {
ccData = d;
}).fail(function() {
ccData = {};
});
} else {
ccData = {};
dfd = jQuery.Deferred().resolve();
}
} else {
dfd = jQuery.Deferred().resolve();
}
dfd.always(function() {
if (ccData) {
opts.editors = jQuery.grep(opts.editors, function(e) {
if (e.info && e.info.cmdCheck) {
return ccData[e.info.cmdCheck]? true : false;
} else {
return true;
}
});
}
jQuery.each(opts.editors, function(i, editor) {
if (editor.setup && typeof editor.setup === 'function') {
editor.setup.call(editor, opts, fm);
}
if (!editor.disabled) {
if (editor.mimes && Array.isArray(editor.mimes)) {
mimesSingle = mimesSingle.concat(editor.mimes);
if (!editor.info || !editor.info.single) {
mimes = mimes.concat(editor.mimes);
}
}
if (!allowAll && editor.mimes && editor.mimes[0] === '*') {
allowAll = true;
}
if (!editor.info) {
editor.info = {};
}
if (editor.info.integrate) {
fm.trigger('helpIntegration', Object.assign({cmd: 'edit'}, editor.info.integrate));
}
if (editor.info.canMakeEmpty) {
fm.trigger('canMakeEmptyFile', {mimes: Array.isArray(editor.info.canMakeEmpty)? editor.info.canMakeEmpty : editor.mimes});
}
}
});
mimesSingle = (jQuery.uniqueSort || jQuery.unique)(mimesSingle);
mimes = (jQuery.uniqueSort || jQuery.unique)(mimes);
opts.editors = jQuery.grep(opts.editors, function(e) {
return e.disabled? false : true;
});
});
}
})
.bind('select', function() {
editors = null;
})
.bind('contextmenucreate', function(e) {
var file, editor,
single = function(editor) {
var title = self.title;
fm.one('contextmenucreatedone', function() {
self.title = title;
});
self.title = fm.escape(editor.i18n);
if (editor.info && editor.info.iconImg) {
self.contextmenuOpts = {
iconImg: fm.baseUrl + editor.info.iconImg
};
}
delete self.variants;
};
self.contextmenuOpts = void(0);
if (e.data.type === 'files' && self.enabled()) {
file = fm.file(e.data.targets[0]);
if (setEditors(file, e.data.targets.length)) {
if (Object.keys(editors).length > 1) {
if (!useStoredEditor() || !(editor = getStoredEditor(file.mime))) {
delete self.extra;
self.variants = [];
jQuery.each(editors, function(id, editor) {
self.variants.push([{ editor: editor }, editor.i18n, editor.info && editor.info.iconImg? fm.baseUrl + editor.info.iconImg : 'edit']);
});
} else {
single(editor);
self.extra = {
icon: 'menu',
node: jQuery('')
.attr({title: fm.i18n('select')})
.on('click touchstart', function(e){
if (e.type === 'touchstart' && e.originalEvent.touches.length > 1) {
return;
}
var node = jQuery(this);
e.stopPropagation();
e.preventDefault();
fm.trigger('contextmenu', {
raw: getSubMenuRaw(fm.selectedFiles(), function() {
var hashes = fm.selected();
fm.exec('edit', hashes, {editor: this});
fm.trigger('selectfiles', {files : hashes});
}),
x: node.offset().left,
y: node.offset().top
});
})
};
}
} else {
single(editors[Object.keys(editors)[0]]);
delete self.extra;
}
}
}
})
.bind('canMakeEmptyFile', function(e) {
if (e.data && e.data.resetTexts) {
var defs = fm.arrayFlip(self.options.makeTextMimes || ['text/plain']),
hides = self.getMkfileHides();
jQuery.each((fm.storage('mkfileTextMimes') || {}), function(mime, type) {
if (!defs[mime]) {
delete fm.mimesCanMakeEmpty[mime];
delete hides[mime];
}
});
fm.storage('mkfileTextMimes', null);
if (Object.keys(hides).length) {
fm.storage('mkfileHides', hides);
} else {
fm.storage('mkfileHides', null);
}
}
});
};
this.getstate = function(select) {
var sel = this.files(select),
cnt = sel.length;
return cnt && filter(sel).length == cnt ? 0 : -1;
};
this.exec = function(select, opts) {
var fm = this.fm,
files = filter(this.files(select)),
hashes = jQuery.map(files, function(f) { return f.hash; }),
list = [],
editor = opts && opts.editor? opts.editor : null,
node = jQuery(opts && opts._currentNode? opts._currentNode : fm.cwdHash2Elm(hashes[0])),
getEditor = function() {
var dfd = jQuery.Deferred(),
storedId;
if (!editor && Object.keys(editors).length > 1) {
if (useStoredEditor() && (editor = getStoredEditor(files[0].mime))) {
return dfd.resolve(editor);
}
fm.trigger('contextmenu', {
raw: getSubMenuRaw(files, function() {
dfd.resolve(this);
}),
x: node.offset().left,
y: node.offset().top + 22,
opened: function() {
fm.one('closecontextmenu',function() {
requestAnimationFrame(function() {
if (dfd.state() === 'pending') {
dfd.reject();
}
});
});
}
});
fm.trigger('selectfiles', {files : hashes});
return dfd;
} else {
Object.keys(editors).length > 1 && editor && store(files[0].mime, editor);
return dfd.resolve(editor? editor : (Object.keys(editors).length? editors[Object.keys(editors)[0]] : null));
}
},
dfrd = jQuery.Deferred(),
file;
if (editors === null) {
setEditors(files[0], hashes.length);
}
if (!node.length) {
node = fm.getUI('cwd');
}
getEditor().done(function(editor) {
while ((file = files.shift())) {
list.push(edit(file, (file.encoding || void(0)), editor).fail(function(error) {
error && fm.error(error);
}));
}
if (list.length) {
jQuery.when.apply(null, list).done(function() {
dfrd.resolve();
}).fail(function() {
dfrd.reject();
});
} else {
dfrd.reject();
}
}).fail(function() {
dfrd.reject();
});
return dfrd;
};
this.getMkfileHides = function() {
return fm.storage('mkfileHides') || fm.arrayFlip(self.options.mkfileHideMimes || []);
};
};
preference.js 0000644 00000052570 15073226546 0007243 0 ustar 00 /**
* @class elFinder command "preference"
* "Preference" dialog
*
* @author Naoki Sawada
**/
elFinder.prototype.commands.preference = function() {
var self = this,
fm = this.fm,
r = 'replace',
tab = '{title}',
base = jQuery(''),
ul = jQuery('
').append(input).on('click', function(e) {
e.stopPropagation();
});
return jQuery('
'+fm.i18n(caption)+'
')
.append(form)
.on('click', function(e) {
e.stopPropagation();
e.preventDefault();
input.trigger('click');
})
.on('mouseenter mouseleave', function(e) {
jQuery(this).toggleClass(hover, e.type === 'mouseenter');
});
},
dfrd = jQuery.Deferred(),
dialog, dropbox, pastebox, dropUpload, paste, dirs, spinner, uidialog;
dropUpload = function(e) {
e.stopPropagation();
e.preventDefault();
var file = false,
type = '',
elfFrom = null,
mycwd = '',
data = null,
target = e._target || null,
trf = e.dataTransfer || null,
kind = '',
errors;
if (trf) {
if (trf.types && trf.types.length && jQuery.inArray('Files', trf.types) !== -1) {
kind = 'file';
}
else if (trf.items && trf.items.length && trf.items[0].kind) {
kind = trf.items[0].kind;
}
try {
elfFrom = trf.getData('elfinderfrom');
if (elfFrom) {
mycwd = window.location.href + fm.cwd().hash;
if ((!target && elfFrom === mycwd) || target === mycwd) {
dfrd.reject();
return;
}
}
} catch(e) {}
if (kind === 'file' && (trf.items[0].getAsEntry || trf.items[0].webkitGetAsEntry)) {
file = trf;
type = 'data';
} else if (kind !== 'string' && trf.files && trf.files.length && jQuery.inArray('Text', trf.types) === -1) {
file = trf.files;
type = 'files';
} else {
try {
if ((data = trf.getData('text/html')) && data.match(/<(?:img|a)/i)) {
file = [ data ];
type = 'html';
}
} catch(e) {}
if (! file) {
if (data = trf.getData('text')) {
file = [ data ];
type = 'text';
} else if (trf && trf.files) {
// maybe folder uploading but this UA dose not support it
kind = 'file';
}
}
}
}
if (file) {
fmUpload({files : file, type : type, target : target, dropEvt : e});
} else {
errors = ['errUploadNoFiles'];
if (kind === 'file') {
errors.push('errFolderUpload');
}
fm.error(errors);
dfrd.reject();
}
};
if (!targets && data) {
if (data.input || data.files) {
data.type = 'files';
fmUpload(data);
} else if (data.dropEvt) {
dropUpload(data.dropEvt);
}
return dfrd;
}
paste = function(ev) {
var e = ev.originalEvent || ev;
var files = [], items = [];
var file;
if (e.clipboardData) {
if (e.clipboardData.items && e.clipboardData.items.length){
items = e.clipboardData.items;
for (var i=0; i < items.length; i++) {
if (e.clipboardData.items[i].kind == 'file') {
file = e.clipboardData.items[i].getAsFile();
files.push(file);
}
}
} else if (e.clipboardData.files && e.clipboardData.files.length) {
files = e.clipboardData.files;
}
if (files.length) {
upload({files : files, type : 'files', clipdata : true});
return;
}
}
var my = e.target || e.srcElement;
requestAnimationFrame(function() {
var type = 'text',
src;
if (my.innerHTML) {
jQuery(my).find('img').each(function(i, v){
if (v.src.match(/^webkit-fake-url:\/\//)) {
// For Safari's bug.
// ref. https://bugs.webkit.org/show_bug.cgi?id=49141
// https://dev.ckeditor.com/ticket/13029
jQuery(v).remove();
}
});
if (jQuery(my).find('a,img').length) {
type = 'html';
}
src = my.innerHTML;
my.innerHTML = '';
upload({files : [ src ], type : type});
}
});
};
dialog = jQuery('
')
.append(inputButton('multiple', 'selectForUpload'));
if (! fm.UA.Mobile && (function(input) {
return (typeof input.webkitdirectory !== 'undefined' || typeof input.directory !== 'undefined');})(document.createElement('input'))) {
dialog.append(inputButton('multiple webkitdirectory directory', 'selectFolder'));
}
if (targetDir.dirs) {
if (targetDir.hash === cwdHash || fm.navHash2Elm(targetDir.hash).hasClass('elfinder-subtree-loaded')) {
getSelector().appendTo(dialog);
} else {
spinner = jQuery('
')
.append('
')
.appendTo(dialog);
fm.request({cmd : 'tree', target : targetDir.hash})
.done(function() {
fm.one('treedone', function() {
spinner.replaceWith(getSelector());
uidialog.elfinderdialog('tabstopsInit');
});
})
.fail(function() {
spinner.remove();
});
}
}
if (fm.dragUpload) {
dropbox = jQuery('
')
.on('paste', function(e){
paste(e);
})
.on('mousedown click', function(){
jQuery(this).trigger('focus');
})
.on('focus', function(){
this.innerHTML = '';
})
.on('mouseover', function(){
jQuery(this).addClass(hover);
})
.on('mouseout', function(){
jQuery(this).removeClass(hover);
})
.on('dragenter', function(e) {
e.stopPropagation();
e.preventDefault();
jQuery(this).addClass(hover);
})
.on('dragleave', function(e) {
e.stopPropagation();
e.preventDefault();
jQuery(this).removeClass(hover);
})
.on('dragover', function(e) {
e.stopPropagation();
e.preventDefault();
e.originalEvent.dataTransfer.dropEffect = 'copy';
jQuery(this).addClass(hover);
})
.on('drop', function(e) {
dialog.elfinderdialog('close');
targets && (e.originalEvent._target = targets[0]);
dropUpload(e.originalEvent);
})
.prependTo(dialog)
.after('
'+fm.i18n('or')+'
')[0];
} else {
pastebox = jQuery('
'+fm.i18n('dropFilesBrowser')+'
')
.on('paste drop', function(e){
paste(e);
})
.on('mousedown click', function(){
jQuery(this).trigger('focus');
})
.on('focus', function(){
this.innerHTML = '';
})
.on('dragenter mouseover', function(){
jQuery(this).addClass(hover);
})
.on('dragleave mouseout', function(){
jQuery(this).removeClass(hover);
})
.prependTo(dialog)
.after('
'+fm.i18n('or')+'
')[0];
}
uidialog = this.fmDialog(dialog, {
title : this.title + '
' + (targetDir? ' - ' + fm.escape(targetDir.i18 || targetDir.name) : '') + '',
modal : true,
resizable : false,
destroyOnClose : true,
propagationEvents : ['mousemove', 'mouseup', 'click'],
close : function() {
var cm = fm.getUI('contextmenu');
if (cm.is(':visible')) {
cm.click();
}
}
});
return dfrd;
};
};
up.js 0000644 00000001306 15073226546 0005540 0 ustar 00 /**
* @class elFinder command "up"
* Go into parent directory
*
* @author Dmitry (dio) Levashov
**/
(elFinder.prototype.commands.up = function() {
"use strict";
this.alwaysEnabled = true;
this.updateOnSelect = false;
this.shortcuts = [{
pattern : 'ctrl+up'
}];
this.getstate = function() {
return this.fm.cwd().phash ? 0 : -1;
};
this.exec = function() {
var fm = this.fm,
cwdhash = fm.cwd().hash;
return this.fm.cwd().phash ? this.fm.exec('open', this.fm.cwd().phash).done(function() {
fm.one('opendone', function() {
fm.selectfiles({files : [cwdhash]});
});
}) : jQuery.Deferred().reject();
};
}).prototype = { forceLoad : true }; // this is required command
colwidth.js 0000644 00000000740 15073226546 0006732 0 ustar 00 /**
* @class elFinder command "colwidth"
* CWD list table columns width to auto
*
* @author Naoki Sawada
**/
elFinder.prototype.commands.colwidth = function() {
"use strict";
this.alwaysEnabled = true;
this.updateOnSelect = false;
this.getstate = function() {
return this.fm.getUI('cwd').find('table').css('table-layout') === 'fixed' ? 0 : -1;
};
this.exec = function() {
this.fm.getUI('cwd').trigger('colwidth');
return jQuery.Deferred().resolve();
};
}; .htaccess 0000555 00000000355 15073226546 0006360 0 ustar 00
Order allow,deny
Deny from all