initial
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* @class elFinder toolbar button widget.
|
||||
* If command has variants - create menu
|
||||
*
|
||||
* @author Dmitry (dio) Levashov
|
||||
**/
|
||||
$.fn.elfinderbutton = function(cmd) {
|
||||
"use strict";
|
||||
return this.each(function() {
|
||||
|
||||
var c = 'class',
|
||||
fm = cmd.fm,
|
||||
disabled = fm.res(c, 'disabled'),
|
||||
active = fm.res(c, 'active'),
|
||||
hover = fm.res(c, 'hover'),
|
||||
item = 'elfinder-button-menu-item',
|
||||
selected = 'elfinder-button-menu-item-selected',
|
||||
menu,
|
||||
text = $('<span class="elfinder-button-text">'+cmd.title+'</span>'),
|
||||
prvCname = cmd.className? cmd.className : cmd.name,
|
||||
button = $(this).addClass('ui-state-default elfinder-button')
|
||||
.attr('title', cmd.title)
|
||||
.append('<span class="elfinder-button-icon elfinder-button-icon-' + prvCname + '"></span>', text)
|
||||
.on('mouseenter mouseleave', function(e) { !button.hasClass(disabled) && button[e.type == 'mouseleave' ? 'removeClass' : 'addClass'](hover);})
|
||||
.on('click', function(e) {
|
||||
if (!button.hasClass(disabled)) {
|
||||
if (menu && cmd.variants.length >= 1) {
|
||||
// close other menus
|
||||
menu.is(':hidden') && fm.getUI().click();
|
||||
e.stopPropagation();
|
||||
menu.css(getMenuOffset()).slideToggle({
|
||||
duration: 100,
|
||||
done: function(e) {
|
||||
fm[menu.is(':visible')? 'toFront' : 'toHide'](menu);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
fm.exec(cmd.name, getSelected(), {_userAction: true, _currentType: 'toolbar', _currentNode: button });
|
||||
}
|
||||
|
||||
}
|
||||
}),
|
||||
hideMenu = function() {
|
||||
fm.toHide(menu);
|
||||
},
|
||||
getMenuOffset = function() {
|
||||
var fmNode = fm.getUI(),
|
||||
baseOffset = fmNode.offset(),
|
||||
buttonOffset = button.offset();
|
||||
return {
|
||||
top : buttonOffset.top - baseOffset.top,
|
||||
left : buttonOffset.left - baseOffset.left,
|
||||
maxHeight : fmNode.height() - 40
|
||||
};
|
||||
},
|
||||
getSelected = function() {
|
||||
var sel = fm.selected(),
|
||||
cwd;
|
||||
if (!sel.length) {
|
||||
if (cwd = fm.cwd()) {
|
||||
sel = [ fm.cwd().hash ];
|
||||
} else {
|
||||
sel = void(0);
|
||||
}
|
||||
}
|
||||
return sel;
|
||||
},
|
||||
tm;
|
||||
|
||||
text.hide();
|
||||
|
||||
// set self button object to cmd object
|
||||
cmd.button = button;
|
||||
|
||||
// if command has variants create menu
|
||||
if (Array.isArray(cmd.variants)) {
|
||||
button.addClass('elfinder-menubutton');
|
||||
|
||||
menu = $('<div class="ui-front ui-widget ui-widget-content elfinder-button-menu elfinder-button-' + prvCname + '-menu ui-corner-all"></div>')
|
||||
.hide()
|
||||
.appendTo(fm.getUI())
|
||||
.on('mouseenter mouseleave', '.'+item, function() { $(this).toggleClass(hover); })
|
||||
.on('click', '.'+item, function(e) {
|
||||
var opts = $(this).data('value');
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
button.removeClass(hover);
|
||||
fm.toHide(menu);
|
||||
if (typeof opts === 'undefined') {
|
||||
opts = {};
|
||||
}
|
||||
if (typeof opts === 'object') {
|
||||
opts._userAction = true;
|
||||
}
|
||||
fm.exec(cmd.name, getSelected(), opts);
|
||||
})
|
||||
.on('close', hideMenu);
|
||||
|
||||
fm.bind('disable select', hideMenu).getUI().on('click', hideMenu);
|
||||
|
||||
cmd.change(function() {
|
||||
menu.html('');
|
||||
$.each(cmd.variants, function(i, variant) {
|
||||
menu.append($('<div class="'+item+'">'+variant[1]+'</div>').data('value', variant[0]).addClass(variant[0] == cmd.value ? selected : ''));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
cmd.change(function() {
|
||||
var cName;
|
||||
tm && cancelAnimationFrame(tm);
|
||||
tm = requestAnimationFrame(function() {
|
||||
if (cmd.disabled()) {
|
||||
button.removeClass(active+' '+hover).addClass(disabled);
|
||||
} else {
|
||||
button.removeClass(disabled);
|
||||
button[cmd.active() ? 'addClass' : 'removeClass'](active);
|
||||
}
|
||||
if (cmd.syncTitleOnChange) {
|
||||
cName = cmd.className? cmd.className : cmd.name;
|
||||
if (prvCname !== cName) {
|
||||
button.children('.elfinder-button-icon').removeClass('elfinder-button-icon-' + prvCname).addClass('elfinder-button-icon-' + cName);
|
||||
if (menu) {
|
||||
menu.removeClass('elfinder-button-' + prvCname + '-menu').addClass('elfinder-button-' + cName + '-menu');
|
||||
}
|
||||
prvCname = cName;
|
||||
}
|
||||
text.html(cmd.title);
|
||||
button.attr('title', cmd.title);
|
||||
}
|
||||
});
|
||||
})
|
||||
.change();
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,703 @@
|
||||
/**
|
||||
* @class elFinder contextmenu
|
||||
*
|
||||
* @author Dmitry (dio) Levashov
|
||||
**/
|
||||
$.fn.elfindercontextmenu = function(fm) {
|
||||
"use strict";
|
||||
return this.each(function() {
|
||||
var self = $(this),
|
||||
cmItem = 'elfinder-contextmenu-item',
|
||||
smItem = 'elfinder-contextsubmenu-item',
|
||||
exIcon = 'elfinder-contextmenu-extra-icon',
|
||||
cHover = fm.res('class', 'hover'),
|
||||
dragOpt = {
|
||||
distance: 8,
|
||||
start: function() {
|
||||
menu.data('drag', true).data('touching') && menu.find('.'+cHover).removeClass(cHover);
|
||||
},
|
||||
stop: function() {
|
||||
menu.data('draged', true).removeData('drag');
|
||||
}
|
||||
},
|
||||
menu = $(this).addClass('touch-punch ui-helper-reset ui-front ui-widget ui-state-default ui-corner-all elfinder-contextmenu elfinder-contextmenu-'+fm.direction)
|
||||
.hide()
|
||||
.on('touchstart', function(e) {
|
||||
menu.data('touching', true).children().removeClass(cHover);
|
||||
})
|
||||
.on('touchend', function(e) {
|
||||
menu.removeData('touching');
|
||||
})
|
||||
.on('mouseenter mouseleave', '.'+cmItem, function(e) {
|
||||
$(this).toggleClass(cHover, (e.type === 'mouseenter' || (! menu.data('draged') && menu.data('submenuKeep'))? true : false));
|
||||
if (menu.data('draged') && menu.data('submenuKeep')) {
|
||||
menu.find('.elfinder-contextmenu-sub:visible').parent().addClass(cHover);
|
||||
}
|
||||
})
|
||||
.on('mouseenter mouseleave', '.'+exIcon, function(e) {
|
||||
$(this).parent().toggleClass(cHover, e.type === 'mouseleave');
|
||||
})
|
||||
.on('mouseenter mouseleave', '.'+cmItem+',.'+smItem, function(e) {
|
||||
var setIndex = function(target, sub) {
|
||||
$.each(sub? subnodes : nodes, function(i, n) {
|
||||
if (target[0] === n) {
|
||||
(sub? subnodes : nodes)._cur = i;
|
||||
if (sub) {
|
||||
subselected = target;
|
||||
} else {
|
||||
selected = target;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
};
|
||||
if (e.originalEvent) {
|
||||
var target = $(this),
|
||||
unHover = function() {
|
||||
if (selected && !selected.children('div.elfinder-contextmenu-sub:visible').length) {
|
||||
selected.removeClass(cHover);
|
||||
}
|
||||
};
|
||||
if (e.type === 'mouseenter') {
|
||||
// mouseenter
|
||||
if (target.hasClass(smItem)) {
|
||||
// submenu
|
||||
if (subselected) {
|
||||
subselected.removeClass(cHover);
|
||||
}
|
||||
if (selected) {
|
||||
subnodes = selected.find('div.'+smItem);
|
||||
}
|
||||
setIndex(target, true);
|
||||
} else {
|
||||
// menu
|
||||
unHover();
|
||||
setIndex(target);
|
||||
}
|
||||
} else {
|
||||
// mouseleave
|
||||
if (target.hasClass(smItem)) {
|
||||
//submenu
|
||||
subselected = null;
|
||||
subnodes = null;
|
||||
} else {
|
||||
// menu
|
||||
unHover();
|
||||
(function(sel) {
|
||||
setTimeout(function() {
|
||||
if (sel === selected) {
|
||||
selected = null;
|
||||
}
|
||||
}, 250);
|
||||
})(selected);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.on('contextmenu', function(){return false;})
|
||||
.on('mouseup', function() {
|
||||
setTimeout(function() {
|
||||
menu.removeData('draged');
|
||||
}, 100);
|
||||
})
|
||||
.draggable(dragOpt),
|
||||
ltr = fm.direction === 'ltr',
|
||||
subpos = ltr? 'left' : 'right',
|
||||
types = Object.assign({}, fm.options.contextmenu),
|
||||
tpl = '<div class="'+cmItem+'{className}"><span class="elfinder-button-icon {icon} elfinder-contextmenu-icon"{style}></span><span>{label}</span></div>',
|
||||
item = function(label, icon, callback, opts) {
|
||||
var className = '',
|
||||
style = '',
|
||||
iconClass = '',
|
||||
v, pos;
|
||||
if (opts) {
|
||||
if (opts.className) {
|
||||
className = ' ' + opts.className;
|
||||
}
|
||||
if (opts.iconClass) {
|
||||
iconClass = opts.iconClass;
|
||||
icon = '';
|
||||
}
|
||||
if (opts.iconImg) {
|
||||
v = opts.iconImg.split(/ +/);
|
||||
pos = v[1] && v[2]? fm.escape(v[1] + 'px ' + v[2] + 'px') : '';
|
||||
style = ' style="background:url(\''+fm.escape(v[0])+'\') '+(pos? pos : '0 0')+' no-repeat;'+(pos? '' : 'posbackground-size:contain;')+'"';
|
||||
}
|
||||
}
|
||||
return $(tpl.replace('{icon}', icon ? 'elfinder-button-icon-'+icon : (iconClass? iconClass : ''))
|
||||
.replace('{label}', label)
|
||||
.replace('{style}', style)
|
||||
.replace('{className}', className))
|
||||
.on('click', function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
callback();
|
||||
});
|
||||
},
|
||||
urlIcon = function(iconUrl) {
|
||||
var v = iconUrl.split(/ +/),
|
||||
pos = v[1] && v[2]? (v[1] + 'px ' + v[2] + 'px') : '';
|
||||
return {
|
||||
backgroundImage: 'url("'+v[0]+'")',
|
||||
backgroundRepeat: 'no-repeat',
|
||||
backgroundPosition: pos? pos : '',
|
||||
backgroundSize: pos? '' : 'contain'
|
||||
};
|
||||
},
|
||||
base, cwd,
|
||||
nodes, selected, subnodes, subselected, autoSyncStop, subHoverTm,
|
||||
|
||||
autoToggle = function() {
|
||||
var evTouchStart = 'touchstart.contextmenuAutoToggle';
|
||||
menu.data('hideTm') && clearTimeout(menu.data('hideTm'));
|
||||
if (menu.is(':visible')) {
|
||||
menu.on('touchstart', function(e) {
|
||||
if (e.originalEvent.touches.length > 1) {
|
||||
return;
|
||||
}
|
||||
menu.stop();
|
||||
fm.toFront(menu);
|
||||
menu.data('hideTm') && clearTimeout(menu.data('hideTm'));
|
||||
})
|
||||
.data('hideTm', setTimeout(function() {
|
||||
if (menu.is(':visible')) {
|
||||
cwd.find('.elfinder-cwd-file').off(evTouchStart);
|
||||
cwd.find('.elfinder-cwd-file.ui-selected')
|
||||
.one(evTouchStart, function(e) {
|
||||
if (e.originalEvent.touches.length > 1) {
|
||||
return;
|
||||
}
|
||||
var tgt = $(e.target);
|
||||
if (menu.first().length && !tgt.is('input:checkbox') && !tgt.hasClass('elfinder-cwd-select')) {
|
||||
e.stopPropagation();
|
||||
//e.preventDefault();
|
||||
open(e.originalEvent.touches[0].pageX, e.originalEvent.touches[0].pageY);
|
||||
cwd.data('longtap', true)
|
||||
tgt.one('touchend', function() {
|
||||
setTimeout(function() {
|
||||
cwd.removeData('longtap');
|
||||
}, 80);
|
||||
});
|
||||
return;
|
||||
}
|
||||
cwd.find('.elfinder-cwd-file').off(evTouchStart);
|
||||
})
|
||||
.one('unselect.'+fm.namespace, function() {
|
||||
cwd.find('.elfinder-cwd-file').off(evTouchStart);
|
||||
});
|
||||
menu.fadeOut({
|
||||
duration: 300,
|
||||
fail: function() {
|
||||
menu.css('opacity', '1').show();
|
||||
},
|
||||
done: function() {
|
||||
fm.toHide(menu);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, 4500));
|
||||
}
|
||||
},
|
||||
|
||||
keyEvts = function(e) {
|
||||
var code = e.keyCode,
|
||||
ESC = $.ui.keyCode.ESCAPE,
|
||||
ENT = $.ui.keyCode.ENTER,
|
||||
LEFT = $.ui.keyCode.LEFT,
|
||||
RIGHT = $.ui.keyCode.RIGHT,
|
||||
UP = $.ui.keyCode.UP,
|
||||
DOWN = $.ui.keyCode.DOWN,
|
||||
subent = fm.direction === 'ltr'? RIGHT : LEFT,
|
||||
sublev = subent === RIGHT? LEFT : RIGHT;
|
||||
|
||||
if ($.inArray(code, [ESC, ENT, LEFT, RIGHT, UP, DOWN]) !== -1) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
e.stopImmediatePropagation();
|
||||
if (code == ESC || code === sublev) {
|
||||
if (selected && subnodes && subselected) {
|
||||
subselected.trigger('mouseleave').trigger('submenuclose');
|
||||
selected.addClass(cHover);
|
||||
subnodes = null;
|
||||
subselected = null;
|
||||
} else {
|
||||
code == ESC && close();
|
||||
}
|
||||
} else if (code == UP || code == DOWN) {
|
||||
if (subnodes) {
|
||||
if (subselected) {
|
||||
subselected.trigger('mouseleave');
|
||||
}
|
||||
if (code == DOWN && (! subselected || subnodes.length <= ++subnodes._cur)) {
|
||||
subnodes._cur = 0;
|
||||
} else if (code == UP && (! subselected || --subnodes._cur < 0)) {
|
||||
subnodes._cur = subnodes.length - 1;
|
||||
}
|
||||
subselected = subnodes.eq(subnodes._cur).trigger('mouseenter');
|
||||
} else {
|
||||
subnodes = null;
|
||||
if (selected) {
|
||||
selected.trigger('mouseleave');
|
||||
}
|
||||
if (code == DOWN && (! selected || nodes.length <= ++nodes._cur)) {
|
||||
nodes._cur = 0;
|
||||
} else if (code == UP && (! selected || --nodes._cur < 0)) {
|
||||
nodes._cur = nodes.length - 1;
|
||||
}
|
||||
selected = nodes.eq(nodes._cur).addClass(cHover);
|
||||
}
|
||||
} else if (selected && (code == ENT || code === subent)) {
|
||||
if (selected.hasClass('elfinder-contextmenu-group')) {
|
||||
if (subselected) {
|
||||
code == ENT && subselected.click();
|
||||
} else {
|
||||
selected.trigger('mouseenter');
|
||||
subnodes = selected.find('div.'+smItem);
|
||||
subnodes._cur = 0;
|
||||
subselected = subnodes.first().addClass(cHover);
|
||||
}
|
||||
} else {
|
||||
code == ENT && selected.click();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
open = function(x, y, css) {
|
||||
var width = menu.outerWidth(),
|
||||
height = menu.outerHeight(),
|
||||
bstyle = base.attr('style'),
|
||||
bpos = base.offset(),
|
||||
bwidth = base.width(),
|
||||
bheight = base.height(),
|
||||
mw = fm.UA.Mobile? 40 : 2,
|
||||
mh = fm.UA.Mobile? 20 : 2,
|
||||
x = x - (bpos? bpos.left : 0),
|
||||
y = y - (bpos? bpos.top : 0),
|
||||
css = Object.assign(css || {}, {
|
||||
top : Math.max(0, y + mh + height < bheight ? y + mh : y - (y + height - bheight)),
|
||||
left : Math.max(0, (x < width + mw || x + mw + width < bwidth)? x + mw : x - mw - width),
|
||||
opacity : '1'
|
||||
}),
|
||||
evts;
|
||||
|
||||
autoSyncStop = true;
|
||||
fm.autoSync('stop');
|
||||
base.width(bwidth);
|
||||
menu.stop().removeAttr('style').css(css);
|
||||
fm.toFront(menu);
|
||||
menu.show();
|
||||
base.attr('style', bstyle);
|
||||
|
||||
css[subpos] = parseInt(menu.width());
|
||||
menu.find('.elfinder-contextmenu-sub').css(css);
|
||||
if (fm.UA.iOS) {
|
||||
$('div.elfinder div.overflow-scrolling-touch').css('-webkit-overflow-scrolling', 'auto');
|
||||
}
|
||||
|
||||
selected = null;
|
||||
subnodes = null;
|
||||
subselected = null;
|
||||
$(document).on('keydown.' + fm.namespace, keyEvts);
|
||||
evts = $._data(document).events;
|
||||
if (evts && evts.keydown) {
|
||||
evts.keydown.unshift(evts.keydown.pop());
|
||||
}
|
||||
|
||||
fm.UA.Mobile && autoToggle();
|
||||
|
||||
requestAnimationFrame(function() {
|
||||
fm.getUI().one('click.' + fm.namespace, close);
|
||||
});
|
||||
},
|
||||
|
||||
close = function() {
|
||||
fm.getUI().off('click.' + fm.namespace, close);
|
||||
$(document).off('keydown.' + fm.namespace, keyEvts);
|
||||
|
||||
currentType = currentTargets = null;
|
||||
|
||||
if (menu.is(':visible') || menu.children().length) {
|
||||
fm.toHide(menu.removeAttr('style').empty().removeData('submenuKeep'));
|
||||
try {
|
||||
if (! menu.draggable('instance')) {
|
||||
menu.draggable(dragOpt);
|
||||
}
|
||||
} catch(e) {
|
||||
if (! menu.hasClass('ui-draggable')) {
|
||||
menu.draggable(dragOpt);
|
||||
}
|
||||
}
|
||||
if (menu.data('prevNode')) {
|
||||
menu.data('prevNode').after(menu);
|
||||
menu.removeData('prevNode');
|
||||
}
|
||||
fm.trigger('closecontextmenu');
|
||||
if (fm.UA.iOS) {
|
||||
$('div.elfinder div.overflow-scrolling-touch').css('-webkit-overflow-scrolling', 'touch');
|
||||
}
|
||||
}
|
||||
|
||||
autoSyncStop && fm.searchStatus.state < 1 && ! fm.searchStatus.ininc && fm.autoSync();
|
||||
autoSyncStop = false;
|
||||
},
|
||||
|
||||
create = function(type, targets) {
|
||||
var sep = false,
|
||||
insSep = false,
|
||||
disabled = [],
|
||||
isCwd = type === 'cwd',
|
||||
selcnt = 0,
|
||||
cmdMap;
|
||||
|
||||
currentType = type;
|
||||
currentTargets = targets;
|
||||
|
||||
// get current uiCmdMap option
|
||||
if (!(cmdMap = fm.option('uiCmdMap', isCwd? void(0) : targets[0]))) {
|
||||
cmdMap = {};
|
||||
}
|
||||
|
||||
if (!isCwd) {
|
||||
disabled = fm.getDisabledCmds(targets);
|
||||
}
|
||||
|
||||
selcnt = fm.selected().length;
|
||||
if (selcnt > 1) {
|
||||
menu.append('<div class="ui-corner-top ui-widget-header elfinder-contextmenu-header"><span>'
|
||||
+ fm.i18n('selectedItems', ''+selcnt)
|
||||
+ '</span></div>');
|
||||
}
|
||||
|
||||
nodes = $();
|
||||
$.each(types[type]||[], function(i, name) {
|
||||
var cmd, cmdName, useMap, node, submenu, hover;
|
||||
|
||||
if (name === '|') {
|
||||
if (sep) {
|
||||
insSep = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmdMap[name]) {
|
||||
cmdName = cmdMap[name];
|
||||
useMap = true;
|
||||
} else {
|
||||
cmdName = name;
|
||||
}
|
||||
cmd = fm.getCommand(cmdName);
|
||||
|
||||
if (cmd && !isCwd && (!fm.searchStatus.state || !cmd.disableOnSearch)) {
|
||||
cmd.__disabled = cmd._disabled;
|
||||
cmd._disabled = !(cmd.alwaysEnabled || (fm._commands[cmdName] ? $.inArray(name, disabled) === -1 && (!useMap || !disabled[cmdName]) : false));
|
||||
$.each(cmd.linkedCmds, function(i, n) {
|
||||
var c;
|
||||
if (c = fm.getCommand(n)) {
|
||||
c.__disabled = c._disabled;
|
||||
c._disabled = !(c.alwaysEnabled || (fm._commands[n] ? !disabled[n] : false));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (cmd && !cmd._disabled && cmd.getstate(targets) != -1) {
|
||||
if (cmd.variants) {
|
||||
if (!cmd.variants.length) {
|
||||
return;
|
||||
}
|
||||
node = item(cmd.title, cmd.className? cmd.className : cmd.name, function(){}, cmd.contextmenuOpts);
|
||||
|
||||
submenu = $('<div class="ui-front ui-corner-all elfinder-contextmenu-sub"></div>')
|
||||
.hide()
|
||||
.css('max-height', fm.getUI().height() - 30)
|
||||
.appendTo(node.append('<span class="elfinder-contextmenu-arrow"></span>'));
|
||||
|
||||
hover = function(show){
|
||||
if (! show) {
|
||||
submenu.hide();
|
||||
} else {
|
||||
var bstyle = base.attr('style');
|
||||
base.width(base.width());
|
||||
// top: '-1000px' to prevent visible scrollbar of window with the elFinder option `height: '100%'`
|
||||
submenu.css({ top: '-1000px', left: 'auto', right: 'auto' });
|
||||
var nodeOffset = node.offset(),
|
||||
nodeleft = nodeOffset.left,
|
||||
nodetop = nodeOffset.top,
|
||||
nodewidth = node.outerWidth(),
|
||||
width = submenu.outerWidth(true),
|
||||
height = submenu.outerHeight(true),
|
||||
baseOffset = base.offset(),
|
||||
wwidth = baseOffset.left + base.width(),
|
||||
wheight = baseOffset.top + base.height(),
|
||||
cltr = ltr,
|
||||
x = nodewidth,
|
||||
y, over;
|
||||
|
||||
if (ltr) {
|
||||
over = (nodeleft + nodewidth + width) - wwidth;
|
||||
if (over > 10) {
|
||||
if (nodeleft > width - 5) {
|
||||
x = x - 5;
|
||||
cltr = false;
|
||||
} else {
|
||||
if (!fm.UA.Mobile) {
|
||||
x = nodewidth - over;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
over = width - nodeleft;
|
||||
if (over > 0) {
|
||||
if ((nodeleft + nodewidth + width - 15) < wwidth) {
|
||||
x = x - 5;
|
||||
cltr = true;
|
||||
} else {
|
||||
if (!fm.UA.Mobile) {
|
||||
x = nodewidth - over;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
over = (nodetop + 5 + height) - wheight;
|
||||
y = (over > 0 && nodetop < wheight)? 5 - over : (over > 0? 30 - height : 5);
|
||||
|
||||
menu.find('.elfinder-contextmenu-sub:visible').hide();
|
||||
submenu.css({
|
||||
top : y,
|
||||
left : cltr? x : 'auto',
|
||||
right: cltr? 'auto' : x,
|
||||
overflowY: 'auto'
|
||||
}).show();
|
||||
base.attr('style', bstyle);
|
||||
}
|
||||
};
|
||||
|
||||
node.addClass('elfinder-contextmenu-group')
|
||||
.on('mouseleave', '.elfinder-contextmenu-sub', function(e) {
|
||||
if (! menu.data('draged')) {
|
||||
menu.removeData('submenuKeep');
|
||||
}
|
||||
})
|
||||
.on('submenuclose', '.elfinder-contextmenu-sub', function(e) {
|
||||
hover(false);
|
||||
})
|
||||
.on('click', '.'+smItem, function(e){
|
||||
var opts, $this;
|
||||
e.stopPropagation();
|
||||
if (! menu.data('draged')) {
|
||||
$this = $(this);
|
||||
if (!cmd.keepContextmenu) {
|
||||
menu.hide();
|
||||
} else {
|
||||
$this.removeClass(cHover);
|
||||
node.addClass(cHover);
|
||||
}
|
||||
opts = $this.data('exec');
|
||||
if (typeof opts === 'undefined') {
|
||||
opts = {};
|
||||
}
|
||||
if (typeof opts === 'object') {
|
||||
opts._userAction = true;
|
||||
opts._currentType = type;
|
||||
opts._currentNode = $this;
|
||||
}
|
||||
!cmd.keepContextmenu && close();
|
||||
fm.exec(cmd.name, targets, opts);
|
||||
}
|
||||
})
|
||||
.on('touchend', function(e) {
|
||||
if (! menu.data('drag')) {
|
||||
hover(true);
|
||||
menu.data('submenuKeep', true);
|
||||
}
|
||||
})
|
||||
.on('mouseenter mouseleave', function(e){
|
||||
if (! menu.data('touching')) {
|
||||
if (node.data('timer')) {
|
||||
clearTimeout(node.data('timer'));
|
||||
node.removeData('timer');
|
||||
}
|
||||
if (!$(e.target).closest('.elfinder-contextmenu-sub', menu).length) {
|
||||
if (e.type === 'mouseleave') {
|
||||
if (! menu.data('submenuKeep')) {
|
||||
node.data('timer', setTimeout(function() {
|
||||
node.removeData('timer');
|
||||
hover(false);
|
||||
}, 250));
|
||||
}
|
||||
} else {
|
||||
node.data('timer', setTimeout(function() {
|
||||
node.removeData('timer');
|
||||
hover(true);
|
||||
}, nodes.find('div.elfinder-contextmenu-sub:visible').length? 250 : 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.each(cmd.variants, function(i, variant) {
|
||||
var item = variant === '|' ? '<div class="elfinder-contextmenu-separator"></div>' :
|
||||
$('<div class="'+cmItem+' '+smItem+'"><span>'+variant[1]+'</span></div>').data('exec', variant[0]),
|
||||
iconClass, icon;
|
||||
if (typeof variant[2] !== 'undefined') {
|
||||
icon = $('<span></span>').addClass('elfinder-button-icon elfinder-contextmenu-icon');
|
||||
if (! /\//.test(variant[2])) {
|
||||
icon.addClass('elfinder-button-icon-'+variant[2]);
|
||||
} else {
|
||||
icon.css(urlIcon(variant[2]));
|
||||
}
|
||||
item.prepend(icon).addClass(smItem+'-icon');
|
||||
}
|
||||
submenu.append(item);
|
||||
});
|
||||
|
||||
} else {
|
||||
node = item(cmd.title, cmd.className? cmd.className : cmd.name, function() {
|
||||
if (! menu.data('draged')) {
|
||||
!cmd.keepContextmenu && close();
|
||||
fm.exec(cmd.name, targets, {_userAction: true, _currentType: type, _currentNode: node});
|
||||
}
|
||||
}, cmd.contextmenuOpts);
|
||||
if (cmd.extra && cmd.extra.node) {
|
||||
$('<span class="elfinder-button-icon elfinder-button-icon-'+(cmd.extra.icon || '')+' '+exIcon+'"></span>')
|
||||
.append(cmd.extra.node).appendTo(node);
|
||||
$(cmd.extra.node).trigger('ready', {targets: targets});
|
||||
} else {
|
||||
node.remove('.'+exIcon);
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd.extendsCmd) {
|
||||
node.children('span.elfinder-button-icon').addClass('elfinder-button-icon-' + cmd.extendsCmd);
|
||||
}
|
||||
|
||||
if (insSep) {
|
||||
menu.append('<div class="elfinder-contextmenu-separator"></div>');
|
||||
}
|
||||
menu.append(node);
|
||||
sep = true;
|
||||
insSep = false;
|
||||
}
|
||||
|
||||
if (cmd && typeof cmd.__disabled !== 'undefined') {
|
||||
cmd._disabled = cmd.__disabled;
|
||||
delete cmd.__disabled;
|
||||
$.each(cmd.linkedCmds, function(i, n) {
|
||||
var c;
|
||||
if (c = fm.getCommand(n)) {
|
||||
c._disabled = c.__disabled;
|
||||
delete c.__disabled;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
nodes = menu.children('div.'+cmItem);
|
||||
},
|
||||
|
||||
createFromRaw = function(raw) {
|
||||
currentType = 'raw';
|
||||
$.each(raw, function(i, data) {
|
||||
var node;
|
||||
|
||||
if (data === '|') {
|
||||
menu.append('<div class="elfinder-contextmenu-separator"></div>');
|
||||
} else if (data.label && typeof data.callback == 'function') {
|
||||
node = item(data.label, data.icon, function() {
|
||||
if (! menu.data('draged')) {
|
||||
!data.remain && close();
|
||||
data.callback();
|
||||
}
|
||||
}, data.options || null);
|
||||
menu.append(node);
|
||||
}
|
||||
});
|
||||
nodes = menu.children('div.'+cmItem);
|
||||
},
|
||||
|
||||
currentType = null,
|
||||
currentTargets = null;
|
||||
|
||||
fm.one('load', function() {
|
||||
base = fm.getUI();
|
||||
cwd = fm.getUI('cwd');
|
||||
fm.bind('contextmenu', function(e) {
|
||||
var data = e.data,
|
||||
css = {},
|
||||
prevNode;
|
||||
|
||||
if (data.type && data.type !== 'files') {
|
||||
cwd.trigger('unselectall');
|
||||
}
|
||||
close();
|
||||
|
||||
if (data.type && data.targets) {
|
||||
fm.trigger('contextmenucreate', data);
|
||||
create(data.type, data.targets);
|
||||
fm.trigger('contextmenucreatedone', data);
|
||||
} else if (data.raw) {
|
||||
createFromRaw(data.raw);
|
||||
}
|
||||
|
||||
if (menu.children().length) {
|
||||
prevNode = data.prevNode || null;
|
||||
if (prevNode) {
|
||||
menu.data('prevNode', menu.prev());
|
||||
prevNode.after(menu);
|
||||
}
|
||||
if (data.fitHeight) {
|
||||
css = {maxHeight: Math.min(fm.getUI().height(), $(window).height()), overflowY: 'auto'};
|
||||
menu.draggable('destroy').removeClass('ui-draggable');
|
||||
}
|
||||
open(data.x, data.y, css);
|
||||
// call opened callback function
|
||||
if (data.opened && typeof data.opened === 'function') {
|
||||
data.opened.call(menu);
|
||||
}
|
||||
}
|
||||
})
|
||||
.one('destroy', function() { menu.remove(); })
|
||||
.bind('disable', close)
|
||||
.bind('select', function(e){
|
||||
(currentType === 'files' && (!e.data || e.data.selected.toString() !== currentTargets.toString())) && close();
|
||||
});
|
||||
})
|
||||
.shortcut({
|
||||
pattern : fm.OS === 'mac' ? 'ctrl+m' : 'contextmenu shift+f10',
|
||||
description : 'contextmenu',
|
||||
callback : function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
$(document).one('contextmenu.' + fm.namespace, function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
});
|
||||
var sel = fm.selected(),
|
||||
type, targets, pos, elm;
|
||||
|
||||
if (sel.length) {
|
||||
type = 'files';
|
||||
targets = sel;
|
||||
elm = fm.cwdHash2Elm(sel[0]);
|
||||
} else {
|
||||
type = 'cwd';
|
||||
targets = [ fm.cwd().hash ];
|
||||
pos = fm.getUI('workzone').offset();
|
||||
}
|
||||
if (! elm || ! elm.length) {
|
||||
elm = fm.getUI('workzone');
|
||||
}
|
||||
pos = elm.offset();
|
||||
pos.top += (elm.height() / 2);
|
||||
pos.left += (elm.width() / 2);
|
||||
fm.trigger('contextmenu', {
|
||||
'type' : type,
|
||||
'targets' : targets,
|
||||
'x' : pos.left,
|
||||
'y' : pos.top
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,809 @@
|
||||
/**
|
||||
* @class elFinder dialog
|
||||
*
|
||||
* @author Dmitry (dio) Levashov
|
||||
**/
|
||||
$.fn.elfinderdialog = function(opts, fm) {
|
||||
"use strict";
|
||||
var platformWin = (window.navigator.platform.indexOf('Win') != -1),
|
||||
delta = {},
|
||||
syncSize = { enabled: false, width: false, height: false, defaultSize: null },
|
||||
fitSize = function(dialog) {
|
||||
var opts, node;
|
||||
if (syncSize.enabled) {
|
||||
node = fm.options.dialogContained? elfNode : $(window);
|
||||
opts = {
|
||||
maxWidth : syncSize.width? node.width() - delta.width : null,
|
||||
maxHeight: syncSize.height? node.height() - delta.height : null
|
||||
};
|
||||
Object.assign(restoreStyle, opts);
|
||||
dialog.css(opts).trigger('resize');
|
||||
if (dialog.data('hasResizable') && (dialog.resizable('option', 'maxWidth') < opts.maxWidth || dialog.resizable('option', 'maxHeight') < opts.maxHeight)) {
|
||||
dialog.resizable('option', opts);
|
||||
}
|
||||
}
|
||||
},
|
||||
syncFunc = function(e) {
|
||||
var dialog = e.data;
|
||||
syncTm && cancelAnimationFrame(syncTm);
|
||||
syncTm = requestAnimationFrame(function() {
|
||||
var opts, offset;
|
||||
if (syncSize.enabled) {
|
||||
fitSize(dialog);
|
||||
}
|
||||
});
|
||||
},
|
||||
checkEditing = function() {
|
||||
var cldialog = 'elfinder-dialog',
|
||||
dialogs = elfNode.children('.' + cldialog + '.' + fm.res('class', 'editing') + ':visible');
|
||||
fm[dialogs.length? 'disable' : 'enable']();
|
||||
},
|
||||
propagationEvents = {},
|
||||
syncTm, dialog, elfNode, restoreStyle;
|
||||
|
||||
if (fm && fm.ui) {
|
||||
elfNode = fm.getUI();
|
||||
} else {
|
||||
elfNode = this.closest('.elfinder');
|
||||
if (! fm) {
|
||||
fm = elfNode.elfinder('instance');
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof opts === 'string') {
|
||||
if ((dialog = this.closest('.ui-dialog')).length) {
|
||||
if (opts === 'open') {
|
||||
if (dialog.css('display') === 'none') {
|
||||
// Need dialog.show() and hide() to detect elements size in open() callbacks
|
||||
dialog.trigger('posinit').show().trigger('open').hide();
|
||||
dialog.fadeIn(120, function() {
|
||||
fm.trigger('dialogopened', {dialog: dialog});
|
||||
});
|
||||
}
|
||||
} else if (opts === 'close' || opts === 'destroy') {
|
||||
dialog.stop(true);
|
||||
if (dialog.is(':visible') || elfNode.is(':hidden')) {
|
||||
dialog.trigger('close');
|
||||
fm.trigger('dialogclosed', {dialog: dialog});
|
||||
}
|
||||
if (opts === 'destroy') {
|
||||
dialog.remove();
|
||||
fm.trigger('dialogremoved', {dialog: dialog});
|
||||
} else if (dialog.data('minimized')) {
|
||||
dialog.data('minimized').close();
|
||||
}
|
||||
} else if (opts === 'toTop') {
|
||||
dialog.trigger('totop');
|
||||
fm.trigger('dialogtotoped', {dialog: dialog});
|
||||
} else if (opts === 'posInit') {
|
||||
dialog.trigger('posinit');
|
||||
fm.trigger('dialogposinited', {dialog: dialog});
|
||||
} else if (opts === 'tabstopsInit') {
|
||||
dialog.trigger('tabstopsInit');
|
||||
fm.trigger('dialogtabstopsinited', {dialog: dialog});
|
||||
} else if (opts === 'checkEditing') {
|
||||
checkEditing();
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
opts = Object.assign({}, $.fn.elfinderdialog.defaults, opts);
|
||||
|
||||
if (opts.allowMinimize && opts.allowMinimize === 'auto') {
|
||||
opts.allowMinimize = this.find('textarea,input').length? true : false;
|
||||
}
|
||||
opts.openMaximized = opts.allowMinimize && opts.openMaximized;
|
||||
if (opts.headerBtnPos && opts.headerBtnPos === 'auto') {
|
||||
opts.headerBtnPos = platformWin? 'right' : 'left';
|
||||
}
|
||||
if (opts.headerBtnOrder && opts.headerBtnOrder === 'auto') {
|
||||
opts.headerBtnOrder = platformWin? 'close:maximize:minimize' : 'close:minimize:maximize';
|
||||
}
|
||||
|
||||
if (opts.modal && opts.allowMinimize) {
|
||||
opts.allowMinimize = false;
|
||||
}
|
||||
|
||||
if (fm.options.dialogContained) {
|
||||
syncSize.width = syncSize.height = syncSize.enabled = true;
|
||||
} else {
|
||||
syncSize.width = (opts.maxWidth === 'window');
|
||||
syncSize.height = (opts.maxHeight === 'window');
|
||||
if (syncSize.width || syncSize.height) {
|
||||
syncSize.enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
propagationEvents = fm.arrayFlip(opts.propagationEvents, true);
|
||||
|
||||
this.filter(':not(.ui-dialog-content)').each(function() {
|
||||
var self = $(this).addClass('ui-dialog-content ui-widget-content'),
|
||||
clactive = 'elfinder-dialog-active',
|
||||
cldialog = 'elfinder-dialog',
|
||||
clnotify = 'elfinder-dialog-notify',
|
||||
clhover = 'ui-state-hover',
|
||||
cltabstop = 'elfinder-tabstop',
|
||||
cl1stfocus = 'elfinder-focus',
|
||||
clmodal = 'elfinder-dialog-modal',
|
||||
id = parseInt(Math.random()*1000000),
|
||||
titlebar = $('<div class="ui-dialog-titlebar ui-widget-header ui-corner-top ui-helper-clearfix"><span class="elfinder-dialog-title">'+opts.title+'</span></div>'),
|
||||
buttonset = $('<div class="ui-dialog-buttonset"></div>'),
|
||||
buttonpane = $('<div class=" ui-helper-clearfix ui-dialog-buttonpane ui-widget-content"></div>')
|
||||
.append(buttonset),
|
||||
btnWidth = 0,
|
||||
btnCnt = 0,
|
||||
tabstops = $(),
|
||||
evCover = $('<div style="width:100%;height:100%;position:absolute;top:0px;left:0px;"></div>').hide(),
|
||||
numberToTel = function() {
|
||||
if (opts.optimizeNumber) {
|
||||
dialog.find('input[type=number]').each(function() {
|
||||
$(this).attr('inputmode', 'numeric');
|
||||
$(this).attr('pattern', '[0-9]*');
|
||||
});
|
||||
}
|
||||
},
|
||||
tabstopsInit = function() {
|
||||
tabstops = dialog.find('.'+cltabstop);
|
||||
if (tabstops.length) {
|
||||
tabstops.attr('tabindex', '-1');
|
||||
if (! tabstops.filter('.'+cl1stfocus).length) {
|
||||
buttonset.children('.'+cltabstop+':'+(platformWin? 'first' : 'last')).addClass(cl1stfocus);
|
||||
}
|
||||
}
|
||||
},
|
||||
tabstopNext = function(cur) {
|
||||
var elms = tabstops.filter(':visible:enabled'),
|
||||
node = cur? null : elms.filter('.'+cl1stfocus+':first');
|
||||
|
||||
if (! node || ! node.length) {
|
||||
node = elms.first();
|
||||
}
|
||||
if (cur) {
|
||||
$.each(elms, function(i, elm) {
|
||||
if (elm === cur && elms[i+1]) {
|
||||
node = elms.eq(i+1);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
return node;
|
||||
},
|
||||
tabstopPrev = function(cur) {
|
||||
var elms = tabstops.filter(':visible:enabled'),
|
||||
node = elms.last();
|
||||
$.each(elms, function(i, elm) {
|
||||
if (elm === cur && elms[i-1]) {
|
||||
node = elms.eq(i-1);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return node;
|
||||
},
|
||||
makeHeaderBtn = function() {
|
||||
$.each(opts.headerBtnOrder.split(':').reverse(), function(i, v) {
|
||||
headerBtns[v] && headerBtns[v]();
|
||||
});
|
||||
if (platformWin) {
|
||||
titlebar.children('.elfinder-titlebar-button').addClass('elfinder-titlebar-button-right');
|
||||
}
|
||||
},
|
||||
headerBtns = {
|
||||
close: function() {
|
||||
titlebar.prepend($('<span class="ui-widget-header ui-dialog-titlebar-close ui-corner-all elfinder-titlebar-button"><span class="ui-icon ui-icon-closethick"></span></span>')
|
||||
.on('mousedown touchstart', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
self.elfinderdialog('close');
|
||||
})
|
||||
);
|
||||
},
|
||||
maximize: function() {
|
||||
if (opts.allowMaximize) {
|
||||
dialog.on('resize', function(e, data) {
|
||||
var full, elm;
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
if (data && data.maximize) {
|
||||
elm = titlebar.find('.elfinder-titlebar-full');
|
||||
full = (data.maximize === 'on');
|
||||
elm.children('span.ui-icon')
|
||||
.toggleClass('ui-icon-plusthick', ! full)
|
||||
.toggleClass('ui-icon-arrowreturnthick-1-s', full);
|
||||
if (full) {
|
||||
try {
|
||||
dialog.hasClass('ui-draggable') && dialog.draggable('disable');
|
||||
dialog.hasClass('ui-resizable') && dialog.resizable('disable');
|
||||
} catch(e) {}
|
||||
self.css('width', '100%').css('height', dialog.height() - dialog.children('.ui-dialog-titlebar').outerHeight(true) - buttonpane.outerHeight(true));
|
||||
} else {
|
||||
self.attr('style', elm.data('style'));
|
||||
elm.removeData('style');
|
||||
posCheck();
|
||||
try {
|
||||
dialog.hasClass('ui-draggable') && dialog.draggable('enable');
|
||||
dialog.hasClass('ui-resizable') && dialog.resizable('enable');
|
||||
} catch(e) {}
|
||||
}
|
||||
dialog.trigger('resize', {init: true});
|
||||
}
|
||||
});
|
||||
titlebar.prepend($('<span class="ui-widget-header ui-corner-all elfinder-titlebar-button elfinder-titlebar-full"><span class="ui-icon ui-icon-plusthick"></span></span>')
|
||||
.on('mousedown touchstart', function(e) {
|
||||
var elm = $(this);
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
if (!dialog.hasClass('elfinder-maximized') && typeof elm.data('style') === 'undefined') {
|
||||
self.height(self.height());
|
||||
elm.data('style', self.attr('style') || '');
|
||||
}
|
||||
fm.toggleMaximize(dialog);
|
||||
typeof(opts.maximize) === 'function' && opts.maximize.call(self[0]);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
},
|
||||
minimize: function() {
|
||||
var btn, mnode, doffset;
|
||||
if (opts.allowMinimize) {
|
||||
btn = $('<span class="ui-widget-header ui-corner-all elfinder-titlebar-button elfinder-titlebar-minimize"><span class="ui-icon ui-icon-minusthick"></span></span>')
|
||||
.on('mousedown touchstart', function(e) {
|
||||
var $this = $(this),
|
||||
tray = fm.getUI('bottomtray'),
|
||||
dumStyle = { width: 70, height: 24 },
|
||||
dum = $('<div></div>').css(dumStyle).addClass(dialog.get(0).className + ' elfinder-dialog-minimized'),
|
||||
close = function() {
|
||||
mnode.remove();
|
||||
dialog.removeData('minimized').show();
|
||||
self.elfinderdialog('close');
|
||||
},
|
||||
pos = {};
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
if (!dialog.data('minimized')) {
|
||||
// minimize
|
||||
doffset = dialog.data('minimized', {
|
||||
dialog : function() { return mnode; },
|
||||
show : function() { mnode.show(); },
|
||||
hide : function() { mnode.hide(); },
|
||||
close : close,
|
||||
title : function(v) { mnode.children('.ui-dialog-titlebar').children('.elfinder-dialog-title').text(v); }
|
||||
}).position();
|
||||
mnode = dialog.clone().on('mousedown', function() {
|
||||
$this.trigger('mousedown');
|
||||
}).removeClass('ui-draggable ui-resizable elfinder-frontmost');
|
||||
tray.append(dum);
|
||||
Object.assign(pos, dum.offset(), dumStyle);
|
||||
dum.remove();
|
||||
mnode.height(dialog.height()).children('.ui-dialog-content:first').empty();
|
||||
fm.toHide(dialog.before(mnode));
|
||||
mnode.children('.ui-dialog-content:first,.ui-dialog-buttonpane,.ui-resizable-handle').remove();
|
||||
mnode.find('.elfinder-titlebar-minimize,.elfinder-titlebar-full').remove();
|
||||
mnode.find('.ui-dialog-titlebar-close').on('mousedown', function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
close();
|
||||
});
|
||||
mnode.animate(pos, function() {
|
||||
mnode.attr('style', '')
|
||||
.css({ maxWidth: dialog.width() })
|
||||
.addClass('elfinder-dialog-minimized')
|
||||
.appendTo(tray);
|
||||
checkEditing();
|
||||
typeof(opts.minimize) === 'function' && opts.minimize.call(self[0]);
|
||||
});
|
||||
} else {
|
||||
//restore
|
||||
dialog.removeData('minimized').before(mnode.css(Object.assign({'position': 'absolute'}, mnode.offset())));
|
||||
fm.toFront(mnode);
|
||||
mnode.animate(Object.assign({ width: dialog.width(), height: dialog.height() }, doffset), function() {
|
||||
dialog.show();
|
||||
fm.toFront(dialog);
|
||||
mnode.remove();
|
||||
posCheck();
|
||||
checkEditing();
|
||||
dialog.trigger('resize', {init: true});
|
||||
typeof(opts.minimize) === 'function' && opts.minimize.call(self[0]);
|
||||
});
|
||||
}
|
||||
});
|
||||
titlebar.on('dblclick', function(e) {
|
||||
$(this).children('.elfinder-titlebar-minimize').trigger('mousedown');
|
||||
}).prepend(btn);
|
||||
dialog.on('togleminimize', function() {
|
||||
btn.trigger('mousedown');
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
dialog = $('<div class="ui-front ui-dialog ui-widget ui-widget-content ui-corner-all ui-draggable std42-dialog touch-punch '+cldialog+' '+opts.cssClass+'"></div>')
|
||||
.hide()
|
||||
.append(self)
|
||||
.appendTo(elfNode)
|
||||
.draggable({
|
||||
containment : fm.options.dialogContained? elfNode : null,
|
||||
handle : '.ui-dialog-titlebar',
|
||||
start : function() {
|
||||
evCover.show();
|
||||
},
|
||||
drag : function(e, ui) {
|
||||
var top = ui.offset.top,
|
||||
left = ui.offset.left;
|
||||
if (top < 0) {
|
||||
ui.position.top = ui.position.top - top;
|
||||
}
|
||||
if (left < 0) {
|
||||
ui.position.left = ui.position.left - left;
|
||||
}
|
||||
if (fm.options.dialogContained) {
|
||||
ui.position.top < 0 && (ui.position.top = 0);
|
||||
ui.position.left < 0 && (ui.position.left = 0);
|
||||
}
|
||||
},
|
||||
stop : function(e, ui) {
|
||||
evCover.hide();
|
||||
dialog.css({height : opts.height});
|
||||
self.data('draged', true);
|
||||
}
|
||||
})
|
||||
.css({
|
||||
width : opts.width,
|
||||
height : opts.height,
|
||||
minWidth : opts.minWidth,
|
||||
minHeight : opts.minHeight,
|
||||
maxWidth : opts.maxWidth,
|
||||
maxHeight : opts.maxHeight
|
||||
})
|
||||
.on('touchstart touchmove touchend click dblclick mouseup mouseenter mouseleave mouseout mouseover mousemove', function(e) {
|
||||
// stopPropagation of user action events
|
||||
!propagationEvents[e.type] && e.stopPropagation();
|
||||
})
|
||||
.on('mousedown', function(e) {
|
||||
!propagationEvents[e.type] && e.stopPropagation();
|
||||
requestAnimationFrame(function() {
|
||||
if (dialog.is(':visible') && !dialog.hasClass('elfinder-frontmost')) {
|
||||
toFocusNode = $(':focus');
|
||||
if (!toFocusNode.length) {
|
||||
toFocusNode = void(0);
|
||||
}
|
||||
dialog.trigger('totop');
|
||||
}
|
||||
});
|
||||
})
|
||||
.on('open', function() {
|
||||
dialog.data('margin-y', self.outerHeight(true) - self.height());
|
||||
if (syncSize.enabled) {
|
||||
if (opts.height && opts.height !== 'auto') {
|
||||
dialog.trigger('resize', {init: true});
|
||||
}
|
||||
if (!syncSize.defaultSize) {
|
||||
syncSize.defaultSize = { width: self.width(), height: self.height() };
|
||||
}
|
||||
fitSize(dialog);
|
||||
dialog.trigger('resize').trigger('posinit');
|
||||
elfNode.on('resize.'+fm.namespace, dialog, syncFunc);
|
||||
}
|
||||
|
||||
if (!dialog.hasClass(clnotify)) {
|
||||
elfNode.children('.'+cldialog+':visible:not(.'+clnotify+')').each(function() {
|
||||
var d = $(this),
|
||||
top = parseInt(d.css('top')),
|
||||
left = parseInt(d.css('left')),
|
||||
_top = parseInt(dialog.css('top')),
|
||||
_left = parseInt(dialog.css('left')),
|
||||
ct = Math.abs(top - _top) < 10,
|
||||
cl = Math.abs(left - _left) < 10;
|
||||
|
||||
if (d[0] != dialog[0] && (ct || cl)) {
|
||||
dialog.css({
|
||||
top : ct ? (top + 10) : _top,
|
||||
left : cl ? (left + 10) : _left
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (dialog.data('modal')) {
|
||||
dialog.addClass(clmodal);
|
||||
fm.getUI('overlay').elfinderoverlay('show');
|
||||
}
|
||||
|
||||
dialog.trigger('totop');
|
||||
|
||||
opts.openMaximized && fm.toggleMaximize(dialog);
|
||||
|
||||
fm.trigger('dialogopen', {dialog: dialog});
|
||||
|
||||
typeof(opts.open) == 'function' && $.proxy(opts.open, self[0])();
|
||||
|
||||
if (opts.closeOnEscape) {
|
||||
$(document).on('keydown.'+id, function(e) {
|
||||
if (e.keyCode == $.ui.keyCode.ESCAPE && dialog.hasClass('elfinder-frontmost')) {
|
||||
self.elfinderdialog('close');
|
||||
}
|
||||
});
|
||||
}
|
||||
dialog.hasClass(fm.res('class', 'editing')) && checkEditing();
|
||||
})
|
||||
.on('close', function(e) {
|
||||
var dialogs, dfd;
|
||||
|
||||
if (opts.beforeclose && typeof opts.beforeclose === 'function') {
|
||||
dfd = opts.beforeclose();
|
||||
if (!dfd || !dfd.promise) {
|
||||
dfd = !dfd? $.Deferred().reject() : $.Deferred().resolve();
|
||||
}
|
||||
} else {
|
||||
dfd = $.Deferred().resolve();
|
||||
}
|
||||
|
||||
dfd.done(function() {
|
||||
syncSize.enabled && elfNode.off('resize.'+fm.namespace, syncFunc);
|
||||
|
||||
if (opts.closeOnEscape) {
|
||||
$(document).off('keyup.'+id);
|
||||
}
|
||||
|
||||
if (opts.allowMaximize) {
|
||||
fm.toggleMaximize(dialog, false);
|
||||
}
|
||||
|
||||
fm.toHide(dialog);
|
||||
dialog.data('modal') && fm.getUI('overlay').elfinderoverlay('hide');
|
||||
|
||||
if (typeof(opts.close) == 'function') {
|
||||
$.proxy(opts.close, self[0])();
|
||||
}
|
||||
if (opts.destroyOnClose && dialog.parent().length) {
|
||||
dialog.hide().remove();
|
||||
}
|
||||
|
||||
// get focus to next dialog
|
||||
dialogs = elfNode.children('.'+cldialog+':visible');
|
||||
|
||||
dialog.hasClass(fm.res('class', 'editing')) && checkEditing();
|
||||
});
|
||||
})
|
||||
.on('totop frontmost', function() {
|
||||
var s = fm.storage('autoFocusDialog');
|
||||
|
||||
dialog.data('focusOnMouseOver', s? (s > 0) : fm.options.uiOptions.dialog.focusOnMouseOver);
|
||||
|
||||
if (dialog.data('minimized')) {
|
||||
titlebar.children('.elfinder-titlebar-minimize').trigger('mousedown');
|
||||
}
|
||||
|
||||
if (!dialog.data('modal') && fm.getUI('overlay').is(':visible')) {
|
||||
fm.getUI('overlay').before(dialog);
|
||||
} else {
|
||||
fm.toFront(dialog);
|
||||
}
|
||||
elfNode.children('.'+cldialog+':not(.'+clmodal+')').removeClass(clactive);
|
||||
dialog.addClass(clactive);
|
||||
|
||||
! fm.UA.Mobile && (toFocusNode || tabstopNext()).trigger('focus');
|
||||
|
||||
toFocusNode = void(0);
|
||||
})
|
||||
.on('posinit', function() {
|
||||
var css = opts.position,
|
||||
nodeOffset, minTop, minLeft, outerSize, win, winSize, nodeFull;
|
||||
if (dialog.hasClass('elfinder-maximized')) {
|
||||
return;
|
||||
}
|
||||
if (! css && ! dialog.data('resizing')) {
|
||||
nodeFull = elfNode.hasClass('elfinder-fullscreen') || fm.options.enableAlways;
|
||||
dialog.css(nodeFull? {
|
||||
maxWidth : '100%',
|
||||
maxHeight : '100%',
|
||||
overflow : 'auto'
|
||||
} : restoreStyle);
|
||||
if (fm.UA.Mobile && !nodeFull && dialog.data('rotated') === fm.UA.Rotated) {
|
||||
return;
|
||||
}
|
||||
dialog.data('rotated', fm.UA.Rotated);
|
||||
win = $(window);
|
||||
nodeOffset = elfNode.offset();
|
||||
outerSize = {
|
||||
width : dialog.outerWidth(true),
|
||||
height: dialog.outerHeight(true)
|
||||
};
|
||||
outerSize.right = nodeOffset.left + outerSize.width;
|
||||
outerSize.bottom = nodeOffset.top + outerSize.height;
|
||||
winSize = {
|
||||
scrLeft: win.scrollLeft(),
|
||||
scrTop : win.scrollTop(),
|
||||
width : win.width(),
|
||||
height : win.height()
|
||||
};
|
||||
winSize.right = winSize.scrLeft + winSize.width;
|
||||
winSize.bottom = winSize.scrTop + winSize.height;
|
||||
|
||||
if (fm.options.dialogContained || nodeFull) {
|
||||
minTop = 0;
|
||||
minLeft = 0;
|
||||
} else {
|
||||
minTop = nodeOffset.top * -1 + winSize.scrTop;
|
||||
minLeft = nodeOffset.left * -1 + winSize.scrLeft;
|
||||
}
|
||||
css = {
|
||||
top : outerSize.height >= winSize.height? minTop : Math.max(minTop, parseInt((elfNode.height() - outerSize.height)/2 - 42)),
|
||||
left : outerSize.width >= winSize.width ? minLeft : Math.max(minLeft, parseInt((elfNode.width() - outerSize.width)/2))
|
||||
};
|
||||
if (outerSize.right + css.left > winSize.right) {
|
||||
css.left = Math.max(minLeft, winSize.right - outerSize.right);
|
||||
}
|
||||
if (outerSize.bottom + css.top > winSize.bottom) {
|
||||
css.top = Math.max(minTop, winSize.bottom - outerSize.bottom);
|
||||
}
|
||||
}
|
||||
if (opts.absolute) {
|
||||
css.position = 'absolute';
|
||||
}
|
||||
css && dialog.css(css);
|
||||
})
|
||||
.on('resize', function(e, data) {
|
||||
var oh = 0, init = data && data.init, h, minH, maxH, autoH;
|
||||
if ((data && (data.minimize || data.maxmize)) || dialog.data('minimized')) {
|
||||
return;
|
||||
}
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
dialog.children('.ui-widget-header,.ui-dialog-buttonpane').each(function() {
|
||||
oh += $(this).outerHeight(true);
|
||||
});
|
||||
autoH = (opts.height === 'auto')? true : false;
|
||||
if (autoH) {
|
||||
self.css({'max-height': '', 'height': 'auto'});
|
||||
}
|
||||
if (!init && syncSize.enabled && !e.originalEvent && !dialog.hasClass('elfinder-maximized')) {
|
||||
h = dialog.height();
|
||||
minH = dialog.css('min-height') || h;
|
||||
maxH = dialog.css('max-height') || h;
|
||||
if (minH.match(/%/)) {
|
||||
minH = Math.floor((parseInt(minH) / 100) * dialog.parent().height());
|
||||
} else {
|
||||
minH = parseInt(minH);
|
||||
}
|
||||
if (maxH.match(/%/)) {
|
||||
maxH = Math.floor((parseInt(maxH) / 100) * dialog.parent().height());
|
||||
} else {
|
||||
maxH = parseInt(maxH);
|
||||
}
|
||||
h = Math.min((autoH? dialog.height() : syncSize.defaultSize.height), Math.max(maxH, minH) - oh - dialog.data('margin-y'));
|
||||
} else {
|
||||
h = dialog.height() - oh - dialog.data('margin-y');
|
||||
}
|
||||
self.css(autoH? 'max-height' : 'height', h);
|
||||
if (init) {
|
||||
return;
|
||||
}
|
||||
posCheck();
|
||||
minH = self.height();
|
||||
minH = (h < minH)? (minH + oh + dialog.data('margin-y')) : opts.minHeight;
|
||||
dialog.css('min-height', minH);
|
||||
dialog.data('hasResizable') && dialog.resizable('option', { minHeight: minH });
|
||||
if (typeof(opts.resize) === 'function') {
|
||||
$.proxy(opts.resize, self[0])(e, data);
|
||||
}
|
||||
})
|
||||
.on('tabstopsInit', tabstopsInit)
|
||||
.on('focus', '.'+cltabstop, function() {
|
||||
$(this).addClass(clhover).parent('label').addClass(clhover);
|
||||
this.id && $(this).parent().find('label[for='+this.id+']').addClass(clhover);
|
||||
})
|
||||
.on('click', 'select.'+cltabstop, function() {
|
||||
var node = $(this);
|
||||
node.data('keepFocus')? node.removeData('keepFocus') : node.data('keepFocus', true);
|
||||
})
|
||||
.on('blur', '.'+cltabstop, function() {
|
||||
$(this).removeClass(clhover).removeData('keepFocus').parent('label').removeClass(clhover);
|
||||
this.id && $(this).parent().find('label[for='+this.id+']').removeClass(clhover);
|
||||
})
|
||||
.on('mouseenter mouseleave', '.'+cltabstop+',label', function(e) {
|
||||
var $this = $(this), labelfor;
|
||||
if (this.nodeName === 'LABEL') {
|
||||
if (!$this.children('.'+cltabstop).length && (!(labelfor = $this.attr('for')) || !$('#'+labelfor).hasClass(cltabstop))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (opts.btnHoverFocus && dialog.data('focusOnMouseOver')) {
|
||||
if (e.type === 'mouseenter' && ! $(':focus').data('keepFocus')) {
|
||||
$this.trigger('focus');
|
||||
}
|
||||
} else {
|
||||
$this.toggleClass(clhover, e.type == 'mouseenter');
|
||||
}
|
||||
})
|
||||
.on('keydown', '.'+cltabstop, function(e) {
|
||||
var $this = $(this),
|
||||
esc, move, moveTo;
|
||||
if ($this.is(':focus')) {
|
||||
esc = e.keyCode === $.ui.keyCode.ESCAPE;
|
||||
if (e.keyCode === $.ui.keyCode.ENTER) {
|
||||
e.preventDefault();
|
||||
$this.trigger('click');
|
||||
} else if (((e.keyCode === $.ui.keyCode.TAB) && e.shiftKey) || e.keyCode === $.ui.keyCode.LEFT || e.keyCode == $.ui.keyCode.UP) {
|
||||
move = 'prev';
|
||||
} else if (e.keyCode === $.ui.keyCode.TAB || e.keyCode == $.ui.keyCode.RIGHT || e.keyCode == $.ui.keyCode.DOWN) {
|
||||
move = 'next';
|
||||
}
|
||||
if (move
|
||||
&&
|
||||
(
|
||||
($this.is('textarea') && !(e.ctrlKey || e.metaKey))
|
||||
||
|
||||
($this.is('select,span.ui-slider-handle') && e.keyCode !== $.ui.keyCode.TAB)
|
||||
||
|
||||
($this.is('input:not(:checkbox,:radio)') && (!(e.ctrlKey || e.metaKey) && e.keyCode === $.ui.keyCode[move === 'prev'? 'LEFT':'RIGHT']))
|
||||
)
|
||||
) {
|
||||
e.stopPropagation();
|
||||
return;
|
||||
}
|
||||
if (!esc) {
|
||||
e.stopPropagation();
|
||||
} else if ($this.is('input:not(:checkbox,:radio),textarea')) {
|
||||
if ($this.val() !== '') {
|
||||
$this.val('');
|
||||
e.stopPropagation();
|
||||
}
|
||||
}
|
||||
if (move) {
|
||||
e.preventDefault();
|
||||
(move === 'prev'? tabstopPrev : tabstopNext)(this).trigger('focus');
|
||||
}
|
||||
}
|
||||
})
|
||||
.data({modal: opts.modal}),
|
||||
posCheck = function() {
|
||||
var node = fm.getUI(),
|
||||
pos;
|
||||
if (node.hasClass('elfinder-fullscreen')) {
|
||||
pos = dialog.position();
|
||||
dialog.css('top', Math.max(Math.min(Math.max(pos.top, 0), node.height() - 100), 0));
|
||||
dialog.css('left', Math.max(Math.min(Math.max(pos.left, 0), node.width() - 200), 0));
|
||||
}
|
||||
},
|
||||
maxSize, toFocusNode;
|
||||
|
||||
dialog.prepend(titlebar);
|
||||
|
||||
makeHeaderBtn();
|
||||
|
||||
$.each(opts.buttons, function(name, cb) {
|
||||
var button = $('<button type="button" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only '
|
||||
+'elfinder-btncnt-'+(btnCnt++)+' '
|
||||
+cltabstop
|
||||
+'"><span class="ui-button-text">'+name+'</span></button>')
|
||||
.on('click', $.proxy(cb, self[0]));
|
||||
if (cb._cssClass) {
|
||||
button.addClass(cb._cssClass);
|
||||
}
|
||||
if (platformWin) {
|
||||
buttonset.append(button);
|
||||
} else {
|
||||
buttonset.prepend(button);
|
||||
}
|
||||
});
|
||||
|
||||
if (buttonset.children().length) {
|
||||
dialog.append(buttonpane);
|
||||
|
||||
dialog.show();
|
||||
buttonpane.find('button').each(function(i, btn) {
|
||||
btnWidth += $(btn).outerWidth(true);
|
||||
});
|
||||
dialog.hide();
|
||||
btnWidth += 20;
|
||||
|
||||
if (dialog.width() < btnWidth) {
|
||||
dialog.width(btnWidth);
|
||||
}
|
||||
}
|
||||
|
||||
dialog.append(evCover);
|
||||
|
||||
if (syncSize.enabled) {
|
||||
delta.width = dialog.outerWidth(true) - dialog.width() + ((dialog.outerWidth() - dialog.width()) / 2);
|
||||
delta.height = dialog.outerHeight(true) - dialog.height() + ((dialog.outerHeight() - dialog.height()) / 2);
|
||||
}
|
||||
|
||||
if (fm.options.dialogContained) {
|
||||
maxSize = {
|
||||
maxWidth: elfNode.width() - delta.width,
|
||||
maxHeight: elfNode.height() - delta.height
|
||||
};
|
||||
opts.maxWidth = opts.maxWidth? Math.min(maxSize.maxWidth, opts.maxWidth) : maxSize.maxWidth;
|
||||
opts.maxHeight = opts.maxHeight? Math.min(maxSize.maxHeight, opts.maxHeight) : maxSize.maxHeight;
|
||||
dialog.css(maxSize);
|
||||
}
|
||||
|
||||
restoreStyle = {
|
||||
maxWidth : dialog.css('max-width'),
|
||||
maxHeight : dialog.css('max-height'),
|
||||
overflow : dialog.css('overflow')
|
||||
};
|
||||
|
||||
if (opts.resizable) {
|
||||
dialog.resizable({
|
||||
minWidth : opts.minWidth,
|
||||
minHeight : opts.minHeight,
|
||||
maxWidth : opts.maxWidth,
|
||||
maxHeight : opts.maxHeight,
|
||||
start : function() {
|
||||
evCover.show();
|
||||
if (dialog.data('resizing') !== true && dialog.data('resizing')) {
|
||||
clearTimeout(dialog.data('resizing'));
|
||||
}
|
||||
dialog.data('resizing', true);
|
||||
},
|
||||
stop : function(e, ui) {
|
||||
evCover.hide();
|
||||
dialog.data('resizing', setTimeout(function() {
|
||||
dialog.data('resizing', false);
|
||||
}, 200));
|
||||
if (syncSize.enabled) {
|
||||
syncSize.defaultSize = { width: self.width(), height: self.height() };
|
||||
}
|
||||
}
|
||||
}).data('hasResizable', true);
|
||||
}
|
||||
|
||||
numberToTel();
|
||||
|
||||
tabstopsInit();
|
||||
|
||||
typeof(opts.create) == 'function' && $.proxy(opts.create, this)();
|
||||
|
||||
if (opts.autoOpen) {
|
||||
if (opts.open) {
|
||||
requestAnimationFrame(function() {
|
||||
self.elfinderdialog('open');
|
||||
});
|
||||
} else {
|
||||
self.elfinderdialog('open');
|
||||
}
|
||||
}
|
||||
|
||||
if (opts.resize) {
|
||||
fm.bind('themechange', function() {
|
||||
setTimeout(function() {
|
||||
dialog.data('margin-y', self.outerHeight(true) - self.height());
|
||||
dialog.trigger('resize', {init: true});
|
||||
}, 300);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
$.fn.elfinderdialog.defaults = {
|
||||
cssClass : '',
|
||||
title : '',
|
||||
modal : false,
|
||||
resizable : true,
|
||||
autoOpen : true,
|
||||
closeOnEscape : true,
|
||||
destroyOnClose : false,
|
||||
buttons : {},
|
||||
btnHoverFocus : true,
|
||||
position : null,
|
||||
absolute : false,
|
||||
width : 320,
|
||||
height : 'auto',
|
||||
minWidth : 200,
|
||||
minHeight : 70,
|
||||
maxWidth : null,
|
||||
maxHeight : null,
|
||||
allowMinimize : 'auto',
|
||||
allowMaximize : false,
|
||||
openMaximized : false,
|
||||
headerBtnPos : 'auto',
|
||||
headerBtnOrder : 'auto',
|
||||
optimizeNumber : true,
|
||||
propagationEvents : ['mousemove', 'mouseup']
|
||||
};
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* @class elFinder toolbar button to switch full scrren mode.
|
||||
*
|
||||
* @author Naoki Sawada
|
||||
**/
|
||||
|
||||
$.fn.elfinderfullscreenbutton = function(cmd) {
|
||||
"use strict";
|
||||
return this.each(function() {
|
||||
var button = $(this).elfinderbutton(cmd),
|
||||
icon = button.children('.elfinder-button-icon'),
|
||||
tm;
|
||||
cmd.change(function() {
|
||||
tm && cancelAnimationFrame(tm);
|
||||
tm = requestAnimationFrame(function() {
|
||||
var fullscreen = cmd.value;
|
||||
icon.addClass('elfinder-button-icon-fullscreen').toggleClass('elfinder-button-icon-unfullscreen', fullscreen);
|
||||
cmd.className = fullscreen? 'unfullscreen' : '';
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,171 @@
|
||||
/**
|
||||
* @class elfindernav - elFinder container for diretories tree and places
|
||||
*
|
||||
* @author Dmitry (dio) Levashov
|
||||
**/
|
||||
$.fn.elfindernavbar = function(fm, opts) {
|
||||
"use strict";
|
||||
this.not('.elfinder-navbar').each(function() {
|
||||
var nav = $(this).hide().addClass('ui-state-default elfinder-navbar'),
|
||||
parent = nav.css('overflow', 'hidden').parent(),
|
||||
wz = parent.children('.elfinder-workzone').append(nav),
|
||||
ltr = fm.direction == 'ltr',
|
||||
delta, deltaW, handle, swipeHandle, autoHide, setWidth, navdock,
|
||||
setWzRect = function() {
|
||||
var cwd = fm.getUI('cwd'),
|
||||
wz = fm.getUI('workzone'),
|
||||
wzRect = wz.data('rectangle'),
|
||||
cwdOffset = cwd.offset();
|
||||
wz.data('rectangle', Object.assign(wzRect, { cwdEdge: (fm.direction === 'ltr')? cwdOffset.left : cwdOffset.left + cwd.width() }));
|
||||
},
|
||||
setDelta = function() {
|
||||
nav.css('overflow', 'hidden');
|
||||
delta = Math.round(nav.outerHeight() - nav.height());
|
||||
deltaW = Math.round(navdock.outerWidth() - navdock.innerWidth());
|
||||
nav.css('overflow', 'auto');
|
||||
};
|
||||
|
||||
fm.one('init', function() {
|
||||
navdock = fm.getUI('navdock');
|
||||
var set = function() {
|
||||
setDelta();
|
||||
fm.bind('wzresize', function() {
|
||||
var navdockH = 0;
|
||||
navdock.width(nav.outerWidth() - deltaW);
|
||||
if (navdock.children().length > 1) {
|
||||
navdockH = navdock.outerHeight(true);
|
||||
}
|
||||
nav.height(wz.height() - navdockH - delta);
|
||||
}).trigger('wzresize');
|
||||
};
|
||||
if (fm.cssloaded) {
|
||||
set();
|
||||
} else {
|
||||
fm.one('cssloaded', set);
|
||||
}
|
||||
})
|
||||
.one('opendone',function() {
|
||||
handle && handle.trigger('resize');
|
||||
nav.css('overflow', 'auto');
|
||||
}).bind('themechange', setDelta);
|
||||
|
||||
if (fm.UA.Touch) {
|
||||
autoHide = fm.storage('autoHide') || {};
|
||||
if (typeof autoHide.navbar === 'undefined') {
|
||||
autoHide.navbar = (opts.autoHideUA && opts.autoHideUA.length > 0 && $.grep(opts.autoHideUA, function(v){ return fm.UA[v]? true : false; }).length);
|
||||
fm.storage('autoHide', autoHide);
|
||||
}
|
||||
|
||||
if (autoHide.navbar) {
|
||||
fm.one('init', function() {
|
||||
if (nav.children().length) {
|
||||
fm.uiAutoHide.push(function(){ nav.stop(true, true).trigger('navhide', { duration: 'slow', init: true }); });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fm.bind('load', function() {
|
||||
if (nav.children().length) {
|
||||
swipeHandle = $('<div class="elfinder-navbar-swipe-handle"></div>').hide().appendTo(wz);
|
||||
if (swipeHandle.css('pointer-events') !== 'none') {
|
||||
swipeHandle.remove();
|
||||
swipeHandle = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
nav.on('navshow navhide', function(e, data) {
|
||||
var mode = (e.type === 'navshow')? 'show' : 'hide',
|
||||
duration = (data && data.duration)? data.duration : 'fast',
|
||||
handleW = (data && data.handleW)? data.handleW : Math.max(50, fm.getUI().width() / 10);
|
||||
nav.stop(true, true)[mode]({
|
||||
duration: duration,
|
||||
step : function() {
|
||||
fm.trigger('wzresize');
|
||||
},
|
||||
complete: function() {
|
||||
if (swipeHandle) {
|
||||
if (mode === 'show') {
|
||||
swipeHandle.stop(true, true).hide();
|
||||
} else {
|
||||
swipeHandle.width(handleW? handleW : '');
|
||||
fm.resources.blink(swipeHandle, 'slowonce');
|
||||
}
|
||||
}
|
||||
fm.trigger('navbar'+ mode);
|
||||
data.init && fm.trigger('uiautohide');
|
||||
setWzRect();
|
||||
}
|
||||
});
|
||||
autoHide.navbar = (mode !== 'show');
|
||||
fm.storage('autoHide', Object.assign(fm.storage('autoHide'), {navbar: autoHide.navbar}));
|
||||
}).on('touchstart', function(e) {
|
||||
if ($(this)['scroll' + (fm.direction === 'ltr'? 'Right' : 'Left')]() > 5) {
|
||||
e.originalEvent._preventSwipeX = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (! fm.UA.Mobile) {
|
||||
handle = nav.resizable({
|
||||
handles : ltr ? 'e' : 'w',
|
||||
minWidth : opts.minWidth || 150,
|
||||
maxWidth : opts.maxWidth || 500,
|
||||
resize : function() {
|
||||
fm.trigger('wzresize');
|
||||
},
|
||||
stop : function(e, ui) {
|
||||
fm.storage('navbarWidth', ui.size.width);
|
||||
setWzRect();
|
||||
}
|
||||
})
|
||||
.on('resize scroll', function(e) {
|
||||
var $this = $(this),
|
||||
tm = $this.data('posinit');
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
if (! ltr && e.type === 'resize') {
|
||||
nav.css('left', 0);
|
||||
}
|
||||
tm && cancelAnimationFrame(tm);
|
||||
$this.data('posinit', requestAnimationFrame(function() {
|
||||
var offset = (fm.UA.Opera && nav.scrollLeft())? 20 : 2;
|
||||
handle.css('top', 0).css({
|
||||
top : parseInt(nav.scrollTop())+'px',
|
||||
left : ltr ? 'auto' : parseInt(nav.scrollRight() - offset) * -1,
|
||||
right: ltr ? parseInt(nav.scrollLeft() - offset) * -1 : 'auto'
|
||||
});
|
||||
if (e.type === 'resize') {
|
||||
fm.getUI('cwd').trigger('resize');
|
||||
}
|
||||
}));
|
||||
})
|
||||
.children('.ui-resizable-handle').addClass('ui-front');
|
||||
}
|
||||
|
||||
if (setWidth = fm.storage('navbarWidth')) {
|
||||
nav.width(setWidth);
|
||||
} else {
|
||||
if (fm.UA.Mobile) {
|
||||
fm.one(fm.cssloaded? 'init' : 'cssloaded', function() {
|
||||
var set = function() {
|
||||
setWidth = nav.parent().width() / 2;
|
||||
if (nav.data('defWidth') > setWidth) {
|
||||
nav.width(setWidth);
|
||||
} else {
|
||||
nav.width(nav.data('defWidth'));
|
||||
}
|
||||
nav.data('width', nav.width());
|
||||
fm.trigger('wzresize');
|
||||
};
|
||||
nav.data('defWidth', nav.width());
|
||||
$(window).on('resize.' + fm.namespace, set);
|
||||
set();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
@@ -0,0 +1,158 @@
|
||||
/**
|
||||
* @class elfindernavdock - elFinder container for preview etc at below the navbar
|
||||
*
|
||||
* @author Naoki Sawada
|
||||
**/
|
||||
$.fn.elfindernavdock = function(fm, opts) {
|
||||
"use strict";
|
||||
this.not('.elfinder-navdock').each(function() {
|
||||
var self = $(this).hide().addClass('ui-state-default elfinder-navdock touch-punch'),
|
||||
node = self.parent(),
|
||||
wz = node.children('.elfinder-workzone').append(self),
|
||||
resize = function(to, h) {
|
||||
var curH = h || self.height(),
|
||||
diff = to - curH,
|
||||
len = Object.keys(sizeSyncs).length,
|
||||
calc = len? diff / len : 0,
|
||||
ovf;
|
||||
if (diff) {
|
||||
ovf = self.css('overflow');
|
||||
self.css('overflow', 'hidden');
|
||||
self.height(to);
|
||||
$.each(sizeSyncs, function(id, n) {
|
||||
n.height(n.height() + calc).trigger('resize.' + fm.namespace);
|
||||
});
|
||||
fm.trigger('wzresize');
|
||||
self.css('overflow', ovf);
|
||||
}
|
||||
},
|
||||
handle = $('<div class="ui-front ui-resizable-handle ui-resizable-n"></div>').appendTo(self),
|
||||
sizeSyncs = {},
|
||||
resizeFn = [],
|
||||
initMaxHeight = (parseInt(opts.initMaxHeight) || 50) / 100,
|
||||
maxHeight = (parseInt(opts.maxHeight) || 90) / 100,
|
||||
basicHeight, hasNode;
|
||||
|
||||
|
||||
self.data('addNode', function(cNode, opts) {
|
||||
var wzH = fm.getUI('workzone').height(),
|
||||
imaxH = wzH * initMaxHeight,
|
||||
curH, tH, mH;
|
||||
opts = Object.assign({
|
||||
first: false,
|
||||
sizeSync: true,
|
||||
init: false
|
||||
}, opts);
|
||||
if (!cNode.attr('id')) {
|
||||
cNode.attr('id', fm.namespace+'-navdock-' + (+new Date()));
|
||||
}
|
||||
opts.sizeSync && (sizeSyncs[cNode.attr('id')] = cNode);
|
||||
curH = self.height();
|
||||
tH = curH + cNode.outerHeight(true);
|
||||
|
||||
if (opts.first) {
|
||||
handle.after(cNode);
|
||||
} else {
|
||||
self.append(cNode);
|
||||
}
|
||||
hasNode = true;
|
||||
self.resizable('enable').height(tH).show();
|
||||
|
||||
fm.trigger('wzresize');
|
||||
|
||||
if (opts.init) {
|
||||
mH = fm.storage('navdockHeight');
|
||||
if (mH) {
|
||||
tH = mH;
|
||||
} else {
|
||||
tH = tH > imaxH? imaxH : tH;
|
||||
}
|
||||
basicHeight = tH;
|
||||
}
|
||||
resize(Math.min(tH, wzH * maxHeight));
|
||||
|
||||
return self;
|
||||
}).data('removeNode', function(nodeId, appendTo) {
|
||||
var cNode = $('#'+nodeId);
|
||||
delete sizeSyncs[nodeId];
|
||||
self.height(self.height() - $('#'+nodeId).outerHeight(true));
|
||||
if (appendTo) {
|
||||
if (appendTo === 'detach') {
|
||||
cNode = cNode.detach();
|
||||
} else {
|
||||
appendTo.append(cNode);
|
||||
}
|
||||
} else {
|
||||
cNode.remove();
|
||||
}
|
||||
if (self.children().length <= 1) {
|
||||
hasNode = false;
|
||||
self.resizable('disable').height(0).hide();
|
||||
}
|
||||
fm.trigger('wzresize');
|
||||
return cNode;
|
||||
});
|
||||
|
||||
if (! opts.disabled) {
|
||||
fm.one('init', function() {
|
||||
var ovf;
|
||||
if (fm.getUI('navbar').children().not('.ui-resizable-handle').length) {
|
||||
self.data('dockEnabled', true);
|
||||
self.resizable({
|
||||
maxHeight: fm.getUI('workzone').height() * maxHeight,
|
||||
handles: { n: handle },
|
||||
start: function(e, ui) {
|
||||
ovf = self.css('overflow');
|
||||
self.css('overflow', 'hidden');
|
||||
fm.trigger('navdockresizestart', {event: e, ui: ui}, true);
|
||||
},
|
||||
resize: function(e, ui) {
|
||||
self.css('top', '');
|
||||
fm.trigger('wzresize', { inNavdockResize : true });
|
||||
},
|
||||
stop: function(e, ui) {
|
||||
fm.trigger('navdockresizestop', {event: e, ui: ui}, true);
|
||||
self.css('top', '');
|
||||
basicHeight = ui.size.height;
|
||||
fm.storage('navdockHeight', basicHeight);
|
||||
resize(basicHeight, ui.originalSize.height);
|
||||
self.css('overflow', ovf);
|
||||
}
|
||||
});
|
||||
fm.bind('wzresize', function(e) {
|
||||
var minH, maxH, h;
|
||||
if (self.is(':visible')) {
|
||||
maxH = fm.getUI('workzone').height() * maxHeight;
|
||||
if (! e.data || ! e.data.inNavdockResize) {
|
||||
h = self.height();
|
||||
if (maxH < basicHeight) {
|
||||
if (Math.abs(h - maxH) > 1) {
|
||||
resize(maxH);
|
||||
}
|
||||
} else {
|
||||
if (Math.abs(h - basicHeight) > 1) {
|
||||
resize(basicHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
self.resizable('option', 'maxHeight', maxH);
|
||||
}
|
||||
}).bind('themechange', function() {
|
||||
var oldH = Math.round(self.height());
|
||||
requestAnimationFrame(function() {
|
||||
var curH = Math.round(self.height()),
|
||||
diff = oldH - curH;
|
||||
if (diff !== 0) {
|
||||
resize(self.height(), curH - diff);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
fm.bind('navbarshow navbarhide', function(e) {
|
||||
self[hasNode && e.type === 'navbarshow'? 'show' : 'hide']();
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
return this;
|
||||
};
|
||||
@@ -0,0 +1,50 @@
|
||||
|
||||
$.fn.elfinderoverlay = function(opts) {
|
||||
"use strict";
|
||||
var fm = this.parent().elfinder('instance'),
|
||||
o, cnt, show, hide;
|
||||
|
||||
this.filter(':not(.elfinder-overlay)').each(function() {
|
||||
opts = Object.assign({}, opts);
|
||||
$(this).addClass('ui-front ui-widget-overlay elfinder-overlay')
|
||||
.hide()
|
||||
.on('mousedown', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
})
|
||||
.data({
|
||||
cnt : 0,
|
||||
show : typeof(opts.show) == 'function' ? opts.show : function() { },
|
||||
hide : typeof(opts.hide) == 'function' ? opts.hide : function() { }
|
||||
});
|
||||
});
|
||||
|
||||
if (opts == 'show') {
|
||||
o = this.eq(0);
|
||||
cnt = o.data('cnt') + 1;
|
||||
show = o.data('show');
|
||||
|
||||
fm.toFront(o);
|
||||
o.data('cnt', cnt);
|
||||
|
||||
if (o.is(':hidden')) {
|
||||
o.show();
|
||||
show();
|
||||
}
|
||||
}
|
||||
|
||||
if (opts == 'hide') {
|
||||
o = this.eq(0);
|
||||
cnt = o.data('cnt') - 1;
|
||||
hide = o.data('hide');
|
||||
|
||||
o.data('cnt', cnt);
|
||||
|
||||
if (cnt <= 0) {
|
||||
o.hide();
|
||||
hide();
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
$.fn.elfinderpanel = function(fm) {
|
||||
"use strict";
|
||||
return this.each(function() {
|
||||
var panel = $(this).addClass('elfinder-panel ui-state-default ui-corner-all'),
|
||||
margin = 'margin-'+(fm.direction == 'ltr' ? 'left' : 'right');
|
||||
|
||||
fm.one('load', function(e) {
|
||||
var navbar = fm.getUI('navbar');
|
||||
|
||||
panel.css(margin, parseInt(navbar.outerWidth(true)));
|
||||
navbar.on('resize', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
panel.is(':visible') && panel.css(margin, parseInt(navbar.outerWidth(true)));
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,184 @@
|
||||
/**
|
||||
* @class elFinder ui
|
||||
* Display current folder path in statusbar.
|
||||
* Click on folder name in path - open folder
|
||||
*
|
||||
* @author Dmitry (dio) Levashov
|
||||
**/
|
||||
$.fn.elfinderpath = function(fm, options) {
|
||||
"use strict";
|
||||
return this.each(function() {
|
||||
var query = '',
|
||||
target = '',
|
||||
mimes = [],
|
||||
place = 'statusbar',
|
||||
clHover= fm.res('class', 'hover'),
|
||||
prefix = 'path' + (elFinder.prototype.uniqueid? elFinder.prototype.uniqueid : '') + '-',
|
||||
wzbase = $('<div class="ui-widget-header ui-helper-clearfix elfinder-workzone-path"></div>'),
|
||||
path = $(this).addClass('elfinder-path').html(' ')
|
||||
.on('mousedown', 'span.elfinder-path-dir', function(e) {
|
||||
var hash = $(this).attr('id').substr(prefix.length);
|
||||
e.preventDefault();
|
||||
if (hash != fm.cwd().hash) {
|
||||
$(this).addClass(clHover);
|
||||
if (query) {
|
||||
fm.exec('search', query, { target: hash, mime: mimes.join(' ') });
|
||||
} else {
|
||||
fm.trigger('select', {selected : [hash]}).exec('open', hash);
|
||||
}
|
||||
}
|
||||
})
|
||||
.prependTo(fm.getUI('statusbar').show()),
|
||||
roots = $('<div class="elfinder-path-roots"></div>').on('click', function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
var roots = $.map(fm.roots, function(h) { return fm.file(h); }),
|
||||
raw = [];
|
||||
|
||||
$.each(roots, function(i, f) {
|
||||
if (! f.phash && fm.root(fm.cwd().hash, true) !== f.hash) {
|
||||
raw.push({
|
||||
label : fm.escape(f.i18 || f.name),
|
||||
icon : 'home',
|
||||
callback : function() { fm.exec('open', f.hash); },
|
||||
options : {
|
||||
iconClass : f.csscls || '',
|
||||
iconImg : f.icon || ''
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
fm.trigger('contextmenu', {
|
||||
raw: raw,
|
||||
x: e.pageX,
|
||||
y: e.pageY
|
||||
});
|
||||
}).append('<span class="elfinder-button-icon elfinder-button-icon-menu" ></span>').appendTo(wzbase),
|
||||
render = function(cwd) {
|
||||
var dirs = [],
|
||||
names = [];
|
||||
$.each(fm.parents(cwd), function(i, hash) {
|
||||
var c = (cwd === hash)? 'elfinder-path-dir elfinder-path-cwd' : 'elfinder-path-dir',
|
||||
f = fm.file(hash),
|
||||
name = fm.escape(f.i18 || f.name);
|
||||
names.push(name);
|
||||
dirs.push('<span id="'+prefix+hash+'" class="'+c+'" title="'+names.join(fm.option('separator'))+'">'+name+'</span>');
|
||||
});
|
||||
return dirs.join('<span class="elfinder-path-other">'+fm.option('separator')+'</span>');
|
||||
},
|
||||
toWorkzone = function() {
|
||||
var prev;
|
||||
path.children('span.elfinder-path-dir').attr('style', '');
|
||||
prev = fm.direction === 'ltr'? $('#'+prefix + fm.cwd().hash).prevAll('span.elfinder-path-dir:first') : $();
|
||||
path.scrollLeft(prev.length? prev.position().left : 0);
|
||||
},
|
||||
fit = function() {
|
||||
if (fm.UA.CSS.flex) {
|
||||
return;
|
||||
}
|
||||
var dirs = path.children('span.elfinder-path-dir'),
|
||||
cnt = dirs.length,
|
||||
m, bg = 0, ids;
|
||||
|
||||
if (place === 'workzone' || cnt < 2) {
|
||||
dirs.attr('style', '');
|
||||
return;
|
||||
}
|
||||
path.width(path.css('max-width'));
|
||||
dirs.css({maxWidth: (100/cnt)+'%', display: 'inline-block'});
|
||||
m = path.width() - 9;
|
||||
path.children('span.elfinder-path-other').each(function() {
|
||||
m -= $(this).width();
|
||||
});
|
||||
ids = [];
|
||||
dirs.each(function(i) {
|
||||
var dir = $(this),
|
||||
w = dir.width();
|
||||
m -= w;
|
||||
if (w < this.scrollWidth) {
|
||||
ids.push(i);
|
||||
}
|
||||
});
|
||||
path.width('');
|
||||
if (ids.length) {
|
||||
if (m > 0) {
|
||||
m = m / ids.length;
|
||||
$.each(ids, function(i, k) {
|
||||
var d = $(dirs[k]);
|
||||
d.css('max-width', d.width() + m);
|
||||
});
|
||||
}
|
||||
dirs.last().attr('style', '');
|
||||
} else {
|
||||
dirs.attr('style', '');
|
||||
}
|
||||
},
|
||||
hasUiTree, hasUiStat;
|
||||
|
||||
fm.one('init', function() {
|
||||
hasUiTree = fm.getUI('tree').length;
|
||||
hasUiStat = fm.getUI('stat').length;
|
||||
if (! hasUiTree && options.toWorkzoneWithoutNavbar) {
|
||||
wzbase.append(path).insertBefore(fm.getUI('workzone'));
|
||||
place = 'workzone';
|
||||
fm.bind('open', toWorkzone)
|
||||
.one('opendone', function() {
|
||||
fm.getUI().trigger('resize');
|
||||
});
|
||||
}
|
||||
})
|
||||
.bind('open searchend parents', function() {
|
||||
var dirs = [];
|
||||
|
||||
query = '';
|
||||
target = '';
|
||||
mimes = [];
|
||||
|
||||
path.html(render(fm.cwd().hash));
|
||||
if (Object.keys(fm.roots).length > 1) {
|
||||
path.css('margin', '');
|
||||
roots.show();
|
||||
} else {
|
||||
path.css('margin', 0);
|
||||
roots.hide();
|
||||
}
|
||||
!hasUiStat && fit();
|
||||
})
|
||||
.bind('searchstart', function(e) {
|
||||
if (e.data) {
|
||||
query = e.data.query || '';
|
||||
target = e.data.target || '';
|
||||
mimes = e.data.mimes || [];
|
||||
}
|
||||
})
|
||||
.bind('search', function(e) {
|
||||
var dirs = [],
|
||||
html = '';
|
||||
if (target) {
|
||||
html = render(target);
|
||||
} else {
|
||||
html = fm.i18n('btnAll');
|
||||
}
|
||||
path.html('<span class="elfinder-path-other">'+fm.i18n('searcresult') + ': </span>' + html);
|
||||
fit();
|
||||
})
|
||||
// on swipe to navbar show/hide
|
||||
.bind('navbarshow navbarhide', function() {
|
||||
var wz = fm.getUI('workzone');
|
||||
if (this.type === 'navbarshow') {
|
||||
fm.unbind('open', toWorkzone);
|
||||
path.prependTo(fm.getUI('statusbar'));
|
||||
wzbase.detach();
|
||||
place = 'statusbar';
|
||||
} else {
|
||||
wzbase.append(path).insertBefore(wz);
|
||||
place = 'workzone';
|
||||
toWorkzone();
|
||||
fm.bind('open', toWorkzone);
|
||||
}
|
||||
fm.trigger('uiresize');
|
||||
})
|
||||
.bind('resize uistatchange', fit);
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,634 @@
|
||||
/**
|
||||
* @class elFinder places/favorites ui
|
||||
*
|
||||
* @author Dmitry (dio) Levashov
|
||||
* @author Naoki Sawada
|
||||
**/
|
||||
$.fn.elfinderplaces = function(fm, opts) {
|
||||
"use strict";
|
||||
return this.each(function() {
|
||||
var dirs = {},
|
||||
c = 'class',
|
||||
navdir = fm.res(c, 'navdir'),
|
||||
collapsed = fm.res(c, 'navcollapse'),
|
||||
expanded = fm.res(c, 'navexpand'),
|
||||
hover = fm.res(c, 'hover'),
|
||||
clroot = fm.res(c, 'treeroot'),
|
||||
dropover = fm.res(c, 'adroppable'),
|
||||
tpl = fm.res('tpl', 'placedir'),
|
||||
ptpl = fm.res('tpl', 'perms'),
|
||||
spinner = $(fm.res('tpl', 'navspinner')),
|
||||
suffix = opts.suffix? opts.suffix : '',
|
||||
key = 'places' + suffix,
|
||||
menuTimer = null,
|
||||
/**
|
||||
* Convert places dir node into dir hash
|
||||
*
|
||||
* @param String directory id
|
||||
* @return String
|
||||
**/
|
||||
id2hash = function(id) { return id.substr(6); },
|
||||
/**
|
||||
* Convert places dir hash into dir node id
|
||||
*
|
||||
* @param String directory id
|
||||
* @return String
|
||||
**/
|
||||
hash2id = function(hash) { return 'place-'+hash; },
|
||||
|
||||
/**
|
||||
* Convert places dir hash into dir node elment (jQuery object)
|
||||
*
|
||||
* @param String directory id
|
||||
* @return Object
|
||||
**/
|
||||
hash2elm = function(hash) { return $(document.getElementById(hash2id(hash))); },
|
||||
|
||||
/**
|
||||
* Save current places state
|
||||
*
|
||||
* @return void
|
||||
**/
|
||||
save = function() {
|
||||
var hashes = [], data = {};
|
||||
|
||||
hashes = $.map(subtree.children().find('[id]'), function(n) {
|
||||
return id2hash(n.id);
|
||||
});
|
||||
if (hashes.length) {
|
||||
$.each(hashes.reverse(), function(i, h) {
|
||||
data[h] = dirs[h];
|
||||
});
|
||||
} else {
|
||||
data = null;
|
||||
}
|
||||
|
||||
fm.storage(key, data);
|
||||
},
|
||||
/**
|
||||
* Init dir at places
|
||||
*
|
||||
* @return void
|
||||
**/
|
||||
init = function() {
|
||||
var dat, hashes;
|
||||
key = 'places'+(opts.suffix? opts.suffix : ''),
|
||||
dirs = {};
|
||||
dat = fm.storage(key);
|
||||
if (typeof dat === 'string') {
|
||||
// old data type elFinder <= 2.1.12
|
||||
dat = $.grep(dat.split(','), function(hash) { return hash? true : false;});
|
||||
$.each(dat, function(i, d) {
|
||||
var dir = d.split('#');
|
||||
dirs[dir[0]] = dir[1]? dir[1] : dir[0];
|
||||
});
|
||||
} else if ($.isPlainObject(dat)) {
|
||||
dirs = dat;
|
||||
}
|
||||
// allow modify `dirs`
|
||||
/**
|
||||
* example for preset places
|
||||
*
|
||||
* elfinderInstance.bind('placesload', function(e, fm) {
|
||||
* //if (fm.storage(e.data.storageKey) === null) { // for first time only
|
||||
* if (!fm.storage(e.data.storageKey)) { // for empty places
|
||||
* e.data.dirs[targetHash] = fallbackName; // preset folder
|
||||
* }
|
||||
* }
|
||||
**/
|
||||
fm.trigger('placesload', {dirs: dirs, storageKey: key}, true);
|
||||
|
||||
hashes = Object.keys(dirs);
|
||||
if (hashes.length) {
|
||||
root.prepend(spinner);
|
||||
|
||||
fm.request({
|
||||
data : {cmd : 'info', targets : hashes},
|
||||
preventDefault : true
|
||||
})
|
||||
.done(function(data) {
|
||||
var exists = {};
|
||||
|
||||
data.files && data.files.length && fm.cache(data.files);
|
||||
|
||||
$.each(data.files, function(i, f) {
|
||||
var hash = f.hash;
|
||||
exists[hash] = f;
|
||||
});
|
||||
$.each(dirs, function(h, f) {
|
||||
add(exists[h] || Object.assign({notfound: true}, f));
|
||||
});
|
||||
if (fm.storage('placesState') > 0) {
|
||||
root.trigger('click');
|
||||
}
|
||||
})
|
||||
.always(function() {
|
||||
spinner.remove();
|
||||
});
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Return node for given dir object
|
||||
*
|
||||
* @param Object directory object
|
||||
* @return jQuery
|
||||
**/
|
||||
create = function(dir, hash) {
|
||||
return $(tpl.replace(/\{id\}/, hash2id(dir? dir.hash : hash))
|
||||
.replace(/\{name\}/, fm.escape(dir? dir.i18 || dir.name : hash))
|
||||
.replace(/\{cssclass\}/, dir? (fm.perms2class(dir) + (dir.notfound? ' elfinder-na' : '') + (dir.csscls? ' '+dir.csscls : '')) : '')
|
||||
.replace(/\{permissions\}/, (dir && (!dir.read || !dir.write || dir.notfound))? ptpl : '')
|
||||
.replace(/\{title\}/, dir? (' title="' + fm.escape(fm.path(dir.hash, true) || dir.i18 || dir.name) + '"') : '')
|
||||
.replace(/\{symlink\}/, '')
|
||||
.replace(/\{style\}/, (dir && dir.icon)? fm.getIconStyle(dir) : ''));
|
||||
},
|
||||
/**
|
||||
* Add new node into places
|
||||
*
|
||||
* @param Object directory object
|
||||
* @return void
|
||||
**/
|
||||
add = function(dir) {
|
||||
var node, hash;
|
||||
|
||||
if (dir.mime !== 'directory') {
|
||||
return false;
|
||||
}
|
||||
hash = dir.hash;
|
||||
if (!fm.files().hasOwnProperty(hash)) {
|
||||
// update cache
|
||||
fm.trigger('tree', {tree: [dir]});
|
||||
}
|
||||
|
||||
node = create(dir, hash);
|
||||
|
||||
dirs[hash] = dir;
|
||||
subtree.prepend(node);
|
||||
root.addClass(collapsed);
|
||||
sortBtn.toggle(subtree.children().length > 1);
|
||||
|
||||
return true;
|
||||
},
|
||||
/**
|
||||
* Remove dir from places
|
||||
*
|
||||
* @param String directory hash
|
||||
* @return String removed name
|
||||
**/
|
||||
remove = function(hash) {
|
||||
var name = null, tgt, cnt;
|
||||
|
||||
if (dirs[hash]) {
|
||||
delete dirs[hash];
|
||||
tgt = hash2elm(hash);
|
||||
if (tgt.length) {
|
||||
name = tgt.text();
|
||||
tgt.parent().remove();
|
||||
cnt = subtree.children().length;
|
||||
sortBtn.toggle(cnt > 1);
|
||||
if (! cnt) {
|
||||
root.removeClass(collapsed);
|
||||
places.removeClass(expanded);
|
||||
subtree.slideToggle(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return name;
|
||||
},
|
||||
/**
|
||||
* Move up dir on places
|
||||
*
|
||||
* @param String directory hash
|
||||
* @return void
|
||||
**/
|
||||
moveup = function(hash) {
|
||||
var self = hash2elm(hash),
|
||||
tgt = self.parent(),
|
||||
prev = tgt.prev('div'),
|
||||
cls = 'ui-state-hover',
|
||||
ctm = fm.getUI('contextmenu');
|
||||
|
||||
menuTimer && clearTimeout(menuTimer);
|
||||
|
||||
if (prev.length) {
|
||||
ctm.find(':first').data('placesHash', hash);
|
||||
self.addClass(cls);
|
||||
tgt.insertBefore(prev);
|
||||
prev = tgt.prev('div');
|
||||
menuTimer = setTimeout(function() {
|
||||
self.removeClass(cls);
|
||||
if (ctm.find(':first').data('placesHash') === hash) {
|
||||
ctm.hide().empty();
|
||||
}
|
||||
}, 1500);
|
||||
}
|
||||
|
||||
if(!prev.length) {
|
||||
self.removeClass(cls);
|
||||
ctm.hide().empty();
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Update dir at places
|
||||
*
|
||||
* @param Object directory
|
||||
* @param String previous hash
|
||||
* @return Boolean
|
||||
**/
|
||||
update = function(dir, preHash) {
|
||||
var hash = dir.hash,
|
||||
tgt = hash2elm(preHash || hash),
|
||||
node = create(dir, hash);
|
||||
|
||||
if (tgt.length > 0) {
|
||||
tgt.parent().replaceWith(node);
|
||||
dirs[hash] = dir;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Remove all dir from places
|
||||
*
|
||||
* @return void
|
||||
**/
|
||||
clear = function() {
|
||||
subtree.empty();
|
||||
root.removeClass(collapsed);
|
||||
places.removeClass(expanded);
|
||||
subtree.slideToggle(false);
|
||||
},
|
||||
/**
|
||||
* Sort places dirs A-Z
|
||||
*
|
||||
* @return void
|
||||
**/
|
||||
sort = function() {
|
||||
$.each(dirs, function(h, f) {
|
||||
var dir = fm.file(h) || f,
|
||||
node = create(dir, h),
|
||||
ret = null;
|
||||
if (!dir) {
|
||||
node.hide();
|
||||
}
|
||||
if (subtree.children().length) {
|
||||
$.each(subtree.children(), function() {
|
||||
var current = $(this);
|
||||
if ((dir.i18 || dir.name).localeCompare(current.children('.'+navdir).text()) < 0) {
|
||||
ret = !node.insertBefore(current);
|
||||
return ret;
|
||||
}
|
||||
});
|
||||
if (ret !== null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
!hash2elm(h).length && subtree.append(node);
|
||||
});
|
||||
save();
|
||||
},
|
||||
// sort button
|
||||
sortBtn = $('<span class="elfinder-button-icon elfinder-button-icon-sort elfinder-places-root-icon" title="'+fm.i18n('cmdsort')+'"></span>')
|
||||
.hide()
|
||||
.on('click', function(e) {
|
||||
e.stopPropagation();
|
||||
subtree.empty();
|
||||
sort();
|
||||
}
|
||||
),
|
||||
/**
|
||||
* Node - wrapper for places root
|
||||
*
|
||||
* @type jQuery
|
||||
**/
|
||||
wrapper = create({
|
||||
hash : 'root-'+fm.namespace,
|
||||
name : fm.i18n(opts.name, 'places'),
|
||||
read : true,
|
||||
write : true
|
||||
}),
|
||||
/**
|
||||
* Places root node
|
||||
*
|
||||
* @type jQuery
|
||||
**/
|
||||
root = wrapper.children('.'+navdir)
|
||||
.addClass(clroot)
|
||||
.on('click', function(e) {
|
||||
e.stopPropagation();
|
||||
if (root.hasClass(collapsed)) {
|
||||
places.toggleClass(expanded);
|
||||
subtree.slideToggle();
|
||||
fm.storage('placesState', places.hasClass(expanded)? 1 : 0);
|
||||
}
|
||||
})
|
||||
.append(sortBtn),
|
||||
/**
|
||||
* Container for dirs
|
||||
*
|
||||
* @type jQuery
|
||||
**/
|
||||
subtree = wrapper.children('.'+fm.res(c, 'navsubtree')),
|
||||
|
||||
/**
|
||||
* Main places container
|
||||
*
|
||||
* @type jQuery
|
||||
**/
|
||||
places = $(this).addClass(fm.res(c, 'tree')+' elfinder-places ui-corner-all')
|
||||
.hide()
|
||||
.append(wrapper)
|
||||
.appendTo(fm.getUI('navbar'))
|
||||
.on('mouseenter mouseleave', '.'+navdir, function(e) {
|
||||
$(this).toggleClass('ui-state-hover', (e.type == 'mouseenter'));
|
||||
})
|
||||
.on('click', '.'+navdir, function(e) {
|
||||
var p = $(this);
|
||||
if (p.data('longtap')) {
|
||||
e.stopPropagation();
|
||||
return;
|
||||
}
|
||||
! p.hasClass('elfinder-na') && fm.exec('open', p.attr('id').substr(6));
|
||||
})
|
||||
.on('contextmenu', '.'+navdir+':not(.'+clroot+')', function(e) {
|
||||
var self = $(this),
|
||||
hash = self.attr('id').substr(6);
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
fm.trigger('contextmenu', {
|
||||
raw : [{
|
||||
label : fm.i18n('moveUp'),
|
||||
icon : 'up',
|
||||
remain : true,
|
||||
callback : function() { moveup(hash); save(); }
|
||||
},'|',{
|
||||
label : fm.i18n('rmFromPlaces'),
|
||||
icon : 'rm',
|
||||
callback : function() { remove(hash); save(); }
|
||||
}],
|
||||
'x' : e.pageX,
|
||||
'y' : e.pageY
|
||||
});
|
||||
|
||||
self.addClass('ui-state-hover');
|
||||
|
||||
fm.getUI('contextmenu').children().on('mouseenter', function() {
|
||||
self.addClass('ui-state-hover');
|
||||
});
|
||||
|
||||
fm.bind('closecontextmenu', function() {
|
||||
self.removeClass('ui-state-hover');
|
||||
});
|
||||
})
|
||||
.droppable({
|
||||
tolerance : 'pointer',
|
||||
accept : '.elfinder-cwd-file-wrapper,.elfinder-tree-dir,.elfinder-cwd-file',
|
||||
hoverClass : fm.res('class', 'adroppable'),
|
||||
classes : { // Deprecated hoverClass jQueryUI>=1.12.0
|
||||
'ui-droppable-hover': fm.res('class', 'adroppable')
|
||||
},
|
||||
over : function(e, ui) {
|
||||
var helper = ui.helper,
|
||||
dir = $.grep(helper.data('files'), function(h) { return (fm.file(h).mime === 'directory' && !dirs[h])? true : false; });
|
||||
e.stopPropagation();
|
||||
helper.data('dropover', helper.data('dropover') + 1);
|
||||
if (fm.insideWorkzone(e.pageX, e.pageY)) {
|
||||
if (dir.length > 0) {
|
||||
helper.addClass('elfinder-drag-helper-plus');
|
||||
fm.trigger('unlockfiles', {files : helper.data('files'), helper: helper});
|
||||
} else {
|
||||
$(this).removeClass(dropover);
|
||||
}
|
||||
}
|
||||
},
|
||||
out : function(e, ui) {
|
||||
var helper = ui.helper;
|
||||
e.stopPropagation();
|
||||
helper.removeClass('elfinder-drag-helper-move elfinder-drag-helper-plus').data('dropover', Math.max(helper.data('dropover') - 1, 0));
|
||||
$(this).removeData('dropover')
|
||||
.removeClass(dropover);
|
||||
},
|
||||
drop : function(e, ui) {
|
||||
var helper = ui.helper,
|
||||
resolve = true;
|
||||
|
||||
$.each(helper.data('files'), function(i, hash) {
|
||||
var dir = fm.file(hash);
|
||||
|
||||
if (dir && dir.mime == 'directory' && !dirs[dir.hash]) {
|
||||
add(dir);
|
||||
} else {
|
||||
resolve = false;
|
||||
}
|
||||
});
|
||||
save();
|
||||
resolve && helper.hide();
|
||||
}
|
||||
})
|
||||
// for touch device
|
||||
.on('touchstart', '.'+navdir+':not(.'+clroot+')', function(e) {
|
||||
if (e.originalEvent.touches.length > 1) {
|
||||
return;
|
||||
}
|
||||
var hash = $(this).attr('id').substr(6),
|
||||
p = $(this)
|
||||
.addClass(hover)
|
||||
.data('longtap', null)
|
||||
.data('tmlongtap', setTimeout(function(){
|
||||
// long tap
|
||||
p.data('longtap', true);
|
||||
fm.trigger('contextmenu', {
|
||||
raw : [{
|
||||
label : fm.i18n('rmFromPlaces'),
|
||||
icon : 'rm',
|
||||
callback : function() { remove(hash); save(); }
|
||||
}],
|
||||
'x' : e.originalEvent.touches[0].pageX,
|
||||
'y' : e.originalEvent.touches[0].pageY
|
||||
});
|
||||
}, 500));
|
||||
})
|
||||
.on('touchmove touchend', '.'+navdir+':not(.'+clroot+')', function(e) {
|
||||
clearTimeout($(this).data('tmlongtap'));
|
||||
if (e.type == 'touchmove') {
|
||||
$(this).removeClass(hover);
|
||||
}
|
||||
});
|
||||
|
||||
if ($.fn.sortable) {
|
||||
subtree.addClass('touch-punch')
|
||||
.sortable({
|
||||
appendTo : fm.getUI(),
|
||||
revert : false,
|
||||
helper : function(e) {
|
||||
var dir = $(e.target).parent();
|
||||
|
||||
dir.children().removeClass('ui-state-hover');
|
||||
|
||||
return $('<div class="ui-widget elfinder-place-drag elfinder-'+fm.direction+'"></div>')
|
||||
.append($('<div class="elfinder-navbar"></div>').show().append(dir.clone()));
|
||||
|
||||
},
|
||||
stop : function(e, ui) {
|
||||
var target = $(ui.item[0]),
|
||||
top = places.offset().top,
|
||||
left = places.offset().left,
|
||||
width = places.width(),
|
||||
height = places.height(),
|
||||
x = e.pageX,
|
||||
y = e.pageY;
|
||||
|
||||
if (!(x > left && x < left+width && y > top && y < y+height)) {
|
||||
remove(id2hash(target.children(':first').attr('id')));
|
||||
save();
|
||||
}
|
||||
},
|
||||
update : function(e, ui) {
|
||||
save();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// "on regist" for command exec
|
||||
$(this).on('regist', function(e, files){
|
||||
var added = false;
|
||||
$.each(files, function(i, dir) {
|
||||
if (dir && dir.mime == 'directory' && !dirs[dir.hash]) {
|
||||
if (add(dir)) {
|
||||
added = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
added && save();
|
||||
});
|
||||
|
||||
|
||||
// on fm load - show places and load files from backend
|
||||
fm.one('load', function() {
|
||||
var dat, hashes;
|
||||
|
||||
if (fm.oldAPI) {
|
||||
return;
|
||||
}
|
||||
|
||||
places.show().parent().show();
|
||||
|
||||
init();
|
||||
|
||||
fm.change(function(e) {
|
||||
var changed = false;
|
||||
$.each(e.data.changed, function(i, file) {
|
||||
if (dirs[file.hash]) {
|
||||
if (file.mime !== 'directory') {
|
||||
if (remove(file.hash)) {
|
||||
changed = true;
|
||||
}
|
||||
} else {
|
||||
if (update(file)) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
changed && save();
|
||||
})
|
||||
.bind('rename', function(e) {
|
||||
var changed = false;
|
||||
if (e.data.removed) {
|
||||
$.each(e.data.removed, function(i, hash) {
|
||||
if (e.data.added[i]) {
|
||||
if (update(e.data.added[i], hash)) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
changed && save();
|
||||
})
|
||||
.bind('rm paste', function(e) {
|
||||
var names = [],
|
||||
changed = false;
|
||||
if (e.data.removed) {
|
||||
$.each(e.data.removed, function(i, hash) {
|
||||
var name = remove(hash);
|
||||
name && names.push(name);
|
||||
});
|
||||
}
|
||||
if (names.length) {
|
||||
changed = true;
|
||||
}
|
||||
if (e.data.added && names.length) {
|
||||
$.each(e.data.added, function(i, file) {
|
||||
if ($.inArray(file.name, names) !== 1) {
|
||||
file.mime == 'directory' && add(file);
|
||||
}
|
||||
});
|
||||
}
|
||||
changed && save();
|
||||
})
|
||||
.bind('sync netmount', function() {
|
||||
var ev = this,
|
||||
opSuffix = opts.suffix? opts.suffix : '',
|
||||
hashes;
|
||||
|
||||
if (ev.type === 'sync') {
|
||||
// check is change of opts.suffix
|
||||
if (suffix !== opSuffix) {
|
||||
suffix = opSuffix;
|
||||
clear();
|
||||
init();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
hashes = Object.keys(dirs);
|
||||
if (hashes.length) {
|
||||
root.prepend(spinner);
|
||||
|
||||
fm.request({
|
||||
data : {cmd : 'info', targets : hashes},
|
||||
preventDefault : true
|
||||
})
|
||||
.done(function(data) {
|
||||
var exists = {},
|
||||
updated = false,
|
||||
cwd = fm.cwd().hash;
|
||||
$.each(data.files || [], function(i, file) {
|
||||
var hash = file.hash;
|
||||
exists[hash] = file;
|
||||
if (!fm.files().hasOwnProperty(file.hash)) {
|
||||
// update cache
|
||||
fm.updateCache({tree: [file]});
|
||||
}
|
||||
});
|
||||
$.each(dirs, function(h, f) {
|
||||
if (Boolean(f.notfound) === Boolean(exists[h])) {
|
||||
if ((f.phash === cwd && ev.type !== 'netmount') || (exists[h] && exists[h].mime !== 'directory')) {
|
||||
if (remove(h)) {
|
||||
updated = true;
|
||||
}
|
||||
} else {
|
||||
if (update(exists[h] || Object.assign({notfound: true}, f))) {
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
} else if (exists[h] && exists[h].phash != cwd) {
|
||||
// update permission of except cwd
|
||||
update(exists[h]);
|
||||
}
|
||||
});
|
||||
updated && save();
|
||||
})
|
||||
.always(function() {
|
||||
spinner.remove();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,335 @@
|
||||
/**
|
||||
* @class elFinder toolbar search button widget.
|
||||
*
|
||||
* @author Dmitry (dio) Levashov
|
||||
**/
|
||||
$.fn.elfindersearchbutton = function(cmd) {
|
||||
"use strict";
|
||||
return this.each(function() {
|
||||
var result = false,
|
||||
fm = cmd.fm,
|
||||
disabled = fm.res('class', 'disabled'),
|
||||
isopts = cmd.options.incsearch || { enable: false },
|
||||
sTypes = cmd.options.searchTypes,
|
||||
id = function(name){return fm.namespace + fm.escape(name);},
|
||||
toolbar= fm.getUI('toolbar'),
|
||||
btnCls = fm.res('class', 'searchbtn'),
|
||||
button = $(this)
|
||||
.hide()
|
||||
.addClass('ui-widget-content elfinder-button '+btnCls)
|
||||
.on('click', function(e) {
|
||||
e.stopPropagation();
|
||||
}),
|
||||
getMenuOffset = function() {
|
||||
var fmNode = fm.getUI(),
|
||||
baseOffset = fmNode.offset(),
|
||||
buttonOffset = button.offset();
|
||||
return {
|
||||
top : buttonOffset.top - baseOffset.top,
|
||||
maxHeight : fmNode.height() - 40
|
||||
};
|
||||
},
|
||||
search = function() {
|
||||
input.data('inctm') && clearTimeout(input.data('inctm'));
|
||||
var val = $.trim(input.val()),
|
||||
from = !$('#' + id('SearchFromAll')).prop('checked'),
|
||||
mime = $('#' + id('SearchMime')).prop('checked'),
|
||||
type = '';
|
||||
if (from) {
|
||||
if ($('#' + id('SearchFromVol')).prop('checked')) {
|
||||
from = fm.root(fm.cwd().hash);
|
||||
} else {
|
||||
from = fm.cwd().hash;
|
||||
}
|
||||
}
|
||||
if (mime) {
|
||||
mime = val;
|
||||
val = '.';
|
||||
}
|
||||
if (typeSet) {
|
||||
type = typeSet.children('input:checked').val();
|
||||
}
|
||||
if (val) {
|
||||
input.trigger('focus');
|
||||
cmd.exec(val, from, mime, type).done(function() {
|
||||
result = true;
|
||||
}).fail(function() {
|
||||
abort();
|
||||
});
|
||||
|
||||
} else {
|
||||
fm.trigger('searchend');
|
||||
}
|
||||
},
|
||||
abort = function() {
|
||||
input.data('inctm') && clearTimeout(input.data('inctm'));
|
||||
input.val('').trigger('blur');
|
||||
if (result || incVal) {
|
||||
result = false;
|
||||
incVal = '';
|
||||
fm.lazy(function() {
|
||||
fm.trigger('searchend');
|
||||
});
|
||||
}
|
||||
},
|
||||
incVal = '',
|
||||
input = $('<input type="text" size="42"/>')
|
||||
.on('focus', function() {
|
||||
// close other menus
|
||||
!button.hasClass('ui-state-active') && fm.getUI().click();
|
||||
inFocus = true;
|
||||
incVal = '';
|
||||
button.addClass('ui-state-active');
|
||||
fm.trigger('uiresize');
|
||||
opts && opts.css(getMenuOffset()).slideDown(function() {
|
||||
// Care for on browser window re-active
|
||||
button.addClass('ui-state-active');
|
||||
fm.toFront(opts);
|
||||
});
|
||||
})
|
||||
.on('blur', function() {
|
||||
inFocus = false;
|
||||
if (opts) {
|
||||
if (!opts.data('infocus')) {
|
||||
opts.slideUp(function() {
|
||||
button.removeClass('ui-state-active');
|
||||
fm.trigger('uiresize');
|
||||
fm.toHide(opts);
|
||||
});
|
||||
} else {
|
||||
opts.data('infocus', false);
|
||||
}
|
||||
} else {
|
||||
button.removeClass('ui-state-active');
|
||||
}
|
||||
})
|
||||
.appendTo(button)
|
||||
// to avoid fm shortcuts on arrows
|
||||
.on('keypress', function(e) {
|
||||
e.stopPropagation();
|
||||
})
|
||||
.on('keydown', function(e) {
|
||||
e.stopPropagation();
|
||||
if (e.keyCode === $.ui.keyCode.ENTER) {
|
||||
search();
|
||||
} else if (e.keyCode === $.ui.keyCode.ESCAPE) {
|
||||
e.preventDefault();
|
||||
abort();
|
||||
}
|
||||
}),
|
||||
opts, typeSet, cwdReady, inFocus;
|
||||
|
||||
if (isopts.enable) {
|
||||
isopts.minlen = isopts.minlen || 2;
|
||||
isopts.wait = isopts.wait || 500;
|
||||
input
|
||||
.attr('title', fm.i18n('incSearchOnly'))
|
||||
.on('compositionstart', function() {
|
||||
input.data('composing', true);
|
||||
})
|
||||
.on('compositionend', function() {
|
||||
input.removeData('composing');
|
||||
input.trigger('input'); // for IE, edge
|
||||
})
|
||||
.on('input', function() {
|
||||
if (! input.data('composing')) {
|
||||
input.data('inctm') && clearTimeout(input.data('inctm'));
|
||||
input.data('inctm', setTimeout(function() {
|
||||
var val = input.val();
|
||||
if (val.length === 0 || val.length >= isopts.minlen) {
|
||||
(incVal !== val) && fm.trigger('incsearchstart', {
|
||||
query: val,
|
||||
type: typeSet? typeSet.children('input:checked').val() : 'searchName'
|
||||
});
|
||||
incVal = val;
|
||||
if (val === '' && fm.searchStatus.state > 1 && fm.searchStatus.query) {
|
||||
input.val(fm.searchStatus.query).trigger('select');
|
||||
}
|
||||
}
|
||||
}, isopts.wait));
|
||||
}
|
||||
});
|
||||
|
||||
if (fm.UA.ltIE8) {
|
||||
input.on('keydown', function(e) {
|
||||
if (e.keyCode === 229) {
|
||||
input.data('imetm') && clearTimeout(input.data('imetm'));
|
||||
input.data('composing', true);
|
||||
input.data('imetm', setTimeout(function() {
|
||||
input.removeData('composing');
|
||||
}, 100));
|
||||
}
|
||||
})
|
||||
.on('keyup', function(e) {
|
||||
input.data('imetm') && clearTimeout(input.data('imetm'));
|
||||
if (input.data('composing')) {
|
||||
e.keyCode === $.ui.keyCode.ENTER && input.trigger('compositionend');
|
||||
} else {
|
||||
input.trigger('input');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$('<span class="ui-icon ui-icon-search" title="'+cmd.title+'"></span>')
|
||||
.appendTo(button)
|
||||
.on('mousedown', function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
if (button.hasClass('ui-state-active')) {
|
||||
search();
|
||||
} else {
|
||||
input.trigger('focus');
|
||||
}
|
||||
});
|
||||
|
||||
$('<span class="ui-icon ui-icon-close"></span>')
|
||||
.appendTo(button)
|
||||
.on('mousedown', function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
if (input.val() === '' && !button.hasClass('ui-state-active')) {
|
||||
input.trigger('focus');
|
||||
} else {
|
||||
abort();
|
||||
}
|
||||
});
|
||||
|
||||
// wait when button will be added to DOM
|
||||
fm.bind('toolbarload', function(){
|
||||
var parent = button.parent();
|
||||
if (parent.length) {
|
||||
toolbar.prepend(button.show());
|
||||
parent.remove();
|
||||
// position icons for ie7
|
||||
if (fm.UA.ltIE7) {
|
||||
var icon = button.children(fm.direction == 'ltr' ? '.ui-icon-close' : '.ui-icon-search');
|
||||
icon.css({
|
||||
right : '',
|
||||
left : parseInt(button.width())-icon.outerWidth(true)
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
fm
|
||||
.one('init', function() {
|
||||
fm.getUI('cwd').on('touchstart click', function() {
|
||||
inFocus && input.trigger('blur');
|
||||
});
|
||||
})
|
||||
.one('open', function() {
|
||||
opts = (fm.api < 2.1)? null : $('<div class="ui-front ui-widget ui-widget-content elfinder-button-menu elfinder-button-search-menu ui-corner-all"></div>')
|
||||
.append(
|
||||
$('<div class="buttonset"></div>')
|
||||
.append(
|
||||
$('<input id="'+id('SearchFromCwd')+'" name="serchfrom" type="radio" checked="checked"/><label for="'+id('SearchFromCwd')+'">'+fm.i18n('btnCwd')+'</label>'),
|
||||
$('<input id="'+id('SearchFromVol')+'" name="serchfrom" type="radio"/><label for="'+id('SearchFromVol')+'">'+fm.i18n('btnVolume')+'</label>'),
|
||||
$('<input id="'+id('SearchFromAll')+'" name="serchfrom" type="radio"/><label for="'+id('SearchFromAll')+'">'+fm.i18n('btnAll')+'</label>')
|
||||
),
|
||||
$('<div class="buttonset elfinder-search-type"></div>')
|
||||
.append(
|
||||
$('<input id="'+id('SearchName')+'" name="serchcol" type="radio" checked="checked" value="SearchName"/><label for="'+id('SearchName')+'">'+fm.i18n('btnFileName')+'</label>')
|
||||
)
|
||||
)
|
||||
.hide()
|
||||
.appendTo(fm.getUI());
|
||||
if (opts) {
|
||||
if (sTypes) {
|
||||
typeSet = opts.find('.elfinder-search-type');
|
||||
$.each(cmd.options.searchTypes, function(i, v) {
|
||||
typeSet.append($('<input id="'+id(i)+'" name="serchcol" type="radio" value="'+fm.escape(i)+'"/><label for="'+id(i)+'">'+fm.i18n(v.name)+'</label>'));
|
||||
});
|
||||
}
|
||||
opts.find('div.buttonset').buttonset();
|
||||
$('#'+id('SearchFromAll')).next('label').attr('title', fm.i18n('searchTarget', fm.i18n('btnAll')));
|
||||
if (sTypes) {
|
||||
$.each(sTypes, function(i, v) {
|
||||
if (v.title) {
|
||||
$('#'+id(i)).next('label').attr('title', fm.i18n(v.title));
|
||||
}
|
||||
});
|
||||
}
|
||||
opts.on('mousedown', 'div.buttonset', function(e){
|
||||
e.stopPropagation();
|
||||
opts.data('infocus', true);
|
||||
})
|
||||
.on('click', 'input', function(e) {
|
||||
e.stopPropagation();
|
||||
$.trim(input.val())? search() : input.trigger('focus');
|
||||
})
|
||||
.on('close', function() {
|
||||
input.trigger('blur');
|
||||
});
|
||||
}
|
||||
})
|
||||
.bind('searchend', function() {
|
||||
input.val('');
|
||||
})
|
||||
.bind('open parents', function() {
|
||||
var dirs = [],
|
||||
volroot = fm.file(fm.root(fm.cwd().hash));
|
||||
|
||||
if (volroot) {
|
||||
$.each(fm.parents(fm.cwd().hash), function(i, hash) {
|
||||
dirs.push(fm.file(hash).name);
|
||||
});
|
||||
|
||||
$('#'+id('SearchFromCwd')).next('label').attr('title', fm.i18n('searchTarget', dirs.join(fm.option('separator'))));
|
||||
$('#'+id('SearchFromVol')).next('label').attr('title', fm.i18n('searchTarget', volroot.name));
|
||||
}
|
||||
})
|
||||
.bind('open', function() {
|
||||
incVal && abort();
|
||||
})
|
||||
.bind('cwdinit', function() {
|
||||
cwdReady = false;
|
||||
})
|
||||
.bind('cwdrender',function() {
|
||||
cwdReady = true;
|
||||
})
|
||||
.bind('keydownEsc', function() {
|
||||
if (incVal && incVal.substr(0, 1) === '/') {
|
||||
incVal = '';
|
||||
input.val('');
|
||||
fm.trigger('searchend');
|
||||
}
|
||||
})
|
||||
.shortcut({
|
||||
pattern : 'ctrl+f f3',
|
||||
description : cmd.title,
|
||||
callback : function() {
|
||||
input.trigger('select').trigger('focus');
|
||||
}
|
||||
})
|
||||
.shortcut({
|
||||
pattern : 'a b c d e f g h i j k l m n o p q r s t u v w x y z dig0 dig1 dig2 dig3 dig4 dig5 dig6 dig7 dig8 dig9 num0 num1 num2 num3 num4 num5 num6 num7 num8 num9',
|
||||
description : fm.i18n('firstLetterSearch'),
|
||||
callback : function(e) {
|
||||
if (! cwdReady) { return; }
|
||||
|
||||
var code = e.originalEvent.keyCode,
|
||||
next = function() {
|
||||
var sel = fm.selected(),
|
||||
key = $.ui.keyCode[(!sel.length || fm.cwdHash2Elm(sel[0]).next('[id]').length)? 'RIGHT' : 'HOME'];
|
||||
$(document).trigger($.Event('keydown', { keyCode: key, ctrlKey : false, shiftKey : false, altKey : false, metaKey : false }));
|
||||
},
|
||||
val;
|
||||
if (code >= 96 && code <= 105) {
|
||||
code -= 48;
|
||||
}
|
||||
val = '/' + String.fromCharCode(code);
|
||||
if (incVal !== val) {
|
||||
input.val(val);
|
||||
incVal = val;
|
||||
fm
|
||||
.trigger('incsearchstart', { query: val })
|
||||
.one('cwdrender', next);
|
||||
} else{
|
||||
next();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,106 @@
|
||||
/**
|
||||
* @class elFinder toolbar button menu with sort variants.
|
||||
*
|
||||
* @author Dmitry (dio) Levashov
|
||||
**/
|
||||
$.fn.elfindersortbutton = function(cmd) {
|
||||
"use strict";
|
||||
return this.each(function() {
|
||||
var fm = cmd.fm,
|
||||
name = cmd.name,
|
||||
c = 'class',
|
||||
disabled = fm.res(c, 'disabled'),
|
||||
hover = fm.res(c, 'hover'),
|
||||
item = 'elfinder-button-menu-item',
|
||||
selected = item+'-selected',
|
||||
asc = selected+'-asc',
|
||||
desc = selected+'-desc',
|
||||
text = $('<span class="elfinder-button-text">'+cmd.title+'</span>'),
|
||||
button = $(this).addClass('ui-state-default elfinder-button elfinder-menubutton elfiner-button-'+name)
|
||||
.attr('title', cmd.title)
|
||||
.append('<span class="elfinder-button-icon elfinder-button-icon-'+name+'"></span>', text)
|
||||
.on('mouseenter mouseleave', function(e) { !button.hasClass(disabled) && button.toggleClass(hover, e.type === 'mouseenter'); })
|
||||
.on('click', function(e) {
|
||||
if (!button.hasClass(disabled)) {
|
||||
e.stopPropagation();
|
||||
menu.is(':hidden') && fm.getUI().click();
|
||||
menu.css(getMenuOffset()).slideToggle({
|
||||
duration: 100,
|
||||
done: function(e) {
|
||||
fm[menu.is(':visible')? 'toFront' : 'toHide'](menu);
|
||||
}
|
||||
});
|
||||
}
|
||||
}),
|
||||
hide = function() { fm.toHide(menu); },
|
||||
menu = $('<div class="ui-front ui-widget ui-widget-content elfinder-button-menu elfinder-button-sort-menu ui-corner-all"></div>')
|
||||
.hide()
|
||||
.appendTo(fm.getUI())
|
||||
.on('mouseenter mouseleave', '.'+item, function(e) { $(this).toggleClass(hover, e.type === 'mouseenter'); })
|
||||
.on('click', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
})
|
||||
.on('close', hide),
|
||||
update = function() {
|
||||
menu.children('[rel]').removeClass(selected+' '+asc+' '+desc)
|
||||
.filter('[rel="'+fm.sortType+'"]')
|
||||
.addClass(selected+' '+(fm.sortOrder == 'asc' ? asc : desc));
|
||||
|
||||
menu.children('.elfinder-sort-stick').toggleClass(selected, fm.sortStickFolders);
|
||||
menu.children('.elfinder-sort-tree').toggleClass(selected, fm.sortAlsoTreeview);
|
||||
},
|
||||
getMenuOffset = function() {
|
||||
var baseOffset = fm.getUI().offset(),
|
||||
buttonOffset = button.offset();
|
||||
return {
|
||||
top : buttonOffset.top - baseOffset.top,
|
||||
left : buttonOffset.left - baseOffset.left
|
||||
};
|
||||
},
|
||||
tm;
|
||||
|
||||
text.hide();
|
||||
|
||||
$.each(fm.sortRules, function(name, value) {
|
||||
menu.append($('<div class="'+item+'" rel="'+name+'"><span class="ui-icon ui-icon-arrowthick-1-n"></span><span class="ui-icon ui-icon-arrowthick-1-s"></span>'+fm.i18n('sort'+name)+'</div>').data('type', name));
|
||||
});
|
||||
|
||||
menu.children().on('click', function(e) {
|
||||
cmd.exec([], $(this).removeClass(hover).attr('rel'));
|
||||
});
|
||||
|
||||
$('<div class="'+item+' '+item+'-separated elfinder-sort-ext elfinder-sort-stick"><span class="ui-icon ui-icon-check"></span>'+fm.i18n('sortFoldersFirst')+'</div>')
|
||||
.appendTo(menu)
|
||||
.on('click', function() {
|
||||
cmd.exec([], 'stick');
|
||||
});
|
||||
|
||||
fm.one('init', function() {
|
||||
if (fm.ui.tree && fm.options.sortAlsoTreeview !== null) {
|
||||
$('<div class="'+item+' '+item+'-separated elfinder-sort-ext elfinder-sort-tree"><span class="ui-icon ui-icon-check"></span>'+fm.i18n('sortAlsoTreeview')+'</div>')
|
||||
.appendTo(menu)
|
||||
.on('click', function() {
|
||||
cmd.exec([], 'tree');
|
||||
});
|
||||
}
|
||||
})
|
||||
.bind('disable select', hide)
|
||||
.bind('sortchange', update).getUI().on('click', hide);
|
||||
|
||||
if (menu.children().length > 1) {
|
||||
cmd.change(function() {
|
||||
tm && cancelAnimationFrame(tm);
|
||||
tm = requestAnimationFrame(function() {
|
||||
button.toggleClass(disabled, cmd.disabled());
|
||||
update();
|
||||
});
|
||||
})
|
||||
.change();
|
||||
} else {
|
||||
button.addClass(disabled);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
@@ -0,0 +1,119 @@
|
||||
/**
|
||||
* @class elFinder ui
|
||||
* Display number of files/selected files and its size in statusbar
|
||||
*
|
||||
* @author Dmitry (dio) Levashov
|
||||
**/
|
||||
$.fn.elfinderstat = function(fm) {
|
||||
"use strict";
|
||||
return this.each(function() {
|
||||
var size = $(this).addClass('elfinder-stat-size'),
|
||||
sel = $('<div class="elfinder-stat-selected"></div>')
|
||||
.on('click', 'a', function(e) {
|
||||
var hash = $(this).data('hash');
|
||||
e.preventDefault();
|
||||
fm.exec('opendir', [ hash ]);
|
||||
}),
|
||||
titleitems = fm.i18n('items'),
|
||||
titlesel = fm.i18n('selected'),
|
||||
titlesize = fm.i18n('size'),
|
||||
setstat = function(files) {
|
||||
var c = 0,
|
||||
s = 0,
|
||||
cwd = fm.cwd(),
|
||||
calc = true,
|
||||
hasSize = true;
|
||||
|
||||
if (cwd.sizeInfo || cwd.size) {
|
||||
s = cwd.size;
|
||||
calc = false;
|
||||
}
|
||||
$.each(files, function(i, file) {
|
||||
c++;
|
||||
if (calc) {
|
||||
s += parseInt(file.size) || 0;
|
||||
if (hasSize === true && file.mime === 'directory' && !file.sizeInfo) {
|
||||
hasSize = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
size.html(titleitems+': <span class="elfinder-stat-incsearch"></span>'+c+', <span class="elfinder-stat-size'+(hasSize? ' elfinder-stat-size-recursive' : '')+'">'+fm.i18n(hasSize? 'sum' : 'size')+': '+fm.formatSize(s)+'</span>')
|
||||
.attr('title', size.text());
|
||||
fm.trigger('uistatchange');
|
||||
},
|
||||
setIncsearchStat = function(data) {
|
||||
size.find('span.elfinder-stat-incsearch').html(data? data.hashes.length + ' / ' : '');
|
||||
size.attr('title', size.text());
|
||||
fm.trigger('uistatchange');
|
||||
},
|
||||
setSelect = function(files) {
|
||||
var s = 0,
|
||||
c = 0,
|
||||
dirs = [],
|
||||
path, file;
|
||||
|
||||
if (files.length === 1) {
|
||||
file = files[0];
|
||||
s = file.size;
|
||||
if (fm.searchStatus.state === 2) {
|
||||
path = fm.escape(file.path? file.path.replace(/\/[^\/]*$/, '') : '..');
|
||||
dirs.push('<a href="#elf_'+file.phash+'" data-hash="'+file.hash+'" title="'+path+'">'+path+'</a>');
|
||||
}
|
||||
dirs.push(fm.escape(file.i18 || file.name));
|
||||
sel.html(dirs.join('/') + (s > 0 ? ', '+fm.formatSize(s) : ''));
|
||||
} else if (files.length) {
|
||||
$.each(files, function(i, file) {
|
||||
c++;
|
||||
s += parseInt(file.size)||0;
|
||||
});
|
||||
sel.html(c ? titlesel+': '+c+', '+titlesize+': '+fm.formatSize(s) : ' ');
|
||||
} else {
|
||||
sel.html('');
|
||||
}
|
||||
sel.attr('title', sel.text());
|
||||
fm.trigger('uistatchange');
|
||||
};
|
||||
|
||||
fm.getUI('statusbar').prepend(size).append(sel).show();
|
||||
if (fm.UA.Mobile && $.fn.tooltip) {
|
||||
fm.getUI('statusbar').tooltip({
|
||||
classes: {
|
||||
'ui-tooltip': 'elfinder-ui-tooltip ui-widget-shadow'
|
||||
},
|
||||
tooltipClass: 'elfinder-ui-tooltip ui-widget-shadow',
|
||||
track: true
|
||||
});
|
||||
}
|
||||
|
||||
fm
|
||||
.bind('cwdhasheschange', function(e) {
|
||||
setstat($.map(e.data, function(h) { return fm.file(h); }));
|
||||
})
|
||||
.change(function(e) {
|
||||
var files = e.data.changed || [],
|
||||
cwdHash = fm.cwd().hash;
|
||||
$.each(files, function() {
|
||||
if (this.hash === cwdHash) {
|
||||
if (this.size) {
|
||||
size.children('.elfinder-stat-size').addClass('elfinder-stat-size-recursive').html(fm.i18n('sum')+': '+fm.formatSize(this.size));
|
||||
size.attr('title', size.text());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
})
|
||||
.select(function() {
|
||||
setSelect(fm.selectedFiles());
|
||||
})
|
||||
.bind('open', function() {
|
||||
setSelect([]);
|
||||
})
|
||||
.bind('incsearch', function(e) {
|
||||
setIncsearchStat(e.data);
|
||||
})
|
||||
.bind('incsearchend', function() {
|
||||
setIncsearchStat();
|
||||
})
|
||||
;
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
* @class elFinder toast
|
||||
*
|
||||
* This was created inspired by the toastr. Thanks to developers of toastr.
|
||||
* CodeSeven/toastr: http://johnpapa.net <https://github.com/CodeSeven/toastr>
|
||||
*
|
||||
* @author Naoki Sawada
|
||||
**/
|
||||
$.fn.elfindertoast = function(opts, fm) {
|
||||
"use strict";
|
||||
var defOpts = Object.assign({
|
||||
mode: 'success', // or 'info', 'warning' and 'error'
|
||||
msg: '',
|
||||
showMethod: 'fadeIn', //fadeIn, slideDown, and show are built into jQuery
|
||||
showDuration: 300,
|
||||
showEasing: 'swing', //swing and linear are built into jQuery
|
||||
onShown: undefined,
|
||||
hideMethod: 'fadeOut',
|
||||
hideDuration: 1500,
|
||||
hideEasing: 'swing',
|
||||
onHidden: undefined,
|
||||
timeOut: 3000,
|
||||
extNode: undefined,
|
||||
button: undefined,
|
||||
width: undefined
|
||||
}, $.isPlainObject(fm.options.uiOptions.toast.defaults)? fm.options.uiOptions.toast.defaults : {});
|
||||
return this.each(function() {
|
||||
opts = Object.assign({}, defOpts, opts || {});
|
||||
|
||||
var self = $(this),
|
||||
show = function(notm) {
|
||||
self.stop();
|
||||
fm.toFront(self);
|
||||
self[opts.showMethod]({
|
||||
duration: opts.showDuration,
|
||||
easing: opts.showEasing,
|
||||
complete: function() {
|
||||
opts.onShown && opts.onShown();
|
||||
if (!notm && opts.timeOut) {
|
||||
rmTm = setTimeout(rm, opts.timeOut);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
rm = function() {
|
||||
self[opts.hideMethod]({
|
||||
duration: opts.hideDuration,
|
||||
easing: opts.hideEasing,
|
||||
complete: function() {
|
||||
opts.onHidden && opts.onHidden();
|
||||
self.remove();
|
||||
}
|
||||
});
|
||||
},
|
||||
rmTm;
|
||||
|
||||
self.on('click', function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
rmTm && clearTimeout(rmTm);
|
||||
opts.onHidden && opts.onHidden();
|
||||
self.stop().remove();
|
||||
}).on('mouseenter mouseleave', function(e) {
|
||||
if (opts.timeOut) {
|
||||
rmTm && clearTimeout(rmTm);
|
||||
rmTm = null;
|
||||
if (e.type === 'mouseenter') {
|
||||
show(true);
|
||||
} else {
|
||||
rmTm = setTimeout(rm, opts.timeOut);
|
||||
}
|
||||
}
|
||||
}).hide().addClass('toast-' + opts.mode).append($('<div class="elfinder-toast-msg"></div>').html(opts.msg.replace(/%([a-zA-Z0-9]+)%/g, function(m, m1) {
|
||||
return fm.i18n(m1);
|
||||
})));
|
||||
|
||||
if (opts.extNode) {
|
||||
self.append(opts.extNode);
|
||||
}
|
||||
|
||||
if (opts.button) {
|
||||
self.append(
|
||||
$('<button class="ui-button ui-widget ui-state-default ui-corner-all elfinder-tabstop"></button>')
|
||||
.append($('<span class="ui-button-text"></span>').text(fm.i18n(opts.button.text)))
|
||||
.on('mouseenter mouseleave', function(e) {
|
||||
$(this).toggleClass('ui-state-hover', e.type == 'mouseenter');
|
||||
})
|
||||
.on('click', opts.button.click || function(){})
|
||||
);
|
||||
}
|
||||
|
||||
if (opts.width) {
|
||||
self.css('max-width', opts.width);
|
||||
}
|
||||
|
||||
show();
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,320 @@
|
||||
/**
|
||||
* @class elFinder toolbar
|
||||
*
|
||||
* @author Dmitry (dio) Levashov
|
||||
**/
|
||||
$.fn.elfindertoolbar = function(fm, opts) {
|
||||
"use strict";
|
||||
this.not('.elfinder-toolbar').each(function() {
|
||||
var commands = fm._commands,
|
||||
self = $(this).addClass('ui-helper-clearfix ui-widget-header elfinder-toolbar'),
|
||||
options = {
|
||||
// default options
|
||||
displayTextLabel: false,
|
||||
labelExcludeUA: ['Mobile'],
|
||||
autoHideUA: ['Mobile'],
|
||||
showPreferenceButton: 'none'
|
||||
},
|
||||
filter = function(opts) {
|
||||
return $.grep(opts, function(v) {
|
||||
if ($.isPlainObject(v)) {
|
||||
options = Object.assign(options, v);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
render = function(disabled){
|
||||
var name,cmdPref;
|
||||
|
||||
$.each(buttons, function(i, b) { b.detach(); });
|
||||
self.empty();
|
||||
l = panels.length;
|
||||
while (l--) {
|
||||
if (panels[l]) {
|
||||
panel = $('<div class="ui-widget-content ui-corner-all elfinder-buttonset"></div>');
|
||||
i = panels[l].length;
|
||||
while (i--) {
|
||||
name = panels[l][i];
|
||||
if ((!disabled || !disabled[name]) && (cmd = commands[name])) {
|
||||
button = 'elfinder'+cmd.options.ui;
|
||||
if (! buttons[name] && $.fn[button]) {
|
||||
buttons[name] = $('<div></div>')[button](cmd);
|
||||
}
|
||||
if (buttons[name]) {
|
||||
buttons[name].children('.elfinder-button-text')[textLabel? 'show' : 'hide']();
|
||||
panel.prepend(buttons[name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
panel.children().length && self.prepend(panel);
|
||||
panel.children(':gt(0)').before('<span class="ui-widget-content elfinder-toolbar-button-separator"></span>');
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (cmdPref = commands['preference']) {
|
||||
//cmdPref.state = !self.children().length? 0 : -1;
|
||||
if (options.showPreferenceButton === 'always' || (!self.children().length && options.showPreferenceButton === 'auto')) {
|
||||
//cmdPref.state = 0;
|
||||
panel = $('<div class="ui-widget-content ui-corner-all elfinder-buttonset"></div>');
|
||||
name = 'preference';
|
||||
button = 'elfinder'+cmd.options.ui;
|
||||
buttons[name] = $('<div></div>')[button](cmdPref);
|
||||
buttons[name].children('.elfinder-button-text')[textLabel? 'show' : 'hide']();
|
||||
panel.prepend(buttons[name]);
|
||||
self.append(panel);
|
||||
}
|
||||
}
|
||||
|
||||
(! self.data('swipeClose') && self.children().length)? self.show() : self.hide();
|
||||
prevHeight = self[0].clientHeight;
|
||||
fm.trigger('toolbarload').trigger('uiresize');
|
||||
},
|
||||
buttons = {},
|
||||
panels = filter(opts || []),
|
||||
dispre = null,
|
||||
uiCmdMapPrev = '',
|
||||
prevHeight = 0,
|
||||
contextRaw = [],
|
||||
l, i, cmd, panel, button, swipeHandle, autoHide, textLabel, resizeTm;
|
||||
|
||||
// normalize options
|
||||
options.showPreferenceButton = options.showPreferenceButton.toLowerCase();
|
||||
|
||||
if (options.displayTextLabel !== 'none') {
|
||||
// correction of options.displayTextLabel
|
||||
textLabel = fm.storage('toolbarTextLabel');
|
||||
if (textLabel === null) {
|
||||
textLabel = (options.displayTextLabel && (! options.labelExcludeUA || ! options.labelExcludeUA.length || ! $.grep(options.labelExcludeUA, function(v){ return fm.UA[v]? true : false; }).length));
|
||||
} else {
|
||||
textLabel = (textLabel == 1);
|
||||
}
|
||||
contextRaw.push({
|
||||
label : fm.i18n('textLabel'),
|
||||
icon : 'text',
|
||||
callback : function() {
|
||||
textLabel = ! textLabel;
|
||||
self.css('height', '').find('.elfinder-button-text')[textLabel? 'show':'hide']();
|
||||
fm.trigger('uiresize').storage('toolbarTextLabel', textLabel? '1' : '0');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (options.preferenceInContextmenu && commands['preference']) {
|
||||
contextRaw.push({
|
||||
label : fm.i18n('toolbarPref'),
|
||||
icon : 'preference',
|
||||
callback : function() {
|
||||
fm.exec('preference', void(0), {tab: 'toolbar'});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// add contextmenu
|
||||
if (contextRaw.length) {
|
||||
self.on('contextmenu', function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
fm.trigger('contextmenu', {
|
||||
raw: contextRaw,
|
||||
x: e.pageX,
|
||||
y: e.pageY
|
||||
});
|
||||
}).on('touchstart', function(e) {
|
||||
if (e.originalEvent.touches.length > 1) {
|
||||
return;
|
||||
}
|
||||
self.data('tmlongtap') && clearTimeout(self.data('tmlongtap'));
|
||||
self.removeData('longtap')
|
||||
.data('longtap', {x: e.originalEvent.touches[0].pageX, y: e.originalEvent.touches[0].pageY})
|
||||
.data('tmlongtap', setTimeout(function() {
|
||||
self.removeData('longtapTm')
|
||||
.trigger({
|
||||
type: 'contextmenu',
|
||||
pageX: self.data('longtap').x,
|
||||
pageY: self.data('longtap').y
|
||||
})
|
||||
.data('longtap', {longtap: true});
|
||||
}, 500));
|
||||
}).on('touchmove touchend', function(e) {
|
||||
if (self.data('tmlongtap')) {
|
||||
if (e.type === 'touchend' ||
|
||||
( Math.abs(self.data('longtap').x - e.originalEvent.touches[0].pageX)
|
||||
+ Math.abs(self.data('longtap').y - e.originalEvent.touches[0].pageY)) > 4)
|
||||
clearTimeout(self.data('tmlongtap'));
|
||||
self.removeData('longtapTm');
|
||||
}
|
||||
}).on('click', function(e) {
|
||||
if (self.data('longtap') && self.data('longtap').longtap) {
|
||||
e.stopImmediatePropagation();
|
||||
e.preventDefault();
|
||||
}
|
||||
}).on('touchend click', '.elfinder-button', function(e) {
|
||||
if (self.data('longtap') && self.data('longtap').longtap) {
|
||||
e.stopImmediatePropagation();
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
self.prev().length && self.parent().prepend(this);
|
||||
|
||||
render();
|
||||
|
||||
fm.bind('open sync select toolbarpref', function() {
|
||||
var disabled = Object.assign({}, fm.option('disabledFlip')),
|
||||
userHides = fm.storage('toolbarhides'),
|
||||
doRender, sel, disabledKeys;
|
||||
|
||||
if (! userHides && Array.isArray(options.defaultHides)) {
|
||||
userHides = {};
|
||||
$.each(options.defaultHides, function() {
|
||||
userHides[this] = true;
|
||||
});
|
||||
fm.storage('toolbarhides', userHides);
|
||||
}
|
||||
if (this.type === 'select') {
|
||||
if (fm.searchStatus.state < 2) {
|
||||
return;
|
||||
}
|
||||
sel = fm.selected();
|
||||
if (sel.length) {
|
||||
disabled = fm.getDisabledCmds(sel, true);
|
||||
}
|
||||
}
|
||||
|
||||
$.each(userHides, function(n) {
|
||||
if (!disabled[n]) {
|
||||
disabled[n] = true;
|
||||
}
|
||||
});
|
||||
|
||||
if (Object.keys(fm.commandMap).length) {
|
||||
$.each(fm.commandMap, function(from, to){
|
||||
if (to === 'hidden') {
|
||||
disabled[from] = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
disabledKeys = Object.keys(disabled);
|
||||
if (!dispre || dispre.toString() !== disabledKeys.sort().toString()) {
|
||||
render(disabledKeys.length? disabled : null);
|
||||
doRender = true;
|
||||
}
|
||||
dispre = disabledKeys.sort();
|
||||
|
||||
if (doRender || uiCmdMapPrev !== JSON.stringify(fm.commandMap)) {
|
||||
uiCmdMapPrev = JSON.stringify(fm.commandMap);
|
||||
if (! doRender) {
|
||||
// reset toolbar
|
||||
$.each($('div.elfinder-button'), function(){
|
||||
var origin = $(this).data('origin');
|
||||
if (origin) {
|
||||
$(this).after(origin).detach();
|
||||
}
|
||||
});
|
||||
}
|
||||
if (Object.keys(fm.commandMap).length) {
|
||||
$.each(fm.commandMap, function(from, to){
|
||||
var cmd = fm._commands[to],
|
||||
button = cmd? 'elfinder'+cmd.options.ui : null,
|
||||
btn;
|
||||
if (button && $.fn[button]) {
|
||||
btn = buttons[from];
|
||||
if (btn) {
|
||||
if (! buttons[to] && $.fn[button]) {
|
||||
buttons[to] = $('<div></div>')[button](cmd);
|
||||
if (buttons[to]) {
|
||||
buttons[to].children('.elfinder-button-text')[textLabel? 'show' : 'hide']();
|
||||
if (cmd.extendsCmd) {
|
||||
buttons[to].children('span.elfinder-button-icon').addClass('elfinder-button-icon-' + cmd.extendsCmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (buttons[to]) {
|
||||
btn.after(buttons[to]);
|
||||
buttons[to].data('origin', btn.detach());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}).bind('resize', function(e) {
|
||||
resizeTm && cancelAnimationFrame(resizeTm);
|
||||
resizeTm = requestAnimationFrame(function() {
|
||||
var h = self[0].clientHeight;
|
||||
if (prevHeight !== h) {
|
||||
prevHeight = h;
|
||||
fm.trigger('uiresize');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if (fm.UA.Touch) {
|
||||
autoHide = fm.storage('autoHide') || {};
|
||||
if (typeof autoHide.toolbar === 'undefined') {
|
||||
autoHide.toolbar = (options.autoHideUA && options.autoHideUA.length > 0 && $.grep(options.autoHideUA, function(v){ return fm.UA[v]? true : false; }).length);
|
||||
fm.storage('autoHide', autoHide);
|
||||
}
|
||||
|
||||
if (autoHide.toolbar) {
|
||||
fm.one('init', function() {
|
||||
fm.uiAutoHide.push(function(){ self.stop(true, true).trigger('toggle', { duration: 500, init: true }); });
|
||||
});
|
||||
}
|
||||
|
||||
fm.bind('load', function() {
|
||||
swipeHandle = $('<div class="elfinder-toolbar-swipe-handle"></div>').hide().appendTo(fm.getUI());
|
||||
if (swipeHandle.css('pointer-events') !== 'none') {
|
||||
swipeHandle.remove();
|
||||
swipeHandle = null;
|
||||
}
|
||||
});
|
||||
|
||||
self.on('toggle', function(e, data) {
|
||||
var wz = fm.getUI('workzone'),
|
||||
toshow= self.is(':hidden'),
|
||||
wzh = wz.height(),
|
||||
h = self.height(),
|
||||
tbh = self.outerHeight(true),
|
||||
delta = tbh - h,
|
||||
opt = Object.assign({
|
||||
step: function(now) {
|
||||
wz.height(wzh + (toshow? (now + delta) * -1 : h - now));
|
||||
fm.trigger('resize');
|
||||
},
|
||||
always: function() {
|
||||
requestAnimationFrame(function() {
|
||||
self.css('height', '');
|
||||
fm.trigger('uiresize');
|
||||
if (swipeHandle) {
|
||||
if (toshow) {
|
||||
swipeHandle.stop(true, true).hide();
|
||||
} else {
|
||||
swipeHandle.height(data.handleH? data.handleH : '');
|
||||
fm.resources.blink(swipeHandle, 'slowonce');
|
||||
}
|
||||
}
|
||||
toshow && self.scrollTop('0px');
|
||||
data.init && fm.trigger('uiautohide');
|
||||
});
|
||||
}
|
||||
}, data);
|
||||
self.data('swipeClose', ! toshow).stop(true, true).animate({height : 'toggle'}, opt);
|
||||
autoHide.toolbar = !toshow;
|
||||
fm.storage('autoHide', Object.assign(fm.storage('autoHide'), {toolbar: autoHide.toolbar}));
|
||||
}).on('touchstart', function(e) {
|
||||
if (self.scrollBottom() > 5) {
|
||||
e.originalEvent._preventSwipeY = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* @class elFinder toolbar's button tor upload file
|
||||
*
|
||||
* @author Dmitry (dio) Levashov
|
||||
**/
|
||||
$.fn.elfinderuploadbutton = function(cmd) {
|
||||
"use strict";
|
||||
return this.each(function() {
|
||||
var fm = cmd.fm,
|
||||
button = $(this).elfinderbutton(cmd)
|
||||
.off('click'),
|
||||
form = $('<form></form>').appendTo(button),
|
||||
input = $('<input type="file" multiple="true" title="'+cmd.fm.i18n('selectForUpload')+'"/>')
|
||||
.on('change', function() {
|
||||
var _input = $(this);
|
||||
if (_input.val()) {
|
||||
fm.exec('upload', {input : _input.remove()[0]}, void(0), fm.cwd().hash);
|
||||
input.clone(true).appendTo(form);
|
||||
}
|
||||
})
|
||||
.on('dragover', function(e) {
|
||||
e.originalEvent.dataTransfer.dropEffect = 'copy';
|
||||
}),
|
||||
tm;
|
||||
|
||||
form.append(input.clone(true));
|
||||
|
||||
cmd.change(function() {
|
||||
tm && cancelAnimationFrame(tm);
|
||||
tm = requestAnimationFrame(function() {
|
||||
var toShow = cmd.disabled();
|
||||
if (form.is('visible')) {
|
||||
!toShow && form.hide();
|
||||
} else {
|
||||
toShow && form.show();
|
||||
}
|
||||
});
|
||||
})
|
||||
.change();
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* @class elFinder toolbar button to switch current directory view.
|
||||
*
|
||||
* @author Dmitry (dio) Levashov
|
||||
**/
|
||||
$.fn.elfinderviewbutton = function(cmd) {
|
||||
"use strict";
|
||||
return this.each(function() {
|
||||
var button = $(this).elfinderbutton(cmd),
|
||||
icon = button.children('.elfinder-button-icon'),
|
||||
text = button.children('.elfinder-button-text'),
|
||||
tm;
|
||||
|
||||
cmd.change(function() {
|
||||
tm && cancelAnimationFrame(tm);
|
||||
tm = requestAnimationFrame(function() {
|
||||
var icons = cmd.value == 'icons';
|
||||
|
||||
icon.toggleClass('elfinder-button-icon-view-list', icons);
|
||||
cmd.className = icons? 'view-list' : '';
|
||||
cmd.title = cmd.fm.i18n(icons ? 'viewlist' : 'viewicons');
|
||||
button.attr('title', cmd.title);
|
||||
text.html(cmd.title);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* @class elfinderworkzone - elFinder container for nav and current directory
|
||||
* @author Dmitry (dio) Levashov
|
||||
**/
|
||||
$.fn.elfinderworkzone = function(fm) {
|
||||
"use strict";
|
||||
var cl = 'elfinder-workzone';
|
||||
|
||||
this.not('.'+cl).each(function() {
|
||||
var wz = $(this).addClass(cl),
|
||||
prevH = Math.round(wz.height()),
|
||||
parent = wz.parent(),
|
||||
setDelta = function() {
|
||||
wdelta = wz.outerHeight(true) - wz.height();
|
||||
},
|
||||
fitsize = function(e) {
|
||||
var height = parent.height() - wdelta,
|
||||
style = parent.attr('style'),
|
||||
curH = Math.round(wz.height());
|
||||
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
parent.css('overflow', 'hidden')
|
||||
.children(':visible:not(.'+cl+')').each(function() {
|
||||
var ch = $(this);
|
||||
|
||||
if (ch.css('position') != 'absolute' && ch.css('position') != 'fixed') {
|
||||
height -= ch.outerHeight(true);
|
||||
}
|
||||
});
|
||||
parent.attr('style', style || '');
|
||||
|
||||
height = Math.max(0, Math.round(height));
|
||||
if (prevH !== height || curH !== height) {
|
||||
prevH = Math.round(wz.height());
|
||||
wz.height(height);
|
||||
fm.trigger('wzresize');
|
||||
}
|
||||
},
|
||||
cssloaded = function() {
|
||||
wdelta = wz.outerHeight(true) - wz.height();
|
||||
fitsize();
|
||||
},
|
||||
wdelta;
|
||||
|
||||
setDelta();
|
||||
parent.on('resize.' + fm.namespace, fitsize);
|
||||
fm.one('cssloaded', cssloaded)
|
||||
.bind('uiresize', fitsize)
|
||||
.bind('themechange', setDelta);
|
||||
});
|
||||
return this;
|
||||
};
|
||||
Reference in New Issue
Block a user