/*! * elFinder - file manager for web * Version 2.0 rc1 (2012-09-28) * http://elfinder.org * * Copyright 2009-2012, Studio 42 * Licensed under a 3 clauses BSD license */ (function($) { /* * File: /home/osc/elFinder-build/elFinder/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 = $('
').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, 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, beeper = $(document.createElement('audio')).hide().appendTo('body')[0], syncInterval, open = function(data) { if (data.init) { // init - reset cache files = {}; } else { // remove only files from prev cwd for (var i in files) { if (files.hasOwnProperty(i) && files[i].mime != 'directory' && files[i].phash == cwd && $.inArray(i, remember) === -1) { delete files[i]; } } } 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; while (l--) { f = data[l]; 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; } } 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(); } } }, 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; /** * 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'; /** * 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; } $.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 : {}; /** * 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; /** * Base draggable options * * @type Object **/ this.draggable = { appendTo : 'body', addClasses : true, delay : 30, revert : true, refreshPositions : true, cursor : 'move', cursorAt : {left : 50, top : 47}, drag : function(e, ui) { if (! ui.helper.data('locked')) { ui.helper.toggleClass('elfinder-drag-helper-plus', e.shiftKey||e.ctrlKey||e.metaKey); } }, start : function(e, ui) { var targets = $.map(ui.helper.data('files')||[], function(h) { return h || null ;}), cnt, h; cnt = targets.length; while (cnt--) { h = targets[cnt]; if (files[h].locked) { ui.helper.addClass('elfinder-drag-helper-plus').data('locked', true); break; } } }, stop : function() { self.trigger('focus').trigger('dragstop'); }, helper : function(e, ui) { var element = this.id ? $(this) : $(this).parents('[id]:first'), helper = $('