ProShell v2.0
Dashboard
Server Info
Server: 158.106.128.192
PHP: 8.2.33
home
planet5
public_html
bansibaba.com
wp-includes
2026-09-16 20:02:12
Editing: tree.js
Cancel
Save Changes
/** * @class elFinder folders tree * * @author Dmitry (dio) Levashov **/ jQuery.fn.elfindertree = function(fm, opts) { "use strict"; var treeclass = fm.res('class', 'tree'); this.not('.'+treeclass).each(function() { var c = 'class', mobile = fm.UA.Mobile, /** * Root directory class name * * @type String */ root = fm.res(c, 'treeroot'), /** * Open root dir if not opened yet * * @type Boolean */ openRoot = opts.openRootOnLoad, /** * Open current work dir if not opened yet * * @type Boolean */ openCwd = opts.openCwdOnOpen, /** * Auto loading current directory parents and do expand their node * * @type Boolean */ syncTree = openCwd || opts.syncTree, /** * Subtree class name * * @type String */ subtree = fm.res(c, 'navsubtree'), /** * Directory class name * * @type String */ navdir = fm.res(c, 'treedir'), /** * Directory CSS selector * * @type String */ selNavdir = 'span.' + navdir, /** * Collapsed arrow class name * * @type String */ collapsed = fm.res(c, 'navcollapse'), /** * Expanded arrow class name * * @type String */ expanded = fm.res(c, 'navexpand'), /** * Class name to mark arrow for directory with already loaded children * * @type String */ loaded = 'elfinder-subtree-loaded', /** * Class name to mark need subdirs request * * @type String */ chksubdir = 'elfinder-subtree-chksubdir', /** * Arraw class name * * @type String */ arrow = fm.res(c, 'navarrow'), /** * Current directory class name * * @type String */ active = fm.res(c, 'active'), /** * Droppable dirs dropover class * * @type String */ dropover = fm.res(c, 'adroppable'), /** * Hover class name * * @type String */ hover = fm.res(c, 'hover'), /** * Disabled dir class name * * @type String */ disabled = fm.res(c, 'disabled'), /** * Draggable dir class name * * @type String */ draggable = fm.res(c, 'draggable'), /** * Droppable dir class name * * @type String */ droppable = fm.res(c, 'droppable'), /** * root wrapper class * * @type String */ wrapperRoot = 'elfinder-navbar-wrapper-root', /** * Un-disabled cmd `paste` volume's root wrapper class * * @type String */ pastable = 'elfinder-navbar-wrapper-pastable', /** * Un-disabled cmd `upload` volume's root wrapper class * * @type String */ uploadable = 'elfinder-navbar-wrapper-uploadable', /** * Is position x inside Navbar * * @param x Numbar * * @return */ insideNavbar = function(x) { var left = navbar.offset().left; return left <= x && x <= left + navbar.width(); }, /** * To call subdirs elements queue * * @type Object */ subdirsQue = {}, /** * To exec subdirs elements ids * */ subdirsExecQue = [], /** * Request subdirs to backend * * @param id String * * @return Deferred */ subdirs = function(ids) { var targets = []; jQuery.each(ids, function(i, id) { subdirsQue[id] && targets.push(fm.navId2Hash(id)); delete subdirsQue[id]; }); if (targets.length) { return fm.request({ data: { cmd: 'subdirs', targets: targets, preventDefault : true } }).done(function(res) { if (res && res.subdirs) { jQuery.each(res.subdirs, function(hash, subdirs) { var elm = fm.navHash2Elm(hash); elm.removeClass(chksubdir); elm[subdirs? 'addClass' : 'removeClass'](collapsed); }); } }); } }, subdirsJobRes = null, /** * To check target element is in window of subdirs * * @return void */ checkSubdirs = function() { var ids = Object.keys(subdirsQue); if (ids.length) { subdirsJobRes && subdirsJobRes._abort(); execSubdirsTm && clearTimeout(execSubdirsTm); subdirsExecQue = []; subdirsJobRes = fm.asyncJob(function(id) { return fm.isInWindow(jQuery('#'+id))? id : null; }, ids, { numPerOnce: 200 }) .done(function(arr) { if (arr.length) { subdirsExecQue = arr; execSubdirs(); } }); } }, subdirsPending = 0, execSubdirsTm, /** * Exec subdirs as batch request * * @return void */ execSubdirs = function() { var cnt = opts.subdirsMaxConn - subdirsPending, atOnce = fm.maxTargets? Math.min(fm.maxTargets, opts.subdirsAtOnce) : opts.subdirsAtOnce, i, ids; execSubdirsTm && cancelAnimationFrame(execSubdirsTm); if (subdirsExecQue.length) { if (cnt > 0) { for (i = 0; i < cnt; i++) { if (subdirsExecQue.length) { subdirsPending++; subdirs(subdirsExecQue.splice(0, atOnce)).always(function() { subdirsPending--; execSubdirs(); }); } } } else { execSubdirsTm = requestAnimationFrame(function() { subdirsExecQue.length && execSubdirs(); }); } } }, drop = fm.droppable.drop, /** * Droppable options * * @type Object */ droppableopts = jQuery.extend(true, {}, fm.droppable, { // show subfolders on dropover over : function(e, ui) { var dst = jQuery(this), helper = ui.helper, cl = hover+' '+dropover, hash, status; e.stopPropagation(); helper.data('dropover', helper.data('dropover') + 1); dst.data('dropover', true); if (ui.helper.data('namespace') !== fm.namespace || ! fm.insideWorkzone(e.pageX, e.pageY)) { dst.removeClass(cl); helper.removeClass('elfinder-drag-helper-move elfinder-drag-helper-plus'); return; } if (! insideNavbar(e.clientX)) { dst.removeClass(cl); return; } helper.removeClass('elfinder-drag-helper-move elfinder-drag-helper-plus'); dst.addClass(hover); if (dst.is('.'+collapsed+':not(.'+expanded+')')) { dst.data('expandTimer', setTimeout(function() { dst.is('.'+collapsed+'.'+hover) && dst.children('.'+arrow).trigger('click'); }, 500)); } if (dst.is('.elfinder-ro,.elfinder-na')) { dst.removeClass(dropover); //helper.removeClass('elfinder-drag-helper-move elfinder-drag-helper-plus'); return; } hash = fm.navId2Hash(dst.attr('id')); dst.data('dropover', hash); jQuery.each(ui.helper.data('files'), function(i, h) { if (h === hash || (fm.file(h).phash === hash && !ui.helper.hasClass('elfinder-drag-helper-plus'))) { dst.removeClass(cl); return false; // break jQuery.each } }); if (helper.data('locked')) { status = 'elfinder-drag-helper-plus'; } else { status = 'elfinder-drag-helper-move'; if (fm._commands.copy && (e.shiftKey || e.ctrlKey || e.metaKey)) { status += ' elfinder-drag-helper-plus'; } } dst.hasClass(dropover) && helper.addClass(status); requestAnimationFrame(function(){ dst.hasClass(dropover) && helper.addClass(status); }); }, out : function(e, ui) { var dst = jQuery(this), helper = ui.helper; e.stopPropagation(); if (insideNavbar(e.clientX)) { helper.removeClass('elfinder-drag-helper-move elfinder-drag-helper-plus'); } helper.data('dropover', Math.max(helper.data('dropover') - 1, 0)); dst.data('expandTimer') && clearTimeout(dst.data('expandTimer')); dst.removeData('dropover') .removeClass(hover+' '+dropover); }, deactivate : function() { jQuery(this).removeData('dropover') .removeClass(hover+' '+dropover); }, drop : function(e, ui) { insideNavbar(e.clientX) && drop.call(this, e, ui); } }), spinner = jQuery(fm.res('tpl', 'navspinner')), /** * Directory html template * * @type String */ tpl = fm.res('tpl', 'navdir'), /** * Permissions marker html template * * @type String */ ptpl = fm.res('tpl', 'perms'), /** * Lock marker html template * * @type String */ ltpl = fm.res('tpl', 'lock'), /** * Symlink marker html template * * @type String */ stpl = fm.res('tpl', 'symlink'), /** * Directory hashes that has more pages * * @type Object */ hasMoreDirs = {}, /** * Html template replacement methods * * @type Object */ replace = { id : function(dir) { return fm.navHash2Id(dir.hash); }, name : function(dir) { return fm.escape(dir.i18 || dir.name); }, cssclass : function(dir) { var cname = (dir.phash && ! dir.isroot ? '' : root)+' '+navdir+' '+fm.perms2class(dir); dir.dirs && !dir.link && (cname += ' ' + collapsed) && dir.dirs == -1 && (cname += ' ' + chksubdir); opts.getClass && (cname += ' ' + opts.getClass(dir)); dir.csscls && (cname += ' ' + fm.escape(dir.csscls)); return cname; }, title : function(dir) { return opts.attrTitle? (' title="' + fm.escape(fm.path(dir.hash, true) || dir.i18 || dir.name) + '"') : ''; }, root : function(dir) { var cls = ''; if (!dir.phash || dir.isroot) { cls += ' '+wrapperRoot; if (!dir.disabled || dir.disabled.length < 1) { cls += ' '+pastable+' '+uploadable; } else { if (jQuery.inArray('paste', dir.disabled) === -1) { cls += ' '+pastable; } if (jQuery.inArray('upload', dir.disabled) === -1) { cls += ' '+uploadable; } } return cls; } else { return ''; } }, permissions : function(dir) { return !dir.read || !dir.write ? ptpl : ''; }, symlink : function(dir) { return dir.alias ? stpl : ''; }, style : function(dir) { return dir.icon ? fm.getIconStyle(dir) : ''; } }, /** * Return html for given dir * * @param Object directory * @return String */ itemhtml = function(dir) { return tpl.replace(/(?:\{([a-z]+)\})/ig, function(m, key) { var res = replace[key] ? replace[key](dir) : (dir[key] || ''); if (key === 'id' && dir.dirs == -1) { subdirsQue[res] = res; } return res; }); }, /** * Return only dirs from files list * * @param Array files list * @param Boolean do check exists * @return Array */ filter = function(files, checkExists) { return jQuery.map(files || [], function(f) { return (f.mime === 'directory' && (!checkExists || fm.navHash2Elm(f.hash).length)) ? f : null; }); }, /** * Find parent subtree for required directory * * @param String dir hash * @return jQuery */ findSubtree = function(hash) { return hash ? fm.navHash2Elm(hash).next('.'+subtree) : tree; }, /** * Find directory (wrapper) in required node * before which we can insert new directory * * @param jQuery parent directory * @param Object new directory * @return jQuery */ findSibling = function(subtree, dir) { var node = subtree.children(':first'), info; while (node.length) { info = fm.file(fm.navId2Hash(node.children('[id]').attr('id'))); if ((info = fm.file(fm.navId2Hash(node.children('[id]').attr('id')))) && compare(dir, info) < 0) { return node; } node = node.next(); } return subtree.children('button.elfinder-navbar-pager-next'); }, /** * Add new dirs in tree * * @param Array dirs list * @return void */ updateTree = function(dirs) { var length = dirs.length, orphans = [], i = length, tgts = jQuery(), done = {}, cwd = fm.cwd(), append = function(parent, dirs, start, direction) { var hashes = {}, curStart = 0, max = fm.newAPI? Math.min(10000, Math.max(10, opts.subTreeMax)) : 10000, setHashes = function() { hashes = {}; jQuery.each(dirs, function(i, d) { hashes[d.hash] = i; }); }, change = function(mode) { if (mode === 'prepare') { jQuery.each(dirs, function(i, d) { d.node && parent.append(d.node.hide()); }); } else if (mode === 'done') { jQuery.each(dirs, function(i, d) { d.node && d.node.detach().show(); }); } }, update = function(e, data) { var i, changed; e.stopPropagation(); if (data.select) { render(getStart(data.select)); return; } if (data.change) { change(data.change); return; } if (data.removed && data.removed.length) { dirs = jQuery.grep(dirs, function(d) { if (data.removed.indexOf(d.hash) === -1) { return true; } else { !changed && (changed = true); return false; } }); } if (data.added && data.added.length) { dirs = dirs.concat(jQuery.grep(data.added, function(d) { if (hashes[d.hash] === void(0)) { !changed && (changed = true); return true; } else { return false; } })); } if (changed) { dirs.sort(compare); setHashes(); render(curStart); } }, getStart = function(target) { if (hashes[target] !== void(0)) { return Math.floor(hashes[target] / max) * max; } return void(0); }, target = fm.navId2Hash(parent.prev('[id]').attr('id')), render = function(start, direction) { var html = [], nodes = {}, total, page, s, parts, prev, next, prevBtn, nextBtn; delete hasMoreDirs[target]; curStart = start; parent.off('update.'+fm.namespace, update); if (dirs.length > max) { parent.on('update.'+fm.namespace, update); if (start === void(0)) { s = 0; setHashes(); start = getStart(cwd.hash); if (start === void(0)) { start = 0; } } parts = dirs.slice(start, start + max); hasMoreDirs[target] = parent; prev = start? Math.max(-1, start - max) : -1; next = (start + max >= dirs.length)? 0 : start + max; total = Math.ceil(dirs.length/max); page = Math.ceil(start/max); } jQuery.each(parts || dirs, function(i, d) { html.push(itemhtml(d)); if (d.node) { nodes[d.hash] = d.node; } }); if (prev > -1) { prevBtn = jQuery('<button class="elfinder-navbar-pager elfinder-navbar-pager-prev"></button>') .text(fm.i18n('btnPrevious', page, total)) .button({ icons: { primary: "ui-icon-caret-1-n" } }) .on('click', function(e) { e.preventDefault(); e.stopPropagation(); render(prev, 'up'); }); } else { prevBtn = jQuery(); } if (next) { nextBtn = jQuery('<button class="elfinder-navbar-pager elfinder-navbar-pager-next"></button>') .text(fm.i18n('btnNext', page + 2, total)) .button({ icons: { primary: "ui-icon-caret-1-s" } }) .on('click', function(e) { e.preventDefault(); e.stopPropagation(); render(next, 'down'); }); } else { nextBtn = jQuery(); } detach(); parent.empty()[parts? 'addClass' : 'removeClass']('elfinder-navbar-hasmore').append(prevBtn, html.join(''), nextBtn); jQuery.each(nodes, function(h, n) { fm.navHash2Elm(h).parent().replaceWith(n); }); if (direction) { autoScroll(fm.navHash2Id(parts[direction === 'up'? parts.length - 1 : 0].hash)); } ! mobile && fm.lazy(function() { updateDroppable(null, parent); }); }, detach = function() { jQuery.each(parent.children('.elfinder-navbar-wrapper'), function(i, elm) { var n = jQuery(elm), ch = n.children('[id]:first'), h, c; if (ch.hasClass(loaded)) { h = fm.navId2Hash(ch.attr('id')); if (h && (c = hashes[h]) !== void(0)) { dirs[c].node = n.detach(); } } }); }; render(); }, dir, html, parent, sibling, init, atonce = {}, updates = [], base, node, lastKey, lastNodes = {}; while (i--) { dir = dirs[i]; if (done[dir.hash] || fm.navHash2Elm(dir.hash).length) { continue; } done[dir.hash] = true; if ((parent = findSubtree(dir.phash)).length) { lastKey = dir.phash || 'treeroot'; if (typeof lastNodes[lastKey] === 'undefined') { lastNodes[lastKey] = parent.children(':last'); } init = !lastNodes[lastKey].length; if (dir.phash && (init || parent.hasClass('elfinder-navbar-hasmore') || (sibling = findSibling(parent, dir)).length)) { if (init) { if (!atonce[dir.phash]) { atonce[dir.phash] = []; } atonce[dir.phash].push(dir); } else { if (sibling) { node = itemhtml(dir); sibling.before(node); ! mobile && (tgts = tgts.add(node)); } else { updates.push(dir); } } } else { node = itemhtml(dir); if (init) { parent.prepend(node); } else { lastNodes[lastKey].after(node); } if (!dir.phash || dir.isroot) { base = fm.navHash2Elm(dir.hash).parent(); } ! mobile && updateDroppable(null, base); } } else { orphans.push(dir); } } // When init, html append at once if (Object.keys(atonce).length){ jQuery.each(atonce, function(p, dirs){ var parent = findSubtree(p), html = []; dirs.sort(compare); append(parent, dirs); }); } if (updates.length) { parent.trigger('update.' + fm.namespace, { added : updates }); } if (orphans.length && orphans.length < length) { updateTree(orphans); return; } ! mobile && tgts.length && fm.lazy(function() { updateDroppable(tgts); }); }, /** * sort function by dir.name * */ compare = function(dir1, dir2) { if (! fm.sortAlsoTreeview) { return fm.sortRules.name(dir1, dir2); } else { var asc = fm.sortOrder == 'asc', type = fm.sortType, rules = fm.sortRules, res; res = asc? rules[fm.sortType](dir1, dir2) : rules[fm.sortType](dir2, dir1); return type !== 'name' && res === 0 ? res = asc ? rules.name(dir1, dir2) : rules.name(dir2, dir1) : res; } }, /** * Timer ID of autoScroll * * @type Integer */ autoScrTm, /** * Auto scroll to cwd * * @return Object jQuery Deferred */ autoScroll = function(target) { var dfrd = jQuery.Deferred(), current, parent, top, treeH, bottom, tgtTop; autoScrTm && clearTimeout(autoScrTm); autoScrTm = setTimeout(function() { current = jQuery(document.getElementById((target || fm.navHash2Id(fm.cwd().hash)))); if (current.length) { // expand parents directory (openCwd? current : current.parent()).parents('.elfinder-navbar-wrapper').children('.'+loaded).addClass(expanded).next('.'+subtree).show(); parent = tree.parent().stop(false, true); top = parent.offset().top; treeH = parent.height(); bottom = top + treeH - current.outerHeight(); tgtTop = current.offset().top; if (tgtTop < top || tgtTop > bottom) { parent.animate({ scrollTop : parent.scrollTop() + tgtTop - top - treeH / 3 }, { duration : opts.durations.autoScroll, complete : function() { dfrd.resolve(); } }); } else { dfrd.resolve(); } } else { dfrd.reject(); } }, 100); return dfrd; }, /** * Get hashes array of items of the bottom of the leaf root back from the target * * @param Object elFinder item(directory) object * @return Array hashes */ getEnds = function(d) { var cur = d || fm.cwd(), res = cur.hash? [ cur.hash ] : [], phash, root, dir; root = fm.root(cur.hash); dir = fm.file(root); while (dir && (phash = dir.phash)) { res.unshift(phash); root = fm.root(phash); dir = fm.file(root); if (fm.navHash2Elm(dir.hash).hasClass(loaded)) { break; } } return res; }, /** * Select pages back in order to display the target * * @param Object elFinder item(directory) object * @return Object jQuery node object of target node */ selectPages = function(current) { var cur = current || fm.cwd(), curHash = cur.hash, node = fm.navHash2Elm(curHash); if (!node.length) { while(cur && cur.phash) { if (hasMoreDirs[cur.phash] && !fm.navHash2Elm(cur.hash).length) { hasMoreDirs[cur.phash].trigger('update.'+fm.namespace, { select : cur.hash }); } cur = fm.file(cur.phash); } node = fm.navHash2Elm(curHash); } return node; }, /** * Flag indicating that synchronization is currently in progress * * @type Boolean */ syncing, /** * Mark current directory as active * If current directory is not in tree - load it and its parents * * @param Array directory objects of cwd * @param Boolean do auto scroll * @return Object jQuery Deferred */ sync = function(cwdDirs, aScr) { var cwd = fm.cwd(), cwdhash = cwd.hash, autoScr = aScr === void(0)? syncTree : aScr, loadParents = function(dir) { var dfd = jQuery.Deferred(), reqs = [], ends = getEnds(dir), makeReq = function(cmd, h, until) { var data = { cmd : cmd, target : h }; if (until) { data.until = until; } return fm.request({ data : data, preventFail : true }); }, baseHash, baseId; reqs = jQuery.map(ends, function(h) { var d = fm.file(h), isRoot = d? fm.isRoot(d) : false, node = fm.navHash2Elm(h), getPhash = function(h, dep) { var d, ph, depth = dep || 1; ph = (d = fm.file(h))? d.phash : false; if (ph && depth > 1) { return getPhash(ph, --depth); } return ph; }, until, closest = (function() { var phash = getPhash(h); until = phash; while (phash) { if (fm.navHash2Elm(phash).hasClass(loaded)) { break; } until = phash; phash = getPhash(phash); } if (!phash) { until = void(0); phash = fm.root(h); } return phash; })(), cmd; if (!node.hasClass(loaded) && (isRoot || !d || !fm.navHash2Elm(d.phash).hasClass(loaded))) { if (isRoot || closest === getPhash(h) || closest === getPhash(h, 2)) { until = void(0); cmd = 'tree'; if (!isRoot) { h = getPhash(h); } } else { cmd = 'parents'; } if (!baseHash) { baseHash = (cmd === 'tree')? h : closest; } return makeReq(cmd, h, until); } return null; }); if (reqs.length) { selectPages(fm.file(baseHash)); baseId = fm.navHash2Id(baseHash); autoScr && autoScroll(baseId); baseNode = jQuery('#'+baseId); spinner = jQuery(fm.res('tpl', 'navspinner')).insertBefore(baseNode.children('.'+arrow)); baseNode.removeClass(collapsed); jQuery.when.apply($, reqs) .done(function() { var res = {},data, treeDirs, dirs, argLen, i; argLen = arguments.length; if (argLen > 0) { for (i = 0; i < argLen; i++) { data = arguments[i].tree || []; res[ends[i]] = Object.assign([], filter(data)); } } dfd.resolve(res); }) .fail(function() { dfd.reject(); }); return dfd; } else { return dfd.resolve(); } }, done= function(res, dfrd) { var open = function() { if (openRoot && baseNode) { findSubtree(baseNode.hash).show().prev(selNavdir).addClass(expanded); openRoot = false; } if (autoScr) { autoScroll().done(checkSubdirs); } else { checkSubdirs(); } }, current; if (res) { jQuery.each(res, function(endHash, dirs) { dirs && updateTree(dirs); selectPages(fm.file(endHash)); dirs && updateArrows(dirs, loaded); }); } if (cwdDirs) { (fm.api < 2.1) && cwdDirs.push(cwd); updateTree(cwdDirs); } // set current node current = selectPages(); if (!current.hasClass(active)) { tree.find(selNavdir+'.'+active).removeClass(active); current.addClass(active); } // mark as loaded to cwd parents current.parents('.elfinder-navbar-wrapper').children('.'+navdir).addClass(loaded); if (res) { fm.lazy(open).done(function() { dfrd.resolve(); }); } else { open(); dfrd.resolve(); } }, rmSpinner = function(fail) { if (baseNode) { spinner.remove(); baseNode.addClass(collapsed + (fail? '' : (' ' + loaded))); } }, dfrd = jQuery.Deferred(), baseNode, spinner; if (!fm.navHash2Elm(cwdhash).length) { syncing = true; loadParents() .done(function(res) { done(res, dfrd); rmSpinner(); }) .fail(function() { rmSpinner(true); dfrd.reject(); }) .always(function() { syncing = false; }); } else { done(void(0), dfrd); } // trigger 'treesync' with my jQuery.Deferred fm.trigger('treesync', dfrd); return dfrd; }, /** * Make writable and not root dirs droppable * * @return void */ updateDroppable = function(target, node) { var limit = 100, next; if (!target) { if (!node || node.closest('div.'+wrapperRoot).hasClass(uploadable)) { (node || tree.find('div.'+uploadable)).find(selNavdir+':not(.elfinder-ro,.elfinder-na)').addClass('native-droppable'); } if (!node || node.closest('div.'+wrapperRoot).hasClass(pastable)) { target = (node || tree.find('div.'+pastable)).find(selNavdir+':not(.'+droppable+')'); } else { target = jQuery(); } if (node) { // check leaf roots node.children('div.'+wrapperRoot).each(function() { updateDroppable(null, jQuery(this)); }); } } // make droppable on async if (target.length) { fm.asyncJob(function(elm) { jQuery(elm).droppable(droppableopts); }, jQuery.makeArray(target), { interval : 20, numPerOnce : 100 }); } }, /** * Check required folders for subfolders and update arrow classes * * @param Array folders to check * @param String css class * @return void */ updateArrows = function(dirs, cls) { var sel = cls == loaded ? '.'+collapsed+':not(.'+loaded+')' : ':not(.'+collapsed+')'; jQuery.each(dirs, function(i, dir) { fm.navHash2Elm(dir.phash).filter(sel) .filter(function() { return jQuery.grep(jQuery(this).next('.'+subtree).children(), function(n) { return (jQuery(n).children().hasClass(root))? false : true; }).length > 0; }) .addClass(cls); }); }, /** * Navigation tree * * @type JQuery */ tree = jQuery(this).addClass(treeclass) // make dirs draggable and toggle hover class .on('mouseenter mouseleave', selNavdir, function(e) { var enter = (e.type === 'mouseenter'); if (enter && scrolling) { return; } var link = jQuery(this), hash, dir; if (!link.hasClass(dropover+' '+disabled)) { if (!mobile && enter && !link.data('dragRegisted') && !link.hasClass(root+' '+draggable+' elfinder-na elfinder-wo')) { link.data('dragRegisted', true); if (fm.isCommandEnabled('copy', (hash = fm.navId2Hash(link.attr('id'))))) { link.draggable(fm.draggable); } } link.toggleClass(hover, enter); } // update title attr if necessary if (enter && opts.attrTitle) { dir = fm.file(hash || fm.navId2Hash(link.attr('id'))); if (!dir.isroot && link.attr('title') === (dir.i18 || dir.name)) { link.attr('title', fm.path(hash, true)); } } }) // native drag enter .on('dragenter', selNavdir, function(e) { if (e.originalEvent.dataTransfer) { var dst = jQuery(this); dst.addClass(hover); if (dst.is('.'+collapsed+':not(.'+expanded+')')) { dst.data('expandTimer', setTimeout(function() { dst.is('.'+collapsed+'.'+hover) && dst.children('.'+arrow).trigger('click'); }, 500)); } } }) // native drag leave .on('dragleave', selNavdir, function(e) { if (e.originalEvent.dataTransfer) { var dst = jQuery(this); dst.data('expandTimer') && clearTimeout(dst.data('expandTimer')); dst.removeClass(hover); } }) // open dir or open subfolders in tree .on('click', selNavdir, function(e) { var link = jQuery(this), hash = fm.navId2Hash(link.attr('id')), file = fm.file(hash); if (link.data('longtap')) { link.removeData('longtap'); e.stopPropagation(); return; } if (!link.hasClass(active)) { tree.find(selNavdir+'.'+active).removeClass(active); link.addClass(active); } if (hash != fm.cwd().hash && !link.hasClass(disabled)) { fm.exec('open', hash).done(function() { fm.one('opendone', function() { fm.select({selected: [hash], origin: 'navbar'}); }); }); } else { if (link.hasClass(collapsed)) { link.children('.'+arrow).trigger('click'); } fm.select({selected: [hash], origin: 'navbar'}); } }) // for touch device .on('touchstart', selNavdir, function(e) { if (e.originalEvent.touches.length > 1) { return; } var evt = e.originalEvent, p; if (e.target.nodeName === 'INPUT') { e.stopPropagation(); return; } p = jQuery(this).addClass(hover) .removeData('longtap') .data('tmlongtap', setTimeout(function(e){ // long tap p.data('longtap', true); fm.trigger('contextmenu', { 'type' : 'navbar', 'targets' : [fm.navId2Hash(p.attr('id'))], 'x' : evt.touches[0].pageX, 'y' : evt.touches[0].pageY }); }, 500)); }) .on('touchmove touchend', selNavdir, function(e) { if (e.target.nodeName === 'INPUT') { e.stopPropagation(); return; } clearTimeout(jQuery(this).data('tmlongtap')); jQuery(this).removeData('tmlongtap'); if (e.type == 'touchmove') { jQuery(this).removeClass(hover); } }) // toggle subfolders in tree .on('click', selNavdir+'.'+collapsed+' .'+arrow, function(e) { var arrow = jQuery(this), link = arrow.parent(selNavdir), stree = link.next('.'+subtree), dfrd = jQuery.Deferred(), slideTH = 30, cnt; e.stopPropagation(); if (link.hasClass(loaded)) { link.toggleClass(expanded); fm.lazy(function() { cnt = link.hasClass(expanded)? stree.children().length + stree.find('div.elfinder-navbar-subtree[style*=block]').children().length : stree.find('div:visible').length; if (cnt > slideTH) { stree.toggle(); fm.draggingUiHelper && fm.draggingUiHelper.data('refreshPositions', 1); checkSubdirs(); } else { stree.stop(true, true)[link.hasClass(expanded)? 'slideDown' : 'slideUp'](opts.durations.slideUpDown, function(){ fm.draggingUiHelper && fm.draggingUiHelper.data('refreshPositions', 1); checkSubdirs(); }); } }).always(function() { dfrd.resolve(); }); } else { spinner.insertBefore(arrow); link.removeClass(collapsed); fm.request({cmd : 'tree', target : fm.navId2Hash(link.attr('id'))}) .done(function(data) { updateTree(Object.assign([], filter(data.tree))); if (stree.children().length) { link.addClass(collapsed+' '+expanded); if (stree.children().length > slideTH) { stree.show(); fm.draggingUiHelper && fm.draggingUiHelper.data('refreshPositions', 1); checkSubdirs(); } else { stree.stop(true, true).slideDown(opts.durations.slideUpDown, function(){ fm.draggingUiHelper && fm.draggingUiHelper.data('refreshPositions', 1); checkSubdirs(); }); } } }) .always(function(data) { spinner.remove(); link.addClass(loaded); fm.one('treedone', function() { dfrd.resolve(); }); }); } arrow.data('dfrd', dfrd); }) .on('contextmenu', selNavdir, function(e) { e.stopPropagation(); var self = jQuery(this); // now dirname editing if (self.find('input:text').length) { return; } e.preventDefault(); if (!self.data('tmlongtap')) { fm.trigger('contextmenu', { 'type' : 'navbar', 'targets' : [fm.navId2Hash(jQuery(this).attr('id'))], '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'); }); }) .on('scrolltoview', selNavdir, function(e, data) { var self = jQuery(this); autoScroll(self.attr('id')).done(function() { if (!data || data.blink === 'undefined' || data.blink) { fm.resources.blink(self, 'lookme'); } }); }) // prepend fake dir .on('create.'+fm.namespace, function(e, item) { var pdir = findSubtree(item.phash), lock = item.move || false, dir = jQuery(itemhtml(item)).addClass('elfinder-navbar-wrapper-tmp'), selected = fm.selected(); lock && selected.length && fm.trigger('lockfiles', {files: selected}); pdir.prepend(dir); }), scrolling = false, navbarScrTm, // move tree into navbar navbar = fm.getUI('navbar').append(tree).show().on('scroll', function() { scrolling = true; navbarScrTm && cancelAnimationFrame(navbarScrTm); navbarScrTm = requestAnimationFrame(function() { scrolling = false; checkSubdirs(); }); }), prevSortTreeview = fm.sortAlsoTreeview; fm.open(function(e) { var data = e.data, dirs = filter(data.files), contextmenu = fm.getUI('contextmenu'); data.init && tree.empty(); if (fm.UA.iOS) { navbar.removeClass('overflow-scrolling-touch').addClass('overflow-scrolling-touch'); } if (dirs.length) { fm.lazy(function() { if (!contextmenu.data('cmdMaps')) { contextmenu.data('cmdMaps', {}); } updateTree(dirs); updateArrows(dirs, loaded); sync(dirs); }); } else { sync(); } }) // add new dirs .add(function(e) { var dirs = filter(e.data.added); if (dirs.length) { updateTree(dirs); updateArrows(dirs, collapsed); } }) // update changed dirs .change(function(e) { // do ot perfome while syncing if (syncing) { return; } var dirs = filter(e.data.changed, true), length = dirs.length, l = length, tgts = jQuery(), changed = {}, dir, phash, node, tmp, realParent, reqParent, realSibling, reqSibling, isExpanded, isLoaded, parent, subdirs; jQuery.each(hasMoreDirs, function(h, node) { node.trigger('update.'+fm.namespace, { change: 'prepare' }); }); while (l--) { dir = dirs[l]; phash = dir.phash; if ((node = fm.navHash2Elm(dir.hash)).length) { parent = node.parent(); if (phash) { realParent = node.closest('.'+subtree); reqParent = findSubtree(phash); realSibling = node.parent().next(); reqSibling = findSibling(reqParent, dir); if (!reqParent.length) { continue; } if (reqParent[0] !== realParent[0] || realSibling.get(0) !== reqSibling.get(0)) { reqSibling.length ? reqSibling.before(parent) : reqParent.append(parent); } } isExpanded = node.hasClass(expanded); isLoaded = node.hasClass(loaded); tmp = jQuery(itemhtml(dir)); node.replaceWith(tmp.children(selNavdir)); ! mobile && updateDroppable(null, parent); if (dir.dirs && (isExpanded || isLoaded) && (node = fm.navHash2Elm(dir.hash)) && node.next('.'+subtree).children().length) { isExpanded && node.addClass(expanded); isLoaded && node.addClass(loaded); } subdirs |= dir.dirs == -1; } } // to check subdirs if (subdirs) { checkSubdirs(); } jQuery.each(hasMoreDirs, function(h, node) { node.trigger('update.'+fm.namespace, { change: 'done' }); }); length && sync(void(0), false); }) // remove dirs .remove(function(e) { var dirs = e.data.removed, l = dirs.length, node, stree, removed; jQuery.each(hasMoreDirs, function(h, node) { node.trigger('update.'+fm.namespace, { removed : dirs }); node.trigger('update.'+fm.namespace, { change: 'prepare' }); }); while (l--) { if ((node = fm.navHash2Elm(dirs[l])).length) { removed = true; stree = node.closest('.'+subtree); node.parent().detach(); if (!stree.children().length) { stree.hide().prev(selNavdir).removeClass(collapsed+' '+expanded+' '+loaded); } } } removed && fm.getUI('navbar').children('.ui-resizable-handle').trigger('resize'); jQuery.each(hasMoreDirs, function(h, node) { node.trigger('update.'+fm.namespace, { change: 'done' }); }); }) // lock/unlock dirs while moving .bind('lockfiles unlockfiles', function(e) { var lock = e.type == 'lockfiles', helperLocked = e.data.helper? e.data.helper.data('locked') : false, act = (lock && !helperLocked) ? 'disable' : 'enable', dirs = jQuery.grep(e.data.files||[], function(h) { var dir = fm.file(h); return dir && dir.mime == 'directory' ? true : false; }); jQuery.each(dirs, function(i, hash) { var dir = fm.navHash2Elm(hash); if (dir.length && !helperLocked) { dir.hasClass(draggable) && dir.draggable(act); dir.hasClass(droppable) && dir.droppable(act); dir[lock ? 'addClass' : 'removeClass'](disabled); } }); }) .bind('sortchange', function() { if (fm.sortAlsoTreeview || prevSortTreeview !== fm.sortAlsoTreeview) { var dirs, ends = [], endsMap = {}, endsVid = {}, topVid = '', single = false, current; fm.lazy(function() { dirs = filter(fm.files()); prevSortTreeview = fm.sortAlsoTreeview; tree.empty(); // append volume roots at first updateTree(jQuery.map(fm.roots, function(h) { var dir = fm.file(h); return dir && !dir.phash? dir : null; })); if (!Object.keys(hasMoreDirs).length) { updateTree(dirs); current = selectPages(); updateArrows(dirs, loaded); } else { ends = getEnds(); if (ends.length > 1) { jQuery.each(ends, function(i, end) { var vid = fm.file(fm.root(end)).volumeid; if (i === 0) { topVid = vid; } endsVid[vid] = end; endsMap[end] = []; }); jQuery.each(dirs, function(i, d) { if (!d.volumeid) { single = true; return false; } endsMap[endsVid[d.volumeid] || endsVid[topVid]].push(d); }); } else { single = true; } if (single) { jQuery.each(ends, function(i, endHash) { updateTree(dirs); current = selectPages(fm.file(endHash)); updateArrows(dirs, loaded); }); } else { jQuery.each(endsMap, function(endHash, dirs) { updateTree(dirs); current = selectPages(fm.file(endHash)); updateArrows(dirs, loaded); }); } } sync(); }, 100); } }); }); return this; };
Upload Files
Cancel
Upload
Create New
Cancel
Create
Change Permissions
Cancel
Save
Change Date
Cancel
Save
Rename Item
Cancel
Save
Confirm Delete
Are you sure you want to delete the selected items?
Cancel
Delete