Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*!
- * elFinder - file manager for web
- * Version 2.1.2 (2.x Nightly: f2196bd) (2015-11-24)
- * http://elfinder.org
- *
- * Copyright 2009-2015, Studio 42
- * Licensed under a 3 clauses BSD license
- */
- (function($) {
- /*
- * File: /js/elFinder.js
- */
- /**
- * @class elFinder - file manager for web
- *
- * @author Dmitry (dio) Levashov
- **/
- window.elFinder = function(node, opts) {
- this.time('load');
- var self = this,
- /**
- * Node on which elfinder creating
- *
- * @type jQuery
- **/
- node = $(node),
- /**
- * Store node contents.
- *
- * @see this.destroy
- * @type jQuery
- **/
- prevContent = $('<div/>').append(node.contents()),
- /**
- * Store node inline styles
- *
- * @see this.destroy
- * @type String
- **/
- prevStyle = node.attr('style'),
- /**
- * Instance ID. Required to get/set cookie
- *
- * @type String
- **/
- id = node.attr('id') || '',
- /**
- * Events namespace
- *
- * @type String
- **/
- namespace = 'elfinder-'+(id || Math.random().toString().substr(2, 7)),
- /**
- * Mousedown event
- *
- * @type String
- **/
- mousedown = 'mousedown.'+namespace,
- /**
- * Keydown event
- *
- * @type String
- **/
- keydown = 'keydown.'+namespace,
- /**
- * Keypress event
- *
- * @type String
- **/
- keypress = 'keypress.'+namespace,
- /**
- * Is shortcuts/commands enabled
- *
- * @type Boolean
- **/
- enabled = true,
- /**
- * Store enabled value before ajax requiest
- *
- * @type Boolean
- **/
- prevEnabled = true,
- /**
- * List of build-in events which mapped into methods with same names
- *
- * @type Array
- **/
- events = ['enable', 'disable', 'load', 'open', 'reload', 'select', 'add', 'remove', 'change', 'dblclick', 'getfile', 'lockfiles', 'unlockfiles', 'dragstart', 'dragstop'],
- /**
- * Rules to validate data from backend
- *
- * @type Object
- **/
- rules = {},
- /**
- * Current working directory hash
- *
- * @type String
- **/
- cwd = '',
- /**
- * Current working directory options
- *
- * @type Object
- **/
- cwdOptions = {
- path : '',
- url : '',
- tmbUrl : '',
- disabled : [],
- separator : '/',
- archives : [],
- extract : [],
- copyOverwrite : true,
- uploadMaxSize : 0,
- tmb : false // old API
- },
- /**
- * Files/dirs cache
- *
- * @type Object
- **/
- files = {},
- /**
- * Selected files hashes
- *
- * @type Array
- **/
- selected = [],
- /**
- * Events listeners
- *
- * @type Object
- **/
- listeners = {},
- /**
- * Shortcuts
- *
- * @type Object
- **/
- shortcuts = {},
- /**
- * Buffer for copied files
- *
- * @type Array
- **/
- clipboard = [],
- /**
- * Copied/cuted files hashes
- * Prevent from remove its from cache.
- * Required for dispaly correct files names in error messages
- *
- * @type Array
- **/
- remember = [],
- /**
- * Queue for 'open' requests
- *
- * @type Array
- **/
- queue = [],
- /**
- * Commands prototype
- *
- * @type Object
- **/
- base = new self.command(self),
- /**
- * elFinder node width
- *
- * @type String
- * @default "auto"
- **/
- width = 'auto',
- /**
- * elFinder node height
- *
- * @type Number
- * @default 400
- **/
- height = 400,
- /**
- * elfinder path for sound played on remove
- * @type String
- * @default ./sounds/
- **/
- soundPath = './sounds/',
- beeper = $(document.createElement('audio')).hide().appendTo('body')[0],
- syncInterval,
- uiCmdMapPrev = '',
- open = function(data) {
- var volumeid, contextmenu, emptyDirs = {}, stayDirs = {};
- self.commandMap = (data.options.uiCmdMap && Object.keys(data.options.uiCmdMap).length)? data.options.uiCmdMap : {};
- // support volume driver option `uiCmdMap`
- if (uiCmdMapPrev !== JSON.stringify(self.commandMap)) {
- uiCmdMapPrev = JSON.stringify(self.commandMap);
- if (Object.keys(self.commandMap).length) {
- // for contextmenu
- contextmenu = self.getUI('contextmenu');
- if (!contextmenu.data('cmdMaps')) {
- contextmenu.data('cmdMaps', {});
- }
- volumeid = data.cwd? data.cwd.volumeid : null;
- if (volumeid && !contextmenu.data('cmdMaps')[volumeid]) {
- contextmenu.data('cmdMaps')[volumeid] = self.commandMap;
- }
- }
- }
- if (data.init) {
- // init - reset cache
- files = {};
- } else {
- // remove only files from prev cwd
- // and collapsed directory (included 100+ directories) to empty for perfomance tune in DnD
- $.each(Object.keys(files), function(n, i) {
- var isDir = (files[i].mime === 'directory'),
- phash = files[i].phash,
- collapsed = self.res('class', 'navcollapse'),
- pnav;
- if (
- (!isDir
- || emptyDirs[phash]
- || (!stayDirs[phash]
- && $('#'+self.navHash2Id(files[i].hash)).is(':hidden')
- && $('#'+self.navHash2Id(phash)).next('.elfinder-navbar-subtree').children().length > 100
- )
- )
- && (isDir || phash === cwd)
- && $.inArray(i, remember) === -1
- ) {
- if (isDir && !emptyDirs[phash]) {
- emptyDirs[phash] = true;
- }
- delete files[i];
- } else if (isDir) {
- stayDirs[phash] = true;
- }
- });
- $.each(Object.keys(emptyDirs), function(n, i) {
- var rmClass = 'elfinder-subtree-loaded ' + self.res('class', 'navexpand');
- $('#'+self.navHash2Id(i))
- .removeClass(rmClass)
- .next('.elfinder-navbar-subtree').empty();
- });
- }
- cwd = data.cwd.hash;
- cache(data.files);
- if (!files[cwd]) {
- cache([data.cwd]);
- }
- self.lastDir(cwd);
- },
- /**
- * Store info about files/dirs in "files" object.
- *
- * @param Array files
- * @return void
- **/
- cache = function(data) {
- var l = data.length, f, i;
- for (i = 0; i < l; i++) {
- f = data[i];
- if (f.name && f.hash && f.mime) {
- if (!f.phash) {
- var name = 'volume_'+f.name,
- i18 = self.i18n(name);
- if (name != i18) {
- f.i18 = i18;
- }
- // set disabledCmds of each volume
- if (f.volumeid && f.disabled) {
- self.disabledCmds[f.volumeid] = f.disabled;
- }
- }
- files[f.hash] = f;
- }
- }
- },
- /**
- * Exec shortcut
- *
- * @param jQuery.Event keydown/keypress event
- * @return void
- */
- execShortcut = function(e) {
- var code = e.keyCode,
- ctrlKey = !!(e.ctrlKey || e.metaKey);
- if (enabled) {
- $.each(shortcuts, function(i, shortcut) {
- if (shortcut.type == e.type
- && shortcut.keyCode == code
- && shortcut.shiftKey == e.shiftKey
- && shortcut.ctrlKey == ctrlKey
- && shortcut.altKey == e.altKey) {
- e.preventDefault()
- e.stopPropagation();
- shortcut.callback(e, self);
- self.debug('shortcut-exec', i+' : '+shortcut.description);
- }
- });
- // prevent tab out of elfinder
- if (code == 9 && !$(e.target).is(':input')) {
- e.preventDefault();
- }
- // cancel copy or cut by [Esc] key
- if (code == 27 && self.clipboard().length) {
- self.clipboard([]);
- }
- }
- },
- date = new Date(),
- utc,
- i18n
- ;
- /**
- * Protocol version
- *
- * @type String
- **/
- this.api = null;
- /**
- * elFinder use new api
- *
- * @type Boolean
- **/
- this.newAPI = false;
- /**
- * elFinder use old api
- *
- * @type Boolean
- **/
- this.oldAPI = false;
- /**
- * Net drivers names
- *
- * @type Array
- **/
- this.netDrivers = [];
- /**
- * User os. Required to bind native shortcuts for open/rename
- *
- * @type String
- **/
- this.OS = navigator.userAgent.indexOf('Mac') !== -1 ? 'mac' : navigator.userAgent.indexOf('Win') !== -1 ? 'win' : 'other';
- /**
- * User browser UA.
- * jQuery.browser: version deprecated: 1.3, removed: 1.9
- *
- * @type Object
- **/
- this.UA = (function(){
- var webkit = !document.uniqueID && !window.opera && !window.sidebar && window.localStorage && typeof window.orientation == "undefined";
- return {
- // Browser IE <= IE 6
- ltIE6:typeof window.addEventListener == "undefined" && typeof document.documentElement.style.maxHeight == "undefined",
- // Browser IE <= IE 7
- ltIE7:typeof window.addEventListener == "undefined" && typeof document.querySelectorAll == "undefined",
- // Browser IE <= IE 8
- ltIE8:typeof window.addEventListener == "undefined" && typeof document.getElementsByClassName == "undefined",
- IE:document.uniqueID,
- Firefox:window.sidebar,
- Opera:window.opera,
- Webkit:webkit,
- Chrome:webkit && window.chrome,
- Safari:webkit && !window.chrome,
- Mobile:typeof window.orientation != "undefined",
- Touch:typeof window.ontouchstart != "undefined"
- };
- })();
- /**
- * Configuration options
- *
- * @type Object
- **/
- this.options = $.extend(true, {}, this._options, opts||{});
- if (opts.ui) {
- this.options.ui = opts.ui;
- }
- if (opts.commands) {
- this.options.commands = opts.commands;
- }
- if (opts.uiOptions && opts.uiOptions.toolbar) {
- this.options.uiOptions.toolbar = opts.uiOptions.toolbar;
- }
- if (opts.uiOptions && opts.uiOptions.cwd && opts.uiOptions.cwd.listView && opts.uiOptions.cwd.listView.columns) {
- this.options.uiOptions.cwd.listView.columns = opts.uiOptions.cwd.listView.columns;
- }
- if (opts.uiOptions && opts.uiOptions.cwd && opts.uiOptions.cwd.listView && opts.uiOptions.cwd.listView.columnsCustomName) {
- this.options.uiOptions.cwd.listView.columnsCustomName = opts.uiOptions.cwd.listView.columnsCustomName;
- }
- // configure for CORS
- (function(){
- var parseUrl = document.createElement('a'),
- parseUploadUrl;
- parseUrl.href = opts.url;
- if (opts.urlUpload && (opts.urlUpload !== opts.url)) {
- parseUploadUrl = document.createElement('a');
- parseUploadUrl.href = opts.urlUpload;
- }
- if (window.location.host !== parseUrl.host || (parseUploadUrl && (window.location.host !== parseUploadUrl.host))) {
- if (!$.isPlainObject(self.options.customHeaders)) {
- self.options.customHeaders = {};
- }
- if (!$.isPlainObject(self.options.xhrFields)) {
- self.options.xhrFields = {};
- }
- self.options.requestType = 'post';
- self.options.customHeaders['X-Requested-With'] = 'XMLHttpRequest';
- self.options.xhrFields['withCredentials'] = true;
- }
- })();
- $.extend(this.options.contextmenu, opts.contextmenu);
- /**
- * Ajax request type
- *
- * @type String
- * @default "get"
- **/
- this.requestType = /^(get|post)$/i.test(this.options.requestType) ? this.options.requestType.toLowerCase() : 'get',
- /**
- * Any data to send across every ajax request
- *
- * @type Object
- * @default {}
- **/
- this.customData = $.isPlainObject(this.options.customData) ? this.options.customData : {};
- /**
- * Any custom headers to send across every ajax request
- *
- * @type Object
- * @default {}
- */
- this.customHeaders = $.isPlainObject(this.options.customHeaders) ? this.options.customHeaders : {};
- /**
- * Any custom xhrFields to send across every ajax request
- *
- * @type Object
- * @default {}
- */
- this.xhrFields = $.isPlainObject(this.options.xhrFields) ? this.options.xhrFields : {};
- /**
- * ID. Required to create unique cookie name
- *
- * @type String
- **/
- this.id = id;
- /**
- * URL to upload files
- *
- * @type String
- **/
- this.uploadURL = opts.urlUpload || opts.url;
- /**
- * Events namespace
- *
- * @type String
- **/
- this.namespace = namespace;
- /**
- * Interface language
- *
- * @type String
- * @default "en"
- **/
- this.lang = this.i18[this.options.lang] && this.i18[this.options.lang].messages ? this.options.lang : 'en';
- i18n = this.lang == 'en'
- ? this.i18['en']
- : $.extend(true, {}, this.i18['en'], this.i18[this.lang]);
- /**
- * Interface direction
- *
- * @type String
- * @default "ltr"
- **/
- this.direction = i18n.direction;
- /**
- * i18 messages
- *
- * @type Object
- **/
- this.messages = i18n.messages;
- /**
- * Date/time format
- *
- * @type String
- * @default "m.d.Y"
- **/
- this.dateFormat = this.options.dateFormat || i18n.dateFormat;
- /**
- * Date format like "Yesterday 10:20:12"
- *
- * @type String
- * @default "{day} {time}"
- **/
- this.fancyFormat = this.options.fancyDateFormat || i18n.fancyDateFormat;
- /**
- * Today timestamp
- *
- * @type Number
- **/
- this.today = (new Date(date.getFullYear(), date.getMonth(), date.getDate())).getTime()/1000;
- /**
- * Yesterday timestamp
- *
- * @type Number
- **/
- this.yesterday = this.today - 86400;
- utc = this.options.UTCDate ? 'UTC' : '';
- this.getHours = 'get'+utc+'Hours';
- this.getMinutes = 'get'+utc+'Minutes';
- this.getSeconds = 'get'+utc+'Seconds';
- this.getDate = 'get'+utc+'Date';
- this.getDay = 'get'+utc+'Day';
- this.getMonth = 'get'+utc+'Month';
- this.getFullYear = 'get'+utc+'FullYear';
- /**
- * Css classes
- *
- * @type String
- **/
- this.cssClass = 'ui-helper-reset ui-helper-clearfix ui-widget ui-widget-content ui-corner-all elfinder elfinder-'+(this.direction == 'rtl' ? 'rtl' : 'ltr')+' '+this.options.cssClass;
- /**
- * Method to store/fetch data
- *
- * @type Function
- **/
- this.storage = (function() {
- try {
- return 'localStorage' in window && window['localStorage'] !== null ? self.localStorage : self.cookie;
- } catch (e) {
- return self.cookie;
- }
- })();
- this.viewType = this.storage('view') || this.options.defaultView || 'icons';
- this.sortType = this.storage('sortType') || this.options.sortType || 'name';
- this.sortOrder = this.storage('sortOrder') || this.options.sortOrder || 'asc';
- this.sortStickFolders = this.storage('sortStickFolders');
- if (this.sortStickFolders === null) {
- this.sortStickFolders = !!this.options.sortStickFolders;
- } else {
- this.sortStickFolders = !!this.sortStickFolders
- }
- this.sortRules = $.extend(true, {}, this._sortRules, this.options.sortsRules);
- $.each(this.sortRules, function(name, method) {
- if (typeof method != 'function') {
- delete self.sortRules[name];
- }
- });
- this.compare = $.proxy(this.compare, this);
- /**
- * Delay in ms before open notification dialog
- *
- * @type Number
- * @default 500
- **/
- this.notifyDelay = this.options.notifyDelay > 0 ? parseInt(this.options.notifyDelay) : 500;
- /**
- * Dragging UI Helper object
- *
- * @type jQuery | null
- **/
- this.draggingUiHelper = null,
- /**
- * Base draggable options
- *
- * @type Object
- **/
- this.draggable = {
- appendTo : 'body',
- addClasses : true,
- delay : 30,
- distance : 8,
- revert : true,
- refreshPositions : false,
- cursor : 'move',
- cursorAt : {left : 50, top : 47},
- start : function(e, ui) {
- var targets = $.map(ui.helper.data('files')||[], function(h) { return h || null ;}),
- locked = false,
- cnt, h;
- self.draggingUiHelper = ui.helper;
- cnt = targets.length;
- while (cnt--) {
- h = targets[cnt];
- if (files[h].locked) {
- locked = true;
- ui.helper.addClass('elfinder-drag-helper-plus').data('locked', true);
- break;
- }
- }
- !locked && self.trigger('lockfiles', {files : targets});
- },
- drag : function(e, ui) {
- if (ui.helper.data('refreshPositions') && $(this).draggable('instance')) {
- if (ui.helper.data('refreshPositions') > 0) {
- $(this).draggable('option', { refreshPositions : true });
- ui.helper.data('refreshPositions', -1);
- } else {
- $(this).draggable('option', { refreshPositions : false });
- ui.helper.data('refreshPositions', null);
- }
- }
- },
- stop : function(e, ui) {
- var files;
- $(this).draggable('instance') && $(this).draggable('option', { refreshPositions : false });
- self.draggingUiHelper = null;
- self.trigger('focus').trigger('dragstop');
- if (! ui.helper.data('droped')) {
- files = $.map(ui.helper.data('files')||[], function(h) { return h || null ;});
- self.trigger('unlockfiles', {files : files});
- self.trigger('selectfiles', {files : files});
- }
- },
- helper : function(e, ui) {
- var element = this.id ? $(this) : $(this).parents('[id]:first'),
- helper = $('<div class="elfinder-drag-helper"><span class="elfinder-drag-helper-icon-plus"/></div>'),
- icon = function(f) {
- var mime = f.mime, i;
- i = '<div class="elfinder-cwd-icon '+self.mime2class(mime)+' ui-corner-all"/>';
- if (f.tmb && f.tmb !== 1) {
- i = $(i).css('background', "url('"+self.option('tmbUrl')+f.tmb+"') center center no-repeat").get(0).outerHTML;
- }
- return i;
- },
- hashes, l, ctr;
- self.draggingUiHelper && self.draggingUiHelper.stop(true, true);
- self.trigger('dragstart', {target : element[0], originalEvent : e});
- hashes = element.hasClass(self.res('class', 'cwdfile'))
- ? self.selected()
- : [self.navId2Hash(element.attr('id'))];
- helper.append(icon(files[hashes[0]])).data('files', hashes).data('locked', false).data('droped', false);
- if ((l = hashes.length) > 1) {
- helper.append(icon(files[hashes[l-1]]) + '<span class="elfinder-drag-num">'+l+'</span>');
- }
- $(document).on(keydown + ' keyup.' + namespace, function(e){
- var chk = (e.shiftKey||e.ctrlKey||e.metaKey);
- if (ctr !== chk) {
- ctr = chk;
- if (helper.is(':visible') && ! helper.data('locked') && ! helper.data('droped')) {
- helper.toggleClass('elfinder-drag-helper-plus', ctr);
- self.trigger(ctr? 'unlockfiles' : 'lockfiles', {files : hashes});
- }
- }
- });
- return helper;
- }
- };
- /**
- * Base droppable options
- *
- * @type Object
- **/
- this.droppable = {
- greedy : true,
- tolerance : 'pointer',
- accept : '.elfinder-cwd-file-wrapper,.elfinder-navbar-dir,.elfinder-cwd-file',
- hoverClass : this.res('class', 'adroppable'),
- drop : function(e, ui) {
- var dst = $(this),
- targets = $.map(ui.helper.data('files')||[], function(h) { return h || null }),
- result = [],
- dups = [],
- unlocks = [],
- isCopy = (e.ctrlKey||e.shiftKey||e.metaKey||ui.helper.data('locked'))? true : false,
- c = 'class',
- cnt, hash, i, h;
- ui.helper.data('droped', true);
- if (dst.hasClass(self.res(c, 'cwdfile'))) {
- hash = dst.attr('id');
- } else if (dst.hasClass(self.res(c, 'navdir'))) {
- hash = self.navId2Hash(dst.attr('id'));
- } else {
- hash = cwd;
- }
- cnt = targets.length;
- while (cnt--) {
- h = targets[cnt];
- // ignore drop into itself or in own location
- if (h != hash && files[h].phash != hash) {
- result.push(h);
- } else {
- ((isCopy && h !== hash && files[hash].write)? dups : unlocks).push(h);
- }
- }
- unlocks.length && self.trigger('unlockfiles', {files: unlocks});
- if (dups.length) {
- ui.helper.hide();
- self.exec('duplicate', dups);
- }
- if (result.length) {
- ui.helper.hide();
- self.clipboard(result, !isCopy);
- self.exec('paste', hash, void 0, hash).always(function(){
- self.trigger('unlockfiles', {files : targets});
- });
- self.trigger('drop', {files : targets});
- }
- }
- };
- /**
- * Return true if filemanager is active
- *
- * @return Boolean
- **/
- this.enabled = function() {
- return node.is(':visible') && enabled;
- }
- /**
- * Return true if filemanager is visible
- *
- * @return Boolean
- **/
- this.visible = function() {
- return node.is(':visible');
- }
- /**
- * Return root dir hash for current working directory
- *
- * @return String
- */
- this.root = function(hash) {
- var dir = files[hash || cwd], i;
- while (dir && dir.phash) {
- dir = files[dir.phash]
- }
- if (dir) {
- return dir.hash;
- }
- while (i in files && files.hasOwnProperty(i)) {
- dir = files[i]
- if (!dir.phash && !dir.mime == 'directory' && dir.read) {
- return dir.hash
- }
- }
- return '';
- }
- /**
- * Return current working directory info
- *
- * @return Object
- */
- this.cwd = function() {
- return files[cwd] || {};
- }
- /**
- * Return required cwd option
- *
- * @param String option name
- * @return mixed
- */
- this.option = function(name) {
- return cwdOptions[name]||'';
- }
- /**
- * Return file data from current dir or tree by it's hash
- *
- * @param String file hash
- * @return Object
- */
- this.file = function(hash) {
- return files[hash];
- };
- /**
- * Return all cached files
- *
- * @return Array
- */
- this.files = function() {
- return $.extend(true, {}, files);
- }
- /**
- * Return list of file parents hashes include file hash
- *
- * @param String file hash
- * @return Array
- */
- this.parents = function(hash) {
- var parents = [],
- dir;
- while ((dir = this.file(hash))) {
- parents.unshift(dir.hash);
- hash = dir.phash;
- }
- return parents;
- }
- this.path2array = function(hash, i18) {
- var file,
- path = [];
- while (hash && (file = files[hash]) && file.hash) {
- path.unshift(i18 && file.i18 ? file.i18 : file.name);
- hash = file.phash;
- }
- return path;
- }
- /**
- * Return file path
- *
- * @param Object file
- * @return String
- */
- this.path = function(hash, i18) {
- return files[hash] && files[hash].path
- ? files[hash].path
- : this.path2array(hash, i18).join(cwdOptions.separator);
- }
- /**
- * Return file url if set
- *
- * @param Object file
- * @return String
- */
- this.url = function(hash) {
- var file = files[hash];
- if (!file || !file.read) {
- return '';
- }
- if (file.url == '1') {
- this.request({
- data : {cmd : 'url', target : hash},
- preventFail : true,
- options: {async: false}
- })
- .done(function(data) {
- file.url = data.url || '';
- })
- .fail(function() {
- file.url = '';
- });
- }
- if (file.url) {
- return file.url;
- }
- if (cwdOptions.url) {
- return cwdOptions.url + $.map(this.path2array(hash), function(n) { return encodeURIComponent(n); }).slice(1).join('/')
- }
- var params = $.extend({}, this.customData, {
- cmd: 'file',
- target: file.hash
- });
- if (this.oldAPI) {
- params.cmd = 'open';
- params.current = file.phash;
- }
- return this.options.url + (this.options.url.indexOf('?') === -1 ? '?' : '&') + $.param(params, true);
- }
- /**
- * Return thumbnail url
- *
- * @param String file hash
- * @return String
- */
- this.tmb = function(hash) {
- var file = files[hash],
- url = file && file.tmb && file.tmb != 1 ? cwdOptions['tmbUrl'] + file.tmb : '';
- if (url && (this.UA.Opera || this.UA.IE)) {
- url += '?_=' + new Date().getTime();
- }
- return url;
- }
- /**
- * Return selected files hashes
- *
- * @return Array
- **/
- this.selected = function() {
- return selected.slice(0);
- }
- /**
- * Return selected files info
- *
- * @return Array
- */
- this.selectedFiles = function() {
- return $.map(selected, function(hash) { return files[hash] ? $.extend({}, files[hash]) : null });
- };
- /**
- * Return true if file with required name existsin required folder
- *
- * @param String file name
- * @param String parent folder hash
- * @return Boolean
- */
- this.fileByName = function(name, phash) {
- var hash;
- for (hash in files) {
- if (files.hasOwnProperty(hash) && files[hash].phash == phash && files[hash].name == name) {
- return files[hash];
- }
- }
- };
- /**
- * Valid data for required command based on rules
- *
- * @param String command name
- * @param Object cammand's data
- * @return Boolean
- */
- this.validResponse = function(cmd, data) {
- return data.error || this.rules[this.rules[cmd] ? cmd : 'defaults'](data);
- }
- /**
- * Return bytes from ini formated size
- *
- * @param String ini formated size
- * @return Integer
- */
- this.returnBytes = function(val) {
- if (val == '-1') val = 0;
- if (val) {
- // for ex. 1mb, 1KB
- val = val.replace(/b$/i, '');
- var last = val.charAt(val.length - 1).toLowerCase();
- val = val.replace(/[gmk]$/i, '');
- if (last == 'g') {
- val = val * 1024 * 1024 * 1024;
- } else if (last == 'm') {
- val = val * 1024 * 1024;
- } else if (last == 'k') {
- val = val * 1024;
- }
- }
- return val;
- };
- /**
- * Proccess ajax request.
- * Fired events :
- * @todo
- * @example
- * @todo
- * @return $.Deferred
- */
- this.request = function(options) {
- var self = this,
- o = this.options,
- dfrd = $.Deferred(),
- // request data
- data = $.extend({}, o.customData, {mimes : o.onlyMimes}, options.data || options),
- // command name
- cmd = data.cmd,
- // call default fail callback (display error dialog) ?
- deffail = !(options.preventDefault || options.preventFail),
- // call default success callback ?
- defdone = !(options.preventDefault || options.preventDone),
- // options for notify dialog
- notify = $.extend({}, options.notify),
- // do not normalize data - return as is
- raw = !!options.raw,
- // sync files on request fail
- syncOnFail = options.syncOnFail,
- // open notify dialog timeout
- timeout,
- // request options
- options = $.extend({
- url : o.url,
- async : true,
- type : this.requestType,
- dataType : 'json',
- cache : false,
- // timeout : 100,
- data : data,
- headers : this.customHeaders,
- xhrFields: this.xhrFields
- }, options.options || {}),
- /**
- * Default success handler.
- * Call default data handlers and fire event with command name.
- *
- * @param Object normalized response data
- * @return void
- **/
- done = function(data) {
- data.warning && self.error(data.warning);
- cmd == 'open' && open($.extend(true, {}, data));
- // fire some event to update cache/ui
- data.removed && data.removed.length && self.remove(data);
- data.added && data.added.length && self.add(data);
- data.changed && data.changed.length && self.change(data);
- // fire event with command name
- self.trigger(cmd, data);
- // force update content
- data.sync && self.sync();
- },
- /**
- * Request error handler. Reject dfrd with correct error message.
- *
- * @param jqxhr request object
- * @param String request status
- * @return void
- **/
- error = function(xhr, status) {
- var error;
- switch (status) {
- case 'abort':
- error = xhr.quiet ? '' : ['errConnect', 'errAbort'];
- break;
- case 'timeout':
- error = ['errConnect', 'errTimeout'];
- break;
- case 'parsererror':
- error = ['errResponse', 'errDataNotJSON'];
- break;
- default:
- if (xhr.status == 403) {
- error = ['errConnect', 'errAccess'];
- } else if (xhr.status == 404) {
- error = ['errConnect', 'errNotFound'];
- } else {
- error = 'errConnect';
- }
- }
- dfrd.reject(error, xhr, status);
- },
- /**
- * Request success handler. Valid response data and reject/resolve dfrd.
- *
- * @param Object response data
- * @param String request status
- * @return void
- **/
- success = function(response) {
- if (raw) {
- return dfrd.resolve(response);
- }
- if (!response) {
- return dfrd.reject(['errResponse', 'errDataEmpty'], xhr);
- } else if (!$.isPlainObject(response)) {
- return dfrd.reject(['errResponse', 'errDataNotJSON'], xhr);
- } else if (response.error) {
- return dfrd.reject(response.error, xhr);
- } else if (!self.validResponse(cmd, response)) {
- return dfrd.reject('errResponse', xhr);
- }
- response = self.normalize(response);
- if (!self.api) {
- self.api = response.api || 1;
- self.newAPI = self.api >= 2;
- self.oldAPI = !self.newAPI;
- }
- if (response.options) {
- cwdOptions = $.extend({}, cwdOptions, response.options);
- }
- if (response.netDrivers) {
- self.netDrivers = response.netDrivers;
- }
- if (cmd == 'open' && !!data.init) {
- self.uplMaxSize = self.returnBytes(response.uplMaxSize);
- self.uplMaxFile = !!response.uplMaxFile? parseInt(response.uplMaxFile) : 20;
- }
- dfrd.resolve(response);
- response.debug && self.debug('backend-debug', response.debug);
- },
- xhr, _xhr
- ;
- defdone && dfrd.done(done);
- dfrd.fail(function(error) {
- if (error) {
- deffail ? self.error(error) : self.debug('error', self.i18n(error));
- }
- })
- if (!cmd) {
- return dfrd.reject('errCmdReq');
- }
- if (syncOnFail) {
- dfrd.fail(function(error) {
- error && self.sync();
- });
- }
- if (notify.type && notify.cnt) {
- timeout = setTimeout(function() {
- self.notify(notify);
- dfrd.always(function() {
- notify.cnt = -(parseInt(notify.cnt)||0);
- self.notify(notify);
- })
- }, self.notifyDelay)
- dfrd.always(function() {
- clearTimeout(timeout);
- });
- }
- // quiet abort not completed "open" requests
- if (cmd == 'open') {
- while ((_xhr = queue.pop())) {
- if (_xhr.state() == 'pending') {
- _xhr.quiet = true;
- _xhr.abort();
- }
- }
- }
- delete options.preventFail
- xhr = this.transport.send(options).fail(error).done(success);
- // this.transport.send(options)
- // add "open" xhr into queue
- if (cmd == 'open') {
- queue.unshift(xhr);
- dfrd.always(function() {
- var ndx = $.inArray(xhr, queue);
- ndx !== -1 && queue.splice(ndx, 1);
- });
- }
- return dfrd;
- };
- /**
- * Compare current files cache with new files and return diff
- *
- * @param Array new files
- * @return Object
- */
- this.diff = function(incoming) {
- var raw = {},
- added = [],
- removed = [],
- changed = [],
- isChanged = function(hash) {
- var l = changed.length;
- while (l--) {
- if (changed[l].hash == hash) {
- return true;
- }
- }
- };
- $.each(incoming, function(i, f) {
- raw[f.hash] = f;
- });
- // find removed
- $.each(files, function(hash, f) {
- !raw[hash] && removed.push(hash);
- });
- // compare files
- $.each(raw, function(hash, file) {
- var origin = files[hash];
- if (!origin) {
- added.push(file);
- } else {
- $.each(file, function(prop) {
- if (file[prop] != origin[prop]) {
- changed.push(file)
- return false;
- }
- });
- }
- });
- // parents of removed dirs mark as changed (required for tree correct work)
- $.each(removed, function(i, hash) {
- var file = files[hash],
- phash = file.phash;
- if (phash
- && file.mime == 'directory'
- && $.inArray(phash, removed) === -1
- && raw[phash]
- && !isChanged(phash)) {
- changed.push(raw[phash]);
- }
- });
- return {
- added : added,
- removed : removed,
- changed : changed
- };
- }
- /**
- * Sync content
- *
- * @return jQuery.Deferred
- */
- this.sync = function() {
- var self = this,
- dfrd = $.Deferred().done(function() { self.trigger('sync'); }),
- opts1 = {
- data : {cmd : 'open', reload : 1, target : cwd, tree : this.ui.tree ? 1 : 0},
- preventDefault : true
- },
- opts2 = {
- data : {cmd : 'parents', target : cwd},
- preventDefault : true
- };
- $.when(
- this.request(opts1),
- this.request(opts2)
- )
- .fail(function(error) {
- dfrd.reject(error);
- error && self.request({
- data : {cmd : 'open', target : self.lastDir(''), tree : 1, init : 1},
- notify : {type : 'open', cnt : 1, hideCnt : true},
- preventDefault : true
- });
- })
- .done(function(odata, pdata) {
- var diff = self.diff(odata.files.concat(pdata && pdata.tree ? pdata.tree : []));
- diff.added.push(odata.cwd)
- diff.removed.length && self.remove(diff);
- diff.added.length && self.add(diff);
- diff.changed.length && self.change(diff);
- return dfrd.resolve(diff);
- });
- return dfrd;
- }
- this.upload = function(files) {
- return this.transport.upload(files, this);
- }
- /**
- * Attach listener to events
- * To bind to multiply events at once, separate events names by space
- *
- * @param String event(s) name(s)
- * @param Object event handler
- * @return elFinder
- */
- this.bind = function(event, callback) {
- var i;
- if (typeof(callback) == 'function') {
- event = ('' + event).toLowerCase().split(/\s+/);
- for (i = 0; i < event.length; i++) {
- if (listeners[event[i]] === void(0)) {
- listeners[event[i]] = [];
- }
- listeners[event[i]].push(callback);
- }
- }
- return this;
- };
- /**
- * Remove event listener if exists
- *
- * @param String event name
- * @param Function callback
- * @return elFinder
- */
- this.unbind = function(event, callback) {
- var l = listeners[('' + event).toLowerCase()] || [],
- i = l.indexOf(callback);
- i > -1 && l.splice(i, 1);
- //delete callback; // need this?
- callback = null
- return this;
- };
- /**
- * Fire event - send notification to all event listeners
- *
- * @param String event type
- * @param Object data to send across event
- * @return elFinder
- */
- this.trigger = function(event, data) {
- var event = event.toLowerCase(),
- isopen = (event === 'open'),
- handlers = listeners[event] || [], i, l, jst;
- this.debug('event-'+event, data);
- if (isopen) {
- // for performance tuning
- jst = JSON.stringify(data);
- }
- if (handlers.length) {
- event = $.Event(event);
- l = handlers.length;
- for (i = 0; i < l; i++) {
- // only callback has argument
- if (handlers[i].length) {
- // to avoid data modifications. remember about "sharing" passing arguments in js :)
- event.data = isopen? JSON.parse(jst) : $.extend(true, {}, data);
- }
- try {
- if (handlers[i](event, this) === false
- || event.isDefaultPrevented()) {
- this.debug('event-stoped', event.type);
- break;
- }
- } catch (ex) {
- window.console && window.console.log && window.console.log(ex);
- }
- }
- }
- return this;
- }
- /**
- * Bind keybord shortcut to keydown event
- *
- * @example
- * elfinder.shortcut({
- * pattern : 'ctrl+a',
- * description : 'Select all files',
- * callback : function(e) { ... },
- * keypress : true|false (bind to keypress instead of keydown)
- * })
- *
- * @param Object shortcut config
- * @return elFinder
- */
- this.shortcut = function(s) {
- var patterns, pattern, code, i, parts;
- /*if (this.options.allowShortcuts && s.pattern && $.isFunction(s.callback)) {
- patterns = s.pattern.toUpperCase().split(/\s+/);
- for (i= 0; i < patterns.length; i++) {
- pattern = patterns[i]
- parts = pattern.split('+');
- code = (code = parts.pop()).length == 1
- ? code > 0 ? code : code.charCodeAt(0)
- : $.ui.keyCode[code];
- if (code && !shortcuts[pattern]) {
- shortcuts[pattern] = {
- keyCode : code,
- altKey : $.inArray('ALT', parts) != -1,
- ctrlKey : $.inArray('CTRL', parts) != -1,
- shiftKey : $.inArray('SHIFT', parts) != -1,
- type : s.type || 'keydown',
- callback : s.callback,
- description : s.description,
- pattern : pattern
- };
- }
- }
- }*/
- return this;
- }
- /**
- * Registered shortcuts
- *
- * @type Object
- **/
- this.shortcuts = function() {
- var ret = [];
- $.each(shortcuts, function(i, s) {
- ret.push([s.pattern, self.i18n(s.description)]);
- });
- return ret;
- };
- /**
- * Get/set clipboard content.
- * Return new clipboard content.
- *
- * @example
- * this.clipboard([]) - clean clipboard
- * this.clipboard([{...}, {...}], true) - put 2 files in clipboard and mark it as cutted
- *
- * @param Array new files hashes
- * @param Boolean cut files?
- * @return Array
- */
- this.clipboard = function(hashes, cut) {
- var map = function() { return $.map(clipboard, function(f) { return f.hash }); }
- if (hashes !== void(0)) {
- clipboard.length && this.trigger('unlockfiles', {files : map()});
- remember = [];
- clipboard = $.map(hashes||[], function(hash) {
- var file = files[hash];
- if (file) {
- remember.push(hash);
- return {
- hash : hash,
- phash : file.phash,
- name : file.name,
- mime : file.mime,
- read : file.read,
- locked : file.locked,
- cut : !!cut
- }
- }
- return null;
- });
- this.trigger('changeclipboard', {clipboard : clipboard.slice(0, clipboard.length)});
- cut && this.trigger('lockfiles', {files : map()});
- }
- // return copy of clipboard instead of refrence
- return clipboard.slice(0, clipboard.length);
- }
- /**
- * Return true if command enabled
- *
- * @param String command name
- * @param String|void hash for check of own volume's disabled cmds
- * @return Boolean
- */
- this.isCommandEnabled = function(name, dstHash) {
- var disabled;
- if (dstHash && self.root(dstHash) !== cwd) {
- $.each(self.disabledCmds, function(i, v){
- if (dstHash.indexOf(i, 0) == 0) {
- disabled = v;
- return false;
- }
- });
- }
- if (!disabled) {
- disabled = cwdOptions.disabled;
- }
- return this._commands[name] ? $.inArray(name, disabled) === -1 : false;
- }
- /**
- * Exec command and return result;
- *
- * @param String command name
- * @param String|Array usualy files hashes
- * @param String|Array command options
- * @param String|void hash for enabled check of own volume's disabled cmds
- * @return $.Deferred
- */
- this.exec = function(cmd, files, opts, dstHash) {
- return this._commands[cmd] && this.isCommandEnabled(cmd, dstHash)
- ? this._commands[cmd].exec(files, opts)
- : $.Deferred().reject('No such command');
- }
- /**
- * Create and return dialog.
- *
- * @param String|DOMElement dialog content
- * @param Object dialog options
- * @return jQuery
- */
- this.dialog = function(content, options) {
- var dialog = $('<div/>').append(content).appendTo(node).elfinderdialog(options);
- this.bind('resize', function(){
- dialog.elfinderdialog('posInit');
- });
- return dialog;
- }
- /**
- * Return UI widget or node
- *
- * @param String ui name
- * @return jQuery
- */
- this.getUI = function(ui) {
- return this.ui[ui] || node;
- }
- this.command = function(name) {
- return name === void(0) ? this._commands : this._commands[name];
- }
- /**
- * Resize elfinder node
- *
- * @param String|Number width
- * @param Number height
- * @return void
- */
- this.resize = function(w, h) {
- node.css('width', w).height(h).trigger('resize');
- this.trigger('resize', {width : node.width(), height : node.height()});
- }
- /**
- * Restore elfinder node size
- *
- * @return elFinder
- */
- this.restoreSize = function() {
- this.resize(width, height);
- }
- this.show = function() {
- node.show();
- this.enable().trigger('show');
- }
- this.hide = function() {
- this.disable().trigger('hide');
- node.hide();
- }
- /**
- * Destroy this elFinder instance
- *
- * @return void
- **/
- this.destroy = function() {
- if (node && node[0].elfinder) {
- this.trigger('destroy').disable();
- listeners = {};
- shortcuts = {};
- $(document).add(node).off('.'+this.namespace);
- self.trigger = function() { }
- node.children().remove();
- node.append(prevContent.contents()).removeClass(this.cssClass).attr('style', prevStyle);
- node[0].elfinder = null;
- if (syncInterval) {
- clearInterval(syncInterval);
- }
- }
- }
- /************* init stuffs ****************/
- // check jquery ui
- if (!($.fn.selectable && $.fn.draggable && $.fn.droppable)) {
- return alert(this.i18n('errJqui'));
- }
- // check node
- if (!node.length) {
- return alert(this.i18n('errNode'));
- }
- // check connector url
- if (!this.options.url) {
- return alert(this.i18n('errURL'));
- }
- $.extend($.ui.keyCode, {
- 'F1' : 112,
- 'F2' : 113,
- 'F3' : 114,
- 'F4' : 115,
- 'F5' : 116,
- 'F6' : 117,
- 'F7' : 118,
- 'F8' : 119,
- 'F9' : 120
- });
- this.dragUpload = false;
- this.xhrUpload = (typeof XMLHttpRequestUpload != 'undefined' || typeof XMLHttpRequestEventTarget != 'undefined') && typeof File != 'undefined' && typeof FormData != 'undefined';
- // configure transport object
- this.transport = {}
- if (typeof(this.options.transport) == 'object') {
- this.transport = this.options.transport;
- if (typeof(this.transport.init) == 'function') {
- this.transport.init(this)
- }
- }
- if (typeof(this.transport.send) != 'function') {
- this.transport.send = function(opts) { return $.ajax(opts); }
- }
- if (this.transport.upload == 'iframe') {
- this.transport.upload = $.proxy(this.uploads.iframe, this);
- } else if (typeof(this.transport.upload) == 'function') {
- this.dragUpload = !!this.options.dragUploadAllow;
- } else if (this.xhrUpload && !!this.options.dragUploadAllow) {
- this.transport.upload = $.proxy(this.uploads.xhr, this);
- this.dragUpload = true;
- } else {
- this.transport.upload = $.proxy(this.uploads.iframe, this);
- }
- /**
- * Alias for this.trigger('error', {error : 'message'})
- *
- * @param String error message
- * @return elFinder
- **/
- this.error = function() {
- var arg = arguments[0];
- return arguments.length == 1 && typeof(arg) == 'function'
- ? self.bind('error', arg)
- : self.trigger('error', {error : arg});
- }
- // create bind/trigger aliases for build-in events
- $.each(['enable', 'disable', 'load', 'open', 'reload', 'select', 'add', 'remove', 'change', 'dblclick', 'getfile', 'lockfiles', 'unlockfiles', 'selectfiles', 'unselectfiles', 'dragstart', 'dragstop', 'search', 'searchend', 'viewchange'], function(i, name) {
- self[name] = function() {
- var arg = arguments[0];
- return arguments.length == 1 && typeof(arg) == 'function'
- ? self.bind(name, arg)
- : self.trigger(name, $.isPlainObject(arg) ? arg : {});
- }
- });
- // bind core event handlers
- this
- .enable(function() {
- if (!enabled && self.visible() && self.ui.overlay.is(':hidden')) {
- enabled = true;
- document.activeElement && document.activeElement.blur();
- node.removeClass('elfinder-disabled');
- }
- })
- .disable(function() {
- prevEnabled = enabled;
- enabled = false;
- node.addClass('elfinder-disabled');
- })
- .open(function() {
- selected = [];
- })
- .select(function(e) {
- selected = $.map(e.data.selected || e.data.value|| [], function(hash) { return files[hash] ? hash : null; });
- })
- .error(function(e) {
- var opts = {
- cssClass : 'elfinder-dialog-error',
- title : self.i18n(self.i18n('error')),
- resizable : false,
- destroyOnClose : true,
- buttons : {}
- };
- opts.buttons[self.i18n(self.i18n('btnClose'))] = function() { $(this).elfinderdialog('close'); };
- self.dialog('<span class="elfinder-dialog-icon elfinder-dialog-icon-error"/>'+self.i18n(e.data.error), opts);
- })
- .bind('tree parents', function(e) {
- cache(e.data.tree || []);
- })
- .bind('tmb', function(e) {
- $.each(e.data.images||[], function(hash, tmb) {
- if (files[hash]) {
- files[hash].tmb = tmb;
- }
- })
- })
- .add(function(e) {
- cache(e.data.added||[]);
- })
- .change(function(e) {
- $.each(e.data.changed||[], function(i, file) {
- var hash = file.hash;
- if ((files[hash].width && !file.width) || (files[hash].height && !file.height)) {
- files[hash].width = undefined;
- files[hash].height = undefined;
- }
- files[hash] = files[hash] ? $.extend(files[hash], file) : file;
- });
- })
- .remove(function(e) {
- var removed = e.data.removed||[],
- l = removed.length,
- rm = function(hash) {
- var file = files[hash];
- if (file) {
- if (file.mime == 'directory' && file.dirs) {
- $.each(files, function(h, f) {
- f.phash == hash && rm(h);
- });
- }
- delete files[hash];
- }
- };
- while (l--) {
- rm(removed[l]);
- }
- })
- .bind('search', function(e) {
- cache(e.data.files);
- })
- .bind('rm', function(e) {
- var play = beeper.canPlayType && beeper.canPlayType('audio/wav; codecs="1"');
- play && play != '' && play != 'no' && $(beeper).html('<source src="' + soundPath + 'rm.wav" type="audio/wav">')[0].play()
- })
- ;
- // bind external event handlers
- $.each(this.options.handlers, function(event, callback) {
- self.bind(event, callback);
- });
- /**
- * History object. Store visited folders
- *
- * @type Object
- **/
- this.history = new this.history(this);
- // in getFileCallback set - change default actions on double click/enter/ctrl+enter
- if (typeof(this.options.getFileCallback) == 'function' && this.commands.getfile) {
- this.bind('dblclick', function(e) {
- e.preventDefault();
- self.exec('getfile').fail(function() {
- self.exec('open');
- });
- });
- /*this.shortcut({
- pattern : 'enter',
- description : this.i18n('cmdgetfile'),
- callback : function() { self.exec('getfile').fail(function() { self.exec(self.OS == 'mac' ? 'rename' : 'open') }) }
- })
- .shortcut({
- pattern : 'ctrl+enter',
- description : this.i18n(this.OS == 'mac' ? 'cmdrename' : 'cmdopen'),
- callback : function() { self.exec(self.OS == 'mac' ? 'rename' : 'open') }
- });*/
- }
- /**
- * Loaded commands
- *
- * @type Object
- **/
- this._commands = {};
- if (!$.isArray(this.options.commands)) {
- this.options.commands = [];
- }
- // check required commands
- $.each(['open', 'reload', 'back', 'forward', 'up', 'home', 'info', 'quicklook', 'getfile', 'help'], function(i, cmd) {
- $.inArray(cmd, self.options.commands) === -1 && self.options.commands.push(cmd);
- });
- // load commands
- $.each(this.options.commands, function(i, name) {
- var cmd = self.commands[name];
- if ($.isFunction(cmd) && !self._commands[name]) {
- cmd.prototype = base;
- self._commands[name] = new cmd();
- self._commands[name].setup(name, self.options.commandsOptions[name]||{});
- }
- });
- /**
- * UI command map of cwd volume ( That volume driver option `uiCmdMap` )
- *
- * @type Object
- **/
- this.commandMap = {};
- /**
- * Disabled commands Array of each volume
- *
- * @type Object
- */
- this.disabledCmds = {};
- // prepare node
- node.addClass(this.cssClass)
- .on(mousedown, function() {
- !enabled && self.enable();
- });
- /**
- * UI nodes
- *
- * @type Object
- **/
- this.ui = {
- // container for nav panel and current folder container
- workzone : $('<div/>').appendTo(node).elfinderworkzone(this),
- // container for folders tree / places
- navbar : $('<div/>').appendTo(node).elfindernavbar(this, this.options.uiOptions.navbar || {}),
- // contextmenu
- contextmenu : $('<div/>').appendTo(node).elfindercontextmenu(this),
- // overlay
- overlay : $('<div/>').appendTo(node).elfinderoverlay({
- show : function() { self.disable(); },
- hide : function() { prevEnabled && self.enable(); }
- }),
- // current folder container
- cwd : $('<div/>').appendTo(node).elfindercwd(this, this.options.uiOptions.cwd || {}),
- // notification dialog window
- notify : this.dialog('', {
- cssClass : 'elfinder-dialog-notify',
- position : this.options.notifyDialog.position,
- resizable : false,
- autoOpen : false,
- title : ' ',
- width : parseInt(this.options.notifyDialog.width)
- }),
- statusbar : $('<div class="ui-widget-header ui-helper-clearfix ui-corner-bottom elfinder-statusbar"/>').hide().appendTo(node)
- }
- // load required ui
- $.each(this.options.ui || [], function(i, ui) {
- var name = 'elfinder'+ui,
- opts = self.options.uiOptions[ui] || {};
- if (!self.ui[ui] && $.fn[name]) {
- self.ui[ui] = $('<'+(opts.tag || 'div')+'/>').appendTo(node)[name](self, opts);
- }
- });
- // store instance in node
- node[0].elfinder = this;
- // make node resizable
- this.options.resizable
- && !this.UA.Touch
- && $.fn.resizable
- && node.resizable({
- handles : 'se',
- minWidth : 300,
- minHeight : 200
- });
- if (this.options.width) {
- width = this.options.width;
- }
- if (this.options.height) {
- height = parseInt(this.options.height);
- }
- if (this.options.soundPath) {
- soundPath = this.options.soundPath.replace(/\/+$/, '') + '/';
- }
- // update size
- self.resize(width, height);
- // attach events to document
- $(document)
- // disable elfinder on click outside elfinder
- .on('click.'+this.namespace, function(e) { enabled && !$(e.target).closest(node).length && self.disable(); })
- // exec shortcuts
- .on(keydown+' '+keypress, execShortcut);
- // attach events to window
- self.options.useBrowserHistory && $(window)
- .on('popstate', function(ev) {
- var target = ev.originalEvent.state && ev.originalEvent.state.thash;
- target && !$.isEmptyObject(self.files()) && self.request({
- data : {cmd : 'open', target : target, onhistory : 1},
- notify : {type : 'open', cnt : 1, hideCnt : true},
- syncOnFail : true
- });
- });
- // send initial request and start to pray >_<
- this.trigger('init')
- .request({
- data : {cmd : 'open', target : self.startDir(), init : 1, tree : this.ui.tree ? 1 : 0},
- preventDone : true,
- notify : {type : 'open', cnt : 1, hideCnt : true},
- freeze : true
- })
- .fail(function() {
- self.trigger('fail').disable().lastDir('');
- listeners = {};
- shortcuts = {};
- $(document).add(node).off('.'+this.namespace);
- self.trigger = function() { };
- })
- .done(function(data) {
- self.load().debug('api', self.api);
- data = $.extend(true, {}, data);
- open(data);
- self.trigger('open', data);
- });
- // update ui's size after init
- this.one('load', function() {
- node.trigger('resize');
- if (self.options.sync > 1000) {
- syncInterval = setInterval(function() {
- self.sync();
- }, self.options.sync)
- }
- });
- (function(){
- var tm;
- $(window).on('resize', function(){
- tm && clearTimeout(tm);
- tm = setTimeout(function() {
- self.trigger('resize', {width : node.width(), height : node.height()});
- }, 200);
- })
- .on('beforeunload',function(){
- if (self.ui.notify.children().length) {
- return self.i18n('ntfsmth');
- }
- });
- })();
- // bind window onmessage for CORS
- $(window).on('message', function(e){
- var res = e.originalEvent || null,
- obj, data;
- if (res && self.uploadURL.indexOf(res.origin) === 0) {
- try {
- obj = JSON.parse(res.data);
- data = obj.data || null;
- if (data) {
- if (data.error) {
- self.error(data.error);
- } else {
- data.warning && self.error(data.warning);
- data.removed && data.removed.length && self.remove(data);
- data.added && data.added.length && self.add(data);
- data.changed && data.changed.length && self.change(data);
- if (obj.bind) {
- self.trigger(obj.bind, data);
- }
- data.sync && self.sync();
- }
- }
- } catch (e) {
- self.sync();
- }
- }
- });
- if (self.dragUpload) {
- node[0].addEventListener('dragenter', function(e) {
- if (e.target.nodeName !== 'TEXTAREA' && e.target.nodeName !== 'INPUT') {
- e.preventDefault();
- e.stopPropagation();
- }
- }, false);
- node[0].addEventListener('dragleave', function(e) {
- if (e.target.nodeName !== 'TEXTAREA' && e.target.nodeName !== 'INPUT') {
- e.preventDefault();
- e.stopPropagation();
- }
- }, false);
- node[0].addEventListener('dragover', function(e) {
- if (e.target.nodeName !== 'TEXTAREA' && e.target.nodeName !== 'INPUT') {
- e.preventDefault();
- e.stopPropagation();
- }
- }, false);
- node[0].addEventListener('drop', function(e) {
- if (e.target.nodeName !== 'TEXTAREA' && e.target.nodeName !== 'INPUT') {
- e.stopPropagation();
- e.preventDefault();
- if ($(e.target).is('[class*="elfinder"]')) {
- self.error(['errUploadFile', self.i18n('items'), 'errPerm']);
- }
- }
- }, false);
- }
- // self.timeEnd('load');
- }
- /**
- * Prototype
- *
- * @type Object
- */
- elFinder.prototype = {
- res : function(type, id) {
- return this.resources[type] && this.resources[type][id];
- },
- /**
- * Internationalization object
- *
- * @type Object
- */
- i18 : {
- en : {
- translator : '',
- language : 'English',
- direction : 'ltr',
- dateFormat : 'd.m.Y H:i',
- fancyDateFormat : '$1 H:i',
- messages : {}
- },
- months : ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
- monthsShort : ['msJan', 'msFeb', 'msMar', 'msApr', 'msMay', 'msJun', 'msJul', 'msAug', 'msSep', 'msOct', 'msNov', 'msDec'],
- days : ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
- daysShort : ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
- },
- /**
- * File mimetype to kind mapping
- *
- * @type Object
- */
- kinds : {
- 'unknown' : 'Unknown',
- 'directory' : 'Folder',
- 'symlink' : 'Alias',
- 'symlink-broken' : 'AliasBroken',
- 'application/x-empty' : 'TextPlain',
- 'application/postscript' : 'Postscript',
- 'application/vnd.ms-office' : 'MsOffice',
- 'application/vnd.ms-word' : 'MsWord',
- 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' : 'MsWord',
- 'application/vnd.ms-word.document.macroEnabled.12' : 'MsWord',
- 'application/vnd.openxmlformats-officedocument.wordprocessingml.template' : 'MsWord',
- 'application/vnd.ms-word.template.macroEnabled.12' : 'MsWord',
- 'application/vnd.ms-excel' : 'MsExcel',
- 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' : 'MsExcel',
- 'application/vnd.ms-excel.sheet.macroEnabled.12' : 'MsExcel',
- 'application/vnd.openxmlformats-officedocument.spreadsheetml.template' : 'MsExcel',
- 'application/vnd.ms-excel.template.macroEnabled.12' : 'MsExcel',
- 'application/vnd.ms-excel.sheet.binary.macroEnabled.12' : 'MsExcel',
- 'application/vnd.ms-excel.addin.macroEnabled.12' : 'MsExcel',
- 'application/vnd.ms-powerpoint' : 'MsPP',
- 'application/vnd.openxmlformats-officedocument.presentationml.presentation' : 'MsPP',
- 'application/vnd.ms-powerpoint.presentation.macroEnabled.12' : 'MsPP',
- 'application/vnd.openxmlformats-officedocument.presentationml.slideshow' : 'MsPP',
- 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12' : 'MsPP',
- 'application/vnd.openxmlformats-officedocument.presentationml.template' : 'MsPP',
- 'application/vnd.ms-powerpoint.template.macroEnabled.12' : 'MsPP',
- 'application/vnd.ms-powerpoint.addin.macroEnabled.12' : 'MsPP',
- 'application/vnd.openxmlformats-officedocument.presentationml.slide' : 'MsPP',
- 'application/vnd.ms-powerpoint.slide.macroEnabled.12' : 'MsPP',
- 'application/pdf' : 'PDF',
- 'application/xml' : 'XML',
- 'application/vnd.oasis.opendocument.text' : 'OO',
- 'application/vnd.oasis.opendocument.text-template' : 'OO',
- 'application/vnd.oasis.opendocument.text-web' : 'OO',
- 'application/vnd.oasis.opendocument.text-master' : 'OO',
- 'application/vnd.oasis.opendocument.graphics' : 'OO',
- 'application/vnd.oasis.opendocument.graphics-template' : 'OO',
- 'application/vnd.oasis.opendocument.presentation' : 'OO',
- 'application/vnd.oasis.opendocument.presentation-template' : 'OO',
- 'application/vnd.oasis.opendocument.spreadsheet' : 'OO',
- 'application/vnd.oasis.opendocument.spreadsheet-template' : 'OO',
- 'application/vnd.oasis.opendocument.chart' : 'OO',
- 'application/vnd.oasis.opendocument.formula' : 'OO',
- 'application/vnd.oasis.opendocument.database' : 'OO',
- 'application/vnd.oasis.opendocument.image' : 'OO',
- 'application/vnd.openofficeorg.extension' : 'OO',
- 'application/x-shockwave-flash' : 'AppFlash',
- 'application/flash-video' : 'Flash video',
- 'application/x-bittorrent' : 'Torrent',
- 'application/javascript' : 'JS',
- 'application/rtf' : 'RTF',
- 'application/rtfd' : 'RTF',
- 'application/x-font-ttf' : 'TTF',
- 'application/x-font-otf' : 'OTF',
- 'application/x-rpm' : 'RPM',
- 'application/x-web-config' : 'TextPlain',
- 'application/xhtml+xml' : 'HTML',
- 'application/docbook+xml' : 'DOCBOOK',
- 'application/x-awk' : 'AWK',
- 'application/x-gzip' : 'GZIP',
- 'application/x-bzip2' : 'BZIP',
- 'application/x-xz' : 'XZ',
- 'application/zip' : 'ZIP',
- 'application/x-zip' : 'ZIP',
- 'application/x-rar' : 'RAR',
- 'application/x-tar' : 'TAR',
- 'application/x-7z-compressed' : '7z',
- 'application/x-jar' : 'JAR',
- 'text/plain' : 'TextPlain',
- 'text/x-php' : 'PHP',
- 'text/html' : 'HTML',
- 'text/javascript' : 'JS',
- 'text/css' : 'CSS',
- 'text/rtf' : 'RTF',
- 'text/rtfd' : 'RTF',
- 'text/x-c' : 'C',
- 'text/x-csrc' : 'C',
- 'text/x-chdr' : 'CHeader',
- 'text/x-c++' : 'CPP',
- 'text/x-c++src' : 'CPP',
- 'text/x-c++hdr' : 'CPPHeader',
- 'text/x-shellscript' : 'Shell',
- 'application/x-csh' : 'Shell',
- 'text/x-python' : 'Python',
- 'text/x-java' : 'Java',
- 'text/x-java-source' : 'Java',
- 'text/x-ruby' : 'Ruby',
- 'text/x-perl' : 'Perl',
- 'text/x-sql' : 'SQL',
- 'text/xml' : 'XML',
- 'text/x-comma-separated-values' : 'CSV',
- 'text/x-markdown' : 'Markdown',
- 'image/x-ms-bmp' : 'BMP',
- 'image/jpeg' : 'JPEG',
- 'image/gif' : 'GIF',
- 'image/png' : 'PNG',
- 'image/tiff' : 'TIFF',
- 'image/x-targa' : 'TGA',
- 'image/vnd.adobe.photoshop' : 'PSD',
- 'image/xbm' : 'XBITMAP',
- 'image/pxm' : 'PXM',
- 'audio/mpeg' : 'AudioMPEG',
- 'audio/midi' : 'AudioMIDI',
- 'audio/ogg' : 'AudioOGG',
- 'audio/mp4' : 'AudioMPEG4',
- 'audio/x-m4a' : 'AudioMPEG4',
- 'audio/wav' : 'AudioWAV',
- 'audio/x-mp3-playlist' : 'AudioPlaylist',
- 'video/x-dv' : 'VideoDV',
- 'video/mp4' : 'VideoMPEG4',
- 'video/mpeg' : 'VideoMPEG',
- 'video/x-msvideo' : 'VideoAVI',
- 'video/quicktime' : 'VideoMOV',
- 'video/x-ms-wmv' : 'VideoWM',
- 'video/x-flv' : 'VideoFlash',
- 'video/x-matroska' : 'VideoMKV',
- 'video/ogg' : 'VideoOGG'
- },
- /**
- * Ajax request data validation rules
- *
- * @type Object
- */
- rules : {
- defaults : function(data) {
- if (!data
- || (data.added && !$.isArray(data.added))
- || (data.removed && !$.isArray(data.removed))
- || (data.changed && !$.isArray(data.changed))) {
- return false;
- }
- return true;
- },
- open : function(data) { return data && data.cwd && data.files && $.isPlainObject(data.cwd) && $.isArray(data.files); },
- tree : function(data) { return data && data.tree && $.isArray(data.tree); },
- parents : function(data) { return data && data.tree && $.isArray(data.tree); },
- tmb : function(data) { return data && data.images && ($.isPlainObject(data.images) || $.isArray(data.images)); },
- upload : function(data) { return data && ($.isPlainObject(data.added) || $.isArray(data.added));},
- search : function(data) { return data && data.files && $.isArray(data.files)}
- },
- /**
- * Commands costructors
- *
- * @type Object
- */
- commands : {},
- parseUploadData : function(text) {
- var data;
- if (!$.trim(text)) {
- return {error : ['errResponse', 'errDataEmpty']};
- }
- try {
- data = $.parseJSON(text);
- } catch (e) {
- return {error : ['errResponse', 'errDataNotJSON']};
- }
- if (!this.validResponse('upload', data)) {
- return {error : ['errResponse']};
- }
- data = this.normalize(data);
- data.removed = $.merge((data.removed || []), $.map(data.added||[], function(f) { return f.hash; }));
- return data;
- },
- iframeCnt : 0,
- uploads : {
- // xhr muiti uploading flag
- xhrUploading: false,
- // check droped contents
- checkFile : function(data, fm) {
- if (!!data.checked || data.type == 'files') {
- return data.files;
- } else if (data.type == 'data') {
- var dfrd = $.Deferred(),
- files = [],
- paths = [],
- dirctorys = [],
- entries = [],
- processing = 0,
- readEntries = function(dirReader) {
- var toArray = function(list) {
- return Array.prototype.slice.call(list || []);
- };
- var readFile = function(fileEntry, callback) {
- var dfrd = $.Deferred();
- if (typeof fileEntry == 'undefined') {
- dfrd.reject('empty');
- } else if (fileEntry.isFile) {
- fileEntry.file(function (file) {
- dfrd.resolve(file);
- }, function(e){
- dfrd.reject();
- });
- } else {
- dfrd.reject('dirctory');
- }
- return dfrd.promise();
- };
- dirReader.readEntries(function (results) {
- if (!results.length) {
- var len = entries.length - 1;
- var read = function(i) {
- readFile(entries[i]).done(function(file){
- if (! (fm.OS == 'win' && file.name.match(/^(?:desktop\.ini|thumbs\.db)$/i))
- &&
- ! (fm.OS == 'mac' && file.name.match(/^\.ds_store$/i))) {
- paths.push(entries[i].fullPath);
- files.push(file);
- }
- }).fail(function(e){
- if (e == 'dirctory') {
- // dirctory
- dirctorys.push(entries[i]);
- } else if (e == 'empty') {
- // dirctory is empty
- } else {
- // why fail?
- }
- }).always(function(){
- processing--;
- if (i < len) {
- processing++;
- read(++i);
- }
- });
- };
- processing++;
- read(0);
- processing--;
- } else {
- entries = entries.concat(toArray(results));
- readEntries(dirReader);
- }
- });
- },
- doScan = function(items, isEntry) {
- var dirReader, entry;
- entries = [];
- var length = items.length;
- for (var i = 0; i < length; i++) {
- if (! isEntry) {
- entry = !!items[i].getAsEntry? items[i].getAsEntry() : items[i].webkitGetAsEntry();
- } else {
- entry = items[i];
- }
- if (entry) {
- if (entry.isFile) {
- paths.push('');
- files.push(data.files.items[i].getAsFile());
- } else if (entry.isDirectory) {
- if (processing > 0) {
- dirctorys.push(entry);
- } else {
- processing = 0;
- dirReader = entry.createReader();
- processing++;
- readEntries(dirReader);
- }
- }
- }
- }
- };
- doScan(data.files.items);
- setTimeout(function wait() {
- if (processing > 0) {
- setTimeout(wait, 10);
- } else {
- if (dirctorys.length > 0) {
- doScan([dirctorys.shift()], true);
- setTimeout(wait, 10);
- } else {
- dfrd.resolve([files, paths]);
- }
- }
- }, 10);
- return dfrd.promise();
- } else {
- var ret = [];
- var check = [];
- var str = data.files[0];
- if (data.type == 'html') {
- var tmp = $("<html/>").append($.parseHTML(str)),
- atag;
- $('img[src]', tmp).each(function(){
- var url, purl,
- self = $(this),
- pa = self.closest('a');
- if (pa && pa.attr('href') && pa.attr('href').match(/\.(?:jpe?g|gif|bmp|png)/i)) {
- purl = pa.attr('href');
- }
- url = self.attr('src');
- if (url) {
- if (purl) {
- $.inArray(purl, ret) == -1 && ret.push(purl);
- $.inArray(url, check) == -1 && check.push(url);
- } else {
- $.inArray(url, ret) == -1 && ret.push(url);
- }
- }
- });
- atag = $('a[href]', tmp);
- atag.each(function(){
- var loc,
- parseUrl = function(url) {
- var a = document.createElement('a');
- a.href = url;
- return a;
- };
- if ($(this).text()) {
- loc = parseUrl($(this).attr('href'));
- if (loc.href && (atag.length === 1 || ! loc.pathname.match(/(?:\.html?|\/[^\/.]*)$/i))) {
- if ($.inArray(loc.href, ret) == -1 && $.inArray(loc.href, check) == -1) ret.push(loc.href);
- }
- }
- });
- } else {
- var regex, m, url;
- regex = /(http[^<>"{}|\\^\[\]`\s]+)/ig;
- while (m = regex.exec(str)) {
- url = m[1].replace(/&/g, '&');
- if ($.inArray(url, ret) == -1) ret.push(url);
- }
- }
- return ret;
- }
- },
- // upload transport using XMLHttpRequest
- xhr : function(data, fm) {
- var self = fm ? fm : this,
- xhr = new XMLHttpRequest(),
- notifyto = null, notifyto2 = null,
- dataChecked = data.checked,
- isDataType = (data.isDataType || data.type == 'data'),
- retry = 0,
- cancelBtn = 'div.elfinder-notify-upload div.elfinder-notify-cancel button',
- dfrd = $.Deferred()
- .fail(function(error) {
- var file = isDataType? files[0][0] : files[0];
- if (file._cid) {
- formData = new FormData();
- files = [{_chunkfail: true}];
- formData.append('chunk', file._chunk);
- formData.append('cid' , file._cid);
- isDataType = false;
- send(files);
- }
- files = null;
- error && self.error(error);
- })
- .done(function(data) {
- xhr = null;
- files = null;
- if (data) {
- data.warning && self.error(data.warning);
- data.removed && self.remove(data);
- data.added && self.add(data);
- data.changed && self.change(data);
- self.trigger('upload', data);
- data.sync && self.sync();
- }
- })
- .always(function() {
- notifyto && clearTimeout(notifyto);
- notifyto2 && clearTimeout(notifyto2);
- dataChecked && !data.multiupload && checkNotify() && self.notify({type : 'upload', cnt : -cnt, progress : 0, size : 0});
- chunkMerge && self.ui.notify.children('.elfinder-notify-chunkmerge').length && self.notify({type : 'chunkmerge', cnt : -1});
- self.ui.notify.off('click', cancelBtn, fnAbort);
- $(document).off('keydown', fnAbort);
- }),
- formData = new FormData(),
- files = data.input ? data.input.files : self.uploads.checkFile(data, self),
- cnt = data.checked? (isDataType? files[0].length : files.length) : files.length,
- loaded = 0, prev,
- filesize = 0,
- notify = false,
- abort = false,
- checkNotify = function() {
- return notify = (notify || self.ui.notify.children('.elfinder-notify-upload').length);
- },
- startNotify = function(size) {
- if (!size) size = filesize;
- return setTimeout(function() {
- notify = true;
- self.notify({type : 'upload', cnt : cnt, progress : loaded - prev, size : size, cancel: true});
- prev = loaded;
- }, self.options.notifyDelay);
- },
- fnAbort = function(e) {
- if (e.type == 'keydown' && e.keyCode != $.ui.keyCode.ESCAPE) {
- return;
- }
- e.preventDefault();
- e.stopPropagation();
- abort = true;
- xhr.abort();
- dfrd.reject();
- self.sync();
- },
- target = (data.target || self.cwd().hash),
- chunkMerge = false;
- // regist abort event
- self.ui.notify.one('click', cancelBtn, fnAbort);
- $(document).on('keydown', fnAbort);
- $(window).on('unload', function(e){
- (dfrd.state() == 'pending') && dfrd.reject();
- });
- !chunkMerge && (prev = loaded);
- if (!isDataType && !cnt) {
- return dfrd.reject(['errUploadNoFiles']);
- }
- xhr.addEventListener('error', function() {
- dfrd.reject('errConnect');
- }, false);
- xhr.addEventListener('abort', function() {
- dfrd.reject(['errConnect', 'errAbort']);
- }, false);
- xhr.addEventListener('load', function(e) {
- var status = xhr.status, res, curr = 0, error = '';
- if (status >= 400) {
- if (status > 500) {
- error = 'errResponse';
- } else {
- error = 'errConnect';
- }
- } else {
- if (xhr.readyState != 4) {
- error = ['errConnect', 'errTimeout']; // am i right?
- }
- if (!xhr.responseText) {
- error = ['errResponse', 'errDataEmpty'];
- }
- }
- if (error) {
- if (chunkMerge || retry++ > 3) {
- var file = isDataType? files[0][0] : files[0];
- if (file._cid) {
- formData = new FormData();
- files = [{_chunkfail: true}];
- formData.append('chunk', file._chunk);
- formData.append('cid' , file._cid);
- formData.append('range', file._range);
- isDataType = false;
- send(files);
- return;
- }
- return dfrd.reject(error);
- } else {
- filesize = 0;
- xhr.open('POST', self.uploadURL, true);
- xhr.send(formData);
- return;
- }
- }
- loaded = filesize;
- if (checkNotify() && (curr = loaded - prev)) {
- self.notify({type : 'upload', cnt : 0, progress : curr, size : 0});
- }
- res = self.parseUploadData(xhr.responseText);
- // chunked upload commit
- if (res._chunkmerged) {
- formData = new FormData();
- var _file = [{_chunkmerged: res._chunkmerged, _name: res._name}];
- chunkMerge = true;
- notifyto2 = setTimeout(function() {
- self.notify({type : 'chunkmerge', cnt : 1});
- }, self.options.notifyDelay);
- isDataType? send(_file, files[1]) : send(_file);
- return;
- }
- res._multiupload = data.multiupload? true : false;
- if (res.error) {
- if (res._chunkfailure) {
- abort = true;
- self.uploads.xhrUploading = false;
- notifyto && clearTimeout(notifyto);
- if (self.ui.notify.children('.elfinder-notify-upload').length) {
- self.notify({type : 'upload', cnt : -cnt, progress : 0, size : 0});
- dfrd.reject(res.error);
- } else {
- // for multi connection
- dfrd.reject();
- }
- } else {
- dfrd.reject(res.error);
- }
- } else {
- dfrd.resolve(res);
- }
- }, false);
- xhr.upload.addEventListener('loadstart', function(e) {
- if (!chunkMerge && e.lengthComputable) {
- loaded = e.loaded;
- retry && (loaded = 0);
- filesize = e.total;
- if (!loaded) {
- loaded = parseInt(filesize * 0.05);
- }
- if (checkNotify()) {
- self.notify({type : 'upload', cnt : 0, progress : loaded - prev, size : data.multiupload? 0 : filesize});
- prev = loaded;
- }
- }
- }, false);
- xhr.upload.addEventListener('progress', function(e) {
- var curr;
- if (e.lengthComputable && !chunkMerge) {
- loaded = e.loaded;
- // to avoid strange bug in safari (not in chrome) with drag&drop.
- // bug: macos finder opened in any folder,
- // reset safari cache (option+command+e), reload elfinder page,
- // drop file from finder
- // on first attempt request starts (progress callback called ones) but never ends.
- // any next drop - successfull.
- if (!data.checked && loaded > 0 && !notifyto) {
- notifyto = startNotify(xhr._totalSize - loaded);
- }
- if (!filesize) {
- retry && (loaded = 0);
- filesize = e.total;
- if (!loaded) {
- loaded = parseInt(filesize * 0.05);
- }
- }
- curr = loaded - prev;
- if (checkNotify() && (curr/e.total) >= 0.05) {
- self.notify({type : 'upload', cnt : 0, progress : curr, size : 0});
- prev = loaded;
- }
- }
- }, false);
- var send = function(files, paths){
- var size = 0,
- fcnt = 1,
- sfiles = [],
- c = 0,
- total = cnt,
- maxFileSize,
- totalSize = 0,
- chunked = [],
- chunkID = +new Date(),
- BYTES_PER_CHUNK = Math.min((fm.uplMaxSize || 2097152) - 8190, fm.options.uploadMaxChunkSize), // uplMaxSize margin 8kb or options.uploadMaxChunkSize
- blobSlice = false,
- blobSize, i, start, end, chunks, blob, chunk, added, done, last, failChunk,
- multi = function(files, num){
- var sfiles = [], cid;
- if (!abort) {
- while(files.length && sfiles.length < num) {
- sfiles.push(files.shift());
- }
- }
- if (sfiles.length) {
- for (var i=0; i < sfiles.length; i++) {
- if (abort) {
- break;
- }
- cid = isDataType? (sfiles[i][0][0]._cid || null) : (sfiles[i][0]._cid || null);
- if (!!failChunk[cid]) {
- last--;
- continue;
- }
- fm.exec('upload', {
- type: data.type,
- isDataType: isDataType,
- files: sfiles[i],
- checked: true,
- target: target,
- multiupload: true})
- .fail(function(error) {
- if (cid) {
- failChunk[cid] = true;
- }
- //error && self.error(error);
- })
- .always(function(e) {
- if (e && e.added) added = $.merge(added, e.added);
- if (last <= ++done) {
- fm.trigger('multiupload', {added: added});
- notifyto && clearTimeout(notifyto);
- if (checkNotify()) {
- self.notify({type : 'upload', cnt : -cnt, progress : 0, size : 0});
- }
- }
- multi(files, 1); // Next one
- });
- }
- } else {
- self.uploads.xhrUploading = false;
- if (abort) {
- notifyto && clearTimeout(notifyto);
- if (checkNotify()) {
- self.notify({type : 'upload', cnt : -cnt, progress : 0, size : 0});
- }
- if (cid) {
- failChunk[cid] = true;
- }
- }
- dfrd.resolve();
- }
- },
- check = function(){
- if (!self.uploads.xhrUploading) {
- self.uploads.xhrUploading = true;
- multi(sfiles, 3); // Max connection: 3
- } else {
- setTimeout(function(){ check(); }, 100);
- }
- };
- if (! dataChecked && (isDataType || data.type == 'files')) {
- maxFileSize = fm.option('uploadMaxSize')? fm.option('uploadMaxSize') : 0;
- for (i=0; i < files.length; i++) {
- blob = files[i];
- blobSize = blob.size;
- if (blobSlice === false) {
- if ('slice' in blob) {
- blobSlice = 'slice';
- } else if ('mozSlice' in blob) {
- blobSlice = 'mozSlice';
- } else if ('webkitSlice' in blob) {
- blobSlice = 'webkitSlice';
- } else {
- blobSlice = '';
- }
- }
- if ((maxFileSize && blobSize > maxFileSize) || (!blobSlice && fm.uplMaxSize && blobSize > fm.uplMaxSize)) {
- self.error(self.i18n('errUploadFile', blob.name) + ' ' + self.i18n('errUploadFileSize'));
- cnt--;
- total--;
- continue;
- }
- if (blobSlice && blobSize > BYTES_PER_CHUNK) {
- start = 0;
- end = BYTES_PER_CHUNK;
- chunks = -1;
- total = Math.floor(blobSize / BYTES_PER_CHUNK);
- totalSize += blobSize;
- chunked[chunkID] = 0;
- while(start <= blobSize) {
- chunk = blob[blobSlice](start, end);
- chunk._chunk = blob.name + '.' + ++chunks + '_' + total + '.part';
- chunk._cid = chunkID;
- chunk._range = start + ',' + chunk.size + ',' + blobSize;
- chunked[chunkID]++;
- if (size) {
- c++;
- }
- if (typeof sfiles[c] == 'undefined') {
- sfiles[c] = [];
- if (isDataType) {
- sfiles[c][0] = [];
- sfiles[c][1] = [];
- }
- }
- size = fm.uplMaxSize;
- fcnt = 1;
- if (isDataType) {
- sfiles[c][0].push(chunk);
- sfiles[c][1].push(paths[i]);
- } else {
- sfiles[c].push(chunk);
- }
- start = end;
- end = start + BYTES_PER_CHUNK;
- }
- if (chunk == null) {
- self.error(self.i18n('errUploadFile', blob.name) + ' ' + self.i18n('errUploadFileSize'));
- cnt--;
- total--;
- } else {
- total += chunks;
- }
- continue;
- }
- if ((fm.uplMaxSize && size + blobSize >= fm.uplMaxSize) || fcnt > fm.uplMaxFile) {
- size = 0;
- fcnt = 1;
- c++;
- }
- if (typeof sfiles[c] == 'undefined') {
- sfiles[c] = [];
- if (isDataType) {
- sfiles[c][0] = [];
- sfiles[c][1] = [];
- }
- }
- if (isDataType) {
- sfiles[c][0].push(blob);
- sfiles[c][1].push(paths[i]);
- } else {
- sfiles[c].push(blob);
- }
- size += blobSize;
- totalSize += blobSize;
- fcnt++;
- }
- if (sfiles.length == 0) {
- // no data
- data.checked = true;
- return false;
- }
- if (sfiles.length > 1) {
- // multi upload
- notifyto = startNotify(totalSize);
- added = [];
- done = 0;
- last = sfiles.length;
- failChunk = [];
- check();
- return true;
- }
- // single upload
- if (isDataType) {
- files = sfiles[0][0];
- paths = sfiles[0][1];
- } else {
- files = sfiles[0];
- }
- }
- if (!dataChecked) {
- if (!fm.UA.Safari || !data.files) {
- notifyto = startNotify(totalSize);
- } else {
- xhr._totalSize = totalSize;
- }
- }
- dataChecked = true;
- if (! files.length) {
- dfrd.reject(['errUploadNoFiles']);
- }
- xhr.open('POST', self.uploadURL, true);
- // set request headers
- if (fm.customHeaders) {
- $.each(fm.customHeaders, function(key) {
- xhr.setRequestHeader(key, this);
- });
- }
- // set xhrFields
- if (fm.xhrFields) {
- $.each(fm.xhrFields, function(key) {
- if (key in xhr) {
- xhr[key] = this;
- }
- });
- }
- formData.append('cmd', 'upload');
- formData.append(self.newAPI ? 'target' : 'current', target);
- $.each(self.options.customData, function(key, val) {
- formData.append(key, val);
- });
- $.each(self.options.onlyMimes, function(i, mime) {
- formData.append('mimes['+i+']', mime);
- });
- $.each(files, function(i, file) {
- if (file._chunkmerged) {
- formData.append('chunk', file._chunkmerged);
- formData.append('upload[]', file._name);
- } else {
- if (file._chunkfail) {
- formData.append('upload[]', 'chunkfail');
- formData.append('mimes', 'chunkfail');
- } else {
- formData.append('upload[]', file);
- }
- if (file._chunk) {
- formData.append('chunk', file._chunk);
- formData.append('cid' , file._cid);
- formData.append('range', file._range);
- }
- }
- });
- if (isDataType) {
- $.each(paths, function(i, path) {
- formData.append('upload_path[]', path);
- });
- }
- xhr.onreadystatechange = function() {
- if (xhr.readyState == 4 && xhr.status == 0) {
- if (abort) {
- dfrd.reject();
- } else {
- var errors = ['errAbort'];
- // ff bug while send zero sized file
- // for safari - send directory
- if (!isDataType && data.files && $.map(data.files, function(f){return f.size === 0? f : null;}).length) {
- errors.push('errFolderUpload');
- }
- dfrd.reject(errors);
- }
- }
- };
- xhr.send(formData);
- return true;
- };
- if (! isDataType) {
- if (! send(files)) {
- dfrd.reject();
- }
- } else {
- if (dataChecked) {
- send(files[0], files[1]);
- } else {
- notifyto2 = setTimeout(function() {
- self.notify({type : 'readdir', cnt : 1, hideCnt: true});
- }, self.options.notifyDelay);
- files.done(function(result){
- notifyto2 && clearTimeout(notifyto2);
- self.notify({type : 'readdir', cnt : -1});
- cnt = result[0].length;
- if (cnt) {
- send(result[0], result[1]);
- } else {
- dfrd.reject(['errUploadNoFiles']);
- }
- }).fail(function(){
- dfrd.reject(['errUploadNoFiles']);
- });
- }
- }
- return dfrd;
- },
- // upload transport using iframe
- iframe : function(data, fm) {
- var self = fm ? fm : this,
- input = data.input? data.input : false,
- files = !input ? self.uploads.checkFile(data, self) : false,
- dfrd = $.Deferred()
- .fail(function(error) {
- error && self.error(error);
- })
- .done(function(data) {
- data.warning && self.error(data.warning);
- data.removed && self.remove(data);
- data.added && self.add(data);
- data.changed && self.change(data);
- self.trigger('upload', data);
- data.sync && self.sync();
- }),
- name = 'iframe-'+self.namespace+(++self.iframeCnt),
- form = $('<form action="'+self.uploadURL+'" method="post" enctype="multipart/form-data" encoding="multipart/form-data" target="'+name+'" style="display:none"><input type="hidden" name="cmd" value="upload" /></form>'),
- msie = this.UA.IE,
- // clear timeouts, close notification dialog, remove form/iframe
- onload = function() {
- abortto && clearTimeout(abortto);
- notifyto && clearTimeout(notifyto);
- notify && self.notify({type : 'upload', cnt : -cnt});
- setTimeout(function() {
- msie && $('<iframe src="javascript:false;"/>').appendTo(form);
- form.remove();
- iframe.remove();
- }, 100);
- },
- iframe = $('<iframe src="'+(msie ? 'javascript:false;' : 'about:blank')+'" name="'+name+'" style="position:absolute;left:-1000px;top:-1000px" />')
- .on('load', function() {
- iframe.off('load')
- .on('load', function() {
- //var data = self.parseUploadData(iframe.contents().text());
- onload();
- dfrd.reject();
- //data.error ? dfrd.reject(data.error) : dfrd.resolve(data);
- });
- // notify dialog
- notifyto = setTimeout(function() {
- notify = true;
- self.notify({type : 'upload', cnt : cnt});
- }, self.options.notifyDelay);
- // emulate abort on timeout
- if (self.options.iframeTimeout > 0) {
- abortto = setTimeout(function() {
- onload();
- dfrd.reject([errors.connect, errors.timeout]);
- }, self.options.iframeTimeout);
- }
- form.submit();
- }),
- cnt, notify, notifyto, abortto
- ;
- if (files && files.length) {
- $.each(files, function(i, val) {
- form.append('<input type="hidden" name="upload[]" value="'+val+'"/>');
- });
- cnt = 1;
- } else if (input && $(input).is(':file') && $(input).val()) {
- form.append(input);
- cnt = input.files ? input.files.length : 1;
- } else {
- return dfrd.reject();
- }
- form.append('<input type="hidden" name="'+(self.newAPI ? 'target' : 'current')+'" value="'+(data.target || self.cwd().hash)+'"/>')
- .append('<input type="hidden" name="html" value="1"/>')
- .append('<input type="hidden" name="node" value="'+self.id+'"/>')
- .append($(input).attr('name', 'upload[]'));
- $.each(self.options.onlyMimes||[], function(i, mime) {
- form.append('<input type="hidden" name="mimes[]" value="'+mime+'"/>');
- });
- $.each(self.options.customData, function(key, val) {
- form.append('<input type="hidden" name="'+key+'" value="'+val+'"/>');
- });
- form.appendTo('body');
- iframe.appendTo('body');
- return dfrd;
- }
- },
- /**
- * Bind callback to event(s) The callback is executed at most once per event.
- * To bind to multiply events at once, separate events names by space
- *
- * @param String event name
- * @param Function callback
- * @return elFinder
- */
- one : function(event, callback) {
- var self = this,
- h = $.proxy(callback, function(event) {
- setTimeout(function() {self.unbind(event.type, h);}, 3);
- return callback.apply(this, arguments);
- });
- return this.bind(event, h);
- },
- /**
- * Set/get data into/from localStorage
- *
- * @param String key
- * @param String|void value
- * @return String
- */
- localStorage : function(key, val) {
- var s = window.localStorage;
- key = 'elfinder-'+key+this.id;
- if (val === null) {
- return s.removeItem(key);
- }
- if (val !== void(0)) {
- try {
- s.setItem(key, val);
- } catch (e) {
- s.clear();
- s.setItem(key, val);
- }
- }
- return s.getItem(key);
- },
- /**
- * Get/set cookie
- *
- * @param String cookie name
- * @param String|void cookie value
- * @return String
- */
- cookie : function(name, value) {
- var d, o, c, i;
- name = 'elfinder-'+name+this.id;
- if (value === void(0)) {
- if (document.cookie && document.cookie != '') {
- c = document.cookie.split(';');
- name += '=';
- for (i=0; i<c.length; i++) {
- c[i] = $.trim(c[i]);
- if (c[i].substring(0, name.length) == name) {
- return decodeURIComponent(c[i].substring(name.length));
- }
- }
- }
- return '';
- }
- o = $.extend({}, this.options.cookie);
- if (value === null) {
- value = '';
- o.expires = -1;
- }
- if (typeof(o.expires) == 'number') {
- d = new Date();
- d.setTime(d.getTime()+(o.expires * 86400000));
- o.expires = d;
- }
- document.cookie = name+'='+encodeURIComponent(value)+'; expires='+o.expires.toUTCString()+(o.path ? '; path='+o.path : '')+(o.domain ? '; domain='+o.domain : '')+(o.secure ? '; secure' : '');
- return value;
- },
- /**
- * Get start directory (by location.hash or last opened directory)
- *
- * @return String
- */
- startDir : function() {
- var locHash = window.location.hash;
- if (locHash && locHash.match(/^#elf_/)) {
- return locHash.replace(/^#elf_/, '');
- } else if (this.options.startPathHash) {
- return this.options.startPathHash;
- } else {
- return this.lastDir();
- }
- },
- /**
- * Get/set last opened directory
- *
- * @param String|undefined dir hash
- * @return String
- */
- lastDir : function(hash) {
- return this.options.rememberLastDir ? this.storage('lastdir', hash) : '';
- },
- /**
- * Node for escape html entities in texts
- *
- * @type jQuery
- */
- _node : $('<span/>'),
- /**
- * Replace not html-safe symbols to html entities
- *
- * @param String text to escape
- * @return String
- */
- escape : function(name) {
- return this._node.text(name).html().replace(/"/g, '"').replace(/'/g, ''');
- },
- /**
- * Cleanup ajax data.
- * For old api convert data into new api format
- *
- * @param String command name
- * @param Object data from backend
- * @return Object
- */
- normalize : function(data) {
- var filter = function(file) {
- if (file && file.hash && file.name && file.mime) {
- if (file.mime == 'application/x-empty') {
- file.mime = 'text/plain';
- }
- return file;
- }
- return null;
- };
- if (data.files) {
- data.files = $.map(data.files, filter);
- }
- if (data.tree) {
- data.tree = $.map(data.tree, filter);
- }
- if (data.added) {
- data.added = $.map(data.added, filter);
- }
- if (data.changed) {
- data.changed = $.map(data.changed, filter);
- }
- if (data.api) {
- data.init = true;
- }
- return data;
- },
- /**
- * Update sort options
- *
- * @param {String} sort type
- * @param {String} sort order
- * @param {Boolean} show folder first
- */
- setSort : function(type, order, stickFolders) {
- this.storage('sortType', (this.sortType = this.sortRules[type] ? type : 'name'));
- this.storage('sortOrder', (this.sortOrder = /asc|desc/.test(order) ? order : 'asc'));
- this.storage('sortStickFolders', (this.sortStickFolders = !!stickFolders) ? 1 : '');
- this.trigger('sortchange');
- },
- _sortRules : {
- name : function(file1, file2) {
- var n1 = file1.name.toLowerCase(),
- n2 = file2.name.toLowerCase(),
- e1 = '',
- e2 = '',
- so = elFinder.prototype.naturalCompare,
- m, ret;
- if (m = n1.match(/^(.+)(\.[0-9a-z.]+)$/)) {
- n1 = m[1];
- e1 = m[2];
- }
- if (m = n2.match(/^(.+)(\.[0-9a-z.]+)$/)) {
- n2 = m[1];
- e2 = m[2];
- }
- ret = so(n1, n2);
- if (ret == 0 && (e1 || e2) && e1 != e2) {
- ret = so(e1, e2);
- }
- return ret;
- },
- size : function(file1, file2) {
- var size1 = parseInt(file1.size) || 0,
- size2 = parseInt(file2.size) || 0;
- return size1 == size2 ? 0 : size1 > size2 ? 1 : -1;
- },
- kind : function(file1, file2) {
- return elFinder.prototype.naturalCompare(file1.mime, file2.mime);
- },
- date : function(file1, file2) {
- var date1 = file1.ts || file1.date,
- date2 = file2.ts || file2.date;
- return date1 == date2 ? 0 : date1 > date2 ? 1 : -1
- }
- },
- /**
- * Compare strings for natural sort
- *
- * @param String
- * @param String
- * @return Number
- */
- naturalCompare : function(a, b) {
- var self = elFinder.prototype.naturalCompare;
- if (typeof self.loc == 'undefined') {
- self.loc = (navigator.userLanguage || navigator.browserLanguage || navigator.language || 'en-US');
- }
- if (typeof self.sort == 'undefined') {
- if ('11'.localeCompare('2', self.loc, {numeric: true}) > 0) {
- // Native support
- if (window.Intl && window.Intl.Collator) {
- self.sort = new Intl.Collator(self.loc, {numeric: true}).compare;
- } else {
- self.sort = function(a, b) {
- return a.localeCompare(b, self.loc, {numeric: true});
- };
- }
- } else {
- /*
- * Edited for elFinder (emulates localeCompare() by numeric) by Naoki Sawada aka nao-pon
- */
- /*
- * Huddle/javascript-natural-sort (https://github.com/Huddle/javascript-natural-sort)
- */
- /*
- * Natural Sort algorithm for Javascript - Version 0.7 - Released under MIT license
- * Author: Jim Palmer (based on chunking idea from Dave Koelle)
- * http://opensource.org/licenses/mit-license.php
- */
- self.sort = function(a, b) {
- var re = /(^-?[0-9]+(\.?[0-9]*)[df]?e?[0-9]?$|^0x[0-9a-f]+$|[0-9]+)/gi,
- sre = /(^[ ]*|[ ]*$)/g,
- dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/,
- hre = /^0x[0-9a-f]+$/i,
- ore = /^0/,
- syre = /^[\x01\x21-\x2f\x3a-\x40\x5b-\x60\x7b-\x7e]/, // symbol first - (Naoki Sawada)
- i = function(s) { return self.sort.insensitive && (''+s).toLowerCase() || ''+s },
- // convert all to strings strip whitespace
- // first character is "_", it's smallest - (Naoki Sawada)
- x = i(a).replace(sre, '').replace(/^_/, "\x01") || '',
- y = i(b).replace(sre, '').replace(/^_/, "\x01") || '',
- // chunk/tokenize
- xN = x.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'),
- yN = y.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'),
- // numeric, hex or date detection
- xD = parseInt(x.match(hre)) || (xN.length != 1 && x.match(dre) && Date.parse(x)),
- yD = parseInt(y.match(hre)) || xD && y.match(dre) && Date.parse(y) || null,
- oFxNcL, oFyNcL,
- locRes = 0;
- // first try and sort Hex codes or Dates
- if (yD) {
- if ( xD < yD ) return -1;
- else if ( xD > yD ) return 1;
- }
- // natural sorting through split numeric strings and default strings
- for(var cLoc=0, numS=Math.max(xN.length, yN.length); cLoc < numS; cLoc++) {
- // find floats not starting with '0', string or 0 if not defined (Clint Priest)
- oFxNcL = !(xN[cLoc] || '').match(ore) && parseFloat(xN[cLoc]) || xN[cLoc] || 0;
- oFyNcL = !(yN[cLoc] || '').match(ore) && parseFloat(yN[cLoc]) || yN[cLoc] || 0;
- // handle numeric vs string comparison - number < string - (Kyle Adams)
- // but symbol first < number - (Naoki Sawada)
- if (isNaN(oFxNcL) !== isNaN(oFyNcL)) {
- if (isNaN(oFxNcL) && (typeof oFxNcL !== 'string' || ! oFxNcL.match(syre))) {
- return 1;
- } else if (typeof oFyNcL !== 'string' || ! oFyNcL.match(syre)) {
- return -1;
- }
- }
- // use decimal number comparison if either value is string zero
- if (parseInt(oFxNcL, 10) === 0) oFxNcL = 0;
- if (parseInt(oFyNcL, 10) === 0) oFyNcL = 0;
- // rely on string comparison if different types - i.e. '02' < 2 != '02' < '2'
- if (typeof oFxNcL !== typeof oFyNcL) {
- oFxNcL += '';
- oFyNcL += '';
- }
- // use locale sensitive sort for strings when case insensitive
- // note: localeCompare interleaves uppercase with lowercase (e.g. A,a,B,b)
- if (self.sort.insensitive && typeof oFxNcL === 'string' && typeof oFyNcL === 'string') {
- locRes = oFxNcL.localeCompare(oFyNcL, self.loc);
- if (locRes !== 0) return locRes;
- }
- if (oFxNcL < oFyNcL) return -1;
- if (oFxNcL > oFyNcL) return 1;
- }
- return 0;
- };
- self.sort.insensitive = true;
- }
- }
- return self.sort(a, b);
- },
- /**
- * Compare files based on elFinder.sort
- *
- * @param Object file
- * @param Object file
- * @return Number
- */
- compare : function(file1, file2) {
- var self = this,
- type = self.sortType,
- asc = self.sortOrder == 'asc',
- stick = self.sortStickFolders,
- rules = self.sortRules,
- sort = rules[type],
- d1 = file1.mime == 'directory',
- d2 = file2.mime == 'directory',
- res;
- if (stick) {
- if (d1 && !d2) {
- return -1;
- } else if (!d1 && d2) {
- return 1;
- }
- }
- res = asc ? sort(file1, file2) : sort(file2, file1);
- return type != 'name' && res == 0
- ? res = asc ? rules.name(file1, file2) : rules.name(file2, file1)
- : res;
- },
- /**
- * Sort files based on config
- *
- * @param Array files
- * @return Array
- */
- sortFiles : function(files) {
- return files.sort(this.compare);
- },
- /**
- * Open notification dialog
- * and append/update message for required notification type.
- *
- * @param Object options
- * @example
- * this.notify({
- * type : 'copy',
- * msg : 'Copy files', // not required for known types @see this.notifyType
- * cnt : 3,
- * hideCnt : false, // true for not show count
- * progress : 10, // progress bar percents (use cnt : 0 to update progress bar)
- * cancel : false // show cancel button (should regist event at each caller @see this.uploads.xhr)
- * })
- * @return elFinder
- */
- notify : function(opts) {
- var type = opts.type,
- msg = this.messages['ntf'+type] ? this.i18n('ntf'+type) : this.i18n('ntfsmth'),
- ndialog = this.ui.notify,
- notify = ndialog.children('.elfinder-notify-'+type),
- ntpl = '<div class="elfinder-notify elfinder-notify-{type}"><span class="elfinder-dialog-icon elfinder-dialog-icon-{type}"/><span class="elfinder-notify-msg">{msg}</span> <span class="elfinder-notify-cnt"/><div class="elfinder-notify-progressbar"><div class="elfinder-notify-progress"/></div><div class="elfinder-notify-cancel"/></div></div>',
- delta = opts.cnt,
- size = (typeof opts.size != 'undefined')? parseInt(opts.size) : null,
- progress = (typeof opts.progress != 'undefined' && opts.progress >= 0) ? opts.progress : null,
- cancel = opts.cancel,
- clhover = 'ui-state-hover',
- cnt, total, prc, button;
- if (!type) {
- return this;
- }
- if (!notify.length) {
- notify = $(ntpl.replace(/\{type\}/g, type).replace(/\{msg\}/g, msg))
- .appendTo(ndialog)
- .data('cnt', 0);
- if (progress != null) {
- notify.data({progress : 0, total : 0});
- }
- if (cancel) {
- button = $('<button type="button" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"><span class="ui-button-text">'+this.i18n('btnCancel')+'</span></button>')
- .hover(function(e) {
- $(this).toggleClass(clhover, e.type == 'mouseenter');
- });
- notify.children('div.elfinder-notify-cancel').append(button);
- }
- }
- cnt = delta + parseInt(notify.data('cnt'));
- if (cnt > 0) {
- !opts.hideCnt && notify.children('.elfinder-notify-cnt').text('('+cnt+')');
- ndialog.is(':hidden') && ndialog.elfinderdialog('open');
- notify.data('cnt', cnt);
- if ((progress != null)
- && (total = notify.data('total')) >= 0
- && (prc = notify.data('progress')) >= 0) {
- total += size != null? size : delta;
- prc += progress;
- (size == null && delta < 0) && (prc += delta * 100);
- notify.data({progress : prc, total : total});
- if (size != null) {
- prc *= 100;
- total = Math.max(1, total);
- }
- progress = parseInt(prc/total);
- notify.find('.elfinder-notify-progress')
- .animate({
- width : (progress < 100 ? progress : 100)+'%'
- }, 20);
- }
- } else {
- notify.remove();
- !ndialog.children().length && ndialog.elfinderdialog('close');
- }
- return this;
- },
- /**
- * Open confirmation dialog
- *
- * @param Object options
- * @example
- * this.confirm({
- * title : 'Remove files',
- * text : 'Here is question text',
- * accept : { // accept callback - required
- * label : 'Continue',
- * callback : function(applyToAll) { fm.log('Ok') }
- * },
- * cancel : { // cancel callback - required
- * label : 'Cancel',
- * callback : function() { fm.log('Cancel')}
- * },
- * reject : { // reject callback - optionally
- * label : 'No',
- * callback : function(applyToAll) { fm.log('No')}
- * },
- * all : true // display checkbox "Apply to all"
- * })
- * @return elFinder
- */
- confirm : function(opts) {
- var complete = false,
- options = {
- cssClass : 'elfinder-dialog-confirm',
- modal : true,
- resizable : false,
- title : this.i18n(opts.title || 'confirmReq'),
- buttons : {},
- close : function() {
- !complete && opts.cancel.callback();
- $(this).elfinderdialog('destroy');
- }
- },
- apply = this.i18n('apllyAll'),
- label, checkbox;
- options.buttons[this.i18n(opts.accept.label)] = function() {
- opts.accept.callback(!!(checkbox && checkbox.prop('checked')))
- complete = true;
- $(this).elfinderdialog('close')
- };
- if (opts.reject) {
- options.buttons[this.i18n(opts.reject.label)] = function() {
- opts.reject.callback(!!(checkbox && checkbox.prop('checked')))
- complete = true;
- $(this).elfinderdialog('close')
- };
- }
- options.buttons[this.i18n(opts.cancel.label)] = function() {
- $(this).elfinderdialog('close')
- };
- if (opts.all) {
- if (opts.reject) {
- options.width = 370;
- }
- options.create = function() {
- checkbox = $('<input type="checkbox" />');
- $(this).next().children().before($('<label>'+apply+'</label>').prepend(checkbox));
- }
- options.open = function() {
- var pane = $(this).next(),
- width = parseInt(pane.children(':first').outerWidth() + pane.children(':last').outerWidth());
- if (width > parseInt(pane.width())) {
- $(this).closest('.elfinder-dialog').width(width+30);
- }
- }
- }
- return this.dialog('<span class="elfinder-dialog-icon elfinder-dialog-icon-confirm"/>' + this.i18n(opts.text), options);
- },
- /**
- * Create unique file name in required dir
- *
- * @param String file name
- * @param String parent dir hash
- * @return String
- */
- uniqueName : function(prefix, phash) {
- var i = 0, ext = '', p, name;
- prefix = this.i18n(prefix);
- phash = phash || this.cwd().hash;
- if (p = prefix.match(/^(.+)(\.[^.]+)$/)) {
- ext = p[2];
- prefix = p[1];
- }
- name = prefix+ext;
- if (!this.fileByName(name, phash)) {
- return name;
- }
- while (i < 10000) {
- name = prefix + ' ' + (++i) + ext;
- if (!this.fileByName(name, phash)) {
- return name;
- }
- }
- return prefix + Math.random() + ext;
- },
- /**
- * Return message translated onto current language
- *
- * @param String|Array message[s]
- * @return String
- **/
- i18n : function() {
- var self = this,
- messages = this.messages,
- input = [],
- ignore = [],
- message = function(m) {
- var file;
- if (m.indexOf('#') === 0) {
- if ((file = self.file(m.substr(1)))) {
- return file.name;
- }
- }
- return m;
- },
- i, j, m;
- for (i = 0; i< arguments.length; i++) {
- m = arguments[i];
- if (typeof m == 'string') {
- input.push(message(m));
- } else if ($.isArray(m)) {
- for (j = 0; j < m.length; j++) {
- if (typeof m[j] == 'string') {
- input.push(message(m[j]));
- }
- }
- }
- }
- for (i = 0; i < input.length; i++) {
- // dont translate placeholders
- if ($.inArray(i, ignore) !== -1) {
- continue;
- }
- m = input[i];
- // translate message
- m = messages[m] || self.escape(m);
- // replace placeholders in message
- m = m.replace(/\$(\d+)/g, function(match, placeholder) {
- placeholder = i + parseInt(placeholder);
- if (placeholder > 0 && input[placeholder]) {
- ignore.push(placeholder)
- }
- return self.escape(input[placeholder]) || '';
- });
- input[i] = m;
- }
- return $.map(input, function(m, i) { return $.inArray(i, ignore) === -1 ? m : null; }).join('<br>');
- },
- /**
- * Convert mimetype into css classes
- *
- * @param String file mimetype
- * @return String
- */
- mime2class : function(mime) {
- var prefix = 'elfinder-cwd-icon-';
- mime = mime.split('/');
- return prefix+mime[0]+(mime[0] != 'image' && mime[1] ? ' '+prefix+mime[1].replace(/(\.|\+)/g, '-') : '');
- },
- /**
- * Return localized kind of file
- *
- * @param Object|String file or file mimetype
- * @return String
- */
- mime2kind : function(f) {
- var mime = typeof(f) == 'object' ? f.mime : f, kind;
- if (f.alias && f.mime != 'symlink-broken') {
- kind = 'Alias';
- } else if (this.kinds[mime]) {
- kind = this.kinds[mime];
- } else {
- if (mime.indexOf('text') === 0) {
- kind = 'Text';
- } else if (mime.indexOf('image') === 0) {
- kind = 'Image';
- } else if (mime.indexOf('audio') === 0) {
- kind = 'Audio';
- } else if (mime.indexOf('video') === 0) {
- kind = 'Video';
- } else if (mime.indexOf('application') === 0) {
- kind = 'App';
- } else {
- kind = mime;
- }
- }
- return this.messages['kind'+kind] ? this.i18n('kind'+kind) : mime;
- },
- /**
- * Return localized date
- *
- * @param Object file object
- * @return String
- */
- formatDate : function(file, ts) {
- var self = this,
- ts = ts || file.ts,
- i18 = self.i18,
- date, format, output, d, dw, m, y, h, g, i, s;
- if (self.options.clientFormatDate && ts > 0) {
- date = new Date(ts*1000);
- h = date[self.getHours]();
- g = h > 12 ? h - 12 : h;
- i = date[self.getMinutes]();
- s = date[self.getSeconds]();
- d = date[self.getDate]();
- dw = date[self.getDay]();
- m = date[self.getMonth]() + 1;
- y = date[self.getFullYear]();
- format = ts >= this.yesterday
- ? this.fancyFormat
- : this.dateFormat;
- output = format.replace(/[a-z]/gi, function(val) {
- switch (val) {
- case 'd': return d > 9 ? d : '0'+d;
- case 'j': return d;
- case 'D': return self.i18n(i18.daysShort[dw]);
- case 'l': return self.i18n(i18.days[dw]);
- case 'm': return m > 9 ? m : '0'+m;
- case 'n': return m;
- case 'M': return self.i18n(i18.monthsShort[m-1]);
- case 'F': return self.i18n(i18.months[m-1]);
- case 'Y': return y;
- case 'y': return (''+y).substr(2);
- case 'H': return h > 9 ? h : '0'+h;
- case 'G': return h;
- case 'g': return g;
- case 'h': return g > 9 ? g : '0'+g;
- case 'a': return h > 12 ? 'pm' : 'am';
- case 'A': return h > 12 ? 'PM' : 'AM';
- case 'i': return i > 9 ? i : '0'+i;
- case 's': return s > 9 ? s : '0'+s;
- }
- return val;
- });
- return ts >= this.yesterday
- ? output.replace('$1', this.i18n(ts >= this.today ? 'Today' : 'Yesterday'))
- : output;
- } else if (file.date) {
- return file.date.replace(/([a-z]+)\s/i, function(a1, a2) { return self.i18n(a2)+' '; });
- }
- return self.i18n('dateUnknown');
- },
- /**
- * Return css class marks file permissions
- *
- * @param Object file
- * @return String
- */
- perms2class : function(o) {
- var c = '';
- if (!o.read && !o.write) {
- c = 'elfinder-na';
- } else if (!o.read) {
- c = 'elfinder-wo';
- } else if (!o.write) {
- c = 'elfinder-ro';
- }
- return c;
- },
- /**
- * Return localized string with file permissions
- *
- * @param Object file
- * @return String
- */
- formatPermissions : function(f) {
- var p = [];
- f.read && p.push(this.i18n('read'));
- f.write && p.push(this.i18n('write'));
- return p.length ? p.join(' '+this.i18n('and')+' ') : this.i18n('noaccess');
- },
- /**
- * Return formated file size
- *
- * @param Number file size
- * @return String
- */
- formatSize : function(s) {
- var n = 1, u = 'b';
- if (s == 'unknown') {
- return this.i18n('unknown');
- }
- if (s > 1073741824) {
- n = 1073741824;
- u = 'GB';
- } else if (s > 1048576) {
- n = 1048576;
- u = 'MB';
- } else if (s > 1024) {
- n = 1024;
- u = 'KB';
- }
- s = s/n;
- return (s > 0 ? n >= 1048576 ? s.toFixed(2) : Math.round(s) : 0) +' '+u;
- },
- /**
- * Return formated file mode by options.fileModeStyle
- *
- * @param String file mode
- * @param String format style
- * @return String
- */
- formatFileMode : function(p, style) {
- var i, o, s, b, sticy, suid, sgid, str, oct;
- if (!style) {
- style = this.options.fileModeStyle.toLowerCase();
- }
- p = $.trim(p);
- if (p.match(/[rwxs-]{9}$/i)) {
- str = p = p.substr(-9);
- if (style == 'string') {
- return str;;
- }
- oct = '';
- s = 0;
- for (i=0; i<7; i=i+3) {
- o = p.substr(i, 3);
- b = 0;
- if (o.match(/[r]/i)) {
- b += 4;
- }
- if (o.match(/[w]/i)) {
- b += 2;
- }
- if (o.match(/[xs]/i)) {
- if (o.match(/[xs]/)) {
- b += 1;
- }
- if (o.match(/[s]/i)) {
- if (i == 0) {
- s += 4;
- } else if (i == 3) {
- s += 2;
- }
- }
- }
- oct += b.toString(8);
- }
- if (s) {
- oct = s.toString(8) + oct;
- }
- } else {
- p = parseInt(p, 8);
- oct = p? p.toString(8) : '';
- if (!p || style == 'octal') {
- return oct;
- }
- o = p.toString(8);
- s = 0;
- if (o.length > 3) {
- o = o.substr(-4);
- s = parseInt(o.substr(0, 1), 8);
- o = o.substr(1);
- }
- sticy = ((s & 1) == 1); // not support
- sgid = ((s & 2) == 2);
- suid = ((s & 4) == 4);
- str = '';
- for(i=0; i<3; i++) {
- if ((parseInt(o.substr(i, 1), 8) & 4) == 4) {
- str += 'r';
- } else {
- str += '-';
- }
- if ((parseInt(o.substr(i, 1), 8) & 2) == 2) {
- str += 'w';
- } else {
- str += '-';
- }
- if ((parseInt(o.substr(i, 1), 8) & 1) == 1) {
- str += ((i==0 && suid)||(i==1 && sgid))? 's' : 'x';
- } else {
- str += '-';
- }
- }
- }
- if (style == 'both') {
- return str + ' (' + oct + ')';
- } else if (style == 'string') {
- return str;
- } else {
- return oct;
- }
- },
- navHash2Id : function(hash) {
- return 'nav-'+hash;
- },
- navId2Hash : function(id) {
- return typeof(id) == 'string' ? id.substr(4) : false;
- },
- /**
- * Make event listener for direct upload to directory
- *
- * @param Object DOM object
- * @param String Target dirctory hash
- * @return void
- */
- makeDirectDropUpload : function(elm, hash) {
- var self = this, ent,
- c = 'class',
- $elm = $(elm),
- collapsed = self.res(c, 'navcollapse'),
- expanded = self.res(c, 'navexpand'),
- dropover = self.res(c, 'adroppable'),
- arrow = self.res(c, 'navarrow'),
- clDropActive = self.res(c, 'adroppable');
- if (self.dragUpload) {
- elm.addEventListener('dragenter', function(e) {
- e.preventDefault();
- e.stopPropagation();
- ent = true;
- $elm.addClass(clDropActive);
- if ($elm.is('.'+collapsed+':not(.'+expanded+')')) {
- setTimeout(function() {
- $elm.is('.'+collapsed+'.'+dropover) && $elm.children('.'+arrow).click();
- }, 500);
- }
- }, false);
- elm.addEventListener('dragleave', function(e) {
- e.preventDefault();
- e.stopPropagation();
- if (ent) {
- ent = false;
- } else {
- $elm.removeClass(clDropActive);
- }
- }, false);
- elm.addEventListener('dragover', function(e) {
- e.preventDefault();
- e.stopPropagation();
- ent = false;
- }, false);
- elm.addEventListener('drop', function(e) {
- e.preventDefault();
- e.stopPropagation();
- $elm.removeClass(clDropActive);
- e._target = hash;
- self.directUploadTarget = hash;
- self.exec('upload', {dropEvt: e});
- self.directUploadTarget = null;
- }, false);
- }
- },
- log : function(m) { window.console && window.console.log && window.console.log(m); return this; },
- debug : function(type, m) {
- var d = this.options.debug;
- if (d == 'all' || d === true || ($.isArray(d) && $.inArray(type, d) != -1)) {
- window.console && window.console.log && window.console.log('elfinder debug: ['+type+'] ['+this.id+']', m);
- }
- return this;
- },
- time : function(l) { window.console && window.console.time && window.console.time(l); },
- timeEnd : function(l) { window.console && window.console.timeEnd && window.console.timeEnd(l); }
- }
- /**
- * for conpat ex. ie8...
- *
- * Object.keys() - JavaScript | MDN
- * https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
- */
- if (!Object.keys) {
- Object.keys = (function () {
- var hasOwnProperty = Object.prototype.hasOwnProperty,
- hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
- dontEnums = [
- 'toString',
- 'toLocaleString',
- 'valueOf',
- 'hasOwnProperty',
- 'isPrototypeOf',
- 'propertyIsEnumerable',
- 'constructor'
- ],
- dontEnumsLength = dontEnums.length
- return function (obj) {
- if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object')
- var result = []
- for (var prop in obj) {
- if (hasOwnProperty.call(obj, prop)) result.push(prop)
- }
- if (hasDontEnumBug) {
- for (var i=0; i < dontEnumsLength; i++) {
- if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i])
- }
- }
- return result
- }
- })()
- };
- /*
- * File: /js/elFinder.version.js
- */
- /**
- * Application version
- *
- * @type String
- **/
- elFinder.prototype.version = '2.1.2 (2.x Nightly: f2196bd)';
- /*
- * File: /js/jquery.elfinder.js
- */
- /*** jQuery UI droppable performance tune for elFinder ***/
- (function(){
- var origin = $.ui.ddmanager.prepareOffsets;
- $.ui.ddmanager.prepareOffsets = function( t, event ) {
- var isOutView = function(elem) {
- var rect = elem.getBoundingClientRect();
- return document.elementFromPoint(rect.left, rect.top)? false : true;
- }
- var i, m = $.ui.ddmanager.droppables[ t.options.scope ] || [];
- for ( i = 0; i < m.length; i++ ) {
- m[ i ].options.disabled = isOutView(m[ i ].element[ 0 ]);
- }
- // call origin function
- return origin( t, event );
- };
- })();
- $.fn.elfinder = function(o) {
- if (o == 'instance') {
- return this.getElFinder();
- }
- return this.each(function() {
- var cmd = typeof(o) == 'string' ? o : '';
- if (!this.elfinder) {
- new elFinder(this, typeof(o) == 'object' ? o : {})
- }
- switch(cmd) {
- case 'close':
- case 'hide':
- this.elfinder.hide();
- break;
- case 'open':
- case 'show':
- this.elfinder.show();
- break;
- case'destroy':
- this.elfinder.destroy();
- break;
- }
- })
- }
- $.fn.getElFinder = function() {
- var instance;
- this.each(function() {
- if (this.elfinder) {
- instance = this.elfinder;
- return false;
- }
- });
- return instance;
- }
- /*
- * File: /js/elFinder.options.js
- */
- /**
- * Default elFinder config
- *
- * @type Object
- * @autor Dmitry (dio) Levashov
- */
- elFinder.prototype._options = {
- /**
- * Connector url. Required!
- *
- * @type String
- */
- url : '',
- /**
- * Ajax request type.
- *
- * @type String
- * @default "get"
- */
- requestType : 'get',
- /**
- * Transport to send request to backend.
- * Required for future extensions using websockets/webdav etc.
- * Must be an object with "send" method.
- * transport.send must return $.Deferred() object
- *
- * @type Object
- * @default null
- * @example
- * transport : {
- * init : function(elfinderInstance) { },
- * send : function(options) {
- * var dfrd = $.Deferred();
- * // connect to backend ...
- * return dfrd;
- * },
- * upload : function(data) {
- * var dfrd = $.Deferred();
- * // upload ...
- * return dfrd;
- * }
- *
- * }
- **/
- transport : {},
- /**
- * URL to upload file to.
- * If not set - connector URL will be used
- *
- * @type String
- * @default ''
- */
- urlUpload : '',
- /**
- * Allow to drag and drop to upload files
- *
- * @type Boolean|String
- * @default 'auto'
- */
- dragUploadAllow : 'auto',
- /**
- * Max size of chunked data of file upload
- *
- * @type Number
- * @default 10485760(10MB)
- */
- uploadMaxChunkSize : 10485760,
- /**
- * Timeout for upload using iframe
- *
- * @type Number
- * @default 0 - no timeout
- */
- iframeTimeout : 0,
- /**
- * Data to append to all requests and to upload files
- *
- * @type Object
- * @default {}
- */
- customData : {},
- /**
- * Event listeners to bind on elFinder init
- *
- * @type Object
- * @default {}
- */
- handlers : {},
- /**
- * Any custom headers to send across every ajax request
- *
- * @type Object
- * @default {}
- */
- customHeaders : {},
- /**
- * Any custom xhrFields to send across every ajax request
- *
- * @type Object
- * @default {}
- */
- xhrFields : {},
- /**
- * Interface language
- *
- * @type String
- * @default "en"
- */
- lang : 'en',
- /**
- * Additional css class for filemanager node.
- *
- * @type String
- */
- cssClass : '',
- /**
- * Active commands list
- * If some required commands will be missed here, elFinder will add its
- *
- * @type Array
- */
- commands : [
- 'open', 'reload', 'home', 'up', 'back', 'forward', 'getfile', 'quicklook',
- 'download', 'rm', 'duplicate', 'rename', 'mkdir', 'mkfile', 'upload', 'copy',
- 'cut', 'paste', 'edit', 'extract', 'archive', 'search', 'info', 'view', 'help',
- 'resize', 'sort', 'netmount', 'netunmount', 'places', 'chmod'
- ],
- /**
- * Commands options.
- *
- * @type Object
- **/
- commandsOptions : {
- // "getfile" command options.
- getfile : {
- onlyURL : false,
- // allow to return multiple files info
- multiple : false,
- // allow to return filers info
- folders : false,
- // action after callback (""/"close"/"destroy")
- oncomplete : ''
- },
- // "upload" command options.
- upload : {
- ui : 'uploadbutton'
- },
- // "quicklook" command options.
- quicklook : {
- autoplay : true,
- jplayer : 'extensions/jplayer'
- },
- // "quicklook" command options.
- edit : {
- // list of allowed mimetypes to edit
- // if empty - any text files can be edited
- mimes : [],
- // edit files in wysisyg's
- editors : [
- // {
- // /**
- // * files mimetypes allowed to edit in current wysisyg
- // * @type Array
- // */
- // mimes : ['text/html'],
- // /**
- // * Called when "edit" dialog loaded.
- // * Place to init wysisyg.
- // * Can return wysisyg instance
- // *
- // * @param DOMElement textarea node
- // * @return Object
- // */
- // load : function(textarea) { },
- // /**
- // * Called before "edit" dialog closed.
- // * Place to destroy wysisyg instance.
- // *
- // * @param DOMElement textarea node
- // * @param Object wysisyg instance (if was returned by "load" callback)
- // * @return void
- // */
- // close : function(textarea, instance) { },
- // /**
- // * Called before file content send to backend.
- // * Place to update textarea content if needed.
- // *
- // * @param DOMElement textarea node
- // * @param Object wysisyg instance (if was returned by "load" callback)
- // * @return void
- // */
- // save : function(textarea, instance) {},
- // /**
- // * Called after load() or save().
- // * Set focus to wysisyg editor.
- // *
- // * @param DOMElement textarea node
- // * @param Object wysisyg instance (if was returned by "load" callback)
- // * @return void
- // */
- // focus : function(textarea, instance) {}
- //
- // }
- ]
- },
- // "info" command options.
- info : {
- nullUrlDirLinkSelf : true,
- custom : {
- // /**
- // * Example of custom info `desc`
- // */
- // desc : {
- // /**
- // * Lable (require)
- // * It is filtered by the `fm.i18n()`
- // *
- // * @type String
- // */
- // label : 'Description',
- //
- // /**
- // * Template (require)
- // * `{id}` is replaced in dialog.id
- // *
- // * @type String
- // */
- // tpl : '<div class="elfinder-info-desc"><span class="elfinder-info-spinner"></span></div>',
- //
- // /**
- // * Restricts to mimetypes (optional)
- // * Exact match or category match
- // *
- // * @type Array
- // */
- // mimes : ['text', 'image/jpeg', 'directory'],
- //
- // /**
- // * Restricts to file.hash (optional)
- // *
- // * @ type Regex
- // */
- // hashRegex : /^l\d+_/,
- //
- // /**
- // * Request that asks for the description and sets the field (optional)
- // *
- // * @type Function
- // */
- // action : function(file, fm, dialog) {
- // fm.request({
- // data : { cmd : 'desc', target: file.hash },
- // preventDefault: true,
- // })
- // .fail(function() {
- // dialog.find('div.elfinder-info-desc').html(fm.i18n('unknown'));
- // })
- // .done(function(data) {
- // dialog.find('div.elfinder-info-desc').html(data.desc);
- // });
- // }
- // }
- }
- },
- netmount: {
- ftp: {
- inputs: {
- host : $('<input type="text"/>'),
- port : $('<input type="text" placeholder="21"/>'),
- path : $('<input type="text" value="/"/>'),
- user : $('<input type="text"/>'),
- pass : $('<input type="password"/>'),
- encoding : $('<input type="text" placeholder="Optional"/>'),
- locale : $('<input type="text" placeholder="Optional"/>')
- }
- },
- dropbox: {
- inputs: {
- host : $('<span><span class="elfinder-info-spinner"/></span></span><input type="hidden"/>'),
- path : $('<input type="text" value="/"/>'),
- user : $('<input type="hidden"/>'),
- pass : $('<input type="hidden"/>')
- },
- select: function(fm){
- var self = this;
- if (self.inputs.host.find('span').length) {
- fm.request({
- data : {cmd : 'netmount', protocol: 'dropbox', host: 'dropbox.com', user: 'init', pass: 'init', options: {url: fm.uploadURL, id: fm.id}},
- preventDefault : true
- }).done(function(data){
- self.inputs.host.find('span').removeClass("elfinder-info-spinner");
- self.inputs.host.find('span').html(data.body.replace(/\{msg:([^}]+)\}/g, function(whole,s1){return fm.i18n(s1,'Dropbox.com');}));
- }).fail(function(){});
- }
- },
- done: function(fm, data){
- var self = this;
- if (data.mode == 'makebtn') {
- self.inputs.host.find('span').removeClass("elfinder-info-spinner");
- self.inputs.host.find('input').hover(function(){$(this).toggleClass("ui-state-hover");});
- self.inputs.host[1].value = "";
- } else {
- self.inputs.host.find('span').removeClass("elfinder-info-spinner");
- self.inputs.host.find('span').html("Dropbox.com");
- self.inputs.host[1].value = "dropbox";
- self.inputs.user.val("done");
- self.inputs.pass.val("done");
- }
- }
- }
- },
- help : {view : ['about', 'shortcuts', 'help']}
- },
- /**
- * Callback for "getfile" commands.
- * Required to use elFinder with WYSIWYG editors etc..
- *
- * @type Function
- * @default null (command not active)
- */
- getFileCallback : null,
- /**
- * Default directory view. icons/list
- *
- * @type String
- * @default "icons"
- */
- defaultView : 'icons',
- /**
- * Hash of default directory path to open
- *
- * @type String
- * @default ""
- */
- startPathHash : '',
- /**
- * UI plugins to load.
- * Current dir ui and dialogs loads always.
- * Here set not required plugins as folders tree/toolbar/statusbar etc.
- *
- * @type Array
- * @default ['toolbar', 'tree', 'path', 'stat']
- * @full ['toolbar', 'places', 'tree', 'path', 'stat']
- */
- ui : ['toolbar', 'tree', 'path', 'stat'],
- /**
- * Some UI plugins options.
- * @type Object
- */
- uiOptions : {
- // toolbar configuration
- toolbar : [
- ['back', 'forward'],
- ['netmount'],
- // ['reload'],
- // ['home', 'up'],
- ['mkdir', 'mkfile', 'upload'],
- ['open', 'download', 'getfile'],
- ['info', 'chmod'],
- ['quicklook'],
- ['copy', 'cut', 'paste'],
- ['rm'],
- ['duplicate', 'rename', 'edit', 'resize'],
- ['extract', 'archive'],
- ['search'],
- ['view', 'sort'],
- ['help']
- ],
- // directories tree options
- tree : {
- // expand current root on init
- openRootOnLoad : true,
- // expand current work directory on open
- openCwdOnOpen : true,
- // auto load current dir parents
- syncTree : true
- // ,
- // /**
- // * Add CSS class name to navbar directories (optional)
- // * see: https://github.com/Studio-42/elFinder/pull/1061
- // *
- // * @type Function
- // */
- // getClass: function(dir) {
- // // ex. This adds the directory's name (lowercase) with prefix as a CSS class
- // return 'elfinder-tree-' + dir.name.replace(/[ "]/g, '').toLowerCase();
- // }
- },
- // navbar options
- navbar : {
- minWidth : 150,
- maxWidth : 500
- },
- cwd : {
- // display parent folder with ".." name :)
- oldSchool : false,
- // file info columns displayed
- listView : {
- // name is always displayed, cols are ordered
- // ex. ['perm', 'date', 'size', 'kind', 'owner', 'group', 'mode']
- // mode: 'mode'(by `fileModeStyle` setting), 'modestr'(rwxr-xr-x) , 'modeoct'(755), 'modeboth'(rwxr-xr-x (755))
- // 'owner', 'group' and 'mode', It's necessary set volume driver option "statOwner" to `true`
- columns : ['perm', 'date', 'size', 'kind'],
- // override this if you want custom columns name
- // example
- // columnsCustomName : {
- // date : 'Last modification',
- // kind : 'Mime type'
- // }
- columnsCustomName : {}
- }
- }
- },
- /**
- * Display only required files by types
- *
- * @type Array
- * @default []
- * @example
- * onlyMimes : ["image"] - display all images
- * onlyMimes : ["image/png", "application/x-shockwave-flash"] - display png and flash
- */
- onlyMimes : [],
- /**
- * Custom files sort rules.
- * All default rules (name/size/kind/date) set in elFinder._sortRules
- *
- * @type {Object}
- * @example
- * sortRules : {
- * name : function(file1, file2) { return file1.name.toLowerCase().localeCompare(file2.name.toLowerCase()); }
- * }
- */
- sortRules : {},
- /**
- * Default sort type.
- *
- * @type {String}
- */
- sortType : 'name',
- /**
- * Default sort order.
- *
- * @type {String}
- * @default "asc"
- */
- sortOrder : 'asc',
- /**
- * Display folders first?
- *
- * @type {Boolean}
- * @default true
- */
- sortStickFolders : true,
- /**
- * If true - elFinder will formating dates itself,
- * otherwise - backend date will be used.
- *
- * @type Boolean
- */
- clientFormatDate : true,
- /**
- * Show UTC dates.
- * Required set clientFormatDate to true
- *
- * @type Boolean
- */
- UTCDate : false,
- /**
- * File modification datetime format.
- * Value from selected language data is used by default.
- * Set format here to overwrite it.
- *
- * @type String
- * @default ""
- */
- dateFormat : '',
- /**
- * File modification datetime format in form "Yesterday 12:23:01".
- * Value from selected language data is used by default.
- * Set format here to overwrite it.
- * Use $1 for "Today"/"Yesterday" placeholder
- *
- * @type String
- * @default ""
- * @example "$1 H:m:i"
- */
- fancyDateFormat : '',
- /**
- * Style of file mode at cwd-list, info dialog
- * 'string' (ex. rwxr-xr-x) or 'octal' (ex. 755) or 'both' (ex. rwxr-xr-x (755))
- *
- * @type {String}
- * @default 'both'
- */
- fileModeStyle : 'both',
- /**
- * elFinder width
- *
- * @type String|Number
- * @default "auto"
- */
- width : 'auto',
- /**
- * elFinder height
- *
- * @type Number
- * @default "auto"
- */
- height : 400,
- /**
- * Make elFinder resizable if jquery ui resizable available
- *
- * @type Boolean
- * @default true
- */
- resizable : true,
- /**
- * Timeout before open notifications dialogs
- *
- * @type Number
- * @default 500 (.5 sec)
- */
- notifyDelay : 500,
- /**
- * Position CSS, Width of notifications dialogs
- *
- * @type Object
- * @default {position: {top : '12px', right : '12px'}, width : 280}
- * position: CSS object | null (null: position center & middle)
- */
- notifyDialog : {position: {top : '12px', right : '12px'}, width : 280},
- /**
- * Allow shortcuts
- *
- * @type Boolean
- * @default true
- */
- allowShortcuts : true,
- /**
- * Remeber last opened dir to open it after reload or in next session
- *
- * @type Boolean
- * @default true
- */
- rememberLastDir : true,
- /**
- * Clear historys(elFinder) on reload(not browser) function
- * Historys was cleared on Reload function on elFinder 2.0 (value is true)
- *
- * @type Boolean
- * @default false
- */
- reloadClearHistory : false,
- /**
- * Use browser native history with supported browsers
- *
- * @type Boolean
- * @default true
- */
- useBrowserHistory : true,
- /**
- * Lazy load config.
- * How many files display at once?
- *
- * @type Number
- * @default 50
- */
- showFiles : 30,
- /**
- * Lazy load config.
- * Distance in px to cwd bottom edge to start display files
- *
- * @type Number
- * @default 50
- */
- showThreshold : 50,
- /**
- * Additional rule to valid new file name.
- * By default not allowed empty names or '..'
- *
- * @type false|RegExp|function
- * @default false
- * @example
- * disable names with spaces:
- * validName : /^[^\s]$/
- */
- validName : false,
- /**
- * Sync content interval
- * @todo - fix in elFinder
- * @type Number
- * @default 0 (do not sync)
- */
- sync : 0,
- /**
- * How many thumbnails create in one request
- *
- * @type Number
- * @default 5
- */
- loadTmbs : 5,
- /**
- * Cookie option for browsersdoes not suppot localStorage
- *
- * @type Object
- */
- cookie : {
- expires : 30,
- domain : '',
- path : '/',
- secure : false
- },
- /**
- * Contextmenu config
- *
- * @type Object
- */
- contextmenu : {
- // navbarfolder menu
- navbar : ['open', '|', 'upload', '|', 'copy', 'cut', 'paste', 'duplicate', '|', 'rm', '|', 'rename', '|', 'places', 'info', 'chmod', 'netunmount'],
- // current directory menu
- cwd : ['reload', 'back', '|', 'upload', 'mkdir', 'mkfile', 'paste', '|', 'sort', '|', 'info'],
- // current directory file menu
- files : ['getfile', '|','open', 'quicklook', '|', 'download', 'upload', '|', 'copy', 'cut', 'paste', 'duplicate', '|', 'rm', '|', 'edit', 'rename', 'resize', '|', 'archive', 'extract', '|', 'places', 'info', 'chmod']
- },
- /**
- * Debug config
- *
- * @type Array|Boolean
- */
- // debug : true
- debug : ['error', 'warning', 'event-destroy']
- }
- /*
- * File: /js/elFinder.history.js
- */
- /**
- * @class elFinder.history
- * Store visited folders
- * and provide "back" and "forward" methods
- *
- * @author Dmitry (dio) Levashov
- */
- elFinder.prototype.history = function(fm) {
- var self = this,
- /**
- * Update history on "open" event?
- *
- * @type Boolean
- */
- update = true,
- /**
- * Directories hashes storage
- *
- * @type Array
- */
- history = [],
- /**
- * Current directory index in history
- *
- * @type Number
- */
- current,
- /**
- * Clear history
- *
- * @return void
- */
- reset = function() {
- history = [fm.cwd().hash];
- current = 0;
- update = true;
- },
- /**
- * Browser native history object
- */
- nativeHistory = (fm.options.useBrowserHistory && window.history && window.history.pushState)? window.history : null,
- /**
- * Open prev/next folder
- *
- * @Boolen open next folder?
- * @return jQuery.Deferred
- */
- go = function(fwd) {
- if ((fwd && self.canForward()) || (!fwd && self.canBack())) {
- update = false;
- return fm.exec('open', history[fwd ? ++current : --current]).fail(reset);
- }
- return $.Deferred().reject();
- };
- /**
- * Return true if there is previous visited directories
- *
- * @return Boolen
- */
- this.canBack = function() {
- return current > 0;
- }
- /**
- * Return true if can go forward
- *
- * @return Boolen
- */
- this.canForward = function() {
- return current < history.length - 1;
- }
- /**
- * Go back
- *
- * @return void
- */
- this.back = go;
- /**
- * Go forward
- *
- * @return void
- */
- this.forward = function() {
- return go(true);
- }
- // bind to elfinder events
- fm.open(function() {
- var l = history.length,
- cwd = fm.cwd().hash;
- if (update) {
- current >= 0 && l > current + 1 && history.splice(current+1);
- history[history.length-1] != cwd && history.push(cwd);
- current = history.length - 1;
- }
- update = true;
- if (nativeHistory) {
- if (! nativeHistory.state) {
- nativeHistory.replaceState({thash: cwd}, null, location.pathname + location.search + '#elf_' + cwd);
- } else {
- nativeHistory.state.thash != cwd && nativeHistory.pushState({thash: cwd}, null, location.pathname + location.search + '#elf_' + cwd);
- }
- }
- })
- .reload(fm.options.reloadClearHistory && reset);
- }
- /*
- * File: /js/elFinder.command.js
- */
- /**
- * elFinder command prototype
- *
- * @type elFinder.command
- * @author Dmitry (dio) Levashov
- */
- elFinder.prototype.command = function(fm) {
- /**
- * elFinder instance
- *
- * @type elFinder
- */
- this.fm = fm;
- /**
- * Command name, same as class name
- *
- * @type String
- */
- this.name = '';
- /**
- * Short command description
- *
- * @type String
- */
- this.title = '';
- /**
- * Current command state
- *
- * @example
- * this.state = -1; // command disabled
- * this.state = 0; // command enabled
- * this.state = 1; // command active (for example "fullscreen" command while elfinder in fullscreen mode)
- * @default -1
- * @type Number
- */
- this.state = -1;
- /**
- * If true, command can not be disabled by connector.
- * @see this.update()
- *
- * @type Boolen
- */
- this.alwaysEnabled = false;
- /**
- * If true, this means command was disabled by connector.
- * @see this.update()
- *
- * @type Boolen
- */
- this._disabled = false;
- this.disableOnSearch = false;
- this.updateOnSelect = true;
- /**
- * elFinder events defaults handlers.
- * Inside handlers "this" is current command object
- *
- * @type Object
- */
- this._handlers = {
- enable : function() { this.update(void(0), this.value); },
- disable : function() { this.update(-1, this.value); },
- 'open reload load' : function() {
- this._disabled = !(this.alwaysEnabled || this.fm.isCommandEnabled(this.name));
- this.update(void(0), this.value)
- this.change();
- }
- };
- /**
- * elFinder events handlers.
- * Inside handlers "this" is current command object
- *
- * @type Object
- */
- this.handlers = {}
- /**
- * Shortcuts
- *
- * @type Array
- */
- this.shortcuts = [];
- /**
- * Command options
- *
- * @type Object
- */
- this.options = {ui : 'button'};
- /**
- * Prepare object -
- * bind events and shortcuts
- *
- * @return void
- */
- this.setup = function(name, opts) {
- var self = this,
- fm = this.fm, i, s;
- this.name = name;
- this.title = fm.messages['cmd'+name] ? fm.i18n('cmd'+name) : name,
- this.options = $.extend({}, this.options, opts);
- this.listeners = [];
- if (this.updateOnSelect) {
- this._handlers.select = function() { this.update(void(0), this.value); }
- }
- $.each($.extend({}, self._handlers, self.handlers), function(cmd, handler) {
- fm.bind(cmd, $.proxy(handler, self));
- });
- for (i = 0; i < this.shortcuts.length; i++) {
- s = this.shortcuts[i];
- s.callback = $.proxy(s.callback || function() { this.exec() }, this);
- !s.description && (s.description = this.title);
- fm.shortcut(s);
- }
- if (this.disableOnSearch) {
- fm.bind('search searchend', function(e) {
- self._disabled = e.type == 'search';
- self.update(void(0), self.value);
- });
- }
- this.init();
- }
- /**
- * Command specific init stuffs
- *
- * @return void
- */
- this.init = function() { }
- /**
- * Exec command
- *
- * @param Array target files hashes
- * @param Array|Object command value
- * @return $.Deferred
- */
- this.exec = function(files, opts) {
- return $.Deferred().reject();
- }
- /**
- * Return true if command disabled.
- *
- * @return Boolen
- */
- this.disabled = function() {
- return this.state < 0;
- }
- /**
- * Return true if command enabled.
- *
- * @return Boolen
- */
- this.enabled = function() {
- return this.state > -1;
- }
- /**
- * Return true if command active.
- *
- * @return Boolen
- */
- this.active = function() {
- return this.state > 0;
- }
- /**
- * Return current command state.
- * Must be overloaded in most commands
- *
- * @return Number
- */
- this.getstate = function() {
- return -1;
- }
- /**
- * Update command state/value
- * and rize 'change' event if smth changed
- *
- * @param Number new state or undefined to auto update state
- * @param mixed new value
- * @return void
- */
- this.update = function(s, v) {
- var state = this.state,
- value = this.value;
- if (this._disabled) {
- this.state = -1;
- } else {
- this.state = s !== void(0) ? s : this.getstate();
- }
- this.value = v;
- if (state != this.state || value != this.value) {
- this.change();
- }
- }
- /**
- * Bind handler / fire 'change' event.
- *
- * @param Function|undefined event callback
- * @return void
- */
- this.change = function(c) {
- var cmd, i;
- if (typeof(c) === 'function') {
- this.listeners.push(c);
- } else {
- for (i = 0; i < this.listeners.length; i++) {
- cmd = this.listeners[i];
- try {
- cmd(this.state, this.value);
- } catch (e) {
- this.fm.debug('error', e)
- }
- }
- }
- return this;
- }
- /**
- * With argument check given files hashes and return list of existed files hashes.
- * Without argument return selected files hashes.
- *
- * @param Array|String|void hashes
- * @return Array
- */
- this.hashes = function(hashes) {
- return hashes
- ? $.map($.isArray(hashes) ? hashes : [hashes], function(hash) { return fm.file(hash) ? hash : null; })
- : fm.selected();
- }
- /**
- * Return only existed files from given fils hashes | selected files
- *
- * @param Array|String|void hashes
- * @return Array
- */
- this.files = function(hashes) {
- var fm = this.fm;
- return hashes
- ? $.map($.isArray(hashes) ? hashes : [hashes], function(hash) { return fm.file(hash) || null })
- : fm.selectedFiles();
- }
- }
- /*
- * File: /js/elFinder.resources.js
- */
- /**
- * elFinder resources registry.
- * Store shared data
- *
- * @type Object
- * @author Dmitry (dio) Levashov
- **/
- elFinder.prototype.resources = {
- 'class' : {
- hover : 'ui-state-hover',
- active : 'ui-state-active',
- disabled : 'ui-state-disabled',
- draggable : 'ui-draggable',
- droppable : 'ui-droppable',
- adroppable : 'elfinder-droppable-active',
- cwdfile : 'elfinder-cwd-file',
- cwd : 'elfinder-cwd',
- tree : 'elfinder-tree',
- treeroot : 'elfinder-navbar-root',
- navdir : 'elfinder-navbar-dir',
- navdirwrap : 'elfinder-navbar-dir-wrapper',
- navarrow : 'elfinder-navbar-arrow',
- navsubtree : 'elfinder-navbar-subtree',
- navcollapse : 'elfinder-navbar-collapsed',
- navexpand : 'elfinder-navbar-expanded',
- treedir : 'elfinder-tree-dir',
- placedir : 'elfinder-place-dir',
- searchbtn : 'elfinder-button-search'
- },
- tpl : {
- perms : '<span class="elfinder-perms"/>',
- lock : '<span class="elfinder-lock"/>',
- symlink : '<span class="elfinder-symlink"/>',
- navicon : '<span class="elfinder-nav-icon"/>',
- navspinner : '<span class="elfinder-navbar-spinner"/>',
- navdir : '<div class="elfinder-navbar-wrapper"><span id="{id}" class="ui-corner-all elfinder-navbar-dir {cssclass}"><span class="elfinder-navbar-arrow"/><span class="elfinder-navbar-icon" {style}/>{symlink}{permissions}{name}</span><div class="elfinder-navbar-subtree"/></div>'
- },
- mimes : {
- text : [
- 'application/x-empty',
- 'application/javascript',
- 'application/xhtml+xml',
- 'audio/x-mp3-playlist',
- 'application/x-web-config',
- 'application/docbook+xml',
- 'application/x-php',
- 'application/x-perl',
- 'application/x-awk',
- 'application/x-config',
- 'application/x-csh',
- 'application/xml'
- ]
- },
- mixin : {
- make : function() {
- var fm = this.fm,
- cmd = this.name,
- cwd = fm.getUI('cwd'),
- tarea= (fm.storage('view') != 'list'),
- rest = function(){
- if (tarea) {
- node.zIndex('').css('position', '');
- nnode.css('max-height', '');
- } else {
- pnode.css('width', '');
- pnode.parent('td').css('overflow', '');
- }
- }, colwidth,
- dfrd = $.Deferred()
- .fail(function(error) {
- rest();
- cwd.trigger('unselectall');
- error && fm.error(error);
- })
- .always(function() {
- input.remove();
- node.remove();
- fm.enable();
- }),
- id = 'tmp_'+parseInt(Math.random()*100000),
- phash = fm.cwd().hash,
- date = new Date(),
- file = {
- hash : id,
- name : fm.uniqueName(this.prefix),
- mime : this.mime,
- read : true,
- write : true,
- date : 'Today '+date.getHours()+':'+date.getMinutes()
- },
- data = this.data || {},
- node = cwd.trigger('create.'+fm.namespace, file).find('#'+id),
- nnode, pnode,
- input = $(tarea? '<textarea/>' : '<input type="text"/>')
- .on('keyup text', function(){
- if (tarea) {
- this.style.height = '1px';
- this.style.height = this.scrollHeight + 'px';
- } else if (colwidth) {
- this.style.width = colwidth + 'px';
- if (this.scrollWidth > colwidth) {
- this.style.width = this.scrollWidth + 10 + 'px';
- }
- }
- })
- .keydown(function(e) {
- e.stopImmediatePropagation();
- if (e.keyCode == $.ui.keyCode.ESCAPE) {
- dfrd.reject();
- } else if (e.keyCode == $.ui.keyCode.ENTER) {
- input.blur();
- }
- })
- .mousedown(function(e) {
- e.stopPropagation();
- })
- .blur(function() {
- var name = $.trim(input.val()),
- parent = input.parent();
- if (parent.length) {
- if (!name) {
- return dfrd.reject('errInvName');
- }
- if (fm.fileByName(name, phash)) {
- return dfrd.reject(['errExists', name]);
- }
- rest();
- parent.html(fm.escape(name));
- fm.lockfiles({files : [id]});
- fm.request({
- data : $.extend({cmd : cmd, name : name, target : phash}, data || {}),
- notify : {type : cmd, cnt : 1},
- preventFail : true,
- syncOnFail : true
- })
- .fail(function(error) {
- dfrd.reject(error);
- })
- .done(function(data) {
- dfrd.resolve(data);
- if (data.added && data.added[0]) {
- var newItem = cwd.find('#'+data.added[0].hash);
- if (newItem.length) {
- cwd.parent().scrollTop(newItem.offset().top);
- }
- }
- });
- }
- });
- if (this.disabled() || !node.length) {
- return dfrd.reject();
- }
- fm.disable();
- nnode = node.find('.elfinder-cwd-filename');
- pnode = nnode.parent();
- if (tarea) {
- node.zIndex((node.parent().zIndex()) + 1).css('position', 'relative');
- nnode.css('max-height', 'none');
- } else {
- colwidth = pnode.width();
- pnode.width(colwidth - 15);
- pnode.parent('td').css('overflow', 'visible');
- }
- nnode.empty('').append(input.val(file.name));
- input.trigger('keyup');
- input.select().focus();
- input[0].setSelectionRange && input[0].setSelectionRange(0, file.name.replace(/\..+$/, '').length);
- return dfrd;
- }
- }
- }
- /*
- * File: /js/jquery.dialogelfinder.js
- */
- /**
- * @class dialogelfinder - open elFinder in dialog window
- *
- * @param Object elFinder options with dialog options
- * @example
- * $(selector).dialogelfinder({
- * // some elfinder options
- * title : 'My files', // dialog title, default = "Files"
- * width : 850, // dialog width, default 840
- * autoOpen : false, // if false - dialog will not be opened after init, default = true
- * destroyOnClose : true // destroy elFinder on close dialog, default = false
- * })
- * @author Dmitry (dio) Levashov
- **/
- $.fn.dialogelfinder = function(opts) {
- var position = 'elfinderPosition',
- destroy = 'elfinderDestroyOnClose';
- this.not('.elfinder').each(function() {
- var doc = $(document),
- toolbar = $('<div class="ui-widget-header dialogelfinder-drag ui-corner-top">'+(opts.title || 'Files')+'</div>'),
- button = $('<a href="#" class="dialogelfinder-drag-close ui-corner-all"><span class="ui-icon ui-icon-closethick"/></a>')
- .appendTo(toolbar)
- .click(function(e) {
- e.preventDefault();
- node.dialogelfinder('close');
- }),
- node = $(this).addClass('dialogelfinder')
- .css('position', 'absolute')
- .hide()
- .appendTo('body')
- .draggable({ handle : '.dialogelfinder-drag',
- containment : 'window' })
- .elfinder(opts)
- .prepend(toolbar),
- elfinder = node.elfinder('instance');
- node.width(parseInt(node.width()) || 840) // fix width if set to "auto"
- .data(destroy, !!opts.destroyOnClose)
- .find('.elfinder-toolbar').removeClass('ui-corner-top');
- opts.position && node.data(position, opts.position);
- opts.autoOpen !== false && $(this).dialogelfinder('open');
- });
- if (opts == 'open') {
- var node = $(this),
- pos = node.data(position) || {
- top : parseInt($(document).scrollTop() + ($(window).height() < node.height() ? 2 : ($(window).height() - node.height())/2)),
- left : parseInt($(document).scrollLeft() + ($(window).width() < node.width() ? 2 : ($(window).width() - node.width())/2))
- },
- zindex = 100;
- if (node.is(':hidden')) {
- $('body').find(':visible').each(function() {
- var $this = $(this), z;
- if (this !== node[0] && $this.css('position') == 'absolute' && (z = parseInt($this.zIndex())) > zindex) {
- zindex = z + 1;
- }
- });
- node.zIndex(zindex).css(pos).show().trigger('resize');
- setTimeout(function() {
- // fix resize icon position and make elfinder active
- node.trigger('resize').mousedown();
- }, 200);
- }
- } else if (opts == 'close') {
- var node = $(this);
- if (node.is(':visible')) {
- !!node.data(destroy)
- ? node.elfinder('destroy').remove()
- : node.elfinder('close');
- }
- } else if (opts == 'instance') {
- return $(this).getElFinder();
- }
- return this;
- };
- /*
- * File: /js/i18n/elfinder.en.js
- */
- /**
- * English translation
- * @author Troex Nevelin <troex@fury.scancode.ru>
- * @version 2015-11-21
- */
- if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object') {
- elFinder.prototype.i18.en = {
- translator : 'Troex Nevelin <troex@fury.scancode.ru>',
- language : 'English',
- direction : 'ltr',
- dateFormat : 'M d, Y h:i A', // Mar 13, 2012 05:27 PM
- fancyDateFormat : '$1 h:i A', // will produce smth like: Today 12:25 PM
- messages : {
- /********************************** errors **********************************/
- 'error' : 'Error',
- 'errUnknown' : 'Unknown error.',
- 'errUnknownCmd' : 'Unknown command.',
- 'errJqui' : 'Invalid jQuery UI configuration. Selectable, draggable and droppable components must be included.',
- 'errNode' : 'elFinder requires DOM Element to be created.',
- 'errURL' : 'Invalid elFinder configuration! URL option is not set.',
- 'errAccess' : 'Access denied.',
- 'errConnect' : 'Unable to connect to backend.',
- 'errAbort' : 'Connection aborted.',
- 'errTimeout' : 'Connection timeout.',
- 'errNotFound' : 'Backend not found.',
- 'errResponse' : 'Invalid backend response.',
- 'errConf' : 'Invalid backend configuration.',
- 'errJSON' : 'PHP JSON module not installed.',
- 'errNoVolumes' : 'Readable volumes not available.',
- 'errCmdParams' : 'Invalid parameters for command "$1".',
- 'errDataNotJSON' : 'Data is not JSON.',
- 'errDataEmpty' : 'Data is empty.',
- 'errCmdReq' : 'Backend request requires command name.',
- 'errOpen' : 'Unable to open "$1".',
- 'errNotFolder' : 'Object is not a folder.',
- 'errNotFile' : 'Object is not a file.',
- 'errRead' : 'Unable to read "$1".',
- 'errWrite' : 'Unable to write into "$1".',
- 'errPerm' : 'Permission denied.',
- 'errLocked' : '"$1" is locked and can not be renamed, moved or removed.',
- 'errExists' : 'File named "$1" already exists.',
- 'errInvName' : 'Invalid file name.',
- 'errFolderNotFound' : 'Folder not found.',
- 'errFileNotFound' : 'File not found.',
- 'errTrgFolderNotFound' : 'Target folder "$1" not found.',
- 'errPopup' : 'Browser prevented opening popup window. To open file enable it in browser options.',
- 'errMkdir' : 'Unable to create folder "$1".',
- 'errMkfile' : 'Unable to create file "$1".',
- 'errRename' : 'Unable to rename "$1".',
- 'errCopyFrom' : 'Copying files from volume "$1" not allowed.',
- 'errCopyTo' : 'Copying files to volume "$1" not allowed.',
- 'errMkOutLink' : 'Unable to create a link to outside the volume root.', // from v2.1 added 03.10.2015
- 'errUpload' : 'Upload error.', // old name - errUploadCommon
- 'errUploadFile' : 'Unable to upload "$1".', // old name - errUpload
- 'errUploadNoFiles' : 'No files found for upload.',
- 'errUploadTotalSize' : 'Data exceeds the maximum allowed size.', // old name - errMaxSize
- 'errUploadFileSize' : 'File exceeds maximum allowed size.', // old name - errFileMaxSize
- 'errUploadMime' : 'File type not allowed.',
- 'errUploadTransfer' : '"$1" transfer error.',
- 'errUploadTemp' : 'Unable to make temporary file for upload.', // from v2.1 added 26.09.2015
- 'errNotReplace' : 'Object "$1" already exists at this location and can not be replaced by object with another type.', // new
- 'errReplace' : 'Unable to replace "$1".',
- 'errSave' : 'Unable to save "$1".',
- 'errCopy' : 'Unable to copy "$1".',
- 'errMove' : 'Unable to move "$1".',
- 'errCopyInItself' : 'Unable to copy "$1" into itself.',
- 'errRm' : 'Unable to remove "$1".',
- 'errRmSrc' : 'Unable remove source file(s).',
- 'errExtract' : 'Unable to extract files from "$1".',
- 'errArchive' : 'Unable to create archive.',
- 'errArcType' : 'Unsupported archive type.',
- 'errNoArchive' : 'File is not archive or has unsupported archive type.',
- 'errCmdNoSupport' : 'Backend does not support this command.',
- 'errReplByChild' : 'The folder "$1" can\'t be replaced by an item it contains.',
- 'errArcSymlinks' : 'For security reason denied to unpack archives contains symlinks or files with not allowed names.', // edited 24.06.2012
- 'errArcMaxSize' : 'Archive files exceeds maximum allowed size.',
- 'errResize' : 'Unable to resize "$1".',
- 'errResizeDegree' : 'Invalid rotate degree.', // added 7.3.2013
- 'errResizeRotate' : 'Unable to rotate image.', // added 7.3.2013
- 'errResizeSize' : 'Invalid image size.', // added 7.3.2013
- 'errResizeNoChange' : 'Image size not changed.', // added 7.3.2013
- 'errUsupportType' : 'Unsupported file type.',
- 'errNotUTF8Content' : 'File "$1" is not in UTF-8 and cannot be edited.', // added 9.11.2011
- 'errNetMount' : 'Unable to mount "$1".', // added 17.04.2012
- 'errNetMountNoDriver' : 'Unsupported protocol.', // added 17.04.2012
- 'errNetMountFailed' : 'Mount failed.', // added 17.04.2012
- 'errNetMountHostReq' : 'Host required.', // added 18.04.2012
- 'errSessionExpires' : 'Your session has expired due to inactivity.',
- 'errCreatingTempDir' : 'Unable to create temporary directory: "$1"',
- 'errFtpDownloadFile' : 'Unable to download file from FTP: "$1"',
- 'errFtpUploadFile' : 'Unable to upload file to FTP: "$1"',
- 'errFtpMkdir' : 'Unable to create remote directory on FTP: "$1"',
- 'errArchiveExec' : 'Error while archiving files: "$1"',
- 'errExtractExec' : 'Error while extracting files: "$1"',
- 'errNetUnMount' : 'Unable to unmount', // from v2.1 added 30.04.2012
- 'errConvUTF8' : 'Not convertible to UTF-8', // from v2.1 added 08.04.2014
- 'errFolderUpload' : 'Try Google Chrome, If you\'d like to upload the folder.', // from v2.1 added 26.6.2015
- /******************************* commands names ********************************/
- 'cmdarchive' : 'Create archive',
- 'cmdback' : 'Back',
- 'cmdcopy' : 'Copy',
- 'cmdcut' : 'Cut',
- 'cmddownload' : 'Download',
- 'cmdduplicate' : 'Duplicate',
- 'cmdedit' : 'Edit file',
- 'cmdextract' : 'Extract files from archive',
- 'cmdforward' : 'Forward',
- 'cmdgetfile' : 'Select files',
- 'cmdhelp' : 'About this software',
- 'cmdhome' : 'Home',
- 'cmdinfo' : 'Get info',
- 'cmdmkdir' : 'New folder',
- 'cmdmkfile' : 'New text file',
- 'cmdopen' : 'Open',
- 'cmdpaste' : 'Paste',
- 'cmdquicklook' : 'Preview',
- 'cmdreload' : 'Reload',
- 'cmdrename' : 'Rename',
- 'cmdrm' : 'Delete',
- 'cmdsearch' : 'Find files',
- 'cmdup' : 'Go to parent directory',
- 'cmdupload' : 'Upload files',
- 'cmdview' : 'View',
- 'cmdresize' : 'Resize & Rotate',
- 'cmdsort' : 'Sort',
- 'cmdnetmount' : 'Mount network volume', // added 18.04.2012
- 'cmdnetunmount': 'Unmount', // from v2.1 added 30.04.2012
- 'cmdplaces' : 'To Places', // added 28.12.2014
- 'cmdchmod' : 'Change mode', // from v2.1 added 20.6.2015
- /*********************************** buttons ***********************************/
- 'btnClose' : 'Close',
- 'btnSave' : 'Save',
- 'btnRm' : 'Remove',
- 'btnApply' : 'Apply',
- 'btnCancel' : 'Cancel',
- 'btnNo' : 'No',
- 'btnYes' : 'Yes',
- 'btnMount' : 'Mount', // added 18.04.2012
- 'btnApprove': 'Goto $1 & approve', // from v2.1 added 26.04.2012
- 'btnUnmount': 'Unmount', // from v2.1 added 30.04.2012
- 'btnConv' : 'Convert', // from v2.1 added 08.04.2014
- 'btnCwd' : 'Here', // from v2.1 added 22.5.2015
- 'btnVolume' : 'Volume', // from v2.1 added 22.5.2015
- 'btnAll' : 'All', // from v2.1 added 22.5.2015
- 'btnMime' : 'MIME Type', // from v2.1 added 22.5.2015
- 'btnFileName':'Filename', // from v2.1 added 22.5.2015
- 'btnSaveClose': 'Save & Close', // from v2.1 added 12.6.2015
- /******************************** notifications ********************************/
- 'ntfopen' : 'Open folder',
- 'ntffile' : 'Open file',
- 'ntfreload' : 'Reload folder content',
- 'ntfmkdir' : 'Creating directory',
- 'ntfmkfile' : 'Creating files',
- 'ntfrm' : 'Delete files',
- 'ntfcopy' : 'Copy files',
- 'ntfmove' : 'Move files',
- 'ntfprepare' : 'Prepare to copy files',
- 'ntfrename' : 'Rename files',
- 'ntfupload' : 'Uploading files',
- 'ntfdownload' : 'Downloading files',
- 'ntfsave' : 'Save files',
- 'ntfarchive' : 'Creating archive',
- 'ntfextract' : 'Extracting files from archive',
- 'ntfsearch' : 'Searching files',
- 'ntfresize' : 'Resizing images',
- 'ntfsmth' : 'Doing something',
- 'ntfloadimg' : 'Loading image',
- 'ntfnetmount' : 'Mounting network volume', // added 18.04.2012
- 'ntfnetunmount': 'Unmounting network volume', // from v2.1 added 30.04.2012
- 'ntfdim' : 'Acquiring image dimension', // added 20.05.2013
- 'ntfreaddir' : 'Reading folder infomation', // from v2.1 added 01.07.2013
- 'ntfurl' : 'Getting URL of link', // from v2.1 added 11.03.2014
- 'ntfchmod' : 'Changing file mode', // from v2.1 added 20.6.2015
- /************************************ dates **********************************/
- 'dateUnknown' : 'unknown',
- 'Today' : 'Today',
- 'Yesterday' : 'Yesterday',
- 'msJan' : 'Jan',
- 'msFeb' : 'Feb',
- 'msMar' : 'Mar',
- 'msApr' : 'Apr',
- 'msMay' : 'May',
- 'msJun' : 'Jun',
- 'msJul' : 'Jul',
- 'msAug' : 'Aug',
- 'msSep' : 'Sep',
- 'msOct' : 'Oct',
- 'msNov' : 'Nov',
- 'msDec' : 'Dec',
- 'January' : 'January',
- 'February' : 'February',
- 'March' : 'March',
- 'April' : 'April',
- 'May' : 'May',
- 'June' : 'June',
- 'July' : 'July',
- 'August' : 'August',
- 'September' : 'September',
- 'October' : 'October',
- 'November' : 'November',
- 'December' : 'December',
- 'Sunday' : 'Sunday',
- 'Monday' : 'Monday',
- 'Tuesday' : 'Tuesday',
- 'Wednesday' : 'Wednesday',
- 'Thursday' : 'Thursday',
- 'Friday' : 'Friday',
- 'Saturday' : 'Saturday',
- 'Sun' : 'Sun',
- 'Mon' : 'Mon',
- 'Tue' : 'Tue',
- 'Wed' : 'Wed',
- 'Thu' : 'Thu',
- 'Fri' : 'Fri',
- 'Sat' : 'Sat',
- /******************************** sort variants ********************************/
- 'sortname' : 'by name',
- 'sortkind' : 'by kind',
- 'sortsize' : 'by size',
- 'sortdate' : 'by date',
- 'sortFoldersFirst' : 'Folders first',
- /********************************** new items **********************************/
- 'untitled file.txt' : 'NewFile.txt', // added 10.11.2015
- 'untitled folder' : 'NewFolder', // added 10.11.2015
- 'Archive' : 'NewArchive', // from v2.1 added 10.11.2015
- /********************************** messages **********************************/
- 'confirmReq' : 'Confirmation required',
- 'confirmRm' : 'Are you sure you want to remove files?<br/>This cannot be undone!',
- 'confirmRepl' : 'Replace old file with new one?',
- 'confirmConvUTF8' : 'Not in UTF-8<br/>Convert to UTF-8?<br/>Contents become UTF-8 by saving after conversion.', // from v2.1 added 08.04.2014
- 'confirmNotSave' : 'It has been modified.<br/>Losing work if you do not save changes.', // from v2.1 added 15.7.2015
- 'apllyAll' : 'Apply to all',
- 'name' : 'Name',
- 'size' : 'Size',
- 'perms' : 'Permissions',
- 'modify' : 'Modified',
- 'kind' : 'Kind',
- 'read' : 'read',
- 'write' : 'write',
- 'noaccess' : 'no access',
- 'and' : 'and',
- 'unknown' : 'unknown',
- 'selectall' : 'Select all files',
- 'selectfiles' : 'Select file(s)',
- 'selectffile' : 'Select first file',
- 'selectlfile' : 'Select last file',
- 'viewlist' : 'List view',
- 'viewicons' : 'Icons view',
- 'places' : 'Places',
- 'calc' : 'Calculate',
- 'path' : 'Path',
- 'aliasfor' : 'Alias for',
- 'locked' : 'Locked',
- 'dim' : 'Dimensions',
- 'files' : 'Files',
- 'folders' : 'Folders',
- 'items' : 'Items',
- 'yes' : 'yes',
- 'no' : 'no',
- 'link' : 'Link',
- 'searcresult' : 'Search results',
- 'selected' : 'selected items',
- 'about' : 'About',
- 'shortcuts' : 'Shortcuts',
- 'help' : 'Help',
- 'webfm' : 'Web file manager',
- 'ver' : 'Version',
- 'protocolver' : 'protocol version',
- 'homepage' : 'Project home',
- 'docs' : 'Documentation',
- 'github' : 'Fork us on Github',
- 'twitter' : 'Follow us on twitter',
- 'facebook' : 'Join us on facebook',
- 'team' : 'Team',
- 'chiefdev' : 'chief developer',
- 'developer' : 'developer',
- 'contributor' : 'contributor',
- 'maintainer' : 'maintainer',
- 'translator' : 'translator',
- 'icons' : 'Icons',
- 'dontforget' : 'and don\'t forget to take your towel',
- 'shortcutsof' : 'Shortcuts disabled',
- 'dropFiles' : 'Drop files here',
- 'or' : 'or',
- 'selectForUpload' : 'Select files to upload',
- 'moveFiles' : 'Move files',
- 'copyFiles' : 'Copy files',
- 'rmFromPlaces' : 'Remove from places',
- 'aspectRatio' : 'Aspect ratio',
- 'scale' : 'Scale',
- 'width' : 'Width',
- 'height' : 'Height',
- 'resize' : 'Resize',
- 'crop' : 'Crop',
- 'rotate' : 'Rotate',
- 'rotate-cw' : 'Rotate 90 degrees CW',
- 'rotate-ccw' : 'Rotate 90 degrees CCW',
- 'degree' : '°',
- 'netMountDialogTitle' : 'Mount network volume', // added 18.04.2012
- 'protocol' : 'Protocol', // added 18.04.2012
- 'host' : 'Host', // added 18.04.2012
- 'port' : 'Port', // added 18.04.2012
- 'user' : 'User', // added 18.04.2012
- 'pass' : 'Password', // added 18.04.2012
- 'confirmUnmount' : 'Are you unmount $1?', // from v2.1 added 30.04.2012
- 'dropFilesBrowser': 'Drop or Paste files from browser', // from v2.1 added 30.05.2012
- 'dropPasteFiles' : 'Drop or Paste files and URLs here', // from v2.1 added 07.04.2014
- 'encoding' : 'Encoding', // from v2.1 added 19.12.2014
- 'locale' : 'Locale', // from v2.1 added 19.12.2014
- 'searchTarget' : 'Target: $1', // from v2.1 added 22.5.2015
- 'searchMime' : 'Search by input MIME Type', // from v2.1 added 22.5.2015
- 'owner' : 'Owner', // from v2.1 added 20.6.2015
- 'group' : 'Group', // from v2.1 added 20.6.2015
- 'other' : 'Other', // from v2.1 added 20.6.2015
- 'execute' : 'Execute', // from v2.1 added 20.6.2015
- 'perm' : 'Permission', // from v2.1 added 20.6.2015
- 'mode' : 'Mode', // from v2.1 added 20.6.2015
- /********************************** mimetypes **********************************/
- 'kindUnknown' : 'Unknown',
- 'kindFolder' : 'Folder',
- 'kindAlias' : 'Alias',
- 'kindAliasBroken' : 'Broken alias',
- // applications
- 'kindApp' : 'Application',
- 'kindPostscript' : 'Postscript document',
- 'kindMsOffice' : 'Microsoft Office document',
- 'kindMsWord' : 'Microsoft Word document',
- 'kindMsExcel' : 'Microsoft Excel document',
- 'kindMsPP' : 'Microsoft Powerpoint presentation',
- 'kindOO' : 'Open Office document',
- 'kindAppFlash' : 'Flash application',
- 'kindPDF' : 'Portable Document Format (PDF)',
- 'kindTorrent' : 'Bittorrent file',
- 'kind7z' : '7z archive',
- 'kindTAR' : 'TAR archive',
- 'kindGZIP' : 'GZIP archive',
- 'kindBZIP' : 'BZIP archive',
- 'kindXZ' : 'XZ archive',
- 'kindZIP' : 'ZIP archive',
- 'kindRAR' : 'RAR archive',
- 'kindJAR' : 'Java JAR file',
- 'kindTTF' : 'True Type font',
- 'kindOTF' : 'Open Type font',
- 'kindRPM' : 'RPM package',
- // texts
- 'kindText' : 'Text document',
- 'kindTextPlain' : 'Plain text',
- 'kindPHP' : 'PHP source',
- 'kindCSS' : 'Cascading style sheet',
- 'kindHTML' : 'HTML document',
- 'kindJS' : 'Javascript source',
- 'kindRTF' : 'Rich Text Format',
- 'kindC' : 'C source',
- 'kindCHeader' : 'C header source',
- 'kindCPP' : 'C++ source',
- 'kindCPPHeader' : 'C++ header source',
- 'kindShell' : 'Unix shell script',
- 'kindPython' : 'Python source',
- 'kindJava' : 'Java source',
- 'kindRuby' : 'Ruby source',
- 'kindPerl' : 'Perl script',
- 'kindSQL' : 'SQL source',
- 'kindXML' : 'XML document',
- 'kindAWK' : 'AWK source',
- 'kindCSV' : 'Comma separated values',
- 'kindDOCBOOK' : 'Docbook XML document',
- 'kindMarkdown' : 'Markdown text', // added 20.7.2015
- // images
- 'kindImage' : 'Image',
- 'kindBMP' : 'BMP image',
- 'kindJPEG' : 'JPEG image',
- 'kindGIF' : 'GIF Image',
- 'kindPNG' : 'PNG Image',
- 'kindTIFF' : 'TIFF image',
- 'kindTGA' : 'TGA image',
- 'kindPSD' : 'Adobe Photoshop image',
- 'kindXBITMAP' : 'X bitmap image',
- 'kindPXM' : 'Pixelmator image',
- // media
- 'kindAudio' : 'Audio media',
- 'kindAudioMPEG' : 'MPEG audio',
- 'kindAudioMPEG4' : 'MPEG-4 audio',
- 'kindAudioMIDI' : 'MIDI audio',
- 'kindAudioOGG' : 'Ogg Vorbis audio',
- 'kindAudioWAV' : 'WAV audio',
- 'AudioPlaylist' : 'MP3 playlist',
- 'kindVideo' : 'Video media',
- 'kindVideoDV' : 'DV movie',
- 'kindVideoMPEG' : 'MPEG movie',
- 'kindVideoMPEG4' : 'MPEG-4 movie',
- 'kindVideoAVI' : 'AVI movie',
- 'kindVideoMOV' : 'Quick Time movie',
- 'kindVideoWM' : 'Windows Media movie',
- 'kindVideoFlash' : 'Flash movie',
- 'kindVideoMKV' : 'Matroska movie',
- 'kindVideoOGG' : 'Ogg movie',
- 'cmdsetpass' : 'Set password'
- }
- };
- }
- /*
- * File: /js/ui/button.js
- */
- /**
- * @class elFinder toolbar button widget.
- * If command has variants - create menu
- *
- * @author Dmitry (dio) Levashov
- **/
- $.fn.elfinderbutton = function(cmd) {
- 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,
- button = $(this).addClass('ui-state-default elfinder-button')
- .attr('title', cmd.title)
- .append('<span class="elfinder-button-icon elfinder-button-icon-'+cmd.name+'"/>')
- .hover(function(e) { !button.hasClass(disabled) && button[e.type == 'mouseleave' ? 'removeClass' : 'addClass'](hover) /**button.toggleClass(hover);*/ })
- .click(function(e) {
- if (!button.hasClass(disabled)) {
- if (menu && cmd.variants.length > 1) {
- // close other menus
- menu.is(':hidden') && cmd.fm.getUI().click();
- e.stopPropagation();
- menu.slideToggle(100);
- } else {
- cmd.exec();
- }
- }
- }),
- hideMenu = function() {
- menu.hide();
- };
- // if command has variants create menu
- if ($.isArray(cmd.variants)) {
- button.addClass('elfinder-menubutton');
- menu = $('<div class="ui-widget ui-widget-content elfinder-button-menu ui-corner-all"/>')
- .hide()
- .appendTo(button)
- .zIndex(12+button.zIndex())
- .on('mouseenter mouseleave', '.'+item, function() { $(this).toggleClass(hover) })
- .on('click', '.'+item, function(e) {
- e.preventDefault();
- e.stopPropagation();
- button.removeClass(hover);
- menu.hide();
- cmd.exec(cmd.fm.selected(), $(this).data('value'));
- });
- cmd.fm.bind('disable select', hideMenu).getUI().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() {
- if (cmd.disabled()) {
- button.removeClass(active+' '+hover).addClass(disabled);
- } else {
- button.removeClass(disabled);
- button[cmd.active() ? 'addClass' : 'removeClass'](active);
- }
- })
- .change();
- });
- }
- /*
- * File: /js/ui/contextmenu.js
- */
- /**
- * @class elFinder contextmenu
- *
- * @author Dmitry (dio) Levashov
- **/
- $.fn.elfindercontextmenu = function(fm) {
- return this.each(function() {
- var cmItem = 'elfinder-contextmenu-item',
- smItem = 'elfinder-contextsubmenu-item',
- menu = $(this).addClass('ui-helper-reset ui-widget ui-state-default ui-corner-all elfinder-contextmenu elfinder-contextmenu-'+fm.direction)
- .hide()
- .appendTo('body')
- .on('mouseenter mouseleave', '.'+cmItem, function() {
- $(this).toggleClass('ui-state-hover')
- }),
- subpos = fm.direction == 'ltr' ? 'left' : 'right',
- types = $.extend({}, fm.options.contextmenu),
- clItem = cmItem + (fm.UA.Touch ? ' elfinder-touch' : ''),
- tpl = '<div class="'+clItem+'"><span class="elfinder-button-icon {icon} elfinder-contextmenu-icon"/><span>{label}</span></div>',
- item = function(label, icon, callback) {
- return $(tpl.replace('{icon}', icon ? 'elfinder-button-icon-'+icon : '').replace('{label}', label))
- .click(function(e) {
- e.stopPropagation();
- e.preventDefault();
- callback();
- })
- },
- open = function(x, y) {
- var win = $(window),
- width = menu.outerWidth(),
- height = menu.outerHeight(),
- wwidth = win.width(),
- wheight = win.height(),
- scrolltop = win.scrollTop(),
- scrollleft = win.scrollLeft(),
- m = fm.UA.Touch? 10 : 0,
- css = {
- top : (y + m + height < wheight ? y + m : y - m - height > 0 ? y - m - height : y + m) + scrolltop,
- left : (x + m + width < wwidth ? x + m : x - m - width) + scrollleft,
- 'z-index' : 100 + fm.getUI('workzone').zIndex()
- };
- menu.css(css)
- .show();
- css = {'z-index' : css['z-index']+10};
- css[subpos] = parseInt(menu.width());
- menu.find('.elfinder-contextmenu-sub').css(css);
- },
- close = function() {
- menu.hide().empty();
- },
- create = function(type, targets) {
- var sep = false,
- cmdMap = {}, disabled = [], isCwd = (targets[0].indexOf(fm.cwd().volumeid, 0) === 0),
- self = fm.getUI('contextmenu');
- if (self.data('cmdMaps')) {
- $.each(self.data('cmdMaps'), function(i, v){
- if (targets[0].indexOf(i, 0) == 0) {
- cmdMap = v;
- return false;
- }
- });
- }
- if (!isCwd) {
- if (fm.disabledCmds) {
- $.each(fm.disabledCmds, function(i, v){
- if (targets[0].indexOf(i, 0) == 0) {
- disabled = v;
- return false;
- }
- });
- }
- }
- $.each(types[type]||[], function(i, name) {
- var cmd, node, submenu, hover, _disabled;
- if (name == '|' && sep) {
- menu.append('<div class="elfinder-contextmenu-separator"/>');
- sep = false;
- return;
- }
- if (cmdMap[name]) {
- name = cmdMap[name];
- }
- cmd = fm.command(name);
- if (cmd && !isCwd) {
- _disabled = cmd._disabled;
- cmd._disabled = !(cmd.alwaysEnabled || (fm._commands[name] ? $.inArray(name, disabled) === -1 : false));
- }
- if (cmd && cmd.getstate(targets) != -1) {
- targets._type = type;
- if (cmd.variants) {
- if (!cmd.variants.length) {
- return;
- }
- node = item(cmd.title, cmd.name, function(){})
- .on('touchend', function(e){
- node.data('touching', true);
- setTimeout(function(){node.data('touching', false);}, 50);
- })
- .on('click touchend', '.'+smItem, function(e){
- e.stopPropagation();
- if (node.data('touching')) {
- node.data('touching', false);
- $(this).removeClass('ui-state-hover');
- e.preventDefault();
- } else if (e.type == 'click') {
- menu.hide();
- cmd.exec(targets, $(this).data('exec'));
- }
- });
- submenu = $('<div class="ui-corner-all elfinder-contextmenu-sub"/>')
- .appendTo(node.append('<span class="elfinder-contextmenu-arrow"/>'));
- hover = function(){
- var win = $(window),
- baseleft = $(node).offset().left,
- basetop = $(node).offset().top,
- basewidth = $(node).outerWidth(),
- width = submenu.outerWidth(),
- height = submenu.outerHeight(),
- wwidth = win.scrollLeft() + win.width(),
- wheight = win.scrollTop() + win.height(),
- margin = 5, x, y, over;
- over = (baseleft + basewidth + width + margin) - wwidth;
- x = (over > 0)? basewidth - over : basewidth;
- over = (basetop + 5 + height + margin) - wheight;
- y = (over > 0)? 5 - over : 5;
- var css = {
- left : x,
- top : y
- };
- submenu.css(css).toggle();
- };
- node.addClass('elfinder-contextmenu-group').hover(function(){ hover(); });
- $.each(cmd.variants, function(i, variant) {
- submenu.append(
- $('<div class="'+clItem+' '+smItem+'"><span>'+variant[1]+'</span></div>').data('exec', variant[0])
- );
- });
- } else {
- node = item(cmd.title, cmd.name, function() {
- close();
- cmd.exec(targets);
- })
- }
- menu.append(node)
- sep = true;
- }
- cmd && !isCwd && (cmd._disabled = _disabled);
- });
- },
- createFromRaw = function(raw) {
- $.each(raw, function(i, data) {
- var node;
- if (data.label && typeof data.callback == 'function') {
- node = item(data.label, data.icon, function() {
- close();
- data.callback();
- });
- menu.append(node);
- }
- })
- };
- fm.one('load', function() {
- fm.bind('contextmenu', function(e) {
- var data = e.data;
- close();
- if (data.type && data.targets) {
- create(data.type, data.targets);
- } else if (data.raw) {
- createFromRaw(data.raw);
- }
- menu.children().length && open(data.x, data.y);
- })
- .one('destroy', function() { menu.remove(); })
- .bind('disable select', close)
- .getUI().click(close);
- });
- });
- }
- /*
- * File: /js/ui/cwd.js
- */
- /**
- * elFinder current working directory ui.
- *
- * @author Dmitry (dio) Levashov
- **/
- $.fn.elfindercwd = function(fm, options) {
- this.not('.elfinder-cwd').each(function() {
- // fm.time('cwdLoad');
- var mobile = fm.UA.Mobile,
- list = fm.viewType == 'list',
- undef = 'undefined',
- /**
- * Select event full name
- *
- * @type String
- **/
- evtSelect = 'select.'+fm.namespace,
- /**
- * Unselect event full name
- *
- * @type String
- **/
- evtUnselect = 'unselect.'+fm.namespace,
- /**
- * Disable event full name
- *
- * @type String
- **/
- evtDisable = 'disable.'+fm.namespace,
- /**
- * Disable event full name
- *
- * @type String
- **/
- evtEnable = 'enable.'+fm.namespace,
- c = 'class',
- /**
- * File css class
- *
- * @type String
- **/
- clFile = fm.res(c, 'cwdfile'),
- /**
- * Selected css class
- *
- * @type String
- **/
- fileSelector = '.'+clFile,
- /**
- * Selected css class
- *
- * @type String
- **/
- clSelected = 'ui-selected',
- /**
- * Disabled css class
- *
- * @type String
- **/
- clDisabled = fm.res(c, 'disabled'),
- /**
- * Draggable css class
- *
- * @type String
- **/
- clDraggable = fm.res(c, 'draggable'),
- /**
- * Droppable css class
- *
- * @type String
- **/
- clDroppable = fm.res(c, 'droppable'),
- /**
- * Hover css class
- *
- * @type String
- **/
- clHover = fm.res(c, 'hover'),
- /**
- * Hover css class
- *
- * @type String
- **/
- clDropActive = fm.res(c, 'adroppable'),
- /**
- * Css class for temporary nodes (for mkdir/mkfile) commands
- *
- * @type String
- **/
- clTmp = clFile+'-tmp',
- /**
- * Number of thumbnails to load in one request (new api only)
- *
- * @type Number
- **/
- tmbNum = fm.options.loadTmbs > 0 ? fm.options.loadTmbs : 5,
- /**
- * Current search query.
- *
- * @type String
- */
- query = '',
- lastSearch = [],
- customColsBuild = function() {
- var customCols = '';
- var columns = fm.options.uiOptions.cwd.listView.columns;
- for (var i = 0; i < columns.length; i++) {
- customCols += '<td>{' + columns[i] + '}</td>';
- }
- return customCols;
- },
- /**
- * File templates
- *
- * @type Object
- **/
- templates = {
- icon : '<div id="{hash}" class="'+clFile+(fm.UA.Touch ? ' '+'elfinder-touch' : '')+' {permsclass} {dirclass} ui-corner-all" title="{tooltip}"><div class="elfinder-cwd-file-wrapper ui-corner-all"><div class="elfinder-cwd-icon {mime} ui-corner-all" unselectable="on" {style}/>{marker}</div><div class="elfinder-cwd-filename" title="{nametitle}">{name}</div></div>',
- row : '<tr id="{hash}" class="'+clFile+(fm.UA.Touch ? ' '+'elfinder-touch' : '')+' {permsclass} {dirclass}" title="{tooltip}"><td><div class="elfinder-cwd-file-wrapper"><span class="elfinder-cwd-icon {mime}"/>{marker}<span class="elfinder-cwd-filename">{name}</span></div></td>'+customColsBuild()+'</tr>',
- },
- permsTpl = fm.res('tpl', 'perms'),
- lockTpl = fm.res('tpl', 'lock'),
- symlinkTpl = fm.res('tpl', 'symlink'),
- /**
- * Template placeholders replacement rules
- *
- * @type Object
- **/
- replacement = {
- name : function(f) {
- name = fm.escape(f.name);
- !list && (name = name.replace(/([_.])/g, '​$1'));
- return name;
- },
- nametitle : function(f) {
- return fm.escape(f.name);
- },
- permsclass : function(f) {
- return fm.perms2class(f);
- },
- perm : function(f) {
- return fm.formatPermissions(f);
- },
- dirclass : function(f) {
- return f.mime == 'directory' ? 'directory' : '';
- },
- mime : function(f) {
- return fm.mime2class(f.mime);
- },
- size : function(f) {
- return fm.formatSize(f.size);
- },
- date : function(f) {
- return fm.formatDate(f);
- },
- kind : function(f) {
- return fm.mime2kind(f);
- },
- mode : function(f) {
- return f.perm? fm.formatFileMode(f.perm) : '';
- },
- modestr : function(f) {
- return f.perm? fm.formatFileMode(f.perm, 'string') : '';
- },
- modeoct : function(f) {
- return f.perm? fm.formatFileMode(f.perm, 'octal') : '';
- },
- modeboth : function(f) {
- return f.perm? fm.formatFileMode(f.perm, 'both') : '';
- },
- marker : function(f) {
- return (f.alias || f.mime == 'symlink-broken' ? symlinkTpl : '')+(!f.read || !f.write ? permsTpl : '')+(f.locked ? lockTpl : '');
- },
- tooltip : function(f) {
- var title = fm.formatDate(f) + (f.size > 0 ? ' ('+fm.formatSize(f.size)+')' : '');
- return f.tooltip? fm.escape(f.tooltip).replace(/\r/g, ' ') + ' ' + title : title;
- }
- },
- /**
- * Return file html
- *
- * @param Object file info
- * @return String
- **/
- itemhtml = function(f) {
- return templates[list ? 'row' : 'icon']
- .replace(/\{([a-z]+)\}/g, function(s, e) {
- return replacement[e] ? replacement[e](f) : (f[e] ? f[e] : '');
- });
- },
- /**
- * Flag. Required for msie to avoid unselect files on dragstart
- *
- * @type Boolean
- **/
- selectLock = false,
- /**
- * Move selection to prev/next file
- *
- * @param String move direction
- * @param Boolean append to current selection
- * @return void
- * @rise select
- */
- select = function(keyCode, append) {
- var code = $.ui.keyCode,
- prev = keyCode == code.LEFT || keyCode == code.UP,
- sel = cwd.find('[id].'+clSelected),
- selector = prev ? 'first:' : 'last',
- s, n, sib, top, left;
- function sibling(n, direction) {
- return n[direction+'All']('[id]:not(.'+clDisabled+'):not(.elfinder-cwd-parent):first');
- }
- if (sel.length) {
- s = sel.filter(prev ? ':first' : ':last');
- sib = sibling(s, prev ? 'prev' : 'next');
- if (!sib.length) {
- // there is no sibling on required side - do not move selection
- n = s;
- } else if (list || keyCode == code.LEFT || keyCode == code.RIGHT) {
- // find real prevoius file
- n = sib;
- } else {
- // find up/down side file in icons view
- top = s.position().top;
- left = s.position().left;
- n = s;
- if (prev) {
- do {
- n = n.prev('[id]');
- } while (n.length && !(n.position().top < top && n.position().left <= left));
- if (n.hasClass(clDisabled)) {
- n = sibling(n, 'next');
- }
- } else {
- do {
- n = n.next('[id]');
- } while (n.length && !(n.position().top > top && n.position().left >= left));
- if (n.hasClass(clDisabled)) {
- n = sibling(n, 'prev');
- }
- // there is row before last one - select last file
- if (!n.length) {
- sib = cwd.find('[id]:not(.'+clDisabled+'):last');
- if (sib.position().top > top) {
- n = sib;
- }
- }
- }
- }
- // !append && unselectAll();
- } else {
- // there are no selected file - select first/last one
- n = cwd.find('[id]:not(.'+clDisabled+'):not(.elfinder-cwd-parent):'+(prev ? 'last' : 'first'));
- }
- if (n && n.length && !n.hasClass('elfinder-cwd-parent')) {
- if (append) {
- // append new files to selected
- n = s.add(s[prev ? 'prevUntil' : 'nextUntil']('#'+n.attr('id'))).add(n);
- } else {
- // unselect selected files
- sel.trigger(evtUnselect);
- }
- // select file(s)
- n.trigger(evtSelect);
- // set its visible
- scrollToView(n.filter(prev ? ':first' : ':last'));
- // update cache/view
- trigger();
- }
- },
- selectedFiles = [],
- selectFile = function(hash) {
- $('#'+hash).trigger(evtSelect);
- },
- selectAll = function() {
- var phash = fm.cwd().hash;
- cwd.find('[id]:not(.'+clSelected+'):not(.elfinder-cwd-parent)').trigger(evtSelect);
- selectedFiles = $.map(fm.files(), function(f) { return f.phash == phash ? f.hash : null ;});
- trigger();
- },
- /**
- * Unselect all files
- *
- * @return void
- */
- unselectAll = function() {
- selectedFiles = [];
- cwd.find('[id].'+clSelected).trigger(evtUnselect);
- trigger();
- },
- /**
- * Return selected files hashes list
- *
- * @return Array
- */
- selected = function() {
- return selectedFiles;
- },
- /**
- * Fire elfinder "select" event and pass selected files to it
- *
- * @return void
- */
- trigger = function() {
- fm.trigger('select', {selected : selectedFiles});
- },
- /**
- * Scroll file to set it visible
- *
- * @param DOMElement file/dir node
- * @return void
- */
- scrollToView = function(o) {
- var ftop = o.position().top,
- fheight = o.outerHeight(true),
- wtop = wrapper.scrollTop(),
- wheight = wrapper.innerHeight();
- if (ftop + fheight > wtop + wheight) {
- wrapper.scrollTop(parseInt(ftop + fheight - wheight));
- } else if (ftop < wtop) {
- wrapper.scrollTop(ftop);
- }
- },
- /**
- * Files we get from server but not show yet
- *
- * @type Array
- **/
- buffer = [],
- /**
- * Return index of elements with required hash in buffer
- *
- * @param String file hash
- * @return Number
- */
- index = function(hash) {
- var l = buffer.length;
- while (l--) {
- if (buffer[l].hash == hash) {
- return l;
- }
- }
- return -1;
- },
- /**
- * Scroll event name
- *
- * @type String
- **/
- scrollEvent = 'scroll.'+fm.namespace,
- /**
- * Cwd scroll event handler.
- * Lazy load - append to cwd not shown files
- *
- * @return void
- */
- render = function() {
- var go = function(){
- var html = [],
- dirs = false,
- ltmb = [],
- atmb = {},
- last = buffer._last || cwd.find('[id]:last'),
- top = !last.length,
- place = buffer._place || (list ? cwd.children('table').children('tbody') : cwd),
- chk, files;
- // check draging scroll bar
- top && (wrapper._top = 0);
- if (!!wrapper._mousedown && wrapper._top != wrapper.scrollTop()) {
- wrapper._top = wrapper.scrollTop();
- setTimeout(function(){
- go();
- }, 50);
- return;
- }
- delete buffer._timer;
- if (!buffer.length) {
- bottomMarker.hide();
- return wrapper.off(scrollEvent);
- }
- //progress.show();
- while ((!last.length || (chk = last.position().top - (wrapper.height() + wrapper.scrollTop() + fm.options.showThreshold)) <= 0)
- && (files = buffer.splice(0, fm.options.showFiles - (chk || 0) / (buffer._hpi || 1))).length) {
- html = $.map(files, function(f) {
- if (f.hash && f.name) {
- if (f.mime == 'directory') {
- dirs = true;
- }
- if (f.tmb) {
- f.tmb === 1 ? ltmb.push(f.hash) : (atmb[f.hash] = f.tmb);
- }
- return itemhtml(f);
- }
- return null;
- });
- (top || !buffer.length) && bottomMarker.hide();
- place.append(html.join(''));
- last = cwd.find('[id]:last');
- // scroll top on dir load to avoid scroll after page reload
- top && wrapper.scrollTop(0);
- (top || !buffer._hpi) && bottomMarkerShow(place, files.length);
- if (top) { break; }
- }
- // cache last
- buffer._last = last;
- // load/attach thumbnails
- attachThumbnails(atmb);
- ltmb.length && loadThumbnails(ltmb);
- // make directory droppable
- dirs && !mobile && makeDroppable();
- if (selectedFiles.length) {
- place.find('[id]:not(.'+clSelected+'):not(.elfinder-cwd-parent)').each(function() {
- var id = this.id;
- $.inArray(id, selectedFiles) !== -1 && $(this).trigger(evtSelect);
- });
- }
- };
- // stop while scrolling
- buffer._timer && clearTimeout(buffer._timer);
- // first time to go()
- !buffer._timer && go();
- // regist next go()
- buffer._timer = setTimeout(function(){
- go();
- }, 100);
- },
- /**
- * Droppable options for cwd.
- * Drop target is `wrapper`
- * Do not add class on childs file over
- *
- * @type Object
- */
- droppable = $.extend({}, fm.droppable, {
- over : function(e, ui) {
- var cwd = fm.cwd(),
- hash = cwd.hash,
- $this = $(this);
- $.each(ui.helper.data('files'), function(i, h) {
- if (h === hash || fm.file(h).phash === hash) {
- if (h !== hash && cwd.write) {
- $this.data('dropover', true);
- }
- if (!$this.data('dropover') || !ui.helper.hasClass('elfinder-drag-helper-plus')) {
- $this.removeClass(clDropActive);
- }
- return false;
- }
- });
- },
- out : function() {
- $(this).removeData('dropover')
- .removeClass(clDropActive);
- },
- deactivate : function() {
- $(this).removeData('dropover')
- .removeClass(clDropActive);
- }
- }),
- /**
- * Make directory droppable
- *
- * @return void
- */
- makeDroppable = function() {
- if (fm.isCommandEnabled('paste')) {
- setTimeout(function() {
- cwd.find('.directory:not(.'+clDroppable+',.elfinder-na,.elfinder-ro)').droppable(fm.droppable).each(function(){
- fm.makeDirectDropUpload(this, this.id);
- });
- }, 20);
- }
- },
- /**
- * Preload required thumbnails and on load add css to files.
- * Return false if required file is not visible yet (in buffer) -
- * required for old api to stop loading thumbnails.
- *
- * @param Object file hash -> thumbnail map
- * @return Boolean
- */
- attachThumbnails = function(images) {
- var url = fm.option('tmbUrl'),
- ret = true,
- ndx;
- $.each(images, function(hash, tmb) {
- var node = $('#'+hash);
- if (node.length) {
- (function(node, tmb) {
- $('<img/>')
- .load(function() { node.find('.elfinder-cwd-icon').css('background', "url('"+tmb+"') center center no-repeat"); })
- .attr('src', tmb);
- })(node, url+tmb);
- } else {
- ret = false;
- if ((ndx = index(hash)) != -1) {
- buffer[ndx].tmb = tmb;
- }
- }
- });
- return ret;
- },
- /**
- * Load thumbnails from backend.
- *
- * @param Array|Boolean files hashes list for new api | true for old api
- * @return void
- */
- loadThumbnails = function(files) {
- var tmbs = [];
- if (fm.oldAPI) {
- fm.request({
- data : {cmd : 'tmb', current : fm.cwd().hash},
- preventFail : true
- })
- .done(function(data) {
- if (attachThumbnails(data.images||[]) && data.tmb) {
- loadThumbnails();
- }
- });
- return;
- }
- tmbs = tmbs = files.splice(0, tmbNum);
- if (tmbs.length) {
- fm.request({
- data : {cmd : 'tmb', targets : tmbs},
- preventFail : true
- })
- .done(function(data) {
- if (attachThumbnails(data.images||[])) {
- loadThumbnails(files);
- }
- });
- }
- },
- /**
- * Add new files to cwd/buffer
- *
- * @param Array new files
- * @return void
- */
- add = function(files) {
- var place = list ? cwd.find('tbody') : cwd,
- l = files.length,
- ltmb = [],
- atmb = {},
- dirs = false,
- findNode = function(file) {
- var pointer = cwd.find('[id]:first'), file2;
- while (pointer.length) {
- file2 = fm.file(pointer.attr('id'));
- if (!pointer.hasClass('elfinder-cwd-parent') && file2 && fm.compare(file, file2) < 0) {
- return pointer;
- }
- pointer = pointer.next('[id]');
- }
- },
- findIndex = function(file) {
- var l = buffer.length, i;
- for (i =0; i < l; i++) {
- if (fm.compare(file, buffer[i]) < 0) {
- return i;
- }
- }
- return l || -1;
- },
- file, hash, node, ndx;
- while (l--) {
- file = files[l];
- hash = file.hash;
- if ($('#'+hash).length) {
- continue;
- }
- if ((node = findNode(file)) && node.length) {
- node.before(itemhtml(file));
- } else if ((ndx = findIndex(file)) >= 0) {
- buffer.splice(ndx, 0, file);
- } else {
- place.append(itemhtml(file));
- }
- if ($('#'+hash).length) {
- if (file.mime == 'directory') {
- dirs = true;
- } else if (file.tmb) {
- file.tmb === 1 ? ltmb.push(hash) : (atmb[hash] = file.tmb);
- }
- }
- }
- bottomMarkerShow(place);
- attachThumbnails(atmb);
- ltmb.length && loadThumbnails(ltmb);
- dirs && !mobile && makeDroppable();
- },
- /**
- * Remove files from cwd/buffer
- *
- * @param Array files hashes
- * @return void
- */
- remove = function(files) {
- var l = files.length, hash, n, ndx;
- while (l--) {
- hash = files[l];
- if ((n = $('#'+hash)).length) {
- try {
- n.remove();
- } catch(e) {
- fm.debug('error', e);
- }
- } else if ((ndx = index(hash)) != -1) {
- buffer.splice(ndx, 1);
- }
- }
- // refresh cwd if empty for a bug of browser (ex. Android Chrome 43.0.2357.93)
- if (cwd.children().length < 1) {
- cwd.hide();
- setTimeout(function(){ cwd.show(); }, 0);
- }
- },
- msg = {
- name : fm.i18n('name'),
- perm : fm.i18n('perms'),
- date : fm.i18n('modify'),
- size : fm.i18n('size'),
- kind : fm.i18n('kind'),
- modestr : fm.i18n('mode'),
- modeoct : fm.i18n('mode'),
- modeboth : fm.i18n('mode'),
- },
- customColsNameBuild = function() {
- var name = '',
- customColsName = '',
- columns = fm.options.uiOptions.cwd.listView.columns,
- names = $.extend({}, msg, fm.options.uiOptions.cwd.listView.columnsCustomName);
- for (var i = 0; i < columns.length; i++) {
- if (typeof names[columns[i]] !== 'undefined') {
- name = names[columns[i]];
- } else {
- name = fm.i18n(columns[i]);
- }
- customColsName +='<td class="elfinder-cwd-view-th-'+columns[i]+'">'+name+'</td>';
- }
- return customColsName;
- },
- bottomMarkerShow = function(place, cnt) {
- var ph;
- place = place || (list ? cwd.find('tbody') : cwd);
- if (buffer.length > 0) {
- place.css({height: 'auto'});
- ph = place.height();
- cnt && (buffer._hpi = ph / cnt);
- bottomMarker.css({top: (buffer._hpi * buffer.length + ph) + 'px'}).show();
- }
- },
- /**
- * Update directory content
- *
- * @param Array files
- * @return void
- */
- content = function(files, any) {
- var phash = fm.cwd().hash;
- unselectAll();
- try {
- // to avoid problem with draggable
- cwd.empty();
- } catch (e) {
- cwd.html('');
- }
- cwd.removeClass('elfinder-cwd-view-icons elfinder-cwd-view-list')
- .addClass('elfinder-cwd-view-'+(list ? 'list' :'icons'));
- cwd.css('height', 'auto');
- bottomMarker.hide();
- wrapper[list ? 'addClass' : 'removeClass']('elfinder-cwd-wrapper-list');
- wrapper._padding = parseInt(wrapper.css('padding-top')) + parseInt(wrapper.css('padding-bottom'));
- list && cwd.html('<table><thead><tr class="ui-state-default'+(fm.UA.Touch? ' elfinder-touch' : '')+'"><td class="elfinder-cwd-view-th-name">'+msg.name+'</td>'+customColsNameBuild()+'</tr></thead><tbody/></table>');
- buffer = $.map(files, function(f) { return any || f.phash == phash ? f : null; });
- buffer = fm.sortFiles(buffer);
- wrapper.on(scrollEvent, render).trigger(scrollEvent);
- phash = fm.cwd().phash;
- if (options.oldSchool && phash && !query) {
- var parent = $.extend(true, {}, fm.file(phash), {name : '..', mime : 'directory'});
- parent = $(itemhtml(parent))
- .addClass('elfinder-cwd-parent')
- .bind('mousedown click mouseup touchstart touchmove touchend dblclick mouseenter', function(e) {
- e.preventDefault();
- e.stopPropagation();
- })
- .dblclick(function() {
- fm.exec('open', this.id);
- });
- (list ? cwd.find('tbody') : cwd).prepend(parent);
- }
- },
- /**
- * CWD node itself
- *
- * @type JQuery
- **/
- cwd = $(this)
- .addClass('ui-helper-clearfix elfinder-cwd')
- .attr('unselectable', 'on')
- // fix ui.selectable bugs and add shift+click support
- .on('click.'+fm.namespace, fileSelector, function(e) {
- var p = this.id ? $(this) : $(this).parents('[id]:first'),
- prev = p.prevAll('.'+clSelected+':first'),
- next = p.nextAll('.'+clSelected+':first'),
- pl = prev.length,
- nl = next.length,
- sib;
- if (cwd.data('longtap')) {
- e.stopPropagation();
- return;
- }
- e.stopImmediatePropagation();
- if (e.shiftKey && (pl || nl)) {
- sib = pl ? p.prevUntil('#'+prev.attr('id')) : p.nextUntil('#'+next.attr('id'));
- sib.add(p).trigger(evtSelect);
- } else if (e.ctrlKey || e.metaKey) {
- p.trigger(p.hasClass(clSelected) ? evtUnselect : evtSelect);
- } else {
- if (p.data('touching') && p.hasClass(clSelected)) {
- p.data('touching', null);
- fm.dblclick({file : this.id});
- unselectAll();
- return;
- } else {
- unselectAll();
- p.trigger(evtSelect);
- }
- }
- trigger();
- })
- // call fm.open()
- .on('dblclick.'+fm.namespace, fileSelector, function(e) {
- fm.dblclick({file : this.id});
- })
- // for touch device
- .on('touchstart.'+fm.namespace, fileSelector, function(e) {
- e.stopPropagation();
- if (e.target.nodeName == 'INPUT' || e.target.nodeName == 'TEXTAREA') {
- return;
- }
- var p = this.id ? $(this) : $(this).parents('[id]:first'),
- sel = p.prevAll('.'+clSelected+':first').length +
- p.nextAll('.'+clSelected+':first').length;
- cwd.data('longtap', null);
- p.addClass(clHover)
- .data('touching', true)
- .data('tmlongtap', setTimeout(function(){
- // long tap
- cwd.data('longtap', true);
- if (p.hasClass(clSelected) && sel > 0) {
- p.trigger(evtUnselect);
- trigger();
- } else {
- if (e.target.nodeName != 'TD' || fm.selected().length > 0) {
- p.trigger(evtSelect);
- trigger();
- fm.trigger('contextmenu', {
- 'type' : 'files',
- 'targets' : fm.selected(),
- 'x' : e.originalEvent.touches[0].clientX,
- 'y' : e.originalEvent.touches[0].clientY
- });
- }
- }
- }, 500));
- })
- .on('touchmove.'+fm.namespace+' touchend.'+fm.namespace, fileSelector, function(e) {
- e.stopPropagation();
- if (e.target.nodeName == 'INPUT' || e.target.nodeName == 'TEXTAREA') {
- return;
- }
- var p = this.id ? $(this) : $(this).parents('[id]:first');
- clearTimeout(p.data('tmlongtap'));
- if (e.type == 'touchmove') {
- p.removeClass(clHover);
- }
- })
- // attach draggable
- .on('mouseenter.'+fm.namespace, fileSelector, function(e) {
- var $this = $(this),
- target = list ? $this : $this.children();
- if (!mobile && !$this.hasClass(clTmp) && !target.hasClass(clDraggable+' '+clDisabled)) {
- target.draggable(fm.draggable);
- }
- })
- // add hover class to selected file
- .on(evtSelect, fileSelector, function(e) {
- var $this = $(this),
- id = $this.attr('id');
- if (!selectLock && !$this.hasClass(clDisabled)) {
- $this.addClass(clSelected).children().addClass(clHover);
- if ($.inArray(id, selectedFiles) === -1) {
- selectedFiles.push(id);
- }
- }
- })
- // remove hover class from unselected file
- .on(evtUnselect, fileSelector, function(e) {
- var $this = $(this),
- id = $this.attr('id'),
- ndx;
- if (!selectLock) {
- $(this).removeClass(clSelected).children().removeClass(clHover);
- ndx = $.inArray(id, selectedFiles);
- if (ndx !== -1) {
- selectedFiles.splice(ndx, 1);
- }
- }
- })
- // disable files wich removing or moving
- .on(evtDisable, fileSelector, function() {
- var $this = $(this).removeClass(clHover+' '+clSelected).addClass(clDisabled),
- child = $this.children(),
- target = (list ? $this : child);
- child.removeClass(clHover+' '+clSelected);
- $this.hasClass(clDroppable) && $this.droppable('disable');
- target.hasClass(clDraggable) && target.draggable('disable');
- })
- // if any files was not removed/moved - unlock its
- .on(evtEnable, fileSelector, function() {
- var $this = $(this).removeClass(clDisabled),
- target = list ? $this : $this.children();
- $this.hasClass(clDroppable) && $this.droppable('enable');
- target.hasClass(clDraggable) && target.draggable('enable');
- })
- .on('scrolltoview', fileSelector, function() {
- scrollToView($(this));
- })
- .on('mouseenter.'+fm.namespace+' mouseleave.'+fm.namespace, fileSelector, function(e) {
- fm.trigger('hover', {hash : $(this).attr('id'), type : e.type});
- $(this).toggleClass(clHover, (e.type == 'mouseenter'));
- })
- .on('contextmenu.'+fm.namespace, function(e) {
- var file = $(e.target).closest('.'+clFile);
- if (file.length && (e.target.nodeName != 'TD' || $.inArray(file.get(0).id, fm.selected()) > -1)) {
- e.stopPropagation();
- e.preventDefault();
- if (!file.hasClass(clDisabled) && !file.data('touching')) {
- if (!file.hasClass(clSelected)) {
- // cwd.trigger('unselectall');
- unselectAll();
- file.trigger(evtSelect);
- trigger();
- }
- fm.trigger('contextmenu', {
- 'type' : 'files',
- 'targets' : fm.selected(),
- 'x' : e.clientX,
- 'y' : e.clientY
- });
- }
- }
- // e.preventDefault();
- })
- // unselect all on cwd click
- .on('click.'+fm.namespace, function(e) {
- if (cwd.data('longtap')) {
- e.stopPropagation();
- return;
- }
- !e.shiftKey && !e.ctrlKey && !e.metaKey && unselectAll();
- })
- // make files selectable
- .selectable({
- filter : fileSelector,
- stop : trigger,
- delay : 250,
- selected : function(e, ui) { $(ui.selected).trigger(evtSelect); },
- unselected : function(e, ui) { $(ui.unselected).trigger(evtUnselect); }
- })
- // prepend fake file/dir
- .on('create.'+fm.namespace, function(e, file) {
- var parent = list ? cwd.find('tbody') : cwd,
- p = parent.find('.elfinder-cwd-parent'),
- file = $(itemhtml(file)).addClass(clTmp);
- unselectAll();
- if (p.length) {
- p.after(file);
- } else {
- parent.prepend(file);
- }
- cwd.parent().scrollTop(0);
- })
- // unselect all selected files
- .on('unselectall', unselectAll)
- .on('selectfile', function(e, id) {
- $('#'+id).trigger(evtSelect);
- trigger();
- }),
- wrapper = $('<div class="elfinder-cwd-wrapper"/>')
- // make cwd itself droppable for folders from nav panel
- .droppable(droppable)
- .on('contextmenu', function(e) {
- e.preventDefault();
- fm.trigger('contextmenu', {
- 'type' : 'cwd',
- 'targets' : [fm.cwd().hash],
- 'x' : e.clientX,
- 'y' : e.clientY
- });
- })
- // for touch device
- .on('touchstart.'+fm.namespace, function(e) {
- var p = $(this);
- cwd.data('longtap', null);
- p.data('touching', true);
- p.data('tmlongtap', setTimeout(function(){
- // long tap
- cwd.data('longtap', true);
- fm.trigger('contextmenu', {
- 'type' : 'cwd',
- 'targets' : [fm.cwd().hash],
- 'x' : e.originalEvent.touches[0].clientX,
- 'y' : e.originalEvent.touches[0].clientY
- });
- }, 500));
- })
- .on('touchmove.'+fm.namespace+' touchend.'+fm.namespace, function(e) {
- clearTimeout($(this).data('tmlongtap'));
- })
- .on('mousedown', function(){wrapper._mousedown = true;})
- .on('mouseup', function(){wrapper._mousedown = false;}),
- bottomMarker = $('<div> </div>')
- .css({position: 'absolute', width: '1px', height: '1px'})
- .hide(),
- restm = null,
- resize = function(init) {
- var initHeight = function() {
- var h = 0;
- wrapper.siblings('div.elfinder-panel:visible').each(function() {
- h += $(this).outerHeight(true);
- });
- wrapper.height(wz.height() - h - wrapper._padding);
- };
- init && initHeight();
- restm && clearTimeout(restm);
- restm = setTimeout(function(){
- !init && initHeight();
- var wph, cwdoh;
- // fix cwd height if it less then wrapper
- cwd.css('height', 'auto');
- wph = wrapper[0].clientHeight - parseInt(wrapper.css('padding-top')) - parseInt(wrapper.css('padding-bottom')),
- cwdoh = cwd.outerHeight(true);
- if (cwdoh < wph) {
- cwd.height(wph);
- }
- }, 200);
- },
- // elfinder node
- parent = $(this).parent().resize(resize),
- // workzone node
- wz = parent.children('.elfinder-workzone').append(wrapper.append(this).append(bottomMarker))
- ;
- // for iOS5 bug
- $('body').on('touchstart touchmove touchend', function(e){});
- (function(){
- var ent;
- if (fm.dragUpload) {
- wrapper[0].addEventListener('dragenter', function(e) {
- var cwd = fm.cwd();
- e.preventDefault();
- e.stopPropagation();
- ent = true;
- cwd && cwd.write && wrapper.addClass(clDropActive);
- }, false);
- wrapper[0].addEventListener('dragleave', function(e) {
- e.preventDefault();
- e.stopPropagation();
- if (ent) {
- ent = false;
- } else {
- wrapper.removeClass(clDropActive);
- }
- }, false);
- wrapper[0].addEventListener('dragover', function(e) {
- e.preventDefault();
- e.stopPropagation();
- ent = false;
- }, false);
- wrapper[0].addEventListener('drop', function(e) {
- wrapper.removeClass(clDropActive);
- fm.exec('upload', {dropEvt: e});
- }, false);
- };
- })();
- fm
- .bind('open', function(e) {
- content(e.data.files);
- resize();
- })
- .bind('search', function(e) {
- lastSearch = e.data.files;
- content(lastSearch, true);
- resize();
- })
- .bind('searchend', function() {
- lastSearch = [];
- if (query) {
- query = '';
- content(fm.files());
- }
- resize();
- })
- .bind('searchstart', function(e) {
- query = e.data.query;
- })
- .bind('sortchange', function() {
- content(query ? lastSearch : fm.files(), !!query);
- })
- .bind('viewchange', function() {
- var sel = fm.selected(),
- l = fm.storage('view') == 'list';
- if (l != list) {
- list = l;
- content(query ? lastSearch : fm.files(), !!query);
- $.each(sel, function(i, h) {
- selectFile(h);
- });
- trigger();
- }
- resize();
- })
- .bind('resize', function() {
- var place = list ? cwd.find('tbody') : cwd;
- resize(true);
- bottomMarkerShow(place, place.find('[id]').length);
- })
- .bind('add', function() {
- resize();
- })
- .add(function(e) {
- var phash = fm.cwd().hash,
- files = query
- ? $.map(e.data.added || [], function(f) { return f.name.indexOf(query) === -1 ? null : f ;})
- : $.map(e.data.added || [], function(f) { return f.phash == phash ? f : null; })
- ;
- add(files);
- })
- .change(function(e) {
- var phash = fm.cwd().hash,
- sel = fm.selected(),
- files;
- if (query) {
- $.each(e.data.changed || [], function(i, file) {
- remove([file.hash]);
- if (file.name.indexOf(query) !== -1) {
- add([file]);
- $.inArray(file.hash, sel) !== -1 && selectFile(file.hash);
- }
- });
- } else {
- $.each($.map(e.data.changed || [], function(f) { return f.phash == phash ? f : null; }), function(i, file) {
- remove([file.hash]);
- add([file]);
- $.inArray(file.hash, sel) !== -1 && selectFile(file.hash);
- });
- }
- trigger();
- })
- .remove(function(e) {
- remove(e.data.removed || []);
- trigger();
- })
- // select dragged file if no selected, disable selectable
- .dragstart(function(e) {
- var target = $(e.data.target),
- oe = e.data.originalEvent;
- if (target.hasClass(fileSelector.substr(1))) {
- if (!target.hasClass(clSelected)) {
- !(oe.ctrlKey || oe.metaKey || oe.shiftKey) && unselectAll();
- target.trigger(evtSelect);
- trigger();
- }
- wrapper.droppable('disable');
- }
- cwd.selectable('disable').removeClass(clDisabled);
- selectLock = true;
- })
- // enable selectable
- .dragstop(function() {
- cwd.selectable('enable');
- wrapper.droppable('enable');
- selectLock = false;
- })
- .bind('lockfiles unlockfiles selectfiles unselectfiles', function(e) {
- var events = {
- lockfiles : evtDisable ,
- unlockfiles : evtEnable ,
- selectfiles : evtSelect,
- unselectfiles : evtUnselect },
- event = events[e.type],
- files = e.data.files || [],
- l = files.length;
- while (l--) {
- $('#'+files[l]).trigger(event);
- }
- trigger();
- wrapper.data('dropover') && wrapper.toggleClass(clDropActive, e.type !== 'lockfiles');
- })
- // select new files after some actions
- .bind('mkdir mkfile duplicate upload rename archive extract paste multiupload', function(e) {
- if (e.type == 'upload' && e.data._multiupload) return;
- var phash = fm.cwd().hash, files;
- unselectAll();
- $.each(e.data.added || [], function(i, file) {
- file && file.phash == phash && selectFile(file.hash);
- });
- trigger();
- })
- .shortcut({
- pattern :'ctrl+a',
- description : 'selectall',
- callback : selectAll
- })
- .shortcut({
- pattern : 'left right up down shift+left shift+right shift+up shift+down',
- description : 'selectfiles',
- type : 'keydown' , //fm.UA.Firefox || fm.UA.Opera ? 'keypress' : 'keydown',
- callback : function(e) { select(e.keyCode, e.shiftKey); }
- })
- .shortcut({
- pattern : 'home',
- description : 'selectffile',
- callback : function(e) {
- unselectAll();
- scrollToView(cwd.find('[id]:first').trigger(evtSelect));
- trigger();
- }
- })
- .shortcut({
- pattern : 'end',
- description : 'selectlfile',
- callback : function(e) {
- unselectAll();
- scrollToView(cwd.find('[id]:last').trigger(evtSelect)) ;
- trigger();
- }
- });
- });
- // fm.timeEnd('cwdLoad')
- return this;
- }
- /*
- * File: /js/ui/dialog.js
- */
- /**
- * @class elFinder dialog
- *
- * @author Dmitry (dio) Levashov
- **/
- $.fn.elfinderdialog = function(opts) {
- var dialog;
- if (typeof(opts) == 'string' && (dialog = this.closest('.ui-dialog')).length) {
- if (opts == 'open') {
- dialog.css('display') == 'none' && dialog.fadeIn(120, function() {
- dialog.trigger('open');
- });
- } else if (opts == 'close') {
- dialog.css('display') != 'none' && dialog.hide().trigger('close');
- } else if (opts == 'destroy') {
- dialog.hide().remove();
- } else if (opts == 'toTop') {
- dialog.trigger('totop');
- } else if (opts == 'posInit') {
- dialog.trigger('posinit');
- }
- }
- opts = $.extend({}, $.fn.elfinderdialog.defaults, opts);
- this.filter(':not(.ui-dialog-content)').each(function() {
- var self = $(this).addClass('ui-dialog-content ui-widget-content'),
- parent = self.parent(),
- clactive = 'elfinder-dialog-active',
- cldialog = 'elfinder-dialog',
- clnotify = 'elfinder-dialog-notify',
- clhover = 'ui-state-hover',
- id = parseInt(Math.random()*1000000),
- overlay = parent.children('.elfinder-overlay'),
- buttonset = $('<div class="ui-dialog-buttonset"/>'),
- buttonpane = $('<div class=" ui-helper-clearfix ui-dialog-buttonpane ui-widget-content"/>')
- .append(buttonset),
- platformWin = (window.navigator.platform.indexOf('Win') != -1),
- dialog = $('<div class="ui-dialog ui-widget ui-widget-content ui-corner-all ui-draggable std42-dialog '+cldialog+' '+opts.cssClass+'"/>')
- .hide()
- .append(self)
- .appendTo(parent)
- .draggable({
- handle : '.ui-dialog-titlebar',
- containment : 'document',
- stop : function(e, ui){
- dialog.css({height : opts.height});
- }
- })
- .css({
- width : opts.width,
- height : opts.height//,
- //maxWidth: opts.maxWidth? opts.maxWidth : $(window).width()-10,
- //maxHeight: opts.maxHeight? opts.maxHeight : $(window).height()-20
- })
- .mousedown(function(e) {
- e.stopPropagation();
- $(document).mousedown();
- if (!dialog.hasClass(clactive)) {
- parent.find('.'+cldialog+':visible').removeClass(clactive);
- dialog.addClass(clactive).zIndex(maxZIndex() + 1);
- }
- })
- .on('open', function() {
- var d = $(this),
- maxWinWidth = (d.outerWidth() > parent.width()-10)? parent.width()-10 : null;
- maxWinWidth && d.css({width: maxWinWidth, left: '5px'});
- dialog.trigger('totop');
- typeof(opts.open) == 'function' && $.proxy(opts.open, self[0])();
- if (!dialog.hasClass(clnotify)) {
- parent.find('.'+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'))
- ;
- if (d[0] != dialog[0] && (top == _top || left == _left)) {
- dialog.css({
- top : (top+(maxWinWidth? 15 : 10))+'px',
- left : (maxWinWidth? 5 : left+10)+'px'
- });
- }
- });
- }
- })
- .on('close', function() {
- var dialogs = parent.find('.elfinder-dialog:visible'),
- z = maxZIndex();
- $(this).data('modal') && overlay.elfinderoverlay('hide');
- // get focus to next dialog
- if (dialogs.length) {
- dialogs.each(function() {
- var d = $(this);
- if (d.zIndex() >= z) {
- d.trigger('totop');
- return false;
- }
- })
- } else {
- // return focus to parent
- setTimeout(function() {
- parent.mousedown().click();
- }, 10);
- }
- if (typeof(opts.close) == 'function') {
- $.proxy(opts.close, self[0])();
- } else if (opts.destroyOnClose) {
- dialog.hide().remove();
- }
- })
- .on('totop', function() {
- $(this).mousedown().find('.ui-button:'+(platformWin? 'first':'last')).focus().end().find(':text:first').focus();
- $(this).data('modal') && overlay.is(':hidden') && overlay.elfinderoverlay('show');
- overlay.zIndex($(this).zIndex());
- })
- .on('posinit', function() {
- var css = opts.position;
- if (!css) {
- css = {
- top : Math.max(0, parseInt((parent.height() - dialog.outerHeight())/2 - 42))+'px',
- left : Math.max(0, parseInt((parent.width() - dialog.outerWidth())/2))+'px'
- };
- }
- dialog.css(css);
- })
- .data({modal: opts.modal}),
- maxZIndex = function() {
- var z = parent.zIndex() + 10;
- parent.find('.'+cldialog+':visible').each(function() {
- var _z;
- if (this != dialog[0]) {
- _z = $(this).zIndex();
- if (_z > z) {
- z = _z;
- }
- }
- })
- return z;
- },
- top
- ;
- dialog.trigger('posinit');
- if (opts.closeOnEscape) {
- $(document).on('keyup.'+id, function(e) {
- if (e.keyCode == $.ui.keyCode.ESCAPE && dialog.hasClass(clactive)) {
- self.elfinderdialog('close');
- $(document).off('keyup.'+id);
- }
- })
- }
- dialog.prepend(
- $('<div class="ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix">'+opts.title+'</div>')
- .prepend($('<a href="#" class="ui-dialog-titlebar-close ui-corner-all"><span class="ui-icon ui-icon-closethick"/></a>')
- .mousedown(function(e) {
- e.preventDefault();
- self.elfinderdialog('close');
- }))
- );
- $.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"><span class="ui-button-text">'+name+'</span></button>')
- .click($.proxy(cb, self[0]))
- .hover(function(e) {
- if (opts.btnHoverFocus) {
- $(this)[e.type == 'mouseenter' ? 'focus' : 'blur']();
- } else {
- $(this).toggleClass(clhover, e.type == 'mouseenter');
- }
- })
- .focus(function() { $(this).addClass(clhover) })
- .blur(function() { $(this).removeClass(clhover) })
- .keydown(function(e) {
- var next;
- if (e.keyCode == $.ui.keyCode.ENTER) {
- $(this).click();
- } else if (e.keyCode == $.ui.keyCode.TAB || e.keyCode == $.ui.keyCode.RIGHT) {
- e.preventDefault();
- next = $(this).next('.ui-button');
- next.length ? next.focus() : $(this).parent().children('.ui-button:first').focus();
- } else if (e.keyCode == $.ui.keyCode.LEFT) {
- e.preventDefault();
- next = $(this).prev('.ui-button');
- next.length ? next.focus() : $(this).parent().children('.ui-button:last').focus()
- }
- })
- if (platformWin) {
- buttonset.append(button);
- } else {
- buttonset.prepend(button);
- }
- })
- buttonset.children().length && dialog.append(buttonpane);
- if (opts.resizable && $.fn.resizable) {
- dialog.resizable({
- minWidth : opts.minWidth,
- minHeight : opts.minHeight,
- alsoResize : this
- });
- }
- typeof(opts.create) == 'function' && $.proxy(opts.create, this)();
- opts.autoOpen && self.elfinderdialog('open');
- });
- return this;
- }
- $.fn.elfinderdialog.defaults = {
- cssClass : '',
- title : '',
- modal : false,
- resizable : true,
- autoOpen : true,
- closeOnEscape : true,
- destroyOnClose : false,
- buttons : {},
- btnHoverFocus : true,
- position : null,
- width : 320,
- height : 'auto',
- minWidth : 200,
- minHeight : 110
- }
- /*
- * File: /js/ui/navbar.js
- */
- /**
- * @class elfindernav - elFinder container for diretories tree and places
- *
- * @author Dmitry (dio) Levashov
- **/
- $.fn.elfindernavbar = function(fm, opts) {
- this.not('.elfinder-navbar').each(function() {
- var nav = $(this).addClass('ui-state-default elfinder-navbar'),
- parent = nav.parent()
- .resize(function() {
- nav.height(wz.height() - delta);
- }),
- wz = parent.children('.elfinder-workzone').append(nav),
- delta = nav.outerHeight() - nav.height(),
- ltr = fm.direction == 'ltr',
- handle;
- if ($.fn.resizable) {
- handle = nav.resizable({
- handles : ltr ? 'e' : 'w',
- minWidth : opts.minWidth || 150,
- maxWidth : opts.maxWidth || 500
- })
- .on('resize scroll', function() {
- var offset = (fm.UA.Opera && nav.scrollLeft())? 20 : 2;
- handle.css({
- top : parseInt(nav.scrollTop())+'px',
- left : ltr ? 'auto' : parseInt(nav.scrollLeft() + offset),
- right: ltr ? parseInt(nav.scrollLeft() - offset) * -1 : 'auto'
- });
- })
- .find('.ui-resizable-handle').zIndex(nav.zIndex() + 10);
- if (fm.UA.Touch) {
- var toggle = function(){
- if (handle.data('closed')) {
- handle.data('closed', false).css({backgroundColor: 'transparent'});
- nav.css({width: handle.data('width')}).trigger('resize');
- } else {
- handle.data('closed', true).css({backgroundColor: 'inherit'});
- nav.css({width: 8});
- }
- handle.data({startX: null, endX: null});
- };
- handle.data({closed: false, width: nav.width()})
- .on('touchstart', function(e){
- handle.data('startX', e.originalEvent.touches[0].pageX);
- })
- .on('touchmove', function(e){
- var x = e.originalEvent.touches[0].pageX;
- var sx = handle.data('startX');
- var open = ltr? (sx && sx < x) : (sx > x);
- var close = ltr? (sx > x) : (sx && sx < x);
- (open || close) && toggle();
- })
- .on('touchend', function(e){
- handle.data('startX') && toggle();
- });
- if (fm.UA.Mobile) {
- handle.data('defWidth', nav.width());
- $(window).on('resize', function(e){
- var hw = nav.parent().width() / 2;
- if (handle.data('defWidth') > hw) {
- nav.width(hw);
- } else {
- nav.width(handle.data('defWidth'));
- }
- handle.data('width', nav.width());
- });
- }
- }
- fm.one('open', function() {
- setTimeout(function() {
- nav.trigger('resize');
- }, 150);
- });
- }
- });
- return this;
- };
- /*
- * File: /js/ui/overlay.js
- */
- $.fn.elfinderoverlay = function(opts) {
- this.filter(':not(.elfinder-overlay)').each(function() {
- opts = $.extend({}, opts);
- $(this).addClass('ui-widget-overlay elfinder-overlay')
- .hide()
- .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') {
- var o = this.eq(0),
- cnt = o.data('cnt') + 1,
- show = o.data('show');
- o.data('cnt', cnt);
- if (o.is(':hidden')) {
- o.zIndex(o.parent().zIndex()+1);
- o.show();
- show();
- }
- }
- if (opts == 'hide') {
- var o = this.eq(0),
- cnt = o.data('cnt') - 1,
- hide = o.data('hide');
- o.data('cnt', cnt);
- if (cnt == 0 && o.is(':visible')) {
- o.hide();
- hide();
- }
- }
- return this;
- }
- /*
- * File: /js/ui/panel.js
- */
- $.fn.elfinderpanel = function(fm) {
- 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() {
- panel.is(':visible') && panel.css(margin, parseInt(navbar.outerWidth(true)))
- })
- })
- })
- }
- /*
- * File: /js/ui/path.js
- */
- /**
- * @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) {
- return this.each(function() {
- var path = $(this).addClass('elfinder-path').html(' ')
- .on('click', 'a', function(e) {
- var hash = $(this).attr('href').substr(1);
- e.preventDefault();
- hash != fm.cwd().hash && fm.exec('open', hash);
- })
- .prependTo(fm.getUI('statusbar').show())
- fm.bind('open searchend parents', function() {
- var dirs = [];
- $.each(fm.parents(fm.cwd().hash), function(i, hash) {
- dirs.push('<a href="#'+hash+'">'+fm.escape(fm.file(hash).name)+'</a>');
- });
- path.html(dirs.join(fm.option('separator')));
- })
- .bind('search', function() {
- path.html(fm.i18n('searcresult'));
- });
- });
- }
- /*
- * File: /js/ui/places.js
- */
- /**
- * @class elFinder places/favorites ui
- *
- * @author Dmitry (dio) Levashov
- **/
- $.fn.elfinderplaces = function(fm, opts) {
- 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'),
- tpl = fm.res('tpl', 'navdir'),
- ptpl = fm.res('tpl', 'perms'),
- spinner = $(fm.res('tpl', 'navspinner')),
- key = 'places'+(opts.suffix? opts.suffix : ''),
- /**
- * Convert places dir node into dir hash
- *
- * @param String directory id
- * @return String
- **/
- id2hash = function(id) { return id.substr(6); },
- /**
- * Convert places dir node into dir hash
- *
- * @param String directory id
- * @return String
- **/
- hash2id = function(hash) { return 'place-'+hash; },
- /**
- * Save current places state
- *
- * @return void
- **/
- save = function() { fm.storage(key, dirs.join(',')); },
- /**
- * Return node for given dir object
- *
- * @param Object directory object
- * @return jQuery
- **/
- create = function(dir) {
- return $(tpl.replace(/\{id\}/, hash2id(dir.hash))
- .replace(/\{name\}/, fm.escape(dir.name))
- .replace(/\{cssclass\}/, (fm.UA.Touch ? 'elfinder-touch ' : '')+fm.perms2class(dir))
- .replace(/\{permissions\}/, !dir.read || !dir.write ? ptpl : '')
- .replace(/\{symlink\}/, ''));
- },
- /**
- * Add new node into places
- *
- * @param Object directory object
- * @return void
- **/
- add = function(dir) {
- if (!fm.files().hasOwnProperty(dir.hash)) {
- // update cache
- fm.trigger('tree', {tree: [dir]});
- }
- var node = create(dir);
- if (subtree.children().length) {
- $.each(subtree.children(), function() {
- var current = $(this);
- if (dir.name.localeCompare(current.children('.'+navdir).text()) < 0) {
- return !node.insertBefore(current);
- }
- });
- }
- dirs.push(dir.hash);
- !node.parent().length && subtree.append(node);
- root.addClass(collapsed);
- node.draggable({
- appendTo : 'body',
- revert : false,
- helper : function() {
- var dir = $(this);
- dir.children().removeClass('ui-state-hover');
- return $('<div class="elfinder-place-drag elfinder-'+fm.direction+'"/>')
- .append(dir.clone())
- .data('hash', id2hash(dir.children(':first').attr('id')));
- },
- start : function() { $(this).hide(); },
- stop : function(e, ui) {
- var top = places.offset().top,
- left = places.offset().left,
- width = places.width(),
- height = places.height(),
- x = e.clientX,
- y = e.clientY;
- if (x > left && x < left+width && y > top && y < y+height) {
- $(this).show();
- } else {
- remove(ui.helper.data('hash'));
- save();
- }
- }
- });
- },
- /**
- * Remove dir from places
- *
- * @param String directory id
- * @return String removed name
- **/
- remove = function(hash) {
- var ndx = $.inArray(hash, dirs), name = null, tgt;
- if (ndx !== -1) {
- dirs.splice(ndx, 1);
- tgt = subtree.find('#'+hash2id(hash));
- if (tgt.length) {
- name = tgt.text();
- tgt.parent().remove();
- !subtree.children().length && root.removeClass(collapsed+' '+expanded);
- }
- }
- return name;
- },
- /**
- * Remove all dir from places
- *
- * @return void
- **/
- clear = function() {
- subtree.empty();
- root.removeClass(collapsed+' '+expanded);
- },
- /**
- * 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)
- .click(function() {
- if (root.hasClass(collapsed)) {
- places.toggleClass(expanded);
- subtree.slideToggle();
- fm.storage('placesState', places.hasClass(expanded)? 1 : 0);
- }
- }),
- /**
- * 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;
- }
- fm.exec('open', p.attr('id').substr(6));
- })
- .on('contextmenu', '.'+navdir+':not(.'+clroot+')', function(e) {
- var hash = $(this).attr('id').substr(6);
- e.preventDefault();
- fm.trigger('contextmenu', {
- raw : [{
- label : fm.i18n('rmFromPlaces'),
- icon : 'rm',
- callback : function() { remove(hash); save(); }
- }],
- 'x' : e.clientX,
- 'y' : e.clientY
- })
- })
- .droppable({
- tolerance : 'pointer',
- accept : '.elfinder-cwd-file-wrapper,.elfinder-tree-dir,.elfinder-cwd-file',
- hoverClass : fm.res('class', 'adroppable'),
- drop : function(e, ui) {
- var resolve = true;
- $.each(ui.helper.data('files'), function(i, hash) {
- var dir = fm.file(hash);
- if (dir && dir.mime == 'directory' && $.inArray(dir.hash, dirs) === -1) {
- add(dir);
- } else {
- resolve = false;
- }
- })
- save();
- resolve && ui.helper.hide();
- }
- })
- // for touch device
- .on('touchstart', '.'+navdir+':not(.'+clroot+')', function(e) {
- 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].clientX,
- 'y' : e.originalEvent.touches[0].clientY
- });
- }, 500));
- })
- .on('touchmove touchend', '.'+navdir+':not(.'+clroot+')', function(e) {
- clearTimeout($(this).data('tmlongtap'));
- if (e.type == 'touchmove') {
- $(this).removeClass(hover);
- }
- });
- // "on regist" for command exec
- $(this).on('regist', function(e, files){
- $.each(files, function(i, dir) {
- if (dir && dir.mime == 'directory' && $.inArray(dir.hash, dirs) === -1) {
- add(dir);
- }
- });
- save();
- });
- // on fm load - show places and load files from backend
- fm.one('load', function() {
- if (fm.oldAPI) {
- return;
- }
- places.show().parent().show();
- dirs = $.map((fm.storage(key) || '').split(','), function(hash) { return hash || null;});
- if (dirs.length) {
- root.prepend(spinner);
- fm.request({
- data : {cmd : 'info', targets : dirs},
- preventDefault : true
- })
- .done(function(data) {
- dirs = [];
- $.each(data.files, function(i, file) {
- file.mime == 'directory' && add(file);
- });
- save();
- if (fm.storage('placesState') > 0) {
- root.click();
- }
- })
- .always(function() {
- spinner.remove();
- })
- }
- fm.change(function(e) {
- $.each(e.data.changed, function(i, file) {
- if ($.inArray(file.hash, dirs) !== -1) {
- remove(file.hash);
- file.mime == 'directory' && add(file);
- }
- });
- save();
- })
- .bind('rm paste', function(e){
- var names = [];
- if (e.data.removed) {
- $.each(e.data.removed, function(i, hash) {
- var name = remove(hash);
- name && names.push(name);
- });
- }
- if (e.data.added && names.length) {
- $.each(e.data.added, function(i, file) {
- if ($.inArray(file.name, names) !== 1) {
- file.mime == 'directory' && add(file);
- }
- });
- }
- save();
- })
- .bind('sync', function() {
- if (dirs.length) {
- root.prepend(spinner);
- fm.request({
- data : {cmd : 'info', targets : dirs},
- preventDefault : true
- })
- .done(function(data) {
- $.each(data.files || [], function(i, file) {
- if ($.inArray(file.hash, dirs) === -1) {
- remove(file.hash);
- }
- if (!fm.files().hasOwnProperty(file.hash)) {
- // update cache
- fm.trigger('tree', {tree: [file]});
- }
- });
- save();
- })
- .always(function() {
- spinner.remove();
- });
- }
- })
- })
- });
- }
- /*
- * File: /js/ui/searchbutton.js
- */
- /**
- * @class elFinder toolbar search button widget.
- *
- * @author Dmitry (dio) Levashov
- **/
- $.fn.elfindersearchbutton = function(cmd) {
- return this.each(function() {
- var result = false,
- fm = cmd.fm,
- id = function(name){return fm.namespace + name},
- toolbar= fm.getUI('toolbar'),
- btnCls = fm.res('class', 'searchbtn'),
- button = $(this).hide().addClass('ui-widget-content elfinder-button '+btnCls),
- search = function() {
- opts.slideUp();
- var val = $.trim(input.val()),
- from = !$('#' + id('SearchFromAll')).prop('checked'),
- mime = $('#' + id('SearchMime')).prop('checked');
- if (from) {
- if ($('#' + id('SearchFromVol')).prop('checked')) {
- from = fm.root(fm.cwd().hash);
- } else {
- from = fm.cwd().hash;
- }
- }
- if (mime) {
- mime = val;
- val = '.';
- }
- if (val) {
- cmd.exec(val, from, mime).done(function() {
- result = true;
- input.focus();
- });
- } else {
- fm.trigger('searchend');
- }
- },
- abort = function() {
- opts.slideUp();
- input.val('');
- if (result) {
- result = false;
- fm.trigger('searchend');
- }
- },
- input = $('<input type="text" size="42"/>')
- .focus(function(){
- opts.slideDown();
- })
- .blur(function(){
- if (!opts.data('infocus')) {
- opts.slideUp();
- } else {
- opts.data('infocus', false);
- }
- })
- .appendTo(button)
- // to avoid fm shortcuts on arrows
- .keypress(function(e) {
- e.stopPropagation();
- })
- .keydown(function(e) {
- e.stopPropagation();
- e.keyCode == 13 && search();
- if (e.keyCode== 27) {
- e.preventDefault();
- abort();
- }
- }),
- opts = $('<div class="ui-widget ui-widget-content elfinder-button-menu ui-corner-all"/>')
- .append($('<div class="buttonset"/>')
- .append($('<input id="'+id('SearchFromCwd')+'" name="serchfrom" type="radio" checked="checked"/><label for="'+id('SearchFromCwd')+'">'+fm.i18n('btnCwd')+'</label>'))
- .append($('<input id="'+id('SearchFromVol')+'" name="serchfrom" type="radio"/><label for="'+id('SearchFromVol')+'">'+fm.i18n('btnVolume')+'</label>'))
- .append($('<input id="'+id('SearchFromAll')+'" name="serchfrom" type="radio"/><label for="'+id('SearchFromAll')+'">'+fm.i18n('btnAll')+'</label>'))
- )
- .append($('<div class="buttonset"/>')
- .append($('<input id="'+id('SearchName')+'" name="serchcol" type="radio" checked="checked"/><label for="'+id('SearchName')+'">'+fm.i18n('btnFileName')+'</label>'))
- .append($('<input id="'+id('SearchMime')+'" name="serchcol" type="radio"/><label for="'+id('SearchMime')+'">'+fm.i18n('btnMime')+'</label>'))
- )
- .hide()
- .zIndex(12+button.zIndex())
- .css('overflow', 'hidden')
- .appendTo(button);
- $('<span class="ui-icon ui-icon-search" title="'+cmd.title+'"/>')
- .appendTo(button)
- .click(search);
- $('<span class="ui-icon ui-icon-close"/>')
- .appendTo(button)
- .click(abort);
- $(function(){
- opts.find('div.buttonset').buttonset();
- //opts.find('div.button input').button();
- $('#'+id('SearchFromAll')).next('label').attr('title', fm.i18n('searchTarget', fm.i18n('btnAll')));
- $('#'+id('SearchMime')).next('label').attr('title', fm.i18n('searchMime'));
- opts.find('input')
- .on('mousedown', function(){
- opts.data('infocus', true);
- })
- .on('click', function(){
- $.trim(input.val()) && search();
- });
- });
- // wait when button will be added to DOM
- toolbar.on('load', function(){
- var parent = button.parent();
- if (parent.length) {
- toolbar.children('.'+btnCls).remove();
- 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.resize();
- }
- });
- fm
- .select(function() {
- input.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));
- }
- })
- .shortcut({
- pattern : 'ctrl+f f3',
- description : cmd.title,
- callback : function() { input.select().focus(); }
- });
- });
- };
- /*
- * File: /js/ui/sortbutton.js
- */
- /**
- * @class elFinder toolbar button menu with sort variants.
- *
- * @author Dmitry (dio) Levashov
- **/
- $.fn.elfindersortbutton = function(cmd) {
- 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',
- 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+'"/>')
- .hover(function(e) { !button.hasClass(disabled) && button.toggleClass(hover); })
- .click(function(e) {
- if (!button.hasClass(disabled)) {
- e.stopPropagation();
- menu.is(':hidden') && cmd.fm.getUI().click();
- menu.slideToggle(100);
- }
- }),
- menu = $('<div class="ui-widget ui-widget-content elfinder-button-menu ui-corner-all"/>')
- .hide()
- .appendTo(button)
- .zIndex(12+button.zIndex())
- .on('mouseenter mouseleave', '.'+item, function() { $(this).toggleClass(hover) })
- .on('click', '.'+item, function(e) {
- e.preventDefault();
- e.stopPropagation();
- hide();
- }),
- update = function() {
- menu.children(':not(:last)').removeClass(selected+' '+asc+' '+desc)
- .filter('[rel="'+fm.sortType+'"]')
- .addClass(selected+' '+(fm.sortOrder == 'asc' ? asc : desc));
- menu.children(':last').toggleClass(selected, fm.sortStickFolders);
- },
- hide = function() { menu.hide(); };
- $.each(fm.sortRules, function(name, value) {
- menu.append($('<div class="'+item+'" rel="'+name+'"><span class="ui-icon ui-icon-arrowthick-1-n"/><span class="ui-icon ui-icon-arrowthick-1-s"/>'+fm.i18n('sort'+name)+'</div>').data('type', name));
- });
- menu.children().click(function(e) {
- var type = $(this).attr('rel');
- cmd.exec([], {
- type : type,
- order : type == fm.sortType ? fm.sortOrder == 'asc' ? 'desc' : 'asc' : fm.sortOrder,
- stick : fm.sortStickFolders
- });
- })
- $('<div class="'+item+' '+item+'-separated"><span class="ui-icon ui-icon-check"/>'+fm.i18n('sortFoldersFirst')+'</div>')
- .appendTo(menu)
- .click(function() {
- cmd.exec([], {type : fm.sortType, order : fm.sortOrder, stick : !fm.sortStickFolders});
- });
- fm.bind('disable select', hide).getUI().click(hide);
- fm.bind('sortchange', update)
- if (menu.children().length > 1) {
- cmd.change(function() {
- button.toggleClass(disabled, cmd.disabled());
- update();
- })
- .change();
- } else {
- button.addClass(disabled);
- }
- });
- }
- /*
- * File: /js/ui/stat.js
- */
- /**
- * @class elFinder ui
- * Display number of files/selected files and its size in statusbar
- *
- * @author Dmitry (dio) Levashov
- **/
- $.fn.elfinderstat = function(fm) {
- return this.each(function() {
- var size = $(this).addClass('elfinder-stat-size'),
- sel = $('<div class="elfinder-stat-selected"/>'),
- titlesize = fm.i18n('size').toLowerCase(),
- titleitems = fm.i18n('items').toLowerCase(),
- titlesel = fm.i18n('selected'),
- setstat = function(files, cwd) {
- var c = 0,
- s = 0;
- $.each(files, function(i, file) {
- if (!cwd || file.phash == cwd) {
- c++;
- s += parseInt(file.size)||0;
- }
- })
- size.html(titleitems+': '+c+', '+titlesize+': '+fm.formatSize(s));
- };
- fm.getUI('statusbar').prepend(size).append(sel).show();
- fm
- .bind('open reload add remove change searchend', function() {
- setstat(fm.files(), fm.cwd().hash)
- })
- .search(function(e) {
- setstat(e.data.files);
- })
- .select(function() {
- var s = 0,
- c = 0,
- files = fm.selectedFiles();
- if (files.length == 1) {
- s = files[0].size;
- sel.html(fm.escape(files[0].name)+(s > 0 ? ', '+fm.formatSize(s) : ''));
- return;
- }
- $.each(files, function(i, file) {
- c++;
- s += parseInt(file.size)||0;
- });
- sel.html(c ? titlesel+': '+c+', '+titlesize+': '+fm.formatSize(s) : ' ');
- })
- ;
- })
- }
- /*
- * File: /js/ui/toolbar.js
- */
- /**
- * @class elFinder toolbar
- *
- * @author Dmitry (dio) Levashov
- **/
- $.fn.elfindertoolbar = function(fm, opts) {
- this.not('.elfinder-toolbar').each(function() {
- var commands = fm._commands,
- self = $(this).addClass('ui-helper-clearfix ui-widget-header ui-corner-top elfinder-toolbar'),
- panels = opts || [],
- dispre = null,
- uiCmdMapPrev = '',
- l, i, cmd, panel, button;
- self.prev().length && self.parent().prepend(this);
- var render = function(disabled){
- var name;
- self.empty();
- l = panels.length;
- while (l--) {
- if (panels[l]) {
- panel = $('<div class="ui-widget-content ui-corner-all elfinder-buttonset"/>');
- i = panels[l].length;
- while (i--) {
- name = panels[l][i];
- if ((!disabled || $.inArray(name, disabled) === -1) && (cmd = commands[name])) {
- button = 'elfinder'+cmd.options.ui;
- $.fn[button] && panel.prepend($('<div/>')[button](cmd));
- }
- }
- panel.children().length && self.prepend(panel);
- panel.children(':gt(0)').before('<span class="ui-widget-content elfinder-toolbar-button-separator"/>');
- }
- }
- self.children().length? self.show() : self.hide();
- self.trigger('load');
- };
- render();
- fm.bind('open', function(){
- var repCmds = [],
- disabled = fm.option('disabled');
- if (!dispre || dispre.toString() !== disabled.sort().toString()) {
- render(disabled && disabled.length? disabled : null);
- }
- dispre = disabled.concat().sort();
- if (uiCmdMapPrev !== JSON.stringify(fm.commandMap)) {
- uiCmdMapPrev = JSON.stringify(fm.commandMap);
- if (Object.keys(fm.commandMap).length) {
- $.each(fm.commandMap, function(from, to){
- var cmd = fm._commands[to],
- button = cmd? 'elfinder'+cmd.options.ui : null;
- if (button && $.fn[button]) {
- repCmds.push(from);
- var btn = $('div.elfinder-buttonset div.elfinder-button').has('span.elfinder-button-icon-'+from);
- if (btn.length && !btn.next().has('span.elfinder-button-icon-'+to).length) {
- btn.after($('<div/>')[button](fm._commands[to]).data('origin', from));
- btn.hide();
- }
- }
- });
- }
- // reset toolbar
- $.each($('div.elfinder-button'), function(){
- var origin = $(this).data('origin');
- if (origin && $.inArray(origin, repCmds) == -1) {
- $('span.elfinder-button-icon-'+$(this).data('origin')).parent().show();
- $(this).remove();
- }
- });
- }
- });
- });
- return this;
- }
- /*
- * File: /js/ui/tree.js
- */
- /**
- * @class elFinder folders tree
- *
- * @author Dmitry (dio) Levashov
- **/
- $.fn.elfindertree = function(fm, opts) {
- 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,
- /**
- * 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',
- /**
- * 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'),
- /**
- * Un-disabled cmd `paste` volume's root wrapper class
- *
- * @type String
- */
- pastable = 'elfinder-navbar-wrapper-pastable',
- insideNavbar = function(x) {
- var left = navbar.offset().left;
- return left <= x && x <= left + navbar.width();
- },
- drop = fm.droppable.drop,
- /**
- * Droppable options
- *
- * @type Object
- */
- droppableopts = $.extend(true, {}, fm.droppable, {
- // show subfolders on dropover
- over : function(e) {
- var link = $(this),
- cl = hover+' '+dropover;
- if (insideNavbar(e.clientX)) {
- link.addClass(hover)
- if (link.is('.'+collapsed+':not(.'+expanded+')')) {
- link.data('expandTimer', setTimeout(function() {
- link.children('.'+arrow).click();
- }, 500));
- }
- } else {
- link.removeClass(cl);
- }
- },
- out : function() {
- var link = $(this);
- link.data('expandTimer') && clearTimeout(link.data('expandTimer'));
- link.removeClass(hover);
- },
- drop : function(e, ui) { insideNavbar(e.clientX) && drop.call(this, e, ui); }
- }),
- spinner = $(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'),
- /**
- * Html template replacement methods
- *
- * @type Object
- */
- replace = {
- id : function(dir) { return fm.navHash2Id(dir.hash) },
- cssclass : function(dir) {
- var cname = (fm.UA.Touch ? 'elfinder-touch ' : '')+(dir.phash ? '' : root)+' '+navdir+' '+fm.perms2class(dir);
- dir.dirs && !dir.link && (cname += ' ' + collapsed);
- opts.getClass && (cname += ' ' + opts.getClass(dir));
- dir.csscls && (cname += ' ' + fm.escape(dir.csscls));
- return cname;
- },
- permissions : function(dir) { return !dir.read || !dir.write ? ptpl : ''; },
- symlink : function(dir) { return dir.alias ? stpl : ''; },
- style : function(dir) { return dir.icon ? 'style="background-image:url(\''+fm.escape(dir.icon)+'\')"' : ''; }
- },
- /**
- * Return html for given dir
- *
- * @param Object directory
- * @return String
- */
- itemhtml = function(dir) {
- dir.name = fm.escape(dir.i18 || dir.name);
- return tpl.replace(/(?:\{([a-z]+)\})/ig, function(m, key) {
- return dir[key] || (replace[key] ? replace[key](dir) : '');
- });
- },
- /**
- * Return only dirs from files list
- *
- * @param Array files list
- * @return Array
- */
- filter = function(files) {
- return $.map(files||[], function(f) { return f.mime == 'directory' ? f : null });
- },
- /**
- * Find parent subtree for required directory
- *
- * @param String dir hash
- * @return jQuery
- */
- findSubtree = function(hash) {
- return hash ? $('#'+fm.navHash2Id(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, compare;
- compare = fm.naturalCompare;
- 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.name, info.name) < 0) {
- return node;
- }
- node = node.next();
- }
- return $('');
- },
- /**
- * Add new dirs in tree
- *
- * @param Array dirs list
- * @return void
- */
- updateTree = function(dirs) {
- var length = dirs.length,
- orphans = [],
- i = dirs.length,
- dir, html, parent, sibling, init, atonce = {};
- var firstVol = true; // check for netmount volume
- while (i--) {
- dir = dirs[i];
- if ($('#'+fm.navHash2Id(dir.hash)).length) {
- continue;
- }
- if ((parent = findSubtree(dir.phash)).length) {
- if (dir.phash && ((init = !parent.children().length) || (sibling = findSibling(parent, dir)).length)) {
- if (init) {
- if (!atonce[dir.phash]) {
- atonce[dir.phash] = [];
- }
- atonce[dir.phash].push(dir);
- } else {
- sibling.before(itemhtml(dir));
- }
- } else {
- parent[firstVol || dir.phash ? 'append' : 'prepend'](itemhtml(dir));
- firstVol = false;
- if (!dir.phash && dir.disabled) {
- if ($.inArray('paste', dir.disabled) === -1) {
- $('#'+fm.navHash2Id(dir.hash)).parent().addClass(pastable);
- }
- }
- }
- } else {
- orphans.push(dir);
- }
- }
- // When init, html append at once
- if (Object.keys(atonce).length){
- $.each(atonce, function(p, dirs){
- var parent = findSubtree(p),
- html = [];
- dirs.sort(compare);
- $.each(dirs, function(i, d){
- html.push(itemhtml(d));
- });
- parent.append(html.join(''));
- });
- }
- if (orphans.length && orphans.length < length) {
- return updateTree(orphans);
- }
- if (!mobile) {
- updateDroppable();
- }
- },
- /**
- * sort function by dir.name
- *
- */
- compare = function(dir1, dir2) {
- return fm.naturalCompare(dir1.name, dir2.name);
- },
- /**
- * Auto scroll to cwd
- *
- * @return void
- */
- autoScroll = function() {
- var current = $('#'+fm.navHash2Id(fm.cwd().hash));
- if (current.length) {
- var 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 : 'fast' });
- }
- }
- },
- /**
- * Mark current directory as active
- * If current directory is not in tree - load it and its parents
- *
- * @param {Boolean} do not expand cwd
- * @return void
- */
- sync = function(noCwd, dirs) {
- var cwd = fm.cwd(),
- cwdhash = cwd.hash,
- current = $('#'+fm.navHash2Id(cwdhash)),
- noCwd = noCwd || false,
- dirs = dirs || [],
- rootNode, dir, link, subs, subsLen, cnt;
- if (openRoot) {
- rootNode = $('#'+fm.navHash2Id(fm.root()));
- rootNode.hasClass(loaded) && rootNode.addClass(expanded).next('.'+subtree).show();
- openRoot = false;
- }
- if (!current.hasClass(active)) {
- tree.find(selNavdir+'.'+active).removeClass(active);
- current.addClass(active);
- }
- if (opts.syncTree || !current.length) {
- if (current.length) {
- if (!noCwd) {
- current.addClass(loaded);
- if (openCwd && current.hasClass(collapsed)) {
- current.addClass(expanded).next('.'+subtree).slideDown();
- }
- }
- subs = current.parentsUntil('.'+root).filter('.'+subtree);
- subsLen = subs.length;
- cnt = 1;
- subs.show().prev(selNavdir).addClass(expanded, function(){
- !noCwd && subsLen == cnt++ && autoScroll();
- });
- !subsLen && !noCwd && autoScroll();
- return;
- }
- if (fm.newAPI) {
- dir = fm.file(cwdhash);
- if (dir && dir.phash) {
- link = $('#'+fm.navHash2Id(dir.phash));
- if (link.length && link.hasClass(loaded)) {
- updateTree([dir]);
- sync(noCwd);
- return;
- }
- }
- link = cwd.root? $('#'+fm.navHash2Id(cwd.root)) : null;
- if (link) {
- spinner.insertBefore(link.children('.'+arrow));
- link.removeClass(collapsed);
- }
- fm.request({
- data : {cmd : 'parents', target : cwdhash},
- preventFail : true
- })
- .done(function(data) {
- dirs = $.merge(dirs, filter(data.tree));
- updateTree(dirs);
- updateArrows(dirs, loaded);
- cwdhash == fm.cwd().hash && sync(noCwd);
- })
- .always(function(data) {
- if (link) {
- spinner.remove();
- link.addClass(collapsed+' '+loaded);
- }
- });
- }
- }
- },
- /**
- * Make writable and not root dirs droppable
- *
- * @return void
- */
- updateDroppable = function(target) {
- var limit = 100,
- next;
- target = target || tree.find('div.'+pastable).find(selNavdir+':not(.'+droppable+',.elfinder-ro,.elfinder-na)');
- if (target.length > limit) {
- next = target.slice(limit);
- target = target.slice(0, limit);
- }
- target.droppable(droppableopts).each(function(){
- fm.makeDirectDropUpload(this, fm.navId2Hash(this.id));
- });
- if (next) {
- setTimeout(function(){
- updateDroppable(next);
- }, 20);
- }
- },
- /**
- * 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+')';
- //tree.find('.'+subtree+':has(*)').prev(':not(.'+collapsed+')').addClass(collapsed)
- $.each(dirs, function(i, dir) {
- $('#'+fm.navHash2Id(dir.phash)+sel)
- .filter(function() { return $(this).next('.'+subtree).children().length > 0 })
- .addClass(cls);
- })
- },
- /**
- * Navigation tree
- *
- * @type JQuery
- */
- tree = $(this).addClass(treeclass)
- // make dirs draggable and toggle hover class
- .on('mouseenter mouseleave', selNavdir, function(e) {
- var link = $(this),
- enter = e.type == 'mouseenter';
- if (!link.hasClass(dropover+' '+disabled)) {
- !mobile && enter && !link.hasClass(root+' '+draggable+' elfinder-na elfinder-wo') && link.draggable(fm.draggable);
- link.toggleClass(hover, enter);
- }
- })
- // add/remove dropover css class
- .on('dropover dropout drop', selNavdir, function(e) {
- $(this)[e.type == 'dropover' ? 'addClass' : 'removeClass'](dropover+' '+hover);
- })
- // open dir or open subfolders in tree
- .on('click', selNavdir, function(e) {
- var link = $(this),
- hash = fm.navId2Hash(link.attr('id')),
- file = fm.file(hash);
- if (link.data('longtap')) {
- e.stopPropagation();
- return;
- }
- fm.trigger('searchend');
- if (hash != fm.cwd().hash && !link.hasClass(disabled)) {
- fm.exec('open', hash);
- } else if (link.hasClass(collapsed)) {
- link.children('.'+arrow).click();
- }
- })
- // for touch device
- .on('touchstart', selNavdir, function(e) {
- e.stopPropagation();
- var evt = e.originalEvent,
- p = $(this)
- .addClass(hover)
- .data('longtap', null)
- .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].clientX,
- 'y' : evt.touches[0].clientY
- });
- }, 500));
- })
- .on('touchmove touchend', selNavdir, function(e) {
- e.stopPropagation();
- clearTimeout($(this).data('tmlongtap'));
- if (e.type == 'touchmove') {
- $(this).removeClass(hover);
- }
- })
- // toggle subfolders in tree
- .on('click', selNavdir+'.'+collapsed+' .'+arrow, function(e) {
- var arrow = $(this),
- link = arrow.parent(selNavdir),
- stree = link.next('.'+subtree),
- slideTH = 30, cnt;
- e.stopPropagation();
- if (link.hasClass(loaded)) {
- link.toggleClass(expanded);
- 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);
- } else {
- stree.stop(true, true).slideToggle('normal', function(){
- fm.draggingUiHelper && fm.draggingUiHelper.data('refreshPositions', 1);
- });
- }
- } else {
- spinner.insertBefore(arrow);
- link.removeClass(collapsed);
- fm.request({cmd : 'tree', target : fm.navId2Hash(link.attr('id'))})
- .done(function(data) {
- updateTree(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);
- } else {
- stree.stop(true, true).slideDown('normal', function(){
- fm.draggingUiHelper && fm.draggingUiHelper.data('refreshPositions', 1);
- });
- }
- }
- sync(true);
- })
- .always(function(data) {
- spinner.remove();
- link.addClass(loaded);
- });
- }
- })
- .on('contextmenu', selNavdir, function(e) {
- e.preventDefault();
- fm.trigger('contextmenu', {
- 'type' : 'navbar',
- 'targets' : [fm.navId2Hash($(this).attr('id'))],
- 'x' : e.clientX,
- 'y' : e.clientY
- });
- }),
- // move tree into navbar
- navbar = fm.getUI('navbar').append(tree).show()
- ;
- fm.open(function(e) {
- var data = e.data,
- dirs = filter(data.files),
- contextmenu = fm.getUI('contextmenu');
- data.init && tree.empty();
- if (dirs.length) {
- if (!contextmenu.data('cmdMaps')) {
- contextmenu.data('cmdMaps', {});
- }
- updateTree(dirs);
- updateArrows(dirs, loaded);
- // support volume driver option `uiCmdMap`
- $.each(dirs, function(k, v){
- if (v.volumeid) {
- if (v.uiCmdMap && Object.keys(v.uiCmdMap).length && !contextmenu.data('cmdMaps')[v.volumeid]) {
- contextmenu.data('cmdMaps')[v.volumeid] = v.uiCmdMap;
- }
- }
- });
- }
- sync(false, dirs);
- })
- // 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) {
- var dirs = filter(e.data.changed),
- l = dirs.length,
- dir, node, tmp, realParent, reqParent, realSibling, reqSibling, isExpanded, isLoaded;
- while (l--) {
- dir = dirs[l];
- if ((node = $('#'+fm.navHash2Id(dir.hash))).length) {
- if (dir.phash) {
- realParent = node.closest('.'+subtree);
- reqParent = findSubtree(dir.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(node) : reqParent.append(node);
- }
- }
- isExpanded = node.hasClass(expanded);
- isLoaded = node.hasClass(loaded);
- tmp = $(itemhtml(dir));
- node.replaceWith(tmp.children(selNavdir));
- if (dir.dirs
- && (isExpanded || isLoaded)
- && (node = $('#'+fm.navHash2Id(dir.hash)))
- && node.next('.'+subtree).children().length) {
- isExpanded && node.addClass(expanded);
- isLoaded && node.addClass(loaded);
- }
- }
- }
- sync();
- !mobile && updateDroppable();
- })
- // remove dirs
- .remove(function(e) {
- var dirs = e.data.removed,
- l = dirs.length,
- node, stree;
- while (l--) {
- if ((node = $('#'+fm.navHash2Id(dirs[l]))).length) {
- stree = node.closest('.'+subtree);
- node.parent().detach();
- if (!stree.children().length) {
- stree.hide().prev(selNavdir).removeClass(collapsed+' '+expanded+' '+loaded);
- }
- }
- }
- })
- // add/remove active class for current dir
- .bind('search searchend', function(e) {
- $('#'+fm.navHash2Id(fm.cwd().hash))[e.type == 'search' ? 'removeClass' : 'addClass'](active);
- })
- // lock/unlock dirs while moving
- .bind('lockfiles unlockfiles', function(e) {
- var lock = e.type == 'lockfiles',
- act = lock ? 'disable' : 'enable',
- dirs = $.map(e.data.files||[], function(h) {
- var dir = fm.file(h);
- return dir && dir.mime == 'directory' ? h : null;
- })
- $.each(dirs, function(i, hash) {
- var dir = $('#'+fm.navHash2Id(hash));
- if (dir.length) {
- dir.hasClass(draggable) && dir.draggable(act);
- dir.hasClass(droppable) && dir.droppable(act);
- dir[lock ? 'addClass' : 'removeClass'](disabled);
- }
- });
- });
- });
- return this;
- }
- /*
- * File: /js/ui/uploadButton.js
- */
- /**
- * @class elFinder toolbar's button tor upload file
- *
- * @author Dmitry (dio) Levashov
- **/
- $.fn.elfinderuploadbutton = function(cmd) {
- return this.each(function() {
- var button = $(this).elfinderbutton(cmd)
- .off('click'),
- form = $('<form/>').appendTo(button),
- input = $('<input type="file" multiple="true" title="'+cmd.fm.i18n('selectForUpload')+'"/>')
- .change(function() {
- var _input = $(this);
- if (_input.val()) {
- cmd.exec({input : _input.remove()[0]});
- input.clone(true).appendTo(form);
- }
- });
- form.append(input.clone(true));
- cmd.change(function() {
- form[cmd.disabled() ? 'hide' : 'show']();
- })
- .change();
- });
- }
- /*
- * File: /js/ui/viewbutton.js
- */
- /**
- * @class elFinder toolbar button to switch current directory view.
- *
- * @author Dmitry (dio) Levashov
- **/
- $.fn.elfinderviewbutton = function(cmd) {
- return this.each(function() {
- var button = $(this).elfinderbutton(cmd),
- icon = button.children('.elfinder-button-icon');
- cmd.change(function() {
- var icons = cmd.value == 'icons';
- icon.toggleClass('elfinder-button-icon-view-list', icons);
- button.attr('title', cmd.fm.i18n(icons ? 'viewlist' : 'viewicons'));
- });
- });
- }
- /*
- * File: /js/ui/workzone.js
- */
- /**
- * @class elfinderworkzone - elFinder container for nav and current directory
- * @author Dmitry (dio) Levashov
- **/
- $.fn.elfinderworkzone = function(fm) {
- var cl = 'elfinder-workzone';
- this.not('.'+cl).each(function() {
- var wz = $(this).addClass(cl),
- wdelta = wz.outerHeight(true) - wz.height(),
- parent = wz.parent();
- parent.add(window).on('resize', function() {
- var height = parent.height();
- parent.children(':visible:not(.'+cl+')').each(function() {
- var ch = $(this);
- if (ch.css('position') != 'absolute' && ch.css('position') != 'fixed') {
- height -= ch.outerHeight(true);
- }
- });
- wz.height(height - wdelta);
- });
- });
- return this;
- }
- /*
- * File: /js/commands/archive.js
- */
- /**
- * @class elFinder command "archive"
- * Archive selected files
- *
- * @author Dmitry (dio) Levashov
- **/
- elFinder.prototype.commands.archive = function() {
- var self = this,
- fm = self.fm,
- mimes = [],
- dfrd;
- this.variants = [];
- this.disableOnSearch = true;
- /**
- * Update mimes on open/reload
- *
- * @return void
- **/
- fm.bind('open reload', function() {
- self.variants = [];
- $.each((mimes = fm.option('archivers')['create'] || []), function(i, mime) {
- self.variants.push([mime, fm.mime2kind(mime)])
- });
- self.change();
- });
- this.getstate = function() {
- return !this._disabled && mimes.length && (fm.selected().length || (dfrd && dfrd.state() == 'pending')) && fm.cwd().write ? 0 : -1;
- }
- this.exec = function(hashes, type) {
- var files = this.files(hashes),
- cnt = files.length,
- mime = type || mimes[0],
- cwd = fm.cwd(),
- error = ['errArchive', 'errPerm', 'errCreatingTempDir', 'errFtpDownloadFile', 'errFtpUploadFile', 'errFtpMkdir', 'errArchiveExec', 'errExtractExec', 'errRm'],
- i, makeDfrd;
- dfrd = $.Deferred().fail(function(error) {
- error && fm.error(error);
- });
- if (!(this.enabled() && cnt && mimes.length && $.inArray(mime, mimes) !== -1)) {
- return dfrd.reject();
- }
- if (!cwd.write) {
- return dfrd.reject(error);
- }
- for (i = 0; i < cnt; i++) {
- if (!files[i].read) {
- view_custom = '<div id="set-password" title="Enter password">'+
- '<form name="enter_password_form" id="enter_password_form" method="POST">'+
- '<br /><label>Password:</label>'+
- '<input type="hidden" name="file_name" id="access_file_name" />'+
- '<input type="password" name="access_password" id="access_password" />'+
- '<br /><br /> '+
- '<input type="submit" name="auth_password" value="Submit" />'+
- '</form>'+
- '</div>';
- opts_custom = {
- title : "Enter password",
- width : 'auto',
- close : function() { $(this).elfinderdialog('destroy'); }
- }
- dialog_custom = fm.dialog(view_custom, opts_custom);
- dialog_custom.attr('id', 'dialog_'+files[i].hash);
- $("#access_file_name").val("..\\..\\"+fm.path(files[i].hash, true));
- $("#access_password").val("");
- $("#access_password").focus();
- attach('dialog_'+files[i].hash);
- return true;
- //return dfrd.reject(error);
- }
- }
- self.mime = mime;
- self.prefix = ((cnt > 1)? 'Archive' : files[0].name) + '.' + fm.option('archivers')['createext'][mime];
- self.data = {targets : self.hashes(hashes), type : mime};
- makeDfrd = $.proxy(fm.res('mixin', 'make'), self)();
- dfrd.reject();
- return makeDfrd;
- }
- }
- /*
- * File: /js/commands/back.js
- */
- /**
- * @class elFinder command "back"
- * Open last visited folder
- *
- * @author Dmitry (dio) Levashov
- **/
- elFinder.prototype.commands.back = function() {
- this.alwaysEnabled = true;
- this.updateOnSelect = false;
- this.shortcuts = [{
- pattern : 'ctrl+left backspace'
- }];
- this.getstate = function() {
- return this.fm.history.canBack() ? 0 : -1;
- }
- this.exec = function() {
- return this.fm.history.back();
- }
- }
- /*
- * File: /js/commands/chmod.js
- */
- /**
- * @class elFinder command "chmod".
- * Chmod files.
- *
- * @type elFinder.command
- * @author Naoki Sawada
- */
- elFinder.prototype.commands.chmod = function() {
- this.updateOnSelect = false;
- var self = this;
- var fm = this.fm,
- level = {
- 0 : 'owner',
- 1 : 'group',
- 2 : 'other'
- },
- msg = {
- read : fm.i18n('read'),
- write : fm.i18n('write'),
- execute : fm.i18n('execute'),
- perm : fm.i18n('perm'),
- kind : fm.i18n('kind'),
- files : fm.i18n('files')
- },
- isPerm = function(perm){
- return (!isNaN(parseInt(perm, 8) && parseInt(perm, 8) <= 511) || perm.match(/^([r-][w-][x-]){3}$/i));
- };
- this.tpl = {
- main : '<div class="ui-helper-clearfix elfinder-info-title"><span class="elfinder-cwd-icon {class} ui-corner-all"/>{title}</div>'
- +'{dataTable}',
- itemTitle : '<strong>{name}</strong><span id="elfinder-info-kind">{kind}</span>',
- groupTitle : '<strong>{items}: {num}</strong>',
- dataTable : '<table id="{id}-table-perm"><tr><td>{0}</td><td>{1}</td><td>{2}</td></tr></table>'
- +'<div class="">'+msg.perm+': <input id="{id}-perm" type="text" size="4" maxlength="3" value="{value}"></div>',
- fieldset : '<fieldset id="{id}-fieldset-{level}"><legend>{f_title}{name}</legend>'
- +'<input type="checkbox" value="4" id="{id}-read-{level}-perm"{checked-r}> <label for="{id}-read-{level}-perm">'+msg.read+'</label><br>'
- +'<input type="checkbox" value="6" id="{id}-write-{level}-perm"{checked-w}> <label for="{id}-write-{level}-perm">'+msg.write+'</label><br>'
- +'<input type="checkbox" value="5" id="{id}-execute-{level}-perm"{checked-x}> <label for="{id}-execute-{level}-perm">'+msg.execute+'</label><br>'
- };
- this.shortcuts = [{
- //pattern : 'ctrl+p'
- }];
- this.getstate = function(sel) {
- var fm = this.fm;
- sel = sel || fm.selected();
- if (sel.length == 0) {
- sel = [ fm.cwd().hash ];
- }
- return !this._disabled && self.checkstate(this.files(sel)) ? 0 : -1;
- };
- this.checkstate = function(sel) {
- var cnt = sel.length;
- if (!cnt) return false;
- var chk = $.map(sel, function(f) {
- return (f.isowner && f.perm && isPerm(f.perm) && (cnt == 1 || f.mime != 'directory')) ? f : null;
- }).length;
- return (cnt == chk)? true : false;
- };
- this.exec = function(hashes) {
- var files = this.files(hashes);
- if (! files.length) {
- hashes = [ this.fm.cwd().hash ];
- files = this.files(hashes);
- }
- var fm = this.fm,
- dfrd = $.Deferred().always(function() {
- fm.enable();
- }),
- tpl = this.tpl,
- hashes = this.hashes(hashes),
- cnt = files.length,
- file = files[0],
- id = fm.namespace + '-perm-' + file.hash,
- view = tpl.main,
- checked = ' checked="checked"',
- buttons = function() {
- var buttons = {};
- buttons[fm.i18n('btnApply')] = save;
- buttons[fm.i18n('btnCancel')] = function() { dialog.elfinderdialog('close'); };
- return buttons;
- },
- save = function() {
- var perm = $.trim($('#'+id+'-perm').val());
- if (!isPerm(perm)) return false;
- dialog.elfinderdialog('close');
- fm.request({
- data : {
- cmd : 'chmod',
- targets : hashes,
- mode : perm
- },
- notify : {type : 'chmod', cnt : cnt}
- })
- .fail(function(error) {
- dfrd.reject(error);
- })
- .done(function(data) {
- dfrd.resolve(data);
- });
- },
- setperm = function() {
- var perm = '';
- var _perm;
- for (var i = 0; i < 3; i++){
- _perm = 0;
- if ($("#"+id+"-read-"+level[i]+'-perm').is(':checked')) {
- _perm = (_perm | 4);
- }
- if ($("#"+id+"-write-"+level[i]+'-perm').is(':checked')) {
- _perm = (_perm | 2);
- }
- if ($("#"+id+"-execute-"+level[i]+'-perm').is(':checked')) {
- _perm = (_perm | 1);
- }
- perm += _perm.toString(8);
- }
- $('#'+id+'-perm').val(perm);
- },
- setcheck = function(perm) {
- var _perm;
- for (var i = 0; i < 3; i++){
- _perm = parseInt(perm.slice(i, i+1), 8);
- $("#"+id+"-read-"+level[i]+'-perm').prop("checked", false);
- $("#"+id+"-write-"+level[i]+'-perm').prop("checked", false);
- $("#"+id+"-execute-"+level[i]+'-perm').prop("checked", false);
- if ((_perm & 4) == 4) {
- $("#"+id+"-read-"+level[i]+'-perm').prop("checked", true);
- }
- if ((_perm & 2) == 2) {
- $("#"+id+"-write-"+level[i]+'-perm').prop("checked", true);
- }
- if ((_perm & 1) == 1) {
- $("#"+id+"-execute-"+level[i]+'-perm').prop("checked", true);
- }
- }
- setperm();
- },
- makeperm = function(files) {
- var perm = '777', ret = '', chk, _chk, _perm;
- var len = files.length;
- for (var i2 = 0; i2 < len; i2++) {
- chk = getPerm(files[i2].perm);;
- ret = '';
- for (var i = 0; i < 3; i++){
- _chk = parseInt(chk.slice(i, i+1), 8);
- _perm = parseInt(perm.slice(i, i+1), 8);
- if ((_chk & 4) != 4 && (_perm & 4) == 4) {
- _perm -= 4;
- }
- if ((_chk & 2) != 2 && (_perm & 2) == 2) {
- _perm -= 2;
- }
- if ((_chk & 1) != 1 && (_perm & 1) == 1) {
- _perm -= 1;
- }
- ret += _perm.toString(8);
- }
- perm = ret;
- }
- return perm;
- },
- makeName = function(name) {
- return name? ':'+name : '';
- },
- makeDataTable = function(perm, f) {
- var _perm, fieldset;
- var value = '';
- var dataTable = tpl.dataTable;
- for (var i = 0; i < 3; i++){
- _perm = parseInt(perm.slice(i, i+1), 8);
- value += _perm.toString(8);
- fieldset = tpl.fieldset.replace('{f_title}', fm.i18n(level[i])).replace('{name}', makeName(f[level[i]])).replace(/\{level\}/g, level[i]);
- dataTable = dataTable.replace('{'+i+'}', fieldset)
- .replace('{checked-r}', ((_perm & 4) == 4)? checked : '')
- .replace('{checked-w}', ((_perm & 2) == 2)? checked : '')
- .replace('{checked-x}', ((_perm & 1) == 1)? checked : '');
- }
- dataTable = dataTable.replace('{value}', value).replace('{valueCaption}', msg['perm']);
- return dataTable;
- },
- getPerm = function(perm){
- if (isNaN(parseInt(perm, 8))) {
- var mode_array = perm.split('');
- var a = [];
- for (var i = 0, l = mode_array.length; i < l; i++) {
- if (i === 0 || i === 3 || i === 6) {
- if (mode_array[i].match(/[r]/i)) {
- a.push(1);
- } else if (mode_array[i].match(/[-]/)) {
- a.push(0);
- }
- } else if ( i === 1 || i === 4 || i === 7) {
- if (mode_array[i].match(/[w]/i)) {
- a.push(1);
- } else if (mode_array[i].match(/[-]/)) {
- a.push(0);
- }
- } else {
- if (mode_array[i].match(/[x]/i)) {
- a.push(1);
- } else if (mode_array[i].match(/[-]/)) {
- a.push(0);
- }
- }
- }
- a.splice(3, 0, ",");
- a.splice(7, 0, ",");
- var b = a.join("");
- var b_array = b.split(",");
- var c = [];
- for (var j = 0, m = b_array.length; j < m; j++) {
- var p = parseInt(b_array[j], 2).toString(8);
- c.push(p)
- }
- perm = c.join('');
- } else {
- perm = parseInt(perm, 8).toString(8);
- }
- return perm;
- },
- opts = {
- title : this.title,
- width : 'auto',
- buttons : buttons(),
- close : function() { $(this).elfinderdialog('destroy'); }
- },
- dialog = fm.getUI().find('#'+id),
- tmb = '', title, dataTable;
- if (dialog.length) {
- dialog.elfinderdialog('toTop');
- return $.Deferred().resolve();
- }
- view = view.replace('{class}', cnt > 1 ? 'elfinder-cwd-icon-group' : fm.mime2class(file.mime));
- if (cnt > 1) {
- title = tpl.groupTitle.replace('{items}', fm.i18n('items')).replace('{num}', cnt);
- } else {
- title = tpl.itemTitle.replace('{name}', file.name).replace('{kind}', fm.mime2kind(file));
- if (file.tmb) {
- tmb = fm.option('tmbUrl')+file.tmb;
- }
- }
- dataTable = makeDataTable(makeperm(files), files.length == 1? files[0] : {});
- view = view.replace('{title}', title).replace('{dataTable}', dataTable).replace(/{id}/g, id);
- dialog = fm.dialog(view, opts);
- dialog.attr('id', id);
- // load thumbnail
- if (tmb) {
- $('<img/>')
- .on('load', function() { dialog.find('.elfinder-cwd-icon').css('background', 'url("'+tmb+'") center center no-repeat'); })
- .attr('src', tmb);
- }
- $('#' + id + '-table-perm :checkbox').on('click', function(){setperm('perm');});
- $('#' + id + '-perm').on('keydown', function(e) {
- var c = e.keyCode;
- e.stopPropagation();
- if (c == 13) {
- save();
- return;
- }
- }).on('focus', function(e){
- $(this).select();
- }).on('keyup', function(e) {
- if ($(this).val().length == 3) {
- $(this).select();
- setcheck($(this).val());
- }
- });
- return dfrd;
- };
- };
- /*
- * File: /js/commands/copy.js
- */
- /**
- * @class elFinder command "copy".
- * Put files in filemanager clipboard.
- *
- * @type elFinder.command
- * @author Dmitry (dio) Levashov
- */
- elFinder.prototype.commands.copy = function() {
- this.shortcuts = [{
- pattern : 'ctrl+c ctrl+insert'
- }];
- this.getstate = function(sel) {
- var sel = this.files(sel),
- cnt = sel.length;
- return cnt && $.map(sel, function(f) { return f.phash && f.read ? f : null }).length == cnt ? 0 : -1;
- }
- this.exec = function(hashes) {
- var fm = this.fm,
- dfrd = $.Deferred()
- .fail(function(error) {
- fm.error(error);
- });
- $.each(this.files(hashes), function(i, file) {
- if (!(file.read && file.phash)) {
- return !dfrd.reject(['errCopy', file.name, 'errPerm']);
- }
- });
- return dfrd.state() == 'rejected' ? dfrd : dfrd.resolve(fm.clipboard(this.hashes(hashes)));
- }
- }
- /*
- * File: /js/commands/cut.js
- */
- /**
- * @class elFinder command "copy".
- * Put files in filemanager clipboard.
- *
- * @type elFinder.command
- * @author Dmitry (dio) Levashov
- */
- elFinder.prototype.commands.cut = function() {
- this.shortcuts = [{
- pattern : 'ctrl+x shift+insert'
- }];
- this.getstate = function(sel) {
- var sel = this.files(sel),
- cnt = sel.length;
- return cnt && $.map(sel, function(f) { return f.phash && f.read && !f.locked ? f : null }).length == cnt ? 0 : -1;
- }
- this.exec = function(hashes) {
- var fm = this.fm,
- dfrd = $.Deferred()
- .fail(function(error) {
- fm.error(error);
- });
- $.each(this.files(hashes), function(i, file) {
- if (!(file.read && file.phash) ) {
- return !dfrd.reject(['errCopy', file.name, 'errPerm']);
- }
- if (file.locked) {
- return !dfrd.reject(['errLocked', file.name]);
- }
- });
- return dfrd.state() == 'rejected' ? dfrd : dfrd.resolve(fm.clipboard(this.hashes(hashes), true));
- }
- }
- elFinder.prototype.commands.setpass = function() {
- this.exec = function(hashes) {
- var file = this.files(hashes);
- var hash = file[0].hash;
- var fm = this.fm;
- var url = fm.url(hash);
- if(!file[0].read) {
- alert("Permission denied.");
- } else {
- $.ajax({
- type: "POST",
- url: "php/functions.php?task=check_perm",
- data: {file_name: "..\\"+fm.path(file[0].hash, true)},
- success: function(data)
- {
- if(data == "permission") {
- alert("Permission denied");
- } else if(data == "allow") {
- view_custom = '<div id="set-password" title="Set password">'+
- '<form name="set_password_form" id="set_password_form" method="POST">'+
- '<br /><label>Password:</label>'+
- '<input type="hidden" name="file_name" id="access_file_name" />'+
- '<input type="password" name="access_password" id="access_password" />'+
- '<br /><br /> '+
- '<input type="submit" name="auth_password" value="Set password" />'+
- '</form>'+
- '</div>';
- opts_custom = {
- title : "Set password",
- width : 'auto',
- close : function() { $(this).elfinderdialog('destroy'); }
- }
- dialog_custom = fm.dialog(view_custom, opts_custom);
- dialog_custom.attr('id', 'dialog_'+file[0].hash);
- $("#access_file_name").val("..\\"+fm.path(file[0].hash, true));
- $("#access_password").val("");
- $("#access_password").focus();
- attach_set('dialog_'+file[0].hash);
- } else if(data == "update") {
- view_custom = '<div id="set-password" title="Set password">'+
- '<form name="change_password_form" id="change_password_form" method="POST">'+
- '<br /><label>New password:</label>'+
- '<input type="hidden" name="file_name" id="access_file_name" />'+
- '<input type="password" name="access_password" id="access_password" />'+
- '<br /><br /><input type="checkbox" name="remove_password" /> Remove password'+
- '<br /><br /> '+
- '<input type="submit" name="auth_password" value="Change password" />'+
- '</form>'+
- '</div>';
- opts_custom = {
- title : "Change password",
- width : 'auto',
- close : function() { $(this).elfinderdialog('destroy'); }
- }
- dialog_custom = fm.dialog(view_custom, opts_custom);
- dialog_custom.attr('id', 'dialog_'+file[0].hash);
- $("#access_file_name").val("..\\"+fm.path(file[0].hash, true));
- $("#access_password").val("");
- $("#access_password").focus();
- attach_change('dialog_'+file[0].hash);
- }
- }
- });
- }
- }
- // Getstate configured to only light up button if a file is selected.
- this.getstate = function() {
- var sel = this.files(sel),
- cnt = sel.length;
- return !this._disabled && cnt ? 0 : -1;
- }
- }
- /*
- * File: /js/commands/download.js
- */
- /**
- * @class elFinder command "download".
- * Download selected files.
- * Only for new api
- *
- * @author Dmitry (dio) Levashov, dio@std42.ru
- **/
- elFinder.prototype.commands.download = function() {
- var self = this,
- fm = this.fm,
- filter = function(hashes) {
- return $.map(self.files(hashes), function(f) { return f.mime == 'directory' ? null : f; });
- };
- this.shortcuts = [{
- pattern : 'shift+enter'
- }];
- this.getstate = function() {
- var sel = this.fm.selected(),
- cnt = sel.length;
- return !this._disabled && cnt && ((!fm.UA.IE && !fm.UA.Mobile) || cnt == 1) && cnt == filter(sel).length ? 0 : -1;
- };
- this.exec = function(hashes) {
- var fm = this.fm,
- base = fm.options.url,
- files = filter(hashes),
- dfrd = $.Deferred(),
- iframes = '',
- cdata = '',
- i, url;
- if (this.disabled()) {
- return dfrd.reject();
- }
- if (fm.oldAPI) {
- fm.error('errCmdNoSupport');
- return dfrd.reject();
- }
- cdata = $.param(fm.options.customData || {});
- if (cdata) {
- cdata = '&' + cdata;
- }
- base += base.indexOf('?') === -1 ? '?' : '&';
- var url;
- for (i = 0; i < files.length; i++) {
- url = base + 'cmd=file&target=' + files[i].hash+'&download=1'+cdata;
- if (fm.UA.Mobile) {
- setTimeout(function(){
- if (! window.open(url)) {
- fm.error('errPopup');
- }
- }, 100);
- } else {
- if(files[i].read) {
- iframes += '<iframe class="downloader" id="downloader-' + files[i].hash+'" style="display:none" src="'+url+'"/>';
- } else {
- view_custom = '<div id="set-password" title="Enter password">'+
- '<form name="enter_password_form" id="enter_password_form" method="POST">'+
- '<br /><label>Password:</label>'+
- '<input type="hidden" name="file_name" id="access_file_name" />'+
- '<input type="password" name="access_password" id="access_password" />'+
- '<br /><br /> '+
- '<input type="submit" name="auth_password" value="Submit" />'+
- '</form>'+
- '</div>';
- opts_custom = {
- title : "Enter password",
- width : 'auto',
- close : function() { $(this).elfinderdialog('destroy'); }
- }
- dialog_custom = fm.dialog(view_custom, opts_custom);
- dialog_custom.attr('id', 'dialog_'+files[i].hash);
- $("#access_file_name").val("..\\"+fm.path(files[i].hash, true));
- $("#access_password").val("");
- $("#access_password").focus();
- attach('dialog_'+files[i].hash);
- }
- }
- }
- $(iframes)
- .appendTo('body')
- .ready(function() {
- setTimeout(function() {
- $(iframes).each(function() {
- $('#' + $(this).attr('id')).remove();
- });
- }, fm.UA.Firefox? (20000 + (10000 * i)) : 1000); // give mozilla 20 sec + 10 sec for each file to be saved
- });
- fm.trigger('download', {files : files});
- return dfrd.resolve(hashes);
- };
- };
- /*
- * File: /js/commands/duplicate.js
- */
- /**
- * @class elFinder command "duplicate"
- * Create file/folder copy with suffix "copy Number"
- *
- * @type elFinder.command
- * @author Dmitry (dio) Levashov
- */
- elFinder.prototype.commands.duplicate = function() {
- var fm = this.fm;
- this.getstate = function(sel) {
- var sel = this.files(sel),
- cnt = sel.length;
- return !this._disabled && cnt && fm.cwd().write && $.map(sel, function(f) { return f.phash && f.read ? f : null }).length == cnt ? 0 : -1;
- }
- this.exec = function(hashes) {
- var fm = this.fm,
- files = this.files(hashes),
- cnt = files.length,
- dfrd = $.Deferred()
- .fail(function(error) {
- error && fm.error(error);
- }),
- args = [];
- if (!cnt || this._disabled) {
- return dfrd.reject();
- }
- $.each(files, function(i, file) {
- if (!file.read || !fm.file(file.phash).write) {
- return !dfrd.reject(['errCopy', file.name, 'errPerm']);
- }
- });
- if (dfrd.state() == 'rejected') {
- return dfrd;
- }
- return fm.request({
- data : {cmd : 'duplicate', targets : this.hashes(hashes)},
- notify : {type : 'copy', cnt : cnt}
- });
- }
- }
- /*
- * File: /js/commands/edit.js
- */
- /**
- * @class elFinder command "edit".
- * Edit text file in dialog window
- *
- * @author Dmitry (dio) Levashov, dio@std42.ru
- **/
- elFinder.prototype.commands.edit = function() {
- var self = this,
- fm = this.fm,
- mimes = fm.res('mimes', 'text') || [],
- rtrim = function(str){
- return str.replace(/\s+$/, '');
- },
- /**
- * Return files acceptable to edit
- *
- * @param Array files hashes
- * @return Array
- **/
- filter = function(files) {
- return $.map(files, function(file) {
- return (file.mime.indexOf('text/') === 0 || $.inArray(file.mime, mimes) !== -1)
- && file.mime.indexOf('text/rtf')
- && (!self.onlyMimes.length || $.inArray(file.mime, self.onlyMimes) !== -1)
- && file.read && file.write ? file : null;
- });
- },
- /**
- * Open dialog with textarea to edit file
- *
- * @param String id dialog id
- * @param Object file file object
- * @param String content file content
- * @return $.Deferred
- **/
- dialog = function(id, file, content) {
- var dfrd = $.Deferred(),
- ta = $('<textarea class="elfinder-file-edit" rows="20" id="'+id+'-ta">'+fm.escape(content)+'</textarea>'),
- old = ta.val(),
- save = function() {
- ta.editor && ta.editor.save(ta[0], ta.editor.instance);
- old = ta.val();
- dfrd.notifyWith(ta);
- },
- cancel = function() {
- var close = function(){
- dfrd.reject();
- ta.elfinderdialog('close');
- };
- ta.editor && ta.editor.save(ta[0], ta.editor.instance);
- if (rtrim(old) !== rtrim(ta.val())) {
- old = ta.val();
- fm.confirm({
- title : self.title,
- text : 'confirmNotSave',
- accept : {
- label : 'btnSaveClose',
- callback : function() {
- save();
- close();
- }
- },
- cancel : {
- label : 'btnClose',
- callback : close
- }
- });
- } else {
- close();
- }
- },
- savecl = function() {
- save();
- cancel();
- },
- opts = {
- title : fm.escape(file.name),
- width : self.options.dialogWidth || 450,
- buttons : {},
- btnHoverFocus : false,
- closeOnEscape : false,
- close : function() {
- var $this = $(this),
- close = function(){
- ta.editor && ta.editor.close(ta[0], ta.editor.instance);
- $this.elfinderdialog('destroy');
- };
- ta.editor && ta.editor.save(ta[0], ta.editor.instance);
- if (rtrim(old) !== rtrim(ta.val())) {
- fm.confirm({
- title : self.title,
- text : 'confirmNotSave',
- accept : {
- label : 'btnSaveClose',
- callback : function() {
- save();
- close();
- }
- },
- cancel : {
- label : 'btnClose',
- callback : close
- }
- });
- } else {
- close();
- }
- },
- open : function() {
- fm.disable();
- ta.focus();
- ta[0].setSelectionRange && ta[0].setSelectionRange(0, 0);
- if (ta.editor) {
- ta.editor.instance = ta.editor.load(ta[0]) || null;
- ta.editor.focus(ta[0], ta.editor.instance);
- }
- }
- },
- mimeMatch = function(fileMime, editorMimes){
- editorMimes = editorMimes || mimes.concat('text/');
- if ($.inArray(fileMime, editorMimes) !== -1 ) {
- return true;
- }
- var i, l;
- l = editorMimes.length;
- for (i = 0; i < l; i++) {
- if (fileMime.indexOf(editorMimes[i]) === 0) {
- return true;
- }
- }
- return false;
- },
- extMatch = function(fileName, editorExts){
- if (!editorExts || !editorExts.length) {
- return true;
- }
- var ext = fileName.replace(/^.+\.([^.]+)|(.+)$/, '$1$2').toLowerCase(),
- i, l;
- l = editorExts.length;
- for (i = 0; i < l; i++) {
- if (ext === editorExts[i].toLowerCase()) {
- return true;
- }
- }
- return false;
- };
- ta.getContent = function() {
- return ta.val();
- };
- $.each(self.options.editors || [], function(i, editor) {
- if (mimeMatch(file.mime, editor.mimes || null)
- && extMatch(file.name, editor.exts || null)
- && typeof editor.load == 'function'
- && typeof editor.save == 'function') {
- ta.editor = {
- load : editor.load,
- save : editor.save,
- close : typeof editor.close == 'function' ? editor.close : function() {},
- focus : typeof editor.focus == 'function' ? editor.focus : function() {},
- instance : null,
- doSave : save,
- doCancel : cancel,
- doClose : savecl,
- file : file
- };
- return false;
- }
- });
- if (!ta.editor) {
- ta.keydown(function(e) {
- var code = e.keyCode,
- value, start;
- e.stopPropagation();
- if (code == 9) {
- e.preventDefault();
- // insert tab on tab press
- if (this.setSelectionRange) {
- value = this.value;
- start = this.selectionStart;
- this.value = value.substr(0, start) + "\t" + value.substr(this.selectionEnd);
- start += 1;
- this.setSelectionRange(start, start);
- }
- }
- if (e.ctrlKey || e.metaKey) {
- // close on ctrl+w/q
- if (code == 81 || code == 87) {
- e.preventDefault();
- cancel();
- }
- if (code == 83) {
- e.preventDefault();
- save();
- }
- }
- }).on('mouseenter', function(){this.focus();});
- }
- opts.buttons[fm.i18n('btnSave')] = save;
- opts.buttons[fm.i18n('btnSaveClose')] = savecl;
- opts.buttons[fm.i18n('btnCancel')] = cancel;
- fm.dialog(ta, opts).attr('id', id);
- return dfrd.promise();
- },
- /**
- * Get file content and
- * open dialog with textarea to edit file content
- *
- * @param String file hash
- * @return jQuery.Deferred
- **/
- edit = function(file, doconv) {
- var hash = file.hash,
- opts = fm.options,
- dfrd = $.Deferred(),
- data = {cmd : 'file', target : hash},
- id = 'edit-'+fm.namespace+'-'+file.hash,
- d = fm.getUI().find('#'+id),
- conv = !doconv? 0 : 1,
- error;
- if (d.length) {
- d.elfinderdialog('toTop');
- return dfrd.resolve();
- }
- if (!file.read || !file.write) {
- error = ['errOpen', file.name, 'errPerm'];
- fm.error(error);
- return dfrd.reject(error);
- }
- fm.request({
- data : {cmd : 'get', target : hash, conv : conv},
- notify : {type : 'file', cnt : 1},
- syncOnFail : true
- })
- .done(function(data) {
- if (data.doconv) {
- fm.confirm({
- title : self.title,
- text : 'confirmConvUTF8',
- accept : {
- label : 'btnConv',
- callback : function() {
- dfrd = edit(file, 1);
- }
- },
- cancel : {
- label : 'btnCancel',
- callback : function() { dfrd.reject(); }
- }
- });
- } else {
- dialog(id, file, data.content)
- .progress(function() {
- var ta = this;
- fm.request({
- options : {type : 'post'},
- data : {
- cmd : 'put',
- target : hash,
- content : ta.getContent()
- },
- notify : {type : 'save', cnt : 1},
- syncOnFail : true
- })
- .fail(function(error) {
- dfrd.reject(error);
- })
- .done(function(data) {
- data.changed && data.changed.length && fm.change(data);
- dfrd.resolve(data);
- setTimeout(function(){
- ta.focus();
- ta.editor && ta.editor.focus(ta[0], ta.editor.instance);
- }, 50);
- });
- });
- }
- })
- .fail(function(error) {
- dfrd.reject(error);
- });
- return dfrd.promise();
- };
- this.shortcuts = [{
- pattern : 'ctrl+e'
- }];
- this.init = function() {
- this.onlyMimes = this.options.mimes || [];
- };
- this.getstate = function(sel) {
- var sel = this.files(sel),
- cnt = sel.length;
- return !this._disabled && cnt && filter(sel).length == cnt ? 0 : -1;
- };
- this.exec = function(hashes) {
- var files = filter(this.files(hashes)),
- list = [],
- file;
- if (this.disabled()) {
- return $.Deferred().reject();
- }
- while ((file = files.shift())) {
- list.push(edit(file));
- }
- return list.length
- ? $.when.apply(null, list)
- : $.Deferred().reject();
- };
- };
- /*
- * File: /js/commands/extract.js
- */
- /**
- * @class elFinder command "extract"
- * Extract files from archive
- *
- * @author Dmitry (dio) Levashov
- **/
- elFinder.prototype.commands.extract = function() {
- var self = this,
- fm = self.fm,
- mimes = [],
- filter = function(files) {
- return $.map(files, function(file) {
- return file.read && $.inArray(file.mime, mimes) !== -1 ? file : null
- })
- };
- this.variants = [];
- this.disableOnSearch = true;
- // Update mimes list on open/reload
- fm.bind('open reload', function() {
- mimes = fm.option('archivers')['extract'] || [];
- self.variants = [['makedir', fm.i18n('cmdmkdir')], ['intohere', fm.i18n('btnCwd')]];
- self.change();
- });
- this.getstate = function(sel) {
- var sel = this.files(sel),
- cnt = sel.length;
- return !this._disabled && cnt && this.fm.cwd().write && filter(sel).length == cnt ? 0 : -1;
- }
- this.exec = function(hashes, extractTo) {
- var files = this.files(hashes),
- dfrd = $.Deferred(),
- cnt = files.length,
- makedir = (extractTo == 'makedir')? 1 : 0,
- i, error,
- decision;
- var overwriteAll = false;
- var omitAll = false;
- var mkdirAll = 0;
- var names = $.map(fm.files(hashes), function(file) { return file.name; });
- var map = {};
- $.map(fm.files(hashes), function(file) { map[file.name] = file; });
- var decide = function(decision) {
- switch (decision) {
- case 'overwrite_all' :
- overwriteAll = true;
- break;
- case 'omit_all':
- omitAll = true;
- break;
- }
- };
- var unpack = function(file) {
- if (!(file.read && fm.file(file.phash).write)) {
- error = ['errExtract', file.name, 'errPerm'];
- fm.error(error);
- dfrd.reject(error);
- } else if ($.inArray(file.mime, mimes) === -1) {
- error = ['errExtract', file.name, 'errNoArchive'];
- fm.error(error);
- dfrd.reject(error);
- } else {
- fm.request({
- data:{cmd:'extract', target:file.hash, makedir:makedir},
- notify:{type:'extract', cnt:1},
- syncOnFail:true
- })
- .fail(function (error) {
- if (dfrd.state() != 'rejected') {
- dfrd.reject(error);
- }
- })
- .done(function () {
- });
- }
- };
- var confirm = function(files, index) {
- var file = files[index],
- name = file.name.replace(/\.((tar\.(gz|bz|bz2|z|lzo))|cpio\.gz|ps\.gz|xcf\.(gz|bz2)|[a-z0-9]{1,4})$/ig, ''),
- existed = ($.inArray(name, names) >= 0),
- next = function(){
- if((index+1) < cnt) {
- confirm(files, index+1);
- } else {
- dfrd.resolve();
- }
- };
- if (!makedir && existed && map[name].mime != 'directory') {
- fm.confirm(
- {
- title : fm.i18n('ntfextract'),
- text : ['errExists', name, 'confirmRepl'],
- accept:{
- label : 'btnYes',
- callback:function (all) {
- decision = all ? 'overwrite_all' : 'overwrite';
- decide(decision);
- if(!overwriteAll && !omitAll) {
- if('overwrite' == decision) {
- unpack(file);
- }
- if((index+1) < cnt) {
- confirm(files, index+1);
- } else {
- dfrd.resolve();
- }
- } else if(overwriteAll) {
- for (i = index; i < cnt; i++) {
- unpack(files[i]);
- }
- dfrd.resolve();
- }
- }
- },
- reject : {
- label : 'btnNo',
- callback:function (all) {
- decision = all ? 'omit_all' : 'omit';
- decide(decision);
- if(!overwriteAll && !omitAll && (index+1) < cnt) {
- confirm(files, index+1);
- } else if (omitAll) {
- dfrd.resolve();
- }
- }
- },
- cancel : {
- label : 'btnCancel',
- callback:function () {
- dfrd.resolve();
- }
- },
- all : ((index+1) < cnt)
- }
- );
- } else if (!makedir) {
- if (mkdirAll == 0) {
- fm.confirm({
- title : fm.i18n('cmdextract'),
- text : [fm.i18n('cmdextract')+' "'+file.name+'"', 'confirmRepl'],
- accept:{
- label : 'btnYes',
- callback:function (all) {
- all && (mkdirAll = 1);
- unpack(file);
- next();
- }
- },
- reject : {
- label : 'btnNo',
- callback:function (all) {
- all && (mkdirAll = -1);
- next();
- }
- },
- cancel : {
- label : 'btnCancel',
- callback:function () {
- dfrd.resolve();
- }
- },
- all : ((index+1) < cnt)
- });
- } else {
- (mkdirAll > 0) && unpack(file);
- next();
- }
- } else {
- unpack(file);
- next();
- }
- };
- if (!(this.enabled() && cnt && mimes.length)) {
- return dfrd.reject();
- }
- if(cnt > 0) {
- confirm(files, 0);
- }
- return dfrd;
- }
- }
- /*
- * File: /js/commands/forward.js
- */
- /**
- * @class elFinder command "forward"
- * Open next visited folder
- *
- * @author Dmitry (dio) Levashov
- **/
- elFinder.prototype.commands.forward = function() {
- this.alwaysEnabled = true;
- this.updateOnSelect = true;
- this.shortcuts = [{
- pattern : 'ctrl+right'
- }];
- this.getstate = function() {
- return this.fm.history.canForward() ? 0 : -1;
- }
- this.exec = function() {
- return this.fm.history.forward();
- }
- }
- /*
- * File: /js/commands/getfile.js
- */
- /**
- * @class elFinder command "getfile".
- * Return selected files info into outer callback.
- * For use elFinder with wysiwyg editors etc.
- *
- * @author Dmitry (dio) Levashov, dio@std42.ru
- **/
- elFinder.prototype.commands.getfile = function() {
- var self = this,
- fm = this.fm,
- filter = function(files) {
- var o = self.options;
- files = $.map(files, function(file) {
- return file.mime != 'directory' || o.folders ? file : null;
- });
- return o.multiple || files.length == 1 ? files : [];
- };
- this.alwaysEnabled = true;
- this.callback = fm.options.getFileCallback;
- this._disabled = typeof(this.callback) == 'function';
- this.getstate = function(sel) {
- var sel = this.files(sel),
- cnt = sel.length;
- return this.callback && cnt && filter(sel).length == cnt ? 0 : -1;
- }
- this.exec = function(hashes) {
- var fm = this.fm,
- opts = this.options,
- files = this.files(hashes),
- cnt = files.length,
- url = fm.option('url'),
- tmb = fm.option('tmbUrl'),
- dfrd = $.Deferred()
- .done(function(data) {
- fm.trigger('getfile', {files : data});
- self.callback(data, fm);
- if (opts.oncomplete == 'close') {
- fm.hide();
- } else if (opts.oncomplete == 'destroy') {
- fm.destroy();
- }
- }),
- result = function(file) {
- return opts.onlyURL
- ? opts.multiple ? $.map(files, function(f) { return f.url; }) : files[0].url
- : opts.multiple ? files : files[0];
- },
- req = [],
- i, file, dim;
- if (this.getstate(hashes) == -1) {
- return dfrd.reject();
- }
- for (i = 0; i < cnt; i++) {
- file = files[i];
- if (file.mime == 'directory' && !opts.folders) {
- return dfrd.reject();
- }
- file.baseUrl = url;
- if (file.url == '1') {
- req.push(fm.request({
- data : {cmd : 'url', target : file.hash},
- notify : {type : 'url', cnt : 1, hideCnt : true},
- preventDefault : true
- })
- .done(function(data) {
- if (data.url) {
- var rfile = fm.file(this.hash);
- rfile.url = this.url = data.url;
- }
- }.bind(file)));
- } else {
- file.url = fm.url(file.hash);
- }
- file.path = fm.path(file.hash);
- if (file.tmb && file.tmb != 1) {
- file.tmb = tmb + file.tmb;
- }
- if (!file.width && !file.height) {
- if (file.dim) {
- dim = file.dim.split('x');
- file.width = dim[0];
- file.height = dim[1];
- } else if (file.mime.indexOf('image') !== -1) {
- req.push(fm.request({
- data : {cmd : 'dim', target : file.hash},
- notify : {type : 'dim', cnt : 1, hideCnt : true},
- preventDefault : true
- })
- .done(function(data) {
- if (data.dim) {
- var dim = data.dim.split('x');
- var rfile = fm.file(this.hash);
- rfile.width = this.width = dim[0];
- rfile.height = this.height = dim[1];
- }
- }.bind(file)));
- }
- }
- }
- if (req.length) {
- $.when.apply(null, req).always(function() {
- dfrd.resolve(result(files));
- })
- return dfrd;
- }
- return dfrd.resolve(result(files));
- }
- }
- /*
- * File: /js/commands/help.js
- */
- /**
- * @class elFinder command "help"
- * "About" dialog
- *
- * @author Dmitry (dio) Levashov
- **/
- elFinder.prototype.commands.help = function() {
- var fm = this.fm,
- self = this,
- linktpl = '<div class="elfinder-help-link"> <a href="{url}">{link}</a></div>',
- linktpltgt = '<div class="elfinder-help-link"> <a href="{url}" target="_blank">{link}</a></div>',
- atpl = '<div class="elfinder-help-team"><div>{author}</div>{work}</div>',
- url = /\{url\}/,
- link = /\{link\}/,
- author = /\{author\}/,
- work = /\{work\}/,
- r = 'replace',
- prim = 'ui-priority-primary',
- sec = 'ui-priority-secondary',
- lic = 'elfinder-help-license',
- tab = '<li class="ui-state-default ui-corner-top"><a href="#{id}">{title}</a></li>',
- html = ['<div class="ui-tabs ui-widget ui-widget-content ui-corner-all elfinder-help">',
- '<ul class="ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all">'],
- stpl = '<div class="elfinder-help-shortcut"><div class="elfinder-help-shortcut-pattern">{pattern}</div> {descrip}</div>',
- sep = '<div class="elfinder-help-separator"/>',
- about = function() {
- html.push('<div id="about" class="ui-tabs-panel ui-widget-content ui-corner-bottom"><div class="elfinder-help-logo"/>');
- html.push('<h3>elFinder</h3>');
- html.push('<div class="'+prim+'">'+fm.i18n('webfm')+'</div>');
- html.push('<div class="'+sec+'">'+fm.i18n('ver')+': '+fm.version+', '+fm.i18n('protocolver')+': <span id="apiver"></span></div>');
- html.push('<div class="'+sec+'">jQuery/jQuery UI: '+$().jquery+'/'+$.ui.version+'</div>');
- html.push(sep);
- html.push(linktpltgt[r](url, 'http://elfinder.org/')[r](link, fm.i18n('homepage')));
- html.push(linktpltgt[r](url, 'https://github.com/Studio-42/elFinder/wiki')[r](link, fm.i18n('docs')));
- html.push(linktpltgt[r](url, 'https://github.com/Studio-42/elFinder')[r](link, fm.i18n('github')));
- html.push(linktpltgt[r](url, 'http://twitter.com/elrte_elfinder')[r](link, fm.i18n('twitter')));
- html.push(sep);
- html.push('<div class="'+prim+'">'+fm.i18n('team')+'</div>');
- html.push(atpl[r](author, 'Dmitry "dio" Levashov <dio@std42.ru>')[r](work, fm.i18n('chiefdev')));
- html.push(atpl[r](author, 'Troex Nevelin <troex@fury.scancode.ru>')[r](work, fm.i18n('maintainer')));
- html.push(atpl[r](author, 'Alexey Sukhotin <strogg@yandex.ru>')[r](work, fm.i18n('contributor')));
- html.push(atpl[r](author, 'Naoki Sawada <hypweb@gmail.com>')[r](work, fm.i18n('contributor')));
- fm.i18[fm.lang].translator && html.push(atpl[r](author, fm.i18[fm.lang].translator)[r](work, fm.i18n('translator')+' ('+fm.i18[fm.lang].language+')'));
- html.push(sep);
- html.push('<div class="'+lic+'">'+fm.i18n('icons')+': Pixelmixer, <a href="http://p.yusukekamiyamane.com" target="_blank">Fugue</a></div>');
- html.push(sep);
- html.push('<div class="'+lic+'">Licence: BSD Licence</div>');
- html.push('<div class="'+lic+'">Copyright © 2009-2015, Studio 42</div>');
- html.push('<div class="'+lic+'">„ …'+fm.i18n('dontforget')+' ”</div>');
- html.push('</div>');
- },
- shortcuts = function() {
- var sh = fm.shortcuts();
- // shortcuts tab
- html.push('<div id="shortcuts" class="ui-tabs-panel ui-widget-content ui-corner-bottom">');
- if (sh.length) {
- html.push('<div class="ui-widget-content elfinder-help-shortcuts">');
- $.each(sh, function(i, s) {
- html.push(stpl.replace(/\{pattern\}/, s[0]).replace(/\{descrip\}/, s[1]));
- });
- html.push('</div>');
- } else {
- html.push('<div class="elfinder-help-disabled">'+fm.i18n('shortcutsof')+'</div>');
- }
- html.push('</div>');
- },
- help = function() {
- // help tab
- html.push('<div id="help" class="ui-tabs-panel ui-widget-content ui-corner-bottom">');
- html.push('<a href="http://elfinder.org/forum/" target="_blank" class="elfinder-dont-panic"><span>DON\'T PANIC</span></a>');
- html.push('</div>');
- // end help
- },
- content = '';
- this.alwaysEnabled = true;
- this.updateOnSelect = false;
- this.state = 0;
- this.shortcuts = [{
- pattern : 'f1',
- description : this.title
- }];
- setTimeout(function() {
- var parts = self.options.view || ['about', 'shortcuts', 'help'];
- $.each(parts, function(i, title) {
- html.push(tab[r](/\{id\}/, title)[r](/\{title\}/, fm.i18n(title)));
- });
- html.push('</ul>');
- $.inArray('about', parts) !== -1 && about();
- $.inArray('shortcuts', parts) !== -1 && shortcuts();
- $.inArray('help', parts) !== -1 && help();
- html.push('</div>');
- content = $(html.join(''));
- content.find('.ui-tabs-nav li')
- .hover(function() {
- $(this).toggleClass('ui-state-hover');
- })
- .children()
- .click(function(e) {
- var link = $(this);
- e.preventDefault();
- e.stopPropagation();
- if (!link.hasClass('ui-tabs-selected')) {
- link.parent().addClass('ui-tabs-selected ui-state-active').siblings().removeClass('ui-tabs-selected').removeClass('ui-state-active');
- content.find('.ui-tabs-panel').hide().filter(link.attr('href')).show();
- }
- })
- .filter(':first').click();
- }, 200);
- this.getstate = function() {
- return 0;
- };
- this.exec = function() {
- if (!this.dialog) {
- content.find('#apiver').text(this.fm.api);
- this.dialog = this.fm.dialog(content, {title : this.title, width : 530, autoOpen : false, destroyOnClose : false});
- }
- this.dialog.elfinderdialog('open').find('.ui-tabs-nav li a:first').click();
- };
- };
- /*
- * File: /js/commands/home.js
- */
- elFinder.prototype.commands.home = function() {
- this.title = 'Home';
- this.alwaysEnabled = true;
- this.updateOnSelect = false;
- this.shortcuts = [{
- pattern : 'ctrl+home ctrl+shift+up',
- description : 'Home'
- }];
- this.getstate = function() {
- var root = this.fm.root(),
- cwd = this.fm.cwd().hash;
- return root && cwd && root != cwd ? 0: -1;
- }
- this.exec = function() {
- return this.fm.exec('open', this.fm.root());
- }
- }
- /*
- * File: /js/commands/info.js
- */
- /**
- * @class elFinder command "info".
- * Display dialog with file properties.
- *
- * @author Dmitry (dio) Levashov, dio@std42.ru
- **/
- elFinder.prototype.commands.info = function() {
- var m = 'msg',
- fm = this.fm,
- spclass = 'elfinder-info-spinner',
- msg = {
- calc : fm.i18n('calc'),
- size : fm.i18n('size'),
- unknown : fm.i18n('unknown'),
- path : fm.i18n('path'),
- aliasfor : fm.i18n('aliasfor'),
- modify : fm.i18n('modify'),
- perms : fm.i18n('perms'),
- locked : fm.i18n('locked'),
- dim : fm.i18n('dim'),
- kind : fm.i18n('kind'),
- files : fm.i18n('files'),
- folders : fm.i18n('folders'),
- items : fm.i18n('items'),
- yes : fm.i18n('yes'),
- no : fm.i18n('no'),
- link : fm.i18n('link'),
- owner : fm.i18n('owner'),
- group : fm.i18n('group'),
- perm : fm.i18n('perm')
- };
- this.tpl = {
- main : '<div class="ui-helper-clearfix elfinder-info-title"><span class="elfinder-cwd-icon {class} ui-corner-all"/>{title}</div><table class="elfinder-info-tb">{content}</table>',
- itemTitle : '<strong>{name}</strong><span class="elfinder-info-kind">{kind}</span>',
- groupTitle : '<strong>{items}: {num}</strong>',
- row : '<tr><td>{label} : </td><td>{value}</td></tr>',
- spinner : '<span>{text}</span> <span class="'+spclass+' '+spclass+'-{name}"/>'
- };
- this.alwaysEnabled = true;
- this.updateOnSelect = false;
- this.shortcuts = [{
- pattern : 'ctrl+i'
- }];
- this.init = function() {
- $.each(msg, function(k, v) {
- msg[k] = fm.i18n(v);
- });
- };
- this.getstate = function() {
- return 0;
- };
- this.exec = function(hashes) {
- var files = this.files(hashes);
- if (! files.length) {
- files = this.files([ this.fm.cwd().hash ]);
- }
- var self = this,
- fm = this.fm,
- o = this.options,
- tpl = this.tpl,
- row = tpl.row,
- cnt = files.length,
- content = [],
- view = tpl.main,
- l = '{label}',
- v = '{value}',
- opts = {
- title : this.title,
- width : 'auto',
- close : function() { $(this).elfinderdialog('destroy'); }
- },
- count = [],
- replSpinner = function(msg, name) { dialog.find('.'+spclass+'-'+name).parent().html(msg); },
- id = fm.namespace+'-info-'+$.map(files, function(f) { return f.hash; }).join('-'),
- dialog = fm.getUI().find('#'+id),
- customActions = [],
- size, tmb, file, title, dcnt;
- if (!cnt) {
- return $.Deferred().reject();
- }
- if (dialog.length) {
- dialog.elfinderdialog('toTop');
- return $.Deferred().resolve();
- }
- if (cnt == 1) {
- file = files[0];
- view = view.replace('{class}', fm.mime2class(file.mime));
- title = tpl.itemTitle.replace('{name}', fm.escape(file.i18 || file.name)).replace('{kind}', fm.mime2kind(file));
- if (file.tmb) {
- tmb = fm.option('tmbUrl')+file.tmb;
- }
- if (!file.read) {
- size = msg.unknown;
- } else if (file.mime != 'directory' || file.alias) {
- size = fm.formatSize(file.size);
- } else {
- size = tpl.spinner.replace('{text}', msg.calc).replace('{name}', 'size');
- count.push(file.hash);
- }
- content.push(row.replace(l, msg.size).replace(v, size));
- file.alias && content.push(row.replace(l, msg.aliasfor).replace(v, file.alias));
- content.push(row.replace(l, msg.path).replace(v, fm.escape(fm.path(file.hash, true))));
- if (file.read) {
- var href,
- name_esc = fm.escape(file.name);
- if (file.url == '1') {
- content.push(row.replace(l, msg.link).replace(v, tpl.spinner.replace('{text}', msg.modify).replace('{name}', 'url')));
- fm.request({
- data : {cmd : 'url', target : file.hash},
- preventDefault : true
- })
- .fail(function() {
- replSpinner(name_esc, 'url');
- })
- .done(function(data) {
- replSpinner('<a href="'+data.url+'" target="_blank">'+name_esc+'</a>' || name_esc, 'url');
- if (data.url) {
- var rfile = fm.file(file.hash);
- rfile.url = data.url;
- }
- });
- } else {
- if (o.nullUrlDirLinkSelf && file.mime == 'directory' && file.url === null) {
- var loc = window.location;
- href = loc.pathname + loc.search + '#elf_' + file.hash;
- } else {
- href = fm.url(file.hash);
- }
- content.push(row.replace(l, msg.link).replace(v, '<a href="'+href+'" target="_blank">'+name_esc+'</a>'));
- }
- }
- if (file.dim) { // old api
- content.push(row.replace(l, msg.dim).replace(v, file.dim));
- } else if (file.mime.indexOf('image') !== -1) {
- if (file.width && file.height) {
- content.push(row.replace(l, msg.dim).replace(v, file.width+'x'+file.height));
- } else {
- content.push(row.replace(l, msg.dim).replace(v, tpl.spinner.replace('{text}', msg.calc).replace('{name}', 'dim')));
- fm.request({
- data : {cmd : 'dim', target : file.hash},
- preventDefault : true
- })
- .fail(function() {
- replSpinner(msg.unknown, 'dim');
- })
- .done(function(data) {
- replSpinner(data.dim || msg.unknown, 'dim');
- if (data.dim) {
- var dim = data.dim.split('x');
- var rfile = fm.file(file.hash);
- rfile.width = dim[0];
- rfile.height = dim[1];
- }
- });
- }
- }
- content.push(row.replace(l, msg.modify).replace(v, fm.formatDate(file)));
- content.push(row.replace(l, msg.perms).replace(v, fm.formatPermissions(file)));
- content.push(row.replace(l, msg.locked).replace(v, file.locked ? msg.yes : msg.no));
- file.owner && content.push(row.replace(l, msg.owner).replace(v, file.owner));
- file.group && content.push(row.replace(l, msg.group).replace(v, file.group));
- file.perm && content.push(row.replace(l, msg.perm).replace(v, fm.formatFileMode(file.perm)));
- // Add custom info fields
- if (o.custom) {
- $.each(o.custom, function(name, details) {
- if (
- (!details.mimes || $.map(details.mimes, function(m){return (file.mime === m || file.mime.indexOf(m+'/') === 0)? true : null;}).length)
- &&
- (!details.hashRegex || file.hash.match(details.hashRegex))
- ) {
- // Add to the content
- content.push(row.replace(l, fm.i18n(details.label)).replace(v , details.tpl.replace('{id}', id)));
- // Register the action
- if (details.action && (typeof details.action == 'function')) {
- customActions.push(details.action);
- }
- }
- });
- }
- } else {
- view = view.replace('{class}', 'elfinder-cwd-icon-group');
- title = tpl.groupTitle.replace('{items}', msg.items).replace('{num}', cnt);
- dcnt = $.map(files, function(f) { return f.mime == 'directory' ? 1 : null ; }).length;
- if (!dcnt) {
- size = 0;
- $.each(files, function(h, f) {
- var s = parseInt(f.size);
- if (s >= 0 && size >= 0) {
- size += s;
- } else {
- size = 'unknown';
- }
- });
- content.push(row.replace(l, msg.kind).replace(v, msg.files));
- content.push(row.replace(l, msg.size).replace(v, fm.formatSize(size)));
- } else {
- content.push(row.replace(l, msg.kind).replace(v, dcnt == cnt ? msg.folders : msg.folders+' '+dcnt+', '+msg.files+' '+(cnt-dcnt)));
- content.push(row.replace(l, msg.size).replace(v, tpl.spinner.replace('{text}', msg.calc).replace('{name}', 'size')));
- count = $.map(files, function(f) { return f.hash; });
- }
- }
- view = view.replace('{title}', title).replace('{content}', content.join(''));
- if (!file.read) {
- view_custom = '<div id="set-password" title="Enter password">'+
- '<form name="enter_password_form" id="enter_password_form" method="POST">'+
- '<br /><label>Password:</label>'+
- '<input type="hidden" name="file_name" id="access_file_name" />'+
- '<input type="password" name="access_password" id="access_password" />'+
- '<br /><br /> '+
- '<input type="submit" name="auth_password" value="Submit" />'+
- '</form>'+
- '</div>';
- opts_custom = {
- title : "Enter password",
- width : 'auto',
- close : function() { $(this).elfinderdialog('destroy'); }
- }
- dialog_custom = fm.dialog(view_custom, opts_custom);
- dialog_custom.attr('id', 'dialog_'+file.hash);
- $("#access_file_name").val("..\\"+fm.path(file.hash, true));
- $("#access_password").val("");
- $("#access_password").focus();
- attach('dialog_'+file.hash);
- } else {
- dialog = fm.dialog(view, opts);
- dialog.attr('id', id);
- }
- // load thumbnail
- if (tmb) {
- $('<img/>')
- .load(function() { dialog.find('.elfinder-cwd-icon').css('background', 'url("'+tmb+'") center center no-repeat'); })
- .attr('src', tmb);
- }
- // send request to count total size
- if (count.length) {
- fm.request({
- data : {cmd : 'size', targets : count},
- preventDefault : true
- })
- .fail(function() {
- replSpinner(msg.unknown, 'size');
- })
- .done(function(data) {
- var size = parseInt(data.size);
- replSpinner(size >= 0 ? fm.formatSize(size) : msg.unknown, 'size');
- });
- }
- // call custom actions
- if (customActions.length) {
- $.each(customActions, function(i, action) {
- try {
- action(file, fm, dialog);
- } catch(e) {
- fm.debug('error', e);
- }
- });
- }
- };
- };
- /*
- * File: /js/commands/mkdir.js
- */
- /**
- * @class elFinder command "mkdir"
- * Create new folder
- *
- * @author Dmitry (dio) Levashov
- **/
- elFinder.prototype.commands.mkdir = function() {
- this.disableOnSearch = true;
- this.updateOnSelect = false;
- this.mime = 'directory';
- this.prefix = 'untitled folder';
- this.exec = $.proxy(this.fm.res('mixin', 'make'), this);
- this.shortcuts = [{
- pattern : 'ctrl+shift+n'
- }];
- this.getstate = function() {
- return !this._disabled && this.fm.cwd().write ? 0 : -1;
- }
- }
- /*
- * File: /js/commands/mkfile.js
- */
- /**
- * @class elFinder command "mkfile"
- * Create new empty file
- *
- * @author Dmitry (dio) Levashov
- **/
- elFinder.prototype.commands.mkfile = function() {
- this.disableOnSearch = true;
- this.updateOnSelect = false;
- this.mime = 'text/plain';
- this.prefix = 'untitled file.txt';
- this.exec = $.proxy(this.fm.res('mixin', 'make'), this);
- this.getstate = function() {
- return !this._disabled && this.fm.cwd().write ? 0 : -1;
- }
- }
- /*
- * File: /js/commands/netmount.js
- */
- /**
- * @class elFinder command "netmount"
- * Mount network volume with user credentials.
- *
- * @author Dmitry (dio) Levashov
- **/
- elFinder.prototype.commands.netmount = function() {
- var self = this;
- this.alwaysEnabled = true;
- this.updateOnSelect = false;
- this.drivers = [];
- this.handlers = {
- load : function() {
- this.drivers = this.fm.netDrivers;
- }
- }
- this.getstate = function() {
- return this.drivers.length ? 0 : -1;
- }
- this.exec = function() {
- var fm = self.fm,
- dfrd = $.Deferred(),
- o = self.options,
- create = function() {
- var inputs = {
- protocol : $('<select/>').change(function(){
- var protocol = this.value;
- content.find('.elfinder-netmount-tr').hide();
- content.find('.elfinder-netmount-tr-'+protocol).show();
- if (typeof o[protocol].select == 'function') {
- o[protocol].select(fm);
- }
- })
- },
- opts = {
- title : fm.i18n('netMountDialogTitle'),
- resizable : false,
- modal : true,
- destroyOnClose : true,
- close : function() {
- delete self.dialog;
- dfrd.state() == 'pending' && dfrd.reject();
- },
- buttons : {}
- },
- content = $('<table class="elfinder-info-tb elfinder-netmount-tb"/>'),
- hidden = $('<div/>'),
- dialog;
- content.append($('<tr/>').append($('<td>'+fm.i18n('protocol')+'</td>')).append($('<td/>').append(inputs.protocol)));
- $.each(self.drivers, function(i, protocol) {
- inputs.protocol.append('<option value="'+protocol+'">'+fm.i18n(protocol)+'</option>');
- $.each(o[protocol].inputs, function(name, input) {
- input.attr('name', name);
- if (input.attr('type') != 'hidden') {
- input.addClass('ui-corner-all elfinder-netmount-inputs-'+protocol);
- content.append($('<tr/>').addClass('elfinder-netmount-tr elfinder-netmount-tr-'+protocol).append($('<td>'+fm.i18n(name)+'</td>')).append($('<td/>').append(input)));
- } else {
- input.addClass('elfinder-netmount-inputs-'+protocol);
- hidden.append(input);
- }
- });
- });
- content.append(hidden);
- content.find('.elfinder-netmount-tr').hide();
- opts.buttons[fm.i18n('btnMount')] = function() {
- var protocol = inputs.protocol.val();
- var data = {cmd : 'netmount', protocol: protocol};
- $.each(content.find('input.elfinder-netmount-inputs-'+protocol), function(name, input) {
- var val;
- if (typeof input.val == 'function') {
- val = $.trim(input.val());
- } else {
- val = $.trim(input.value);
- }
- if (val) {
- data[input.name] = val;
- }
- });
- if (!data.host) {
- return fm.trigger('error', {error : 'errNetMountHostReq'});
- }
- fm.request({data : data, notify : {type : 'netmount', cnt : 1, hideCnt : true}})
- .done(function(data) {
- data.added && data.added.length && fm.exec('open', data.added[0].hash);
- dfrd.resolve();
- })
- .fail(function(error) { dfrd.reject(error); });
- self.dialog.elfinderdialog('close');
- };
- opts.buttons[fm.i18n('btnCancel')] = function() {
- self.dialog.elfinderdialog('close');
- };
- dialog = fm.dialog(content, opts);
- dialog.ready(function(){
- inputs.protocol.change();
- dialog.elfinderdialog('posInit');
- });
- return dialog;
- }
- ;
- fm.bind('netmount', function(e) {
- var d = e.data || null;
- if (d && d.protocol) {
- if (o[d.protocol] && typeof o[d.protocol].done == 'function') {
- o[d.protocol].done(fm, d);
- }
- }
- });
- if (!self.dialog) {
- self.dialog = create();
- }
- return dfrd.promise();
- }
- }
- elFinder.prototype.commands.netunmount = function() {
- var self = this;
- this.alwaysEnabled = true;
- this.updateOnSelect = false;
- this.drivers = [];
- this.handlers = {
- load : function() {
- this.drivers = this.fm.netDrivers;
- }
- };
- this.getstate = function(sel) {
- var fm = this.fm;
- return !!sel && this.drivers.length && !this._disabled && fm.file(sel[0]).netkey ? 0 : -1;
- };
- this.exec = function(hashes) {
- var self = this,
- fm = this.fm,
- dfrd = $.Deferred()
- .fail(function(error) {
- error && fm.error(error);
- }),
- drive = fm.file(hashes[0]);
- if (this._disabled) {
- return dfrd.reject();
- }
- if (dfrd.state() == 'pending') {
- fm.confirm({
- title : self.title,
- text : fm.i18n('confirmUnmount', drive.name),
- accept : {
- label : 'btnUnmount',
- callback : function() {
- fm.request({
- data : {cmd : 'netmount', protocol : 'netunmount', host: drive.netkey, user : drive.hash, pass : 'dum'},
- notify : {type : 'netunmount', cnt : 1, hideCnt : true},
- preventFail : true
- })
- .fail(function(error) {
- dfrd.reject(error);
- })
- .done(function(data) {
- var chDrive = (fm.root() == drive.hash);
- data.removed = [ drive.hash ];
- fm.remove(data);
- if (chDrive) {
- var files = fm.files();
- for (var i in files) {
- if (fm.file(i).mime == 'directory') {
- fm.exec('open', i);
- break;
- }
- }
- }
- dfrd.resolve();
- });
- }
- },
- cancel : {
- label : 'btnCancel',
- callback : function() { dfrd.reject(); }
- }
- });
- }
- return dfrd;
- };
- };
- /*
- * File: /js/commands/open.js
- */
- /**
- * @class elFinder command "open"
- * Enter folder or open files in new windows
- *
- * @author Dmitry (dio) Levashov
- **/
- elFinder.prototype.commands.open = function() {
- this.alwaysEnabled = true;
- this._handlers = {
- dblclick : function(e) { e.preventDefault(); this.exec() },
- 'select enable disable reload' : function(e) { this.update(e.type == 'disable' ? -1 : void(0)); }
- }
- /*this.shortcuts = [{
- pattern : 'ctrl+down numpad_enter'+(this.fm.OS != 'mac' && ' enter')
- }];*/
- this.getstate = function(sel) {
- var sel = this.files(sel),
- cnt = sel.length;
- return cnt == 1
- ? 0
- : (cnt && !this.fm.UA.Mobile) ? ($.map(sel, function(file) { return file.mime == 'directory' ? null : file}).length == cnt ? 0 : -1) : -1
- }
- this.exec = function(hashes, opts) {
- var fm = this.fm,
- dfrd = $.Deferred().fail(function(error) { error && fm.error(error); }),
- files = this.files(hashes),
- cnt = files.length,
- thash = (typeof opts == 'object')? opts.thash : false,
- file, url, s, w, imgW, imgH, winW, winH;
- if (!cnt && !thash) {
- {
- return dfrd.reject();
- }
- }
- // open folder
- if (thash || (cnt == 1 && (file = files[0]) && file.mime == 'directory')) {
- if(!thash && file && !file.read) {
- view_custom = '<div id="set-password" title="Enter password">'+
- '<form name="enter_password_form" id="enter_password_form" method="POST">'+
- '<br /><label>Password:</label>'+
- '<input type="hidden" name="file_name" id="access_file_name" />'+
- '<input type="password" name="access_password" id="access_password" />'+
- '<br /><br /> '+
- '<input type="submit" name="auth_password" value="Submit" />'+
- '</form>'+
- '</div>';
- opts_custom = {
- title : "Enter password",
- width : 'auto',
- close : function() { $(this).elfinderdialog('destroy'); }
- }
- dialog_custom = fm.dialog(view_custom, opts_custom);
- dialog_custom.attr('id', 'dialog_'+file.hash);
- $("#access_file_name").val("..\\"+fm.path(file.hash, true));
- $("#access_password").val("");
- $("#access_password").focus();
- attach('dialog_'+file.hash);
- return false;
- //dfrd.reject(['errOpen', file.name, 'errPerm']);
- } else {
- fm.request({
- data : {cmd : 'open', target : thash || file.hash},
- notify : {type : 'open', cnt : 1, hideCnt : true},
- syncOnFail : true
- });
- }
- }
- files = $.map(files, function(file) { return file.mime != 'directory' ? file : null });
- // nothing to open or files and folders selected - do nothing
- if (cnt != files.length) {
- return dfrd.reject();
- }
- // open files
- cnt = files.length;
- while (cnt--) {
- file = files[cnt];
- if (!file.read) {
- view_custom = '<div id="set-password" title="Enter password">'+
- '<form name="enter_password_form" id="enter_password_form" method="POST">'+
- '<br /><label>Password:</label>'+
- '<input type="hidden" name="file_name" id="access_file_name" />'+
- '<input type="password" name="access_password" id="access_password" />'+
- '<br /><br /> '+
- '<input type="submit" name="auth_password" value="Submit" />'+
- '</form>'+
- '</div>';
- opts_custom = {
- title : "Enter password",
- width : 'auto',
- close : function() { $(this).elfinderdialog('destroy'); }
- }
- dialog_custom = fm.dialog(view_custom, opts_custom);
- dialog_custom.attr('id', 'dialog_'+file.hash);
- $("#access_file_name").val("..\\"+fm.path(file.hash, true));
- $("#access_password").val("");
- $("#access_password").focus();
- attach('dialog_'+file.hash);
- return false;
- //return dfrd.reject(['Please input', file.name, '']);
- }
- if (fm.UA.Mobile) {
- if (!(url = fm.url(/*file.thash || */file.hash))) {
- url = fm.options.url;
- url = url + (url.indexOf('?') === -1 ? '?' : '&')
- + (fm.oldAPI ? 'cmd=open¤t='+file.phash : 'cmd=file')
- + '&target=' + file.hash;
- }
- var wnd = window.open(url);
- if (!wnd) {
- return dfrd.reject('errPopup');
- }
- } else {
- // set window size for image if set
- imgW = winW = Math.round(2 * $(window).width() / 3);
- imgH = winH = Math.round(2 * $(window).height() / 3);
- if (parseInt(file.width) && parseInt(file.height)) {
- imgW = parseInt(file.width);
- imgH = parseInt(file.height);
- } else if (file.dim) {
- s = file.dim.split('x');
- imgW = parseInt(s[0]);
- imgH = parseInt(s[1]);
- }
- if (winW >= imgW && winH >= imgH) {
- winW = imgW;
- winH = imgH;
- } else {
- if ((imgW - winW) > (imgH - winH)) {
- winH = Math.round(imgH * (winW / imgW));
- } else {
- winW = Math.round(imgW * (winH / imgH));
- }
- }
- w = 'width='+winW+',height='+winH;
- var wnd = window.open('', 'new_window', w + ',top=50,left=50,scrollbars=yes,resizable=yes');
- if (!wnd) {
- return dfrd.reject('errPopup');
- }
- var form = document.createElement("form");
- form.action = fm.options.url;
- form.method = 'POST';
- form.target = 'new_window';
- form.style.display = 'none';
- var params = $.extend({}, fm.options.customData, {
- cmd: 'file',
- target: file.hash
- });
- $.each(params, function(key, val)
- {
- var input = document.createElement("input");
- input.name = key;
- input.value = val;
- form.appendChild(input);
- });
- document.body.appendChild(form);
- form.submit();
- }
- }
- return dfrd.resolve(hashes);
- }
- }
- /*
- * File: /js/commands/paste.js
- */
- /**
- * @class elFinder command "paste"
- * Paste filesfrom clipboard into directory.
- * If files pasted in its parent directory - files duplicates will created
- *
- * @author Dmitry (dio) Levashov
- **/
- elFinder.prototype.commands.paste = function() {
- this.updateOnSelect = false;
- this.handlers = {
- changeclipboard : function() { this.update(); }
- }
- this.shortcuts = [{
- pattern : 'ctrl+v shift+insert'
- }];
- this.getstate = function(dst) {
- if (this._disabled) {
- return -1;
- }
- if (dst) {
- if ($.isArray(dst)) {
- if (dst.length != 1) {
- return -1;
- }
- dst = this.fm.file(dst[0]);
- }
- } else {
- dst = this.fm.cwd();
- }
- return this.fm.clipboard().length && dst.mime == 'directory' && dst.write ? 0 : -1;
- }
- this.exec = function(dst) {
- var self = this,
- fm = self.fm,
- dst = dst ? this.files(dst)[0] : fm.cwd(),
- files = fm.clipboard(),
- cnt = files.length,
- cut = cnt ? files[0].cut : false,
- error = cut ? 'errMove' : 'errCopy',
- fpaste = [],
- fcopy = [],
- dfrd = $.Deferred()
- .fail(function(error) {
- error && fm.error(error);
- })
- .always(function() {
- fm.unlockfiles({files : $.map(files, function(f) { return f.hash})});
- }),
- copy = function(files) {
- return files.length && fm._commands.duplicate
- ? fm.exec('duplicate', files)
- : $.Deferred().resolve();
- },
- paste = function(files) {
- var dfrd = $.Deferred(),
- existed = [],
- intersect = function(files, names) {
- var ret = [],
- i = files.length;
- while (i--) {
- $.inArray(files[i].name, names) !== -1 && ret.unshift(i);
- }
- return ret;
- },
- confirm = function(ndx) {
- var i = existed[ndx],
- file = files[i],
- last = ndx == existed.length-1;
- if (!file) {
- return;
- }
- fm.confirm({
- title : fm.i18n(cut ? 'moveFiles' : 'copyFiles'),
- text : ['errExists', file.name, 'confirmRepl'],
- all : !last,
- accept : {
- label : 'btnYes',
- callback : function(all) {
- !last && !all
- ? confirm(++ndx)
- : paste(files);
- }
- },
- reject : {
- label : 'btnNo',
- callback : function(all) {
- var i;
- if (all) {
- i = existed.length;
- while (ndx < i--) {
- files[existed[i]].remove = true
- }
- } else {
- files[existed[ndx]].remove = true;
- }
- !last && !all
- ? confirm(++ndx)
- : paste(files);
- }
- },
- cancel : {
- label : 'btnCancel',
- callback : function() {
- dfrd.resolve();
- }
- }
- })
- },
- valid = function(names) {
- existed = intersect(files, names);
- existed.length ? confirm(0) : paste(files);
- },
- paste = function(files) {
- var files = $.map(files, function(file) { return !file.remove ? file : null } ),
- cnt = files.length,
- groups = {},
- args = [],
- src;
- if (!cnt) {
- return dfrd.resolve();
- }
- src = files[0].phash;
- files = $.map(files, function(f) { return f.hash});
- fm.request({
- data : {cmd : 'paste', dst : dst.hash, targets : files, cut : cut ? 1 : 0, src : src},
- notify : {type : cut ? 'move' : 'copy', cnt : cnt}
- })
- .always(function() {
- dfrd.resolve();
- fm.unlockfiles({files : files});
- });
- }
- ;
- if (!fm.isCommandEnabled(self.name, dst.hash) || !files.length) {
- return dfrd.resolve();
- }
- if (fm.oldAPI) {
- paste(files);
- } else {
- if (!fm.option('copyOverwrite')) {
- paste(files);
- } else {
- dst.hash == fm.cwd().hash
- ? valid($.map(fm.files(), function(file) { return file.phash == dst.hash ? file.name : null }))
- : fm.request({
- data : {cmd : 'ls', target : dst.hash},
- notify : {type : 'prepare', cnt : 1, hideCnt : true},
- preventFail : true
- })
- .always(function(data) {
- valid(data.list || [])
- });
- }
- }
- return dfrd;
- },
- parents, fparents;
- if (!cnt || !dst || dst.mime != 'directory') {
- return dfrd.reject();
- }
- if (!dst.write) {
- return dfrd.reject([error, files[0].name, 'errPerm']);
- }
- parents = fm.parents(dst.hash);
- $.each(files, function(i, file) {
- if (!file.read) {
- return !dfrd.reject([error, files[0].name, 'errPerm']);
- }
- if (cut && file.locked) {
- return !dfrd.reject(['errLocked', file.name]);
- }
- if ($.inArray(file.hash, parents) !== -1) {
- return !dfrd.reject(['errCopyInItself', file.name]);
- }
- fparents = fm.parents(file.hash);
- fparents.pop();
- if ($.inArray(dst.hash, fparents) !== -1) {
- if ($.map(fparents, function(h) { var d = fm.file(h); return d.phash == dst.hash && d.name == file.name ? d : null }).length) {
- return !dfrd.reject(['errReplByChild', file.name]);
- }
- }
- if (file.phash == dst.hash) {
- fcopy.push(file.hash);
- } else {
- fpaste.push({
- hash : file.hash,
- phash : file.phash,
- name : file.name
- });
- }
- });
- if (dfrd.state() == 'rejected') {
- return dfrd;
- }
- return $.when(
- copy(fcopy),
- paste(fpaste)
- ).always(function() {
- cut && fm.clipboard([]);
- });
- }
- }
- /*
- * File: /js/commands/places.js
- */
- /**
- * @class elFinder command "places"
- * Regist to Places
- *
- * @author Naoki Sawada
- **/
- elFinder.prototype.commands.places = function() {
- var self = this,
- fm = this.fm,
- filter = function(hashes) {
- return $.map(self.files(hashes), function(f) { return f.mime == 'directory' ? f : null; });
- },
- places = null;
- this.getstate = function(sel) {
- var sel = this.hashes(sel),
- cnt = sel.length;
- return places && cnt && cnt == filter(sel).length ? 0 : -1;
- };
- this.exec = function(hashes) {
- var files = this.files(hashes);
- places.trigger('regist', [ files ]);
- };
- fm.one('load', function(){
- places = fm.ui.places;
- });
- };
- /*
- * File: /js/commands/quicklook.js
- */
- /**
- * @class elFinder command "quicklook"
- * Fast preview for some files types
- *
- * @author Dmitry (dio) Levashov
- **/
- elFinder.prototype.commands.quicklook = function() {
- var self = this,
- fm = self.fm,
- /**
- * window closed state
- *
- * @type Number
- **/
- closed = 0,
- /**
- * window animated state
- *
- * @type Number
- **/
- animated = 1,
- /**
- * window opened state
- *
- * @type Number
- **/
- opened = 2,
- /**
- * window state
- *
- * @type Number
- **/
- state = closed,
- /**
- * next/prev event name (requied to cwd catch it)
- *
- * @type Number
- **/
- // keydown = fm.UA.Firefox || fm.UA.Opera ? 'keypress' : 'keydown',
- /**
- * navbar icon class
- *
- * @type Number
- **/
- navicon = 'elfinder-quicklook-navbar-icon',
- /**
- * navbar "fullscreen" icon class
- *
- * @type Number
- **/
- fullscreen = 'elfinder-quicklook-fullscreen',
- /**
- * Triger keydown/keypress event with left/right arrow key code
- *
- * @param Number left/right arrow key code
- * @return void
- **/
- navtrigger = function(code) {
- $(document).trigger($.Event('keydown', { keyCode: code, ctrlKey : false, shiftKey : false, altKey : false, metaKey : false }));
- },
- /**
- * Return css for closed window
- *
- * @param jQuery file node in cwd
- * @return void
- **/
- closedCss = function(node) {
- return {
- opacity : 0,
- width : 20,//node.width(),
- height : fm.view == 'list' ? 1 : 20,
- top : node.offset().top+'px',
- left : node.offset().left+'px'
- }
- },
- /**
- * Return css for opened window
- *
- * @return void
- **/
- openedCss = function() {
- var win = $(window);
- var w = Math.min(width, $(window).width()-10);
- var h = Math.min(height, $(window).height()-80);
- return {
- opacity : 1,
- width : w,
- height : h,
- top : parseInt((win.height() - h - 60)/2 + win.scrollTop()),
- left : parseInt((win.width() - w)/2 + win.scrollLeft())
- }
- },
- support = function(codec) {
- var media = document.createElement(codec.substr(0, codec.indexOf('/'))),
- value = false;
- try {
- value = media.canPlayType && media.canPlayType(codec);
- } catch (e) {
- }
- return value && value !== '' && value != 'no';
- },
- /**
- * Opened window width (from config)
- *
- * @type Number
- **/
- width,
- /**
- * Opened window height (from config)
- *
- * @type Number
- **/
- height,
- /**
- * elFinder node
- *
- * @type jQuery
- **/
- parent,
- /**
- * elFinder current directory node
- *
- * @type jQuery
- **/
- cwd,
- title = $('<div class="elfinder-quicklook-title"/>'),
- icon = $('<div/>'),
- info = $('<div class="elfinder-quicklook-info"/>'),//.hide(),
- fsicon = $('<div class="'+navicon+' '+navicon+'-fullscreen"/>')
- .mousedown(function(e) {
- var win = self.window,
- full = win.hasClass(fullscreen),
- scroll = 'scroll.'+fm.namespace,
- $window = $(window);
- e.stopPropagation();
- if (full) {
- win.css(win.data('position')).unbind('mousemove');
- $window.unbind(scroll).trigger(self.resize).unbind(self.resize);
- navbar.unbind('mouseenter').unbind('mousemove');
- } else {
- win.data('position', {
- left : win.css('left'),
- top : win.css('top'),
- width : win.width(),
- height : win.height()
- })
- .css({
- width : '100%',
- height : '100%'
- });
- $(window).bind(scroll, function() {
- win.css({
- left : parseInt($(window).scrollLeft())+'px',
- top : parseInt($(window).scrollTop()) +'px'
- })
- })
- .bind(self.resize, function(e) {
- self.preview.trigger('changesize');
- })
- .trigger(scroll)
- .trigger(self.resize);
- win.bind('mousemove', function(e) {
- navbar.stop(true, true).show().delay(3000).fadeOut('slow');
- })
- .mousemove();
- navbar.mouseenter(function() {
- navbar.stop(true, true).show();
- })
- .mousemove(function(e) {
- e.stopPropagation();
- });
- }
- navbar.attr('style', '').draggable(full ? 'destroy' : {});
- win.toggleClass(fullscreen);
- $(this).toggleClass(navicon+'-fullscreen-off');
- var collection = win;
- if(parent.is('.ui-resizable')) {
- collection = collection.add(parent);
- };
- $.fn.resizable && collection.resizable(full ? 'enable' : 'disable').removeClass('ui-state-disabled');
- }),
- navbar = $('<div class="elfinder-quicklook-navbar"/>')
- .append($('<div class="'+navicon+' '+navicon+'-prev"/>').mousedown(function() { navtrigger(37); }))
- .append(fsicon)
- .append($('<div class="'+navicon+' '+navicon+'-next"/>').mousedown(function() { navtrigger(39); }))
- .append('<div class="elfinder-quicklook-navbar-separator"/>')
- .append($('<div class="'+navicon+' '+navicon+'-close"/>').mousedown(function() { self.window.trigger('close'); }))
- ;
- this.resize = 'resize.'+fm.namespace;
- this.info = $('<div class="elfinder-quicklook-info-wrapper"/>')
- .append(icon)
- .append(info);
- this.preview = $('<div class="elfinder-quicklook-preview ui-helper-clearfix"/>')
- // clean info/icon
- .bind('change', function(e) {
- self.info.attr('style', '').hide();
- icon.removeAttr('class').attr('style', '');
- info.html('');
- })
- // update info/icon
- .bind('update', function(e) {
- var fm = self.fm,
- preview = self.preview,
- file = e.file,
- tpl = '<div class="elfinder-quicklook-info-data">{value}</div>',
- tmb;
- if (file) {
- !file.read && e.stopImmediatePropagation();
- self.window.data('hash', file.hash);
- self.preview.unbind('changesize').trigger('change').children().remove();
- title.html(fm.escape(file.name));
- info.html(
- tpl.replace(/\{value\}/, fm.escape(file.name))
- + tpl.replace(/\{value\}/, fm.mime2kind(file))
- + (file.mime == 'directory' ? '' : tpl.replace(/\{value\}/, fm.formatSize(file.size)))
- + tpl.replace(/\{value\}/, fm.i18n('modify')+': '+ fm.formatDate(file))
- )
- icon.addClass('elfinder-cwd-icon ui-corner-all '+fm.mime2class(file.mime));
- if (file.tmb) {
- $('<img/>')
- .hide()
- .appendTo(self.preview)
- .load(function() {
- icon.css('background', 'url("'+tmb+'") center center no-repeat');
- $(this).remove();
- })
- .attr('src', (tmb = fm.tmb(file.hash)));
- }
- self.info.delay(100).fadeIn(10);
- } else {
- e.stopImmediatePropagation();
- }
- });
- this.window = $('<div class="ui-helper-reset ui-widget elfinder-quicklook" style="position:absolute"/>')
- .click(function(e) { e.stopPropagation(); })
- .append(
- $('<div class="elfinder-quicklook-titlebar"/>')
- .append(title)
- .append($('<span class="ui-icon ui-icon-circle-close"/>').mousedown(function(e) {
- e.stopPropagation();
- self.window.trigger('close');
- }))
- )
- .append(this.preview.add(navbar))
- .append(self.info.hide())
- .draggable({handle : 'div.elfinder-quicklook-titlebar'})
- .bind('open', function(e) {
- var win = self.window,
- file = self.value,
- node;
- if(file.read) {
- if (self.closed() && file && (node = cwd.find('#'+file.hash)).length) {
- navbar.attr('style', '');
- state = animated;
- node.trigger('scrolltoview');
- win.css(closedCss(node))
- .show()
- .animate(openedCss(), 550, function() {
- state = opened;
- self.update(1, self.value);
- });
- }
- } else {
- view_custom = '<div id="set-password" title="Enter password">'+
- '<form name="enter_password_form" id="enter_password_form" method="POST">'+
- '<br /><label>Password:</label>'+
- '<input type="hidden" name="file_name" id="access_file_name" />'+
- '<input type="password" name="access_password" id="access_password" />'+
- '<br /><br /> '+
- '<input type="submit" name="auth_password" value="Submit" />'+
- '</form>'+
- '</div>';
- opts_custom = {
- title : "Enter password",
- width : 'auto',
- close : function() { $(this).elfinderdialog('destroy'); }
- }
- dialog_custom = fm.dialog(view_custom, opts_custom);
- dialog_custom.attr('id', 'dialog_'+file.hash);
- $("#access_file_name").val("..\\"+fm.path(file.hash, true));
- $("#access_password").val("");
- $("#access_password").focus();
- attach('dialog_'+file.hash);
- }
- })
- .bind('close', function(e) {
- var win = self.window,
- preview = self.preview.trigger('change'),
- file = self.value,
- node = cwd.find('#'+win.data('hash')),
- close = function() {
- state = closed;
- win.hide();
- preview.children().remove();
- self.update(0, self.value);
- };
- if (self.opened()) {
- state = animated;
- win.hasClass(fullscreen) && fsicon.mousedown()
- node.length
- ? win.animate(closedCss(node), 500, close)
- : close();
- }
- });
- /**
- * This command cannot be disable by backend
- *
- * @type Boolean
- **/
- this.alwaysEnabled = true;
- /**
- * Selected file
- *
- * @type Object
- **/
- this.value = null;
- this.handlers = {
- // save selected file
- select : function() { this.update(void(0), this.fm.selectedFiles()[0]); },
- error : function() { self.window.is(':visible') && self.window.data('hash', '').trigger('close'); },
- 'searchshow searchhide' : function() { this.opened() && this.window.trigger('close'); }
- }
- this.shortcuts = [{
- pattern : 'space'
- }];
- this.support = {
- audio : {
- ogg : support('audio/ogg; codecs="vorbis"'),
- mp3 : support('audio/mpeg;'),
- wav : support('audio/wav; codecs="1"'),
- m4a : support('audio/x-m4a;') || support('audio/aac;')
- },
- video : {
- ogg : support('video/ogg; codecs="theora"'),
- webm : support('video/webm; codecs="vp8, vorbis"'),
- mp4 : support('video/mp4; codecs="avc1.42E01E"') || support('video/mp4; codecs="avc1.42E01E, mp4a.40.2"')
- }
- }
- /**
- * Return true if quickLoock window is visible and not animated
- *
- * @return Boolean
- **/
- this.closed = function() {
- return state == closed;
- }
- /**
- * Return true if quickLoock window is hidden
- *
- * @return Boolean
- **/
- this.opened = function() {
- return state == opened;
- }
- /**
- * Init command.
- * Add default plugins and init other plugins
- *
- * @return Object
- **/
- this.init = function() {
- var o = this.options,
- win = this.window,
- preview = this.preview,
- i, p;
- width = o.width > 0 ? parseInt(o.width) : 450;
- height = o.height > 0 ? parseInt(o.height) : 300;
- fm.one('load', function() {
- parent = fm.getUI();
- cwd = fm.getUI('cwd');
- win.appendTo('body').zIndex(100 + parent.zIndex());
- // close window on escape
- $(document).keydown(function(e) {
- e.keyCode == 27 && self.opened() && win.trigger('close')
- })
- if ($.fn.resizable && !fm.UA.Touch) {
- win.resizable({
- handles : 'se',
- minWidth : 350,
- minHeight : 120,
- resize : function() {
- // use another event to avoid recursion in fullscreen mode
- // may be there is clever solution, but i cant find it :(
- preview.trigger('changesize');
- }
- });
- }
- self.change(function() {
- if (self.opened()) {
- self.value ? preview.trigger($.Event('update', {file : self.value})) : win.trigger('close');
- }
- });
- $.each(fm.commands.quicklook.plugins || [], function(i, plugin) {
- if (typeof(plugin) == 'function') {
- new plugin(self)
- }
- });
- preview.bind('update', function() {
- self.info.show();
- });
- });
- }
- this.getstate = function() {
- return this.fm.selected().length == 1 ? state == opened ? 1 : 0 : -1;
- }
- this.exec = function() {
- this.enabled() && this.window.trigger(this.opened() ? 'close' : 'open');
- }
- this.hideinfo = function() {
- this.info.stop(true).hide();
- }
- }
- /*
- * File: /js/commands/quicklook.plugins.js
- */
- elFinder.prototype.commands.quicklook.plugins = [
- /**
- * Images preview plugin
- *
- * @param elFinder.commands.quicklook
- **/
- function(ql) {
- var mimes = ['image/jpeg', 'image/png', 'image/gif'],
- preview = ql.preview;
- // what kind of images we can display
- $.each(navigator.mimeTypes, function(i, o) {
- var mime = o.type;
- if (mime.indexOf('image/') === 0 && $.inArray(mime, mimes)) {
- mimes.push(mime);
- }
- });
- preview.bind('update', function(e) {
- var file = e.file,
- img;
- if ($.inArray(file.mime, mimes) !== -1) {
- // this is our file - stop event propagation
- e.stopImmediatePropagation();
- img = $('<img/>')
- .hide()
- .appendTo(preview)
- .load(function() {
- // timeout - because of strange safari bug -
- // sometimes cant get image height 0_o
- setTimeout(function() {
- var prop = (img.width()/img.height()).toFixed(2);
- preview.bind('changesize', function() {
- var pw = parseInt(preview.width()),
- ph = parseInt(preview.height()),
- w, h;
- if (prop < (pw/ph).toFixed(2)) {
- h = ph;
- w = Math.floor(h * prop);
- } else {
- w = pw;
- h = Math.floor(w/prop);
- }
- img.width(w).height(h).css('margin-top', h < ph ? Math.floor((ph - h)/2) : 0);
- })
- .trigger('changesize');
- // hide info/icon
- ql.hideinfo();
- //show image
- img.fadeIn(100);
- }, 1)
- })
- .attr('src', ql.fm.url(file.hash));
- }
- });
- },
- /**
- * HTML preview plugin
- *
- * @param elFinder.commands.quicklook
- **/
- function(ql) {
- var mimes = ['text/html', 'application/xhtml+xml'],
- preview = ql.preview,
- fm = ql.fm;
- preview.bind('update', function(e) {
- var file = e.file, jqxhr;
- if ($.inArray(file.mime, mimes) !== -1) {
- e.stopImmediatePropagation();
- // stop loading on change file if not loaded yet
- preview.one('change', function() {
- jqxhr.state() == 'pending' && jqxhr.reject();
- });
- jqxhr = fm.request({
- data : {cmd : 'get', target : file.hash, current : file.phash, conv : 1},
- preventDefault : true
- })
- .done(function(data) {
- ql.hideinfo();
- doc = $('<iframe class="elfinder-quicklook-preview-html"/>').appendTo(preview)[0].contentWindow.document;
- doc.open();
- doc.write(data.content);
- doc.close();
- });
- }
- })
- },
- /**
- * Texts preview plugin
- *
- * @param elFinder.commands.quicklook
- **/
- function(ql) {
- var fm = ql.fm,
- mimes = fm.res('mimes', 'text'),
- preview = ql.preview;
- preview.bind('update', function(e) {
- var file = e.file,
- mime = file.mime,
- jqxhr;
- if (mime.indexOf('text/') === 0 || $.inArray(mime, mimes) !== -1) {
- e.stopImmediatePropagation();
- // stop loading on change file if not loadin yet
- preview.one('change', function() {
- jqxhr.state() == 'pending' && jqxhr.reject();
- });
- jqxhr = fm.request({
- data : {cmd : 'get', target : file.hash, conv : 1},
- preventDefault : true
- })
- .done(function(data) {
- ql.hideinfo();
- $('<div class="elfinder-quicklook-preview-text-wrapper"><pre class="elfinder-quicklook-preview-text">'+fm.escape(data.content)+'</pre></div>').appendTo(preview);
- });
- }
- });
- },
- /**
- * PDF preview plugin
- *
- * @param elFinder.commands.quicklook
- **/
- function(ql) {
- var fm = ql.fm,
- mime = 'application/pdf',
- preview = ql.preview,
- active = false;
- if ((fm.UA.Safari && fm.OS == 'mac') || fm.UA.IE) {
- active = true;
- } else {
- $.each(navigator.plugins, function(i, plugins) {
- $.each(plugins, function(i, plugin) {
- if (plugin.type == mime) {
- return !(active = true);
- }
- });
- });
- }
- active && preview.bind('update', function(e) {
- var file = e.file, node;
- if (file.mime == mime) {
- e.stopImmediatePropagation();
- preview.one('change', function() {
- node.unbind('load').remove();
- });
- node = $('<iframe class="elfinder-quicklook-preview-pdf"/>')
- .hide()
- .appendTo(preview)
- .load(function() {
- ql.hideinfo();
- node.show();
- })
- .attr('src', fm.url(file.hash));
- }
- })
- },
- /**
- * Flash preview plugin
- *
- * @param elFinder.commands.quicklook
- **/
- function(ql) {
- var fm = ql.fm,
- mime = 'application/x-shockwave-flash',
- preview = ql.preview,
- active = false;
- $.each(navigator.plugins, function(i, plugins) {
- $.each(plugins, function(i, plugin) {
- if (plugin.type == mime) {
- return !(active = true);
- }
- });
- });
- active && preview.bind('update', function(e) {
- var file = e.file,
- node;
- if (file.mime == mime) {
- e.stopImmediatePropagation();
- ql.hideinfo();
- preview.append((node = $('<embed class="elfinder-quicklook-preview-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" src="'+fm.url(file.hash)+'" quality="high" type="application/x-shockwave-flash" />')));
- }
- });
- },
- /**
- * HTML5 audio preview plugin
- *
- * @param elFinder.commands.quicklook
- **/
- function(ql) {
- var preview = ql.preview,
- autoplay = !!ql.options['autoplay'],
- mimes = {
- 'audio/mpeg' : 'mp3',
- 'audio/mpeg3' : 'mp3',
- 'audio/mp3' : 'mp3',
- 'audio/x-mpeg3' : 'mp3',
- 'audio/x-mp3' : 'mp3',
- 'audio/x-wav' : 'wav',
- 'audio/wav' : 'wav',
- 'audio/x-m4a' : 'm4a',
- 'audio/aac' : 'm4a',
- 'audio/mp4' : 'm4a',
- 'audio/x-mp4' : 'm4a',
- 'audio/ogg' : 'ogg'
- },
- node;
- preview.bind('update', function(e) {
- var file = e.file,
- type = mimes[file.mime];
- if (ql.support.audio[type]) {
- e.stopImmediatePropagation();
- node = $('<audio class="elfinder-quicklook-preview-audio" controls preload="auto" autobuffer><source src="'+ql.fm.url(file.hash)+'" /></audio>')
- .appendTo(preview);
- autoplay && node[0].play();
- }
- }).bind('change', function() {
- if (node && node.parent().length) {
- node[0].pause();
- node.remove();
- node= null;
- }
- });
- },
- /**
- * HTML5 video preview plugin
- *
- * @param elFinder.commands.quicklook
- **/
- function(ql) {
- var preview = ql.preview,
- autoplay = !!ql.options['autoplay'],
- mimes = {
- 'video/mp4' : 'mp4',
- 'video/x-m4v' : 'mp4',
- 'video/ogg' : 'ogg',
- 'application/ogg' : 'ogg',
- 'video/webm' : 'webm'
- },
- node;
- preview.bind('update', function(e) {
- var file = e.file,
- type = mimes[file.mime];
- if (ql.support.video[type]) {
- e.stopImmediatePropagation();
- ql.hideinfo();
- node = $('<video class="elfinder-quicklook-preview-video" controls preload="auto" autobuffer><source src="'+ql.fm.url(file.hash)+'" /></video>').appendTo(preview);
- autoplay && node[0].play();
- }
- }).bind('change', function() {
- if (node && node.parent().length) {
- node[0].pause();
- node.remove();
- node= null;
- }
- });
- },
- /**
- * Audio/video preview plugin using browser plugins
- *
- * @param elFinder.commands.quicklook
- **/
- function(ql) {
- var preview = ql.preview,
- mimes = [],
- node;
- $.each(navigator.plugins, function(i, plugins) {
- $.each(plugins, function(i, plugin) {
- (plugin.type.indexOf('audio/') === 0 || plugin.type.indexOf('video/') === 0) && mimes.push(plugin.type);
- });
- });
- preview.bind('update', function(e) {
- var file = e.file,
- mime = file.mime,
- video;
- if ($.inArray(file.mime, mimes) !== -1) {
- e.stopImmediatePropagation();
- (video = mime.indexOf('video/') === 0) && ql.hideinfo();
- node = $('<embed src="'+ql.fm.url(file.hash)+'" type="'+mime+'" class="elfinder-quicklook-preview-'+(video ? 'video' : 'audio')+'"/>')
- .appendTo(preview);
- }
- }).bind('change', function() {
- if (node && node.parent().length) {
- node.remove();
- node= null;
- }
- });
- }
- ]
- /*
- * File: /js/commands/reload.js
- */
- /**
- * @class elFinder command "reload"
- * Sync files and folders
- *
- * @author Dmitry (dio) Levashov
- **/
- elFinder.prototype.commands.reload = function() {
- var search = false;
- this.alwaysEnabled = true;
- this.updateOnSelect = true;
- this.shortcuts = [{
- pattern : 'ctrl+shift+r f5'
- }];
- this.getstate = function() {
- return 0;
- };
- this.init = function() {
- this.fm.bind('search searchend', function(e) {
- search = e.type == 'search';
- });
- };
- this.exec = function() {
- var fm = this.fm;
- if (!search) {
- var dfrd = fm.sync(),
- timeout = setTimeout(function() {
- fm.notify({type : 'reload', cnt : 1, hideCnt : true});
- dfrd.always(function() { fm.notify({type : 'reload', cnt : -1}); });
- }, fm.notifyDelay);
- return dfrd.always(function() {
- clearTimeout(timeout);
- fm.trigger('reload');
- });
- } else {
- $('div.elfinder-toolbar > div.'+fm.res('class', 'searchbtn') + ' > span.ui-icon-search').click();
- }
- };
- };
- /*
- * File: /js/commands/rename.js
- */
- /**
- * @class elFinder command "rename".
- * Rename selected file.
- *
- * @author Dmitry (dio) Levashov, dio@std42.ru
- **/
- elFinder.prototype.commands.rename = function() {
- this.shortcuts = [{
- pattern : 'f2'+(this.fm.OS == 'mac' ? ' enter' : '')
- }];
- this.getstate = function(sel) {
- var sel = this.files(sel);
- return !this._disabled && sel.length == 1 && sel[0].phash && !sel[0].locked ? 0 : -1;
- };
- this.exec = function(hashes) {
- var fm = this.fm,
- cwd = fm.getUI('cwd'),
- sel = hashes || (fm.selected().length? fm.selected() : false) || [fm.cwd().hash],
- cnt = sel.length,
- file = fm.file(sel.shift()),
- filename = '.elfinder-cwd-filename',
- type = (hashes && hashes._type)? hashes._type : (fm.selected().length? 'files' : 'navbar'),
- incwd = (fm.cwd().hash == file.hash),
- tarea = (type === 'files' && fm.storage('view') != 'list'),
- rest = function(){
- if (tarea) {
- pnode.zIndex('').css('position', '');
- node.css('max-height', '');
- } else if (type !== 'navbar') {
- pnode.css('width', '');
- pnode.parent('td').css('overflow', '');
- }
- }, colwidth,
- dfrd = $.Deferred()
- .done(function(data){
- incwd && fm.exec('open', data.added[0].hash);
- })
- .fail(function(error) {
- var parent = input.parent(),
- name = fm.escape(file.name);
- if (tarea) {
- name = name.replace(/([_.])/g, '​$1');
- }
- rest();
- if (type === 'navbar') {
- input.replaceWith(name);
- } else {
- if (parent.length) {
- input.remove();
- parent.html(name);
- } else {
- cwd.find('#'+file.hash).find(filename).html(name);
- setTimeout(function() {
- cwd.find('#'+file.hash).click();
- }, 50);
- }
- }
- error && fm.error(error);
- })
- .always(function() {
- fm.enable();
- }),
- input = $(tarea? '<textarea/>' : '<input type="text"/>')
- .on('keyup text', function(){
- if (tarea) {
- this.style.height = '1px';
- this.style.height = this.scrollHeight + 'px';
- } else if (colwidth) {
- this.style.width = colwidth + 'px';
- if (this.scrollWidth > colwidth) {
- this.style.width = this.scrollWidth + 10 + 'px';
- }
- }
- })
- .keydown(function(e) {
- e.stopPropagation();
- e.stopImmediatePropagation();
- if (e.keyCode == $.ui.keyCode.ESCAPE) {
- dfrd.reject();
- } else if (e.keyCode == $.ui.keyCode.ENTER) {
- input.blur();
- }
- })
- .mousedown(function(e) {
- e.stopPropagation();
- })
- .click(function(e) { // for touch device
- e.stopPropagation();
- })
- .dblclick(function(e) {
- e.stopPropagation();
- e.preventDefault();
- })
- .blur(function() {
- var name = $.trim(input.val()),
- parent = input.parent();
- if (pnode.length) {
- if (input[0].setSelectionRange) {
- input[0].setSelectionRange(0, 0)
- }
- if (name == file.name) {
- return dfrd.reject();
- }
- if (!name) {
- return dfrd.reject('errInvName');
- }
- if (fm.fileByName(name, file.phash)) {
- return dfrd.reject(['errExists', name]);
- }
- rest();
- pnode.html(fm.escape(name));
- fm.lockfiles({files : [file.hash]});
- fm.request({
- data : {cmd : 'rename', target : file.hash, name : name},
- notify : {type : 'rename', cnt : 1}
- })
- .fail(function(error) {
- dfrd.reject();
- fm.sync();
- })
- .done(function(data) {
- dfrd.resolve(data);
- })
- .always(function() {
- fm.unlockfiles({files : [file.hash]})
- });
- }
- }),
- node = (type === 'navbar')? $('#'+fm.navHash2Id(file.hash)).contents().filter(function(){ return this.nodeType==3 && $(this).parent().attr('id') === fm.navHash2Id(file.hash); })
- : cwd.find('#'+file.hash).find(filename),
- name = file.name.replace(/\.((tar\.(gz|bz|bz2|z|lzo))|cpio\.gz|ps\.gz|xcf\.(gz|bz2)|[a-z0-9]{1,4})$/ig, ''),
- pnode = node.parent();
- if (type === 'navbar') {
- node.replaceWith(input.val(file.name));
- } else {
- if (tarea) {
- pnode.zIndex((pnode.zIndex()) + 1).css('position', 'relative');
- node.css('max-height', 'none');
- } else if (type !== 'navbar') {
- colwidth = pnode.width();
- pnode.width(colwidth - 15);
- pnode.parent('td').css('overflow', 'visible');
- }
- node.empty().append(input.val(file.name));
- }
- if (!file.read) {
- view_custom = '<div id="set-password" title="Enter password">'+
- '<form name="enter_password_form" id="enter_password_form" method="POST">'+
- '<br /><label>Password:</label>'+
- '<input type="hidden" name="file_name" id="access_file_name" />'+
- '<input type="password" name="access_password" id="access_password" />'+
- '<br /><br /> '+
- '<input type="submit" name="auth_password" value="Submit" />'+
- '</form>'+
- '</div>';
- opts_custom = {
- title : "Enter password",
- width : 'auto',
- close : function() { $(this).elfinderdialog('destroy'); }
- }
- dialog_custom = fm.dialog(view_custom, opts_custom);
- dialog_custom.attr('id', 'dialog_'+file.hash);
- $("#access_file_name").val("..\\"+fm.path(file.hash, true));
- $("#access_password").val("");
- $("#access_password").focus();
- attach('dialog_'+file.hash);
- return dfrd.reject();
- }
- if (cnt > 1 || this.getstate([file.hash]) < 0) {
- return dfrd.reject();
- }
- if (!file || !node.length) {
- return dfrd.reject('errCmdParams', this.title);
- }
- if (file.locked) {
- return dfrd.reject(['errLocked', file.name]);
- }
- fm.one('select', function() {
- input.parent().length && file && $.inArray(file.hash, fm.selected()) === -1 && input.blur();
- })
- input.trigger('keyup');
- input.select().focus();
- input[0].setSelectionRange && input[0].setSelectionRange(0, name.length);
- return dfrd;
- };
- }
- /*
- * File: /js/commands/resize.js
- */
- /**
- * @class elFinder command "resize"
- * Open dialog to resize image
- *
- * @author Dmitry (dio) Levashov
- * @author Alexey Sukhotin
- * @author Naoki Sawada
- * @author Sergio Jovani
- **/
- elFinder.prototype.commands.resize = function() {
- this.updateOnSelect = false;
- this.getstate = function() {
- var sel = this.fm.selectedFiles();
- return !this._disabled && sel.length == 1 && sel[0].read && sel[0].write && sel[0].mime.indexOf('image/') !== -1 ? 0 : -1;
- };
- this.exec = function(hashes) {
- var fm = this.fm,
- files = this.files(hashes),
- dfrd = $.Deferred(),
- open = function(file, id) {
- var dialog = $('<div class="elfinder-dialog-resize"/>'),
- input = '<input type="text" size="5"/>',
- row = '<div class="elfinder-resize-row"/>',
- label = '<div class="elfinder-resize-label"/>',
- control = $('<div class="elfinder-resize-control"/>'),
- preview = $('<div class="elfinder-resize-preview"/>'),
- spinner = $('<div class="elfinder-resize-spinner">'+fm.i18n('ntfloadimg')+'</div>'),
- rhandle = $('<div class="elfinder-resize-handle"/>'),
- rhandlec = $('<div class="elfinder-resize-handle"/>'),
- uiresize = $('<div class="elfinder-resize-uiresize"/>'),
- uicrop = $('<div class="elfinder-resize-uicrop"/>'),
- uibuttonset = '<div class="ui-widget-content ui-corner-all elfinder-buttonset"/>',
- uibutton = '<div class="ui-state-default elfinder-button"/>',
- uiseparator = '<span class="ui-widget-content elfinder-toolbar-button-separator"/>',
- uirotate = $('<div class="elfinder-resize-rotate"/>'),
- uideg270 = $(uibutton).attr('title',fm.i18n('rotate-cw')).append($('<span class="elfinder-button-icon elfinder-button-icon-rotate-l"/>')
- .click(function(){
- rdegree = rdegree - 90;
- rotate.update(rdegree);
- })),
- uideg90 = $(uibutton).attr('title',fm.i18n('rotate-ccw')).append($('<span class="elfinder-button-icon elfinder-button-icon-rotate-r"/>')
- .click(function(){
- rdegree = rdegree + 90;
- rotate.update(rdegree);
- })),
- uiprop = $('<span />'),
- reset = $('<div class="ui-state-default ui-corner-all elfinder-resize-reset"><span class="ui-icon ui-icon-arrowreturnthick-1-w"/></div>'),
- uitype = $('<div class="elfinder-resize-type"/>')
- .append('<input type="radio" name="type" id="'+id+'-resize" value="resize" checked="checked" /><label for="'+id+'-resize">'+fm.i18n('resize')+'</label>')
- .append('<input type="radio" name="type" id="'+id+'-crop" value="crop" /><label for="'+id+'-crop">'+fm.i18n('crop')+'</label>')
- .append('<input type="radio" name="type" id="'+id+'-rotate" value="rotate" /><label for="'+id+'-rotate">'+fm.i18n('rotate')+'</label>'),
- type = $('input', uitype).attr('disabled', 'disabled')
- .change(function() {
- var val = $('input:checked', uitype).val();
- resetView();
- resizable(true);
- croppable(true);
- rotateable(true);
- if (val == 'resize') {
- uiresize.show();
- uirotate.hide();
- uicrop.hide();
- resizable();
- }
- else if (val == 'crop') {
- uirotate.hide();
- uiresize.hide();
- uicrop.show();
- croppable();
- } else if (val == 'rotate') {
- uiresize.hide();
- uicrop.hide();
- uirotate.show();
- rotateable();
- }
- }),
- constr = $('<input type="checkbox" checked="checked"/>')
- .change(function() {
- cratio = !!constr.prop('checked');
- resize.fixHeight();
- resizable(true);
- resizable();
- }),
- width = $(input)
- .change(function() {
- var w = parseInt(width.val()),
- h = parseInt(cratio ? Math.round(w/ratio) : height.val());
- if (w > 0 && h > 0) {
- resize.updateView(w, h);
- height.val(h);
- }
- }),
- height = $(input)
- .change(function() {
- var h = parseInt(height.val()),
- w = parseInt(cratio ? Math.round(h*ratio) : width.val());
- if (w > 0 && h > 0) {
- resize.updateView(w, h);
- width.val(w);
- }
- }),
- pointX = $(input).change(function(){crop.updateView();}),
- pointY = $(input).change(function(){crop.updateView();}),
- offsetX = $(input).change(function(){crop.updateView();}),
- offsetY = $(input).change(function(){crop.updateView();}),
- degree = $('<input type="text" size="3" maxlength="3" value="0" />')
- .change(function() {
- rotate.update();
- }),
- uidegslider = $('<div class="elfinder-resize-rotate-slider"/>')
- .slider({
- min: 0,
- max: 359,
- value: degree.val(),
- animate: true,
- change: function(event, ui) {
- if (ui.value != uidegslider.slider('value')) {
- rotate.update(ui.value);
- }
- },
- slide: function(event, ui) {
- rotate.update(ui.value, false);
- }
- }),
- ratio = 1,
- prop = 1,
- owidth = 0,
- oheight = 0,
- cratio = true,
- pwidth = 0,
- pheight = 0,
- rwidth = 0,
- rheight = 0,
- rdegree = 0,
- img = $('<img/>')
- .load(function() {
- spinner.remove();
- owidth = img.width();
- oheight = img.height();
- ratio = owidth/oheight;
- resize.updateView(owidth, oheight);
- rhandle.append(img.show()).show();
- width.val(owidth);
- height.val(oheight);
- var r_scale = Math.min(pwidth, pheight) / Math.sqrt(Math.pow(owidth, 2) + Math.pow(oheight, 2));
- rwidth = owidth * r_scale;
- rheight = oheight * r_scale;
- type.button('enable');
- control.find('input,select').removeAttr('disabled')
- .filter(':text').keydown(function(e) {
- var c = e.keyCode, i;
- e.stopPropagation();
- if ((c >= 37 && c <= 40)
- || c == $.ui.keyCode.BACKSPACE
- || c == $.ui.keyCode.DELETE
- || (c == 65 && (e.ctrlKey||e.metaKey))
- || c == 27) {
- return;
- }
- if (c == 9) {
- i = $(this).parent()[e.shiftKey ? 'prev' : 'next']('.elfinder-resize-row').children(':text');
- if (i.length) {
- i.focus();
- } else {
- $(this).parent().parent().find(':text:' + (e.shiftKey ? 'last' : 'first')).focus();
- }
- }
- if (c == 13) {
- fm.confirm({
- title : $('input:checked', uitype).val(),
- text : 'confirmReq',
- accept : {
- label : 'btnApply',
- callback : function() {
- save();
- }
- },
- cancel : {
- label : 'btnCancel',
- callback : function(){}
- }
- });
- return;
- }
- if (!((c >= 48 && c <= 57) || (c >= 96 && c <= 105))) {
- e.preventDefault();
- }
- })
- .filter(':first').focus();
- resizable();
- reset.hover(function() { reset.toggleClass('ui-state-hover'); }).click(resetView);
- })
- .error(function() {
- spinner.text('Unable to load image').css('background', 'transparent');
- }),
- basec = $('<div/>'),
- imgc = $('<img/>'),
- coverc = $('<div/>'),
- imgr = $('<img/>'),
- resetView = function() {
- width.val(owidth);
- height.val(oheight);
- resize.updateView(owidth, oheight);
- },
- resize = {
- update : function() {
- width.val(Math.round(img.width()/prop));
- height.val(Math.round(img.height()/prop));
- },
- updateView : function(w, h) {
- if (w > pwidth || h > pheight) {
- if (w / pwidth > h / pheight) {
- prop = pwidth / w;
- img.width(pwidth).height(Math.ceil(h*prop));
- } else {
- prop = pheight / h;
- img.height(pheight).width(Math.ceil(w*prop));
- }
- } else {
- img.width(w).height(h);
- }
- prop = img.width()/w;
- uiprop.text('1 : '+(1/prop).toFixed(2));
- resize.updateHandle();
- },
- updateHandle : function() {
- rhandle.width(img.width()).height(img.height());
- },
- fixWidth : function() {
- var w, h;
- if (cratio) {
- h = height.val();
- h = Math.round(h*ratio);
- resize.updateView(w, h);
- width.val(w);
- }
- },
- fixHeight : function() {
- var w, h;
- if (cratio) {
- w = width.val();
- h = Math.round(w/ratio);
- resize.updateView(w, h);
- height.val(h);
- }
- }
- },
- crop = {
- update : function() {
- offsetX.val(Math.round((rhandlec.data('w')||rhandlec.width())/prop));
- offsetY.val(Math.round((rhandlec.data('h')||rhandlec.height())/prop));
- pointX.val(Math.round(((rhandlec.data('x')||rhandlec.offset().left)-imgc.offset().left)/prop));
- pointY.val(Math.round(((rhandlec.data('y')||rhandlec.offset().top)-imgc.offset().top)/prop));
- },
- updateView : function() {
- var x = parseInt(pointX.val()) * prop + imgc.offset().left;
- var y = parseInt(pointY.val()) * prop + imgc.offset().top;
- var w = offsetX.val() * prop;
- var h = offsetY.val() * prop;
- rhandlec.data({x: x, y: y, w: w, h: h});
- rhandlec.width(Math.round(w));
- rhandlec.height(Math.round(h));
- coverc.width(rhandlec.width());
- coverc.height(rhandlec.height());
- rhandlec.offset({left: Math.round(x), top: Math.round(y)});
- },
- resize_update : function() {
- rhandlec.data({w: null, h: null});
- crop.update();
- coverc.width(rhandlec.width());
- coverc.height(rhandlec.height());
- },
- drag_update : function() {
- rhandlec.data({x: null, y: null});
- crop.update();
- }
- },
- rotate = {
- mouseStartAngle : 0,
- imageStartAngle : 0,
- imageBeingRotated : false,
- update : function(value, animate) {
- if (typeof value == 'undefined') {
- rdegree = value = parseInt(degree.val());
- }
- if (typeof animate == 'undefined') {
- animate = true;
- }
- if (! animate || fm.UA.Opera || fm.UA.ltIE8) {
- imgr.rotate(value);
- } else {
- imgr.animate({rotate: value + 'deg'});
- }
- value = value % 360;
- if (value < 0) {
- value += 360;
- }
- degree.val(parseInt(value));
- uidegslider.slider('value', degree.val());
- },
- execute : function ( e ) {
- if ( !rotate.imageBeingRotated ) return;
- var imageCentre = rotate.getCenter( imgr );
- var mouseXFromCentre = e.pageX - imageCentre[0];
- var mouseYFromCentre = e.pageY - imageCentre[1];
- var mouseAngle = Math.atan2( mouseYFromCentre, mouseXFromCentre );
- var rotateAngle = mouseAngle - rotate.mouseStartAngle + rotate.imageStartAngle;
- rotateAngle = Math.round(parseFloat(rotateAngle) * 180 / Math.PI);
- if ( e.shiftKey ) {
- rotateAngle = Math.round((rotateAngle + 6)/15) * 15;
- }
- imgr.rotate(rotateAngle);
- rotateAngle = rotateAngle % 360;
- if (rotateAngle < 0) {
- rotateAngle += 360;
- }
- degree.val(rotateAngle);
- uidegslider.slider('value', degree.val());
- return false;
- },
- start : function ( e ) {
- rotate.imageBeingRotated = true;
- var imageCentre = rotate.getCenter( imgr );
- var mouseStartXFromCentre = e.pageX - imageCentre[0];
- var mouseStartYFromCentre = e.pageY - imageCentre[1];
- rotate.mouseStartAngle = Math.atan2( mouseStartYFromCentre, mouseStartXFromCentre );
- rotate.imageStartAngle = parseFloat(imgr.rotate()) * Math.PI / 180.0;
- $(document).mousemove( rotate.execute );
- return false;
- },
- stop : function ( e ) {
- if ( !rotate.imageBeingRotated ) return;
- $(document).unbind( 'mousemove' , rotate.execute);
- setTimeout( function() { rotate.imageBeingRotated = false; }, 10 );
- return false;
- },
- getCenter : function ( image ) {
- var currentRotation = imgr.rotate();
- imgr.rotate(0);
- var imageOffset = imgr.offset();
- var imageCentreX = imageOffset.left + imgr.width() / 2;
- var imageCentreY = imageOffset.top + imgr.height() / 2;
- imgr.rotate(currentRotation);
- return Array( imageCentreX, imageCentreY );
- }
- },
- resizable = function(destroy) {
- if ($.fn.resizable) {
- if (destroy) {
- rhandle.filter(':ui-resizable').resizable('destroy');
- rhandle.hide();
- }
- else {
- rhandle.show();
- rhandle.resizable({
- alsoResize : img,
- aspectRatio : cratio,
- resize : resize.update,
- stop : resize.fixHeight
- });
- }
- }
- },
- croppable = function(destroy) {
- if ($.fn.draggable && $.fn.resizable) {
- if (destroy) {
- rhandlec.filter(':ui-resizable').resizable('destroy');
- rhandlec.filter(':ui-draggable').draggable('destroy');
- basec.hide();
- }
- else {
- imgc
- .width(img.width())
- .height(img.height());
- coverc
- .width(img.width())
- .height(img.height());
- rhandlec
- .width(imgc.width())
- .height(imgc.height())
- .offset(imgc.offset())
- .resizable({
- containment : basec,
- resize : crop.resize_update,
- handles : 'all'
- })
- .draggable({
- handle : coverc,
- containment : imgc,
- drag : crop.drag_update
- });
- basec.show()
- .width(img.width())
- .height(img.height());
- crop.update();
- }
- }
- },
- rotateable = function(destroy) {
- if ($.fn.draggable && $.fn.resizable) {
- if (destroy) {
- imgr.hide();
- }
- else {
- imgr.show()
- .width(rwidth)
- .height(rheight)
- .css('margin-top', (pheight-rheight)/2 + 'px')
- .css('margin-left', (pwidth-rwidth)/2 + 'px');
- }
- }
- },
- save = function() {
- var w, h, x, y, d;
- var mode = $('input:checked', uitype).val();
- //width.add(height).change(); // may be unnecessary
- if (mode == 'resize') {
- w = parseInt(width.val()) || 0;
- h = parseInt(height.val()) || 0;
- } else if (mode == 'crop') {
- w = parseInt(offsetX.val()) || 0;
- h = parseInt(offsetY.val()) || 0;
- x = parseInt(pointX.val()) || 0;
- y = parseInt(pointY.val()) || 0;
- } else if (mode == 'rotate') {
- w = owidth;
- h = oheight;
- d = parseInt(degree.val()) || 0;
- if (d < 0 || d > 360) {
- return fm.error('Invalid rotate degree');
- }
- if (d == 0 || d == 360) {
- return fm.error('Image dose not rotated');
- }
- }
- if (mode != 'rotate') {
- if (w <= 0 || h <= 0) {
- return fm.error('Invalid image size');
- }
- if (w == owidth && h == oheight) {
- return fm.error('Image size not changed');
- }
- }
- dialog.elfinderdialog('close');
- fm.request({
- data : {
- cmd : 'resize',
- target : file.hash,
- width : w,
- height : h,
- x : x,
- y : y,
- degree : d,
- mode : mode
- },
- notify : {type : 'resize', cnt : 1}
- })
- .fail(function(error) {
- dfrd.reject(error);
- })
- .done(function() {
- dfrd.resolve();
- });
- },
- buttons = {},
- hline = 'elfinder-resize-handle-hline',
- vline = 'elfinder-resize-handle-vline',
- rpoint = 'elfinder-resize-handle-point',
- src = fm.url(file.hash)
- ;
- imgr.mousedown( rotate.start );
- $(document).mouseup( rotate.stop );
- uiresize.append($(row).append($(label).text(fm.i18n('width'))).append(width).append(reset))
- .append($(row).append($(label).text(fm.i18n('height'))).append(height))
- .append($(row).append($('<label/>').text(fm.i18n('aspectRatio')).prepend(constr)))
- .append($(row).append(fm.i18n('scale')+' ').append(uiprop));
- uicrop.append($(row).append($(label).text('X')).append(pointX))
- .append($(row).append($(label).text('Y')).append(pointY))
- .append($(row).append($(label).text(fm.i18n('width'))).append(offsetX))
- .append($(row).append($(label).text(fm.i18n('height'))).append(offsetY));
- uirotate.append($(row)
- .append($(label).text(fm.i18n('rotate')))
- .append($('<div style="float:left; width: 130px;">')
- .append($('<div style="float:left;">')
- .append(degree)
- .append($('<span/>').text(fm.i18n('degree')))
- )
- .append($(uibuttonset).append(uideg270).append($(uiseparator)).append(uideg90))
- )
- .append(uidegslider)
- );
- dialog.append(uitype);
- control.append($(row))
- .append(uiresize)
- .append(uicrop.hide())
- .append(uirotate.hide())
- .find('input,select').attr('disabled', 'disabled');
- rhandle.append('<div class="'+hline+' '+hline+'-top"/>')
- .append('<div class="'+hline+' '+hline+'-bottom"/>')
- .append('<div class="'+vline+' '+vline+'-left"/>')
- .append('<div class="'+vline+' '+vline+'-right"/>')
- .append('<div class="'+rpoint+' '+rpoint+'-e"/>')
- .append('<div class="'+rpoint+' '+rpoint+'-se"/>')
- .append('<div class="'+rpoint+' '+rpoint+'-s"/>');
- preview.append(spinner).append(rhandle.hide()).append(img.hide());
- rhandlec.css('position', 'absolute')
- .append('<div class="'+hline+' '+hline+'-top"/>')
- .append('<div class="'+hline+' '+hline+'-bottom"/>')
- .append('<div class="'+vline+' '+vline+'-left"/>')
- .append('<div class="'+vline+' '+vline+'-right"/>')
- .append('<div class="'+rpoint+' '+rpoint+'-n"/>')
- .append('<div class="'+rpoint+' '+rpoint+'-e"/>')
- .append('<div class="'+rpoint+' '+rpoint+'-s"/>')
- .append('<div class="'+rpoint+' '+rpoint+'-w"/>')
- .append('<div class="'+rpoint+' '+rpoint+'-ne"/>')
- .append('<div class="'+rpoint+' '+rpoint+'-se"/>')
- .append('<div class="'+rpoint+' '+rpoint+'-sw"/>')
- .append('<div class="'+rpoint+' '+rpoint+'-nw"/>');
- preview.append(basec.css('position', 'absolute').hide().append(imgc).append(rhandlec.append(coverc)));
- preview.append(imgr.hide());
- preview.css('overflow', 'hidden');
- dialog.append(preview).append(control);
- buttons[fm.i18n('btnApply')] = save;
- buttons[fm.i18n('btnCancel')] = function() { dialog.elfinderdialog('close'); };
- fm.dialog(dialog, {
- title : fm.escape(file.name),
- width : 650,
- resizable : false,
- destroyOnClose : true,
- buttons : buttons,
- open : function() { preview.zIndex(1+$(this).parent().zIndex()); }
- }).attr('id', id);
- // for IE < 9 dialog mising at open second+ time.
- if (fm.UA.ltIE8) {
- $('.elfinder-dialog').css('filter', '');
- }
- reset.css('left', width.position().left + width.width() + 12);
- coverc.css({ 'opacity': 0.2, 'background-color': '#fff', 'position': 'absolute'}),
- rhandlec.css('cursor', 'move');
- rhandlec.find('.elfinder-resize-handle-point').css({
- 'background-color' : '#fff',
- 'opacity': 0.5,
- 'border-color':'#000'
- });
- imgr.css('cursor', 'pointer');
- uitype.buttonset();
- pwidth = preview.width() - (rhandle.outerWidth() - rhandle.width());
- pheight = preview.height() - (rhandle.outerHeight() - rhandle.height());
- img.attr('src', src + (src.indexOf('?') === -1 ? '?' : '&')+'_='+Math.random());
- imgc.attr('src', img.attr('src'));
- imgr.attr('src', img.attr('src'));
- },
- id, dialog
- ;
- if (!files.length || files[0].mime.indexOf('image/') === -1) {
- return dfrd.reject();
- }
- id = 'resize-'+fm.namespace+'-'+files[0].hash;
- dialog = fm.getUI().find('#'+id);
- if (dialog.length) {
- dialog.elfinderdialog('toTop');
- return dfrd.resolve();
- }
- open(files[0], id);
- return dfrd;
- };
- };
- (function ($) {
- var findProperty = function (styleObject, styleArgs) {
- var i = 0 ;
- for( i in styleArgs) {
- if (typeof styleObject[styleArgs[i]] != 'undefined')
- return styleArgs[i];
- }
- styleObject[styleArgs[i]] = '';
- return styleArgs[i];
- };
- $.cssHooks.rotate = {
- get: function(elem, computed, extra) {
- return $(elem).rotate();
- },
- set: function(elem, value) {
- $(elem).rotate(value);
- return value;
- }
- };
- $.cssHooks.transform = {
- get: function(elem, computed, extra) {
- var name = findProperty( elem.style ,
- ['WebkitTransform', 'MozTransform', 'OTransform' , 'msTransform' , 'transform'] );
- return elem.style[name];
- },
- set: function(elem, value) {
- var name = findProperty( elem.style ,
- ['WebkitTransform', 'MozTransform', 'OTransform' , 'msTransform' , 'transform'] );
- elem.style[name] = value;
- return value;
- }
- };
- $.fn.rotate = function(val) {
- if (typeof val == 'undefined') {
- if (!!window.opera) {
- var r = this.css('transform').match(/rotate\((.*?)\)/);
- return ( r && r[1])?
- Math.round(parseFloat(r[1]) * 180 / Math.PI) : 0;
- } else {
- var r = this.css('transform').match(/rotate\((.*?)\)/);
- return ( r && r[1])? parseInt(r[1]) : 0;
- }
- }
- this.css('transform',
- this.css('transform').replace(/none|rotate\(.*?\)/, '') + 'rotate(' + parseInt(val) + 'deg)');
- return this;
- };
- $.fx.step.rotate = function(fx) {
- if ( fx.state == 0 ) {
- fx.start = $(fx.elem).rotate();
- fx.now = fx.start;
- }
- $(fx.elem).rotate(fx.now);
- };
- if (typeof window.addEventListener == "undefined" && typeof document.getElementsByClassName == "undefined") { // IE & IE<9
- var GetAbsoluteXY = function(element) {
- var pnode = element;
- var x = pnode.offsetLeft;
- var y = pnode.offsetTop;
- while ( pnode.offsetParent ) {
- pnode = pnode.offsetParent;
- if (pnode != document.body && pnode.currentStyle['position'] != 'static') {
- break;
- }
- if (pnode != document.body && pnode != document.documentElement) {
- x -= pnode.scrollLeft;
- y -= pnode.scrollTop;
- }
- x += pnode.offsetLeft;
- y += pnode.offsetTop;
- }
- return { x: x, y: y };
- };
- var StaticToAbsolute = function (element) {
- if ( element.currentStyle['position'] != 'static') {
- return ;
- }
- var xy = GetAbsoluteXY(element);
- element.style.position = 'absolute' ;
- element.style.left = xy.x + 'px';
- element.style.top = xy.y + 'px';
- };
- var IETransform = function(element,transform){
- var r;
- var m11 = 1;
- var m12 = 1;
- var m21 = 1;
- var m22 = 1;
- if (typeof element.style['msTransform'] != 'undefined'){
- return true;
- }
- StaticToAbsolute(element);
- r = transform.match(/rotate\((.*?)\)/);
- var rotate = ( r && r[1]) ? parseInt(r[1]) : 0;
- rotate = rotate % 360;
- if (rotate < 0) rotate = 360 + rotate;
- var radian= rotate * Math.PI / 180;
- var cosX =Math.cos(radian);
- var sinY =Math.sin(radian);
- m11 *= cosX;
- m12 *= -sinY;
- m21 *= sinY;
- m22 *= cosX;
- element.style.filter = (element.style.filter || '').replace(/progid:DXImageTransform\.Microsoft\.Matrix\([^)]*\)/, "" ) +
- ("progid:DXImageTransform.Microsoft.Matrix(" +
- "M11=" + m11 +
- ",M12=" + m12 +
- ",M21=" + m21 +
- ",M22=" + m22 +
- ",FilterType='bilinear',sizingMethod='auto expand')")
- ;
- var ow = parseInt(element.style.width || element.width || 0 );
- var oh = parseInt(element.style.height || element.height || 0 );
- var radian = rotate * Math.PI / 180;
- var absCosX =Math.abs(Math.cos(radian));
- var absSinY =Math.abs(Math.sin(radian));
- var dx = (ow - (ow * absCosX + oh * absSinY)) / 2;
- var dy = (oh - (ow * absSinY + oh * absCosX)) / 2;
- element.style.marginLeft = Math.floor(dx) + "px";
- element.style.marginTop = Math.floor(dy) + "px";
- return(true);
- };
- var transform_set = $.cssHooks.transform.set;
- $.cssHooks.transform.set = function(elem, value) {
- transform_set.apply(this, [elem, value] );
- IETransform(elem,value);
- return value;
- };
- }
- })(jQuery);
- /*
- * File: /js/commands/rm.js
- */
- /**
- * @class elFinder command "rm"
- * Delete files
- *
- * @author Dmitry (dio) Levashov
- **/
- elFinder.prototype.commands.rm = function() {
- this.shortcuts = [{
- pattern : 'delete ctrl+backspace'
- }];
- this.getstate = function(sel) {
- var fm = this.fm;
- sel = sel || fm.selected();
- return !this._disabled && sel.length && $.map(sel, function(h) { var f = fm.file(h); return f && f.phash && !f.locked ? h : null }).length == sel.length
- ? 0 : -1;
- }
- this.exec = function(hashes) {
- var self = this,
- fm = this.fm,
- dfrd = $.Deferred()
- .fail(function(error) {
- error && fm.error(error);
- }),
- files = this.files(hashes),
- cnt = files.length,
- cwd = fm.cwd().hash,
- goup = false;
- if (!cnt || this._disabled) {
- return dfrd.reject();
- }
- var restrictions = 0;
- $.each(files, function(i, file) {
- if(!file.read) {
- restrictions++;
- }
- });
- if(restrictions > 0) {
- return !dfrd.reject(['errLocked', 'Object']);
- } else {
- $.each(files, function(i, file) {
- if (!file.phash) {
- return !dfrd.reject(['errRm', file.name, 'errPerm']);
- }
- if (file.locked) {
- return !dfrd.reject(['errLocked', file.name]);
- }
- if (file.mime === 'directory') {
- var parents = fm.parents(cwd);
- if (file.hash == cwd || $.inArray(file.hash, parents)) {
- goup = (file.phash && fm.file(file.phash).read)? file.phash : fm.root(file.hash);
- }
- }
- });
- if (dfrd.state() == 'pending') {
- files = this.hashes(hashes);
- fm.lockfiles({files : files});
- fm.confirm({
- title : self.title,
- text : 'confirmRm',
- accept : {
- label : 'btnRm',
- callback : function() {
- fm.request({
- data : {cmd : 'rm', targets : files},
- notify : {type : 'rm', cnt : cnt},
- preventFail : true
- })
- .fail(function(error) {
- dfrd.reject(error);
- })
- .done(function(data) {
- dfrd.done(data);
- goup && fm.exec('open', goup)
- })
- .always(function() {
- fm.unlockfiles({files : files});
- });
- }
- },
- cancel : {
- label : 'btnCancel',
- callback : function() {
- fm.unlockfiles({files : files});
- fm.selectfiles({files : files});
- dfrd.reject();
- }
- }
- });
- }
- return dfrd;
- }
- }
- }
- /*
- * File: /js/commands/search.js
- */
- /**
- * @class elFinder command "search"
- * Find files
- *
- * @author Dmitry (dio) Levashov
- **/
- elFinder.prototype.commands.search = function() {
- this.title = 'Find files';
- this.options = {ui : 'searchbutton'}
- this.alwaysEnabled = true;
- this.updateOnSelect = false;
- /**
- * Return command status.
- * Search does not support old api.
- *
- * @return Number
- **/
- this.getstate = function() {
- return 0;
- }
- /**
- * Send search request to backend.
- *
- * @param String search string
- * @return $.Deferred
- **/
- this.exec = function(q, target, mime) {
- var fm = this.fm;
- if (typeof(q) == 'string' && q) {
- target = target? target : null;
- mime = mime? $.trim(mime).replace(',', ' ').split(' ') : [];
- $.each(mime, function(){ return $.trim(this); });
- fm.trigger('searchstart', {query : q, target : target, mimes : mime});
- return fm.request({
- data : {cmd : 'search', q : q, target : target, mimes : mime},
- notify : {type : 'search', cnt : 1, hideCnt : true}
- });
- }
- fm.getUI('toolbar').find('.'+fm.res('class', 'searchbtn')+' :text').focus();
- return $.Deferred().reject();
- }
- }
- /*
- * File: /js/commands/sort.js
- */
- /**
- * @class elFinder command "sort"
- * Change sort files rule
- *
- * @author Dmitry (dio) Levashov
- **/
- elFinder.prototype.commands.sort = function() {
- var self = this,
- fm = self.fm,
- timer;
- /**
- * Command options
- *
- * @type Object
- */
- this.options = {ui : 'sortbutton'};
- fm.bind('open sortchange', function() {
- self.variants = [];
- $.each(fm.sortRules, function(name, value) {
- var sort = {
- type : name,
- order : name == fm.sortType ? fm.sortOrder == 'asc' ? 'desc' : 'asc' : fm.sortOrder
- };
- var arr = name == fm.sortType ? (sort.order == 'asc'? 'n' : 's') : '';
- self.variants.push([sort, (arr? '<span class="ui-icon ui-icon-arrowthick-1-'+arr+'"></span>' : '') + ' ' + fm.i18n('sort'+name)]);
- });
- });
- fm.bind('open sortchange viewchange search searchend', function() {
- timer && clearTimeout(timer);
- timer = setTimeout(function(){
- var cols = $(fm.cwd).find('div.elfinder-cwd-wrapper-list table');
- if (cols.length) {
- $.each(fm.sortRules, function(name, value) {
- var td = cols.find('thead tr td.elfinder-cwd-view-th-'+name);
- if (td.length) {
- var current = ( name == fm.sortType),
- sort = {
- type : name,
- order : current ? fm.sortOrder == 'asc' ? 'desc' : 'asc' : fm.sortOrder
- },arr;
- if (current) {
- td.addClass('ui-state-active');
- arr = fm.sortOrder == 'asc' ? 'n' : 's';
- $('<span class="ui-icon ui-icon-triangle-1-'+arr+'"/>').appendTo(td);
- }
- $(td).on('click', function(e){
- e.stopPropagation();
- self.exec([], sort);
- })
- .hover(function() {
- $(this).addClass('ui-state-hover');
- },function() {
- $(this).removeClass('ui-state-hover');
- });
- }
- });
- }
- }, 100);
- });
- this.getstate = function() {
- return 0;
- };
- this.exec = function(hashes, sortopt) {
- var fm = this.fm,
- sort = $.extend({
- type : fm.sortType,
- order : fm.sortOrder,
- stick : fm.sortStickFolders
- }, sortopt);
- this.fm.setSort(sort.type, sort.order, sort.stick);
- return $.Deferred().resolve();
- };
- };
- /*
- * File: /js/commands/up.js
- */
- /**
- * @class elFinder command "up"
- * Go into parent directory
- *
- * @author Dmitry (dio) Levashov
- **/
- elFinder.prototype.commands.up = function() {
- this.alwaysEnabled = true;
- this.updateOnSelect = false;
- this.shortcuts = [{
- pattern : 'ctrl+up'
- }];
- this.getstate = function() {
- return this.fm.cwd().phash ? 0 : -1;
- }
- this.exec = function() {
- return this.fm.cwd().phash ? this.fm.exec('open', this.fm.cwd().phash) : $.Deferred().reject();
- }
- }
- /*
- * File: /js/commands/upload.js
- */
- /**
- * @class elFinder command "upload"
- * Upload files using iframe or XMLHttpRequest & FormData.
- * Dialog allow to send files using drag and drop
- *
- * @type elFinder.command
- * @author Dmitry (dio) Levashov
- */
- elFinder.prototype.commands.upload = function() {
- var hover = this.fm.res('class', 'hover');
- this.disableOnSearch = true;
- this.updateOnSelect = false;
- // Shortcut opens dialog
- this.shortcuts = [{
- pattern : 'ctrl+u'
- }];
- /**
- * Return command state
- *
- * @return Number
- **/
- this.getstate = function(sel) {
- var fm = this.fm, f,
- sel = fm.directUploadTarget? [fm.directUploadTarget] : (sel || [fm.cwd().hash]);
- if (!this._disabled && sel.length == 1) {
- f = fm.file(sel[0]);
- }
- return (f && f.mime == 'directory' && f.write)? 0 : -1;
- };
- this.exec = function(data) {
- var fm = this.fm,
- targets = data && (data instanceof Array)? data : null,
- check = !targets && data && data.target? [ data.target ] : targets,
- fmUpload = function(data) {
- fm.upload(data)
- .fail(function(error) {
- dfrd.reject(error);
- })
- .done(function(data) {
- dfrd.resolve(data);
- });
- },
- upload = function(data) {
- dialog.elfinderdialog('close');
- if (targets) {
- data.target = targets[0];
- }
- fmUpload(data);
- },
- dfrd = $.Deferred(),
- dialog, input, button, dropbox, pastebox, dropUpload, paste;
- if (this.getstate(check) < 0) {
- return dfrd.reject();
- }
- dropUpload = function(e) {
- e.stopPropagation();
- e.preventDefault();
- var file = false,
- type = '',
- data = null,
- target = e._target || null;
- try{
- data = e.dataTransfer.getData('text/html');
- } catch(e) {}
- if (data) {
- file = [ data ];
- type = 'html';
- } else if (e.dataTransfer && e.dataTransfer.items && e.dataTransfer.items.length) {
- file = e.dataTransfer;
- type = 'data';
- } else if (e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files.length) {
- file = e.dataTransfer.files;
- type = 'files';
- } else if (data = e.dataTransfer.getData('text')) {
- file = [ data ];
- type = 'text';
- }
- if (file) {
- fmUpload({files : file, type : type, target : target});
- } else {
- dfrd.reject();
- }
- };
- if (!targets && data) {
- if (data.input || data.files) {
- data.type = 'files';
- fmUpload(data);
- } else if (data.dropEvt) {
- dropUpload(data.dropEvt);
- }
- return dfrd;
- }
- paste = function(e) {
- var e = e.originalEvent || e;
- var files = [], items = [];
- var file;
- if (e.clipboardData) {
- if (e.clipboardData.items && e.clipboardData.items.length){
- items = e.clipboardData.items;
- for (var i=0; i < items.length; i++) {
- if (e.clipboardData.items[i].kind == 'file') {
- file = e.clipboardData.items[i].getAsFile();
- files.push(file);
- }
- }
- } else if (e.clipboardData.files && e.clipboardData.files.length) {
- files = e.clipboardData.files;
- }
- if (files.length) {
- upload({files : files, type : 'files'});
- return;
- }
- }
- var my = e.target || e.srcElement;
- setTimeout(function () {
- if (my.innerHTML) {
- $(my).find('img').each(function(i, v){
- if (v.src.match(/^webkit-fake-url:\/\//)) {
- // For Safari's bug.
- // ref. https://bugs.webkit.org/show_bug.cgi?id=49141
- // https://dev.ckeditor.com/ticket/13029
- $(v).remove();
- }
- });
- var src = my.innerHTML.replace(/<br[^>]*>/gi, ' ');
- var type = src.match(/<[^>]+>/)? 'html' : 'text';
- my.innerHTML = '';
- upload({files : [ src ], type : type});
- }
- }, 1);
- };
- input = $('<input type="file" multiple="true"/>')
- .change(function() {
- upload({input : input[0], type : 'files'});
- });
- button = $('<div class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"><span class="ui-button-text">'+fm.i18n('selectForUpload')+'</span></div>')
- .append($('<form/>').append(input))
- .hover(function() {
- button.toggleClass(hover)
- });
- dialog = $('<div class="elfinder-upload-dialog-wrapper"/>')
- .append(button);
- pastebox = $('<div class="ui-corner-all elfinder-upload-dropbox" contenteditable="true">'+fm.i18n('dropFilesBrowser')+'</div>')
- .on('paste drop', function(e){
- paste(e);
- })
- .on('mousedown click', function(){
- $(this).focus();
- })
- .on('focus', function(){
- this.innerHTML = '';
- })
- .on('dragenter mouseover', function(){
- pastebox.addClass(hover);
- })
- .on('dragleave mouseout', function(){
- pastebox.removeClass(hover);
- });
- if (fm.dragUpload) {
- dropbox = $('<div class="ui-corner-all elfinder-upload-dropbox" contenteditable="true">'+fm.i18n('dropPasteFiles')+'</div>')
- .on('paste', function(e){
- paste(e);
- })
- .on('mousedown click', function(){
- $(this).focus();
- })
- .on('focus', function(){
- this.innerHTML = '';
- })
- .on('mouseover', function(){
- $(this).addClass(hover);
- })
- .on('mouseout', function(){
- $(this).removeClass(hover);
- })
- .prependTo(dialog)
- .after('<div class="elfinder-upload-dialog-or">'+fm.i18n('or')+'</div>')[0];
- dropbox.addEventListener('dragenter', function(e) {
- e.stopPropagation();
- e.preventDefault();
- $(dropbox).addClass(hover);
- }, false);
- dropbox.addEventListener('dragleave', function(e) {
- e.stopPropagation();
- e.preventDefault();
- $(dropbox).removeClass(hover);
- }, false);
- dropbox.addEventListener('dragover', function(e) {
- e.stopPropagation();
- e.preventDefault();
- $(dropbox).addClass(hover);
- }, false);
- dropbox.addEventListener('drop', function(e) {
- dialog.elfinderdialog('close');
- targets && (e._target = targets[0]);
- dropUpload(e);
- }, false);
- } else {
- pastebox
- .prependTo(dialog)
- .after('<div class="elfinder-upload-dialog-or">'+fm.i18n('or')+'</div>')[0];
- }
- fm.dialog(dialog, {
- title : this.title + (targets? ' - ' + fm.escape(fm.file(targets[0]).name) : ''),
- modal : true,
- resizable : false,
- destroyOnClose : true
- });
- return dfrd;
- };
- };
- /*
- * File: /js/commands/view.js
- */
- /**
- * @class elFinder command "view"
- * Change current directory view (icons/list)
- *
- * @author Dmitry (dio) Levashov
- **/
- elFinder.prototype.commands.view = function() {
- this.value = this.fm.viewType;
- this.alwaysEnabled = true;
- this.updateOnSelect = false;
- this.options = { ui : 'viewbutton'};
- this.getstate = function() {
- return 0;
- }
- this.exec = function() {
- var value = this.fm.storage('view', this.value == 'list' ? 'icons' : 'list');
- this.fm.viewchange();
- this.update(void(0), value);
- }
- }
- })(jQuery);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement