/*jslint browser: true, devel: true, windows: true, forin: true, nomen: true, regexp: true, newcap: true, immed: true */ /* namespace */ function Webfm() {} /* ** Global variables */ //Translation possible by changing the array values (DO NOT ALTER KEYS!) Webfm.js_msg = []; Webfm.js_msg.mkdir = Drupal.t("Create New Dir"); Webfm.js_msg.file = Drupal.t("file"); Webfm.js_msg.dir = Drupal.t("directory"); Webfm.js_msg.u_file = Drupal.t("File"); Webfm.js_msg.u_dir = Drupal.t("Directory"); Webfm.js_msg.tree = Drupal.t(""); Webfm.js_msg.work = Drupal.t("Working... please wait"); Webfm.js_msg.refresh = Drupal.t("refresh"); Webfm.js_msg.sort = Drupal.t("sort by this column"); Webfm.js_msg.newdir = Drupal.t("Create New Folder"); Webfm.js_msg.addtodb = Drupal.t("Add files in this folder to database"); Webfm.js_msg.recursivecaddaddtodb = Drupal.t("Recursive add files to database"); Webfm.js_msg.column1 = Drupal.t("Name"); Webfm.js_msg.column2 = Drupal.t("Modified"); Webfm.js_msg.column3 = Drupal.t("Size"); Webfm.js_msg.column4 = Drupal.t("Owner"); Webfm.js_msg.attachtitle = Drupal.t("Attached Files"); Webfm.js_msg.metatitle = Drupal.t("File Meta Data"); Webfm.js_msg.searchtitle = Drupal.t("File Search"); Webfm.js_msg.debugtitle = Drupal.t("WebFM Debug"); Webfm.js_msg.cachetitle = Drupal.t("Directory Cache"); Webfm.js_msg.searchcur = Drupal.t("Search current directory (see listing breadcrumb trail)"); Webfm.js_msg.nomatch = Drupal.t("No match found"); Webfm.js_msg.search = Drupal.t("Search"); Webfm.js_msg.submit = Drupal.t("Submit"); Webfm.js_msg.reset = Drupal.t("Reset"); Webfm.js_msg.clear = Drupal.t("Clear"); Webfm.js_msg.cancel = Drupal.t("Cancel"); Webfm.js_msg.close = Drupal.t("Close"); Webfm.js_msg.resize = Drupal.t("Resize"); Webfm.js_msg.replace = Drupal.t("Replace and Version original copy of "); Webfm.js_msg.replacedel = Drupal.t("Replace and Delete original copy of "); Webfm.js_msg.noreplace = Drupal.t("Version new copy of "); Webfm.js_msg.cache = Drupal.t("Cache Content"); Webfm.js_msg.curdirundef = Drupal.t("current directory undefined"); Webfm.js_msg.ajaxerr = Drupal.t("server is unreachable"); Webfm.js_msg.moveerr = Drupal.t("move operation fail"); Webfm.js_msg.lengtherr = Drupal.t("Too long"); Webfm.js_msg.confirmdel0 = Drupal.t("Do you want to delete the "); Webfm.js_msg.confirmdel1 = Drupal.t(" and all its contents"); Webfm.js_msg.confirmdet = Drupal.t("Do you want to detach "); Webfm.js_msg.confirmdbrem0 = Drupal.t("Do you want to remove "); Webfm.js_msg.confirmdbrem1 = Drupal.t(" from the database?\n All metadata and attachments for this file will be lost"); Webfm.js_msg.enum_local = Drupal.t("Do you want to add all files of this directory into the database?"); Webfm.js_msg.enum_recur = Drupal.t("Do you want to add all files of this directory and sub-directories into the database?"); Webfm.js_msg.filedwld = Drupal.t("download file"); Webfm.js_msg.nofiledwld = Drupal.t("file not in database"); Webfm.js_msg.inserted = Drupal.t(" files inserted into db"); Webfm.js_msg.notinserted = Drupal.t(" files failed to insert into db"); Webfm.js_msg.metadata = Drupal.t("Metadata"); Webfm.js_msg.fix_input = Drupal.t("correct input"); Webfm.js_msg.perm = Drupal.t("File Permissions"); Webfm.js_msg.noattachments = Drupal.t("No files attached."); Webfm.meta_msg = []; Webfm.meta_msg.fid = Drupal.t("fid"); Webfm.meta_msg.uid = Drupal.t("uid"); Webfm.meta_msg.uname = Drupal.t("file owner"); Webfm.meta_msg.name = Drupal.t("name"); Webfm.meta_msg.title = Drupal.t("title"); Webfm.meta_msg.desc = Drupal.t("description"); Webfm.meta_msg.lang = Drupal.t("language"); Webfm.meta_msg.pub = Drupal.t("publisher"); Webfm.meta_msg.format = Drupal.t("format"); Webfm.meta_msg.ver = Drupal.t("version"); Webfm.meta_msg.type = Drupal.t("image type"); Webfm.meta_msg.width = Drupal.t("width"); Webfm.meta_msg.height = Drupal.t("height"); Webfm.meta_msg.dl_cnt = Drupal.t("downloads"); Webfm.meta_msg.link = Drupal.t("link"); Webfm.perm_msg = []; Webfm.perm_msg.pub_view = Drupal.t("Public download"); Webfm.perm_msg.rol_view = Drupal.t("Role View/Download"); Webfm.perm_msg.rol_att = Drupal.t("Role Attach"); Webfm.perm_msg.rol_full = Drupal.t("Role Full Access"); Webfm.menu_msg = []; Webfm.menu_msg.mkdir = Drupal.t("Create Subdirectory"); Webfm.menu_msg.rmdir = Drupal.t("Delete Directory"); Webfm.menu_msg.rm = Drupal.t("Delete File"); Webfm.menu_msg.rendir = Drupal.t("Rename Directory"); Webfm.menu_msg.search = Drupal.t("Search Directory"); Webfm.menu_msg.ren = Drupal.t("Rename File"); Webfm.menu_msg.meta = Drupal.t("File meta data"); Webfm.menu_msg.att = Drupal.t("Attach to Node"); Webfm.menu_msg.det = Drupal.t("Detach from Node"); Webfm.menu_msg.dwnld = Drupal.t("Download as file"); Webfm.menu_msg.view = Drupal.t("View file"); Webfm.menu_msg.enum_menu = Drupal.t("Add file to database"); Webfm.menu_msg.denum = Drupal.t("Remove file from database"); Webfm.menu_msg.perm = Drupal.t("File permissions"); Webfm.menu_msg.paste = Drupal.t("Paste link in editor window"); //Do not translate any code below this line Webfm.current = null; // current directory // Options that modify behaviour. Webfm.options = { displayTree: true, // Display trees div. displayDir: true, // Display directory breadcrumbRoot: null, // Psuedo root for breadcrumb display. displayColumns: { name: true, modified: true, size: true, owner: true } }; Webfm.numColumns = -1; //Number of display columns Webfm.dragCont = null; Webfm.metaCont = null; Webfm.contextCont = null; Webfm.searchCont = null; Webfm.debugCont = null; Webfm.viewCont = null; Webfm.dragStart = null; Webfm.dragging = false; Webfm.oldOnContextMenu = null; Webfm.activeDropCont = null; Webfm.dropContainers = []; Webfm.attachContainer = null; Webfm.browser = null; Webfm.menuHT = null; Webfm.metadataHT = null; Webfm.dirTreeObj = null; Webfm.dirListObj = null; Webfm.attachObj = null; Webfm.alrtObj = null; Webfm.contextMenuObj = null; Webfm.progressObj = null; Webfm.dbgObj = null; Webfm.metaObj = null; Webfm.searchObj = null; Webfm.permObj = null; Webfm.permKey = null; Webfm.permHT = null; Webfm.permInfoHT = null; Webfm.renameActive = false; Webfm.admin = false; Webfm.zindex = 1000; Webfm.scrollVal = null; // freeze scroll Webfm.eventListeners = []; //Name of node edit form hidden field where attached node list is populated by js Webfm.attachFormInput = "edit-attachlist"; Webfm.icons = { epdf: "pdf", ephp: "php", ephps: "php", ephp4: "php", ephp5: "php", eswf: "swf", esfa: "swf", exls: "xls", eods: "xls", edoc: "doc", ertf: "doc", eodt: "doc", eodd: "doc", ezip: "zip", erar: "zip", egz: "zip", e7z: "zip", etxt: "doc", echm: "hlp", ehlp: "hlp", enfo: "nfo", expi: "xpi", ec: "c", eh: "h", emp3: "mp3", ewav: "mp3", esnd: "mp3", einc: "cod", esql: "sql", edbf: "sql", ediz: "nfo", eion: "nfo", emod: "mp3", es3m: "mp3", eavi: "avi", empg: "avi", empeg: "avi", ewma: "mp3", ewmv: "avi", edwg: "dwg", ejpg: "i", ejpeg: "i", egif: "i", epng: "i", etiff: "i", ebmp: "i", eico: "i", eai: "ai", eskp: "skp", emov: "qt", epps: "pps", eppt: "pps" }; Webfm.lastarea = null; /* ** Functions */ /** * Remember last used textarea for inserting file hrefs. */ function webfmSetlast() { Webfm.lastarea = this; } /** * Determine browser */ Webfm.browserDetect = function() { var b = navigator.userAgent.toLowerCase(); this.isIE = false; this.isOP = false; if(b.indexOf("msie") >= 0) { this.isIE = true; } if(b.indexOf("opera") >= 0) { this.isOP = true; } }; /** * Hashtable (used by directory listing cache and metadata) */ Webfm.ht = function() { this.flush(); }; Webfm.ht.prototype.put = function(key, value) { if((key === null) || (value === null)) { throw "NullPointerException {" + key + "},{" + value + "}"; } this.hash[key] = value; }; Webfm.ht.prototype.get = function(key) { return this.hash[key]; }; Webfm.ht.prototype.containsKey = function(key) { var i; for(i in this.hash) { if(i == key && this.hash[i] !== null) { return true; } } return false; }; Webfm.ht.prototype.remove = function(key) { if(this.hash[key]) { this.hash[key] = null; return true; } return false; }; Webfm.ht.prototype.dump = function() { var i, values; values = []; for(i in this.hash) { if(this.hash[i] !== null) { values.push(this.hash[i]); } } return values; }; Webfm.ht.prototype.flush = function() { this.hash = []; }; /** * Hashable Hashtable (used by menus) */ Webfm.hht = function() { this.flush(); }; Webfm.hht.prototype.put = function(key, obj) { if((key === null) || (obj === null)) { throw "NullPointerException {" + key + "},{" + obj + "}"; } //TODO improve null check if(this.hash[key] === null || typeof this.hash[key] === 'undefined') { this.keys[this.keys.length] = key; this.hash[key] = []; } // append new object to array this.hash[key].push(obj); }; Webfm.hht.prototype.get = function(key) { return this.hash[key]; }; Webfm.hht.prototype.remove = function(key) { if(this.hash[key]) { this.hash[key] = null; return true; } return false; }; Webfm.hht.prototype.removeSub = function(key, subkey) { if(this.hash[key][subkey]) { this.hash[key][subkey] = null; return true; } return false; }; Webfm.hht.prototype.flush = function() { this.hash = []; this.keys = []; }; //Webfm.metaElement objects have description/edit/max_size params Webfm.metaElement = function(desc, edit, size) { this.desc = desc; this.edit = edit; this.size = size; }; /** * Create Web File Manager at 'webfm' id anchor * ..or at node-edit 'webfm-inline' id anchor */ function webfmLayout() { var layoutDiv, textareas, i, textfields; layoutDiv = ''; // Initialize textarea for pasting file hrefs with the most often used // in case we try to paste before a textarea or -field was focussed. Webfm.lastarea = document.getElementById('edit-body'); if(!Webfm.lastarea) { Webfm.lastarea = document.getElementById('edit-comment'); } // Tell textareas and text fields to remember which one was last focussed. textareas = document.getElementsByTagName('textarea'); i = textareas.length; while(i > 0) { i = i - 1; textareas[i].onfocus = webfmSetlast; } textfields = document.getElementsByTagName('input'); i = textfields.length; while(i > 0) { i = i - 1; if(textfields[i].type == 'text') { textfields[i].onfocus = webfmSetlast; } } layoutDiv = Webfm.$('webfm'); if(layoutDiv) { Webfm.commonInterface(layoutDiv); if(Webfm.options.displayTree) { //first param forces trees refresh //second param forces list refresh Webfm.dirTreeObj.fetch(true, true); } else { Webfm.dirListObj.refresh(); } return; } // Shortcut to displaying files only via 'webfm-dir' div id. layoutDiv = Webfm.$('webfm-dir'); if(layoutDiv) { Webfm.options.displayTree = false; Webfm.commonInterface(layoutDiv); Webfm.dirListObj.refresh(); return; } layoutDiv = Webfm.$('webfm-inline'); if(layoutDiv) { Webfm.commonInterface(layoutDiv); //Add attach-list menu and attach option to listing menu try { Webfm.menuHT.put('file', new Webfm.menuElement(Webfm.menu_msg.att, Webfm.menuAttach, Webfm.menuFidVal)); Webfm.menuHT.put('det', new Webfm.menuElement(Webfm.menu_msg.meta, Webfm.menuGetMeta, '')); Webfm.menuHT.put('det', new Webfm.menuElement(Webfm.menu_msg.det, Webfm.menuDetach, '')); Webfm.menuHT.put('det', new Webfm.menuElement(Webfm.menu_msg.paste, Webfm.menuPasteHref, '')); } catch(err) { alert( Drupal.t("Creating Menu failed. \n") + err); } // attach-list anchored to 'webfm-attach' div in webfm_form_alter() Webfm.attachObj = new Webfm.attach('webfm-attach'); Webfm.attachObj.fetch(); if(Webfm.options.displayTree) { //first param forces trees refresh //second param forces list refresh Webfm.dirTreeObj.fetch(true, true); } else { if(Webfm.options.displayDir) { Webfm.dirListObj.refresh(); } } } } /* ** Initialize webfm on the current page (Must come after webfmLayout()). */ if(Drupal.jsEnabled) { $(window).load(webfmLayout); } //Attaches the upload behaviour to the upload form (borrowed jquery). function webfmUploadAutoAttach() { var uri, button, wrapper, hide, upload; button = 'wfmatt-button'; wrapper = 'wfmatt-wrapper'; hide = 'wfmatt-hide'; $('input.webfmupload').each(function() { uri = this.value; upload = new Webfm.jsUpload(uri, button, wrapper, hide); }); } Webfm.commonInterface = function (parent) { var layout_cont, elTreeDiv; Webfm.browser = new Webfm.browserDetect(); //create the popup container for file/dir object draggables Webfm.dragCont = new Webfm.popup("webfm-dragCont"); //create the popup container for image view Webfm.viewCont = new Webfm.popup("webfm-viewCont"); //create context menu popup Webfm.oldOnContextMenu = document.body.oncontextmenu; Webfm.contextCont = new Webfm.popup("webfm-cxtCont"); Webfm.contextMenuObj = new Webfm.context(Webfm.contextCont); //create metadata popup Webfm.metaCont = new Webfm.popup("webfm-paneCont"); Webfm.metaObj = new Webfm.metadata(Webfm.metaCont, 440, 420); //create file permissions popup Webfm.permCont = new Webfm.popup("webfm-permCont"); Webfm.permObj = new Webfm.perm(Webfm.permCont, 300, 200); //create search popup Webfm.searchCont = new Webfm.popup("webfm-searchCont"); Webfm.searchObj = new Webfm.search(Webfm.searchCont, 280, 200); //create debug popup Webfm.debugCont = new Webfm.popup("webfm-debugCont"); Webfm.dbgObj = new Webfm.debug(Webfm.debugCont, 800, 400); //build menu hashtable //global to allow external functions to push new menu elements into the menu array Webfm.menuHT = new Webfm.hht(); try { //Webfm.menuHT.put('root', new Webfm.menuElement(Webfm.menu_msg.mkdir, Webfm.menuMkdir, Webfm.menuAdmin)); Webfm.menuHT.put('root', new Webfm.menuElement(Webfm.menu_msg.mkdir, Webfm.menuMkdir, Webfm.usCreateDir)); //xl666 modification Webfm.menuHT.put('root', new Webfm.menuElement(Webfm.menu_msg.search, Webfm.menuSearch, '')); //Webfm.menuHT.put('dir', new Webfm.menuElement(Webfm.menu_msg.mkdir, Webfm.menuMkdir, Webfm.menuAdmin)); //Webfm.menuHT.put('dir', new Webfm.menuElement(Webfm.menu_msg.rmdir, Webfm.menuRemove, Webfm.menuAdmin)); //Webfm.menuHT.put('dir', new Webfm.menuElement(Webfm.menu_msg.rendir, Webfm.menuRename, Webfm.menuAdmin)); Webfm.menuHT.put('dir', new Webfm.menuElement(Webfm.menu_msg.mkdir, Webfm.menuMkdir, Webfm.usCreateDir));//xl666 modification Webfm.menuHT.put('dir', new Webfm.menuElement(Webfm.menu_msg.rmdir, Webfm.menuRemove, Webfm.menuFileUid));//xl666 modification Webfm.menuHT.put('dir', new Webfm.menuElement(Webfm.menu_msg.rendir, Webfm.menuRename, Webfm.menuRenFileUid)); // xl666 modification Webfm.menuHT.put('dir', new Webfm.menuElement(Webfm.menu_msg.search, Webfm.menuSearch, '')); Webfm.menuHT.put('file', new Webfm.menuElement(Webfm.menu_msg.rm, Webfm.menuRemove, Webfm.menuFileUid)); Webfm.menuHT.put('file', new Webfm.menuElement(Webfm.menu_msg.ren, Webfm.menuRename, Webfm.menuRenFileUid)); Webfm.menuHT.put('file', new Webfm.menuElement(Webfm.menu_msg.meta, Webfm.menuGetMeta, Webfm.menuFidVal)); Webfm.menuHT.put('file', new Webfm.menuElement(Webfm.menu_msg.view, Webfm.menuView, '')); Webfm.menuHT.put('file', new Webfm.menuElement(Webfm.menu_msg.dwnld, Webfm.menuDownload, Webfm.menuFidVal)); Webfm.menuHT.put('file', new Webfm.menuElement(Webfm.menu_msg.enum_menu, Webfm.menuInsert, Webfm.menuAdminNoFidVal)); Webfm.menuHT.put('file', new Webfm.menuElement(Webfm.menu_msg.denum, Webfm.menuDbRem, Webfm.menuAdminFidVal)); Webfm.menuHT.put('file', new Webfm.menuElement(Webfm.menu_msg.perm, Webfm.menuGetPerm, Webfm.menuFilePerm)); Webfm.menuHT.put('file', new Webfm.menuElement(Webfm.menu_msg.paste, Webfm.menuPasteHref, '')); } catch (err) { alert(Drupal.t("Creating Menu failed. \n") + err); } //build metadata hashtable //Webfm.metaElement objects have description/edit/max_size properties Webfm.metadataHT = new Webfm.ht(); Webfm.metadataHT.put('id', new Webfm.metaElement(Webfm.meta_msg.fid, false, 0)); Webfm.metadataHT.put('u', new Webfm.metaElement(Webfm.meta_msg.uid, true, 10)); Webfm.metadataHT.put('un', new Webfm.metaElement(Webfm.meta_msg.uname, false, 0)); Webfm.metadataHT.put('n', new Webfm.metaElement(Webfm.meta_msg.name, false, 0)); Webfm.metadataHT.put('t', new Webfm.metaElement(Webfm.meta_msg.title, true, 255)); Webfm.metadataHT.put('d', new Webfm.metaElement(Webfm.meta_msg.desc, true, 256)); Webfm.metadataHT.put('l', new Webfm.metaElement(Webfm.meta_msg.lang, true, 16)); Webfm.metadataHT.put('p', new Webfm.metaElement(Webfm.meta_msg.pub, true, 255)); Webfm.metadataHT.put('f', new Webfm.metaElement(Webfm.meta_msg.format, true, 255)); Webfm.metadataHT.put('v', new Webfm.metaElement(Webfm.meta_msg.ver, false, 0)); Webfm.metadataHT.put('i', new Webfm.metaElement(Webfm.meta_msg.type, false, 0)); Webfm.metadataHT.put('w', new Webfm.metaElement(Webfm.meta_msg.width, false, 0)); Webfm.metadataHT.put('h', new Webfm.metaElement(Webfm.meta_msg.height, false, 0)); Webfm.metadataHT.put('c', new Webfm.metaElement(Webfm.meta_msg.dl_cnt, false, 0)); Webfm.metadataHT.put('lk', new Webfm.metaElement(Webfm.meta_msg.link, false, 0)); //build permissions hashtable //key is permission bit, value is string Webfm.permInfoHT = new Webfm.ht(); Webfm.permInfoHT.put("id", Webfm.meta_msg.fid); Webfm.permInfoHT.put("u", Webfm.meta_msg.uid); Webfm.permInfoHT.put("n", Webfm.meta_msg.name); Webfm.permKey = ['1', '2', '4', '8']; Webfm.permHT = new Webfm.ht(); Webfm.permHT.put('1', Webfm.perm_msg.pub_view); Webfm.permHT.put('2', Webfm.perm_msg.rol_view); Webfm.permHT.put('4', Webfm.perm_msg.rol_att); Webfm.permHT.put('8', Webfm.perm_msg.rol_full); layout_cont = Webfm.ce('div'); Webfm.alrtObj = new Webfm.alert(layout_cont, 'webfm-alert'); //Container for tree(s) if(Webfm.options.displayTree) { elTreeDiv = Webfm.ce('div'); elTreeDiv.setAttribute('id', 'webfm-tree'); //css id layout_cont.appendChild(elTreeDiv); Webfm.dirTreeObj = new Webfm.treeBuilder( elTreeDiv, Webfm.menuHT.get('root'), Webfm.menuHT.get('dir')); } //progress indicator Webfm.progressObj = new Webfm.progress(layout_cont, 'webfm-progress'); //Directory Listing if(Webfm.options.displayDir) { var claz = Webfm.options.displayTree ? 'narrow' : 'wide'; Webfm.dirListObj = new Webfm.list(layout_cont, 'webfm-dirlist', 'file', claz, true, Webfm.menuHT.get('dir'), Webfm.menuHT.get('file')); } //insert trees, listing, search, metadata, progress and alert divs before upload fset built in php parent.insertBefore(layout_cont, parent.firstChild); // parent.appendChild(layout_cont); //If upload desired to be placed above browser webfmUploadAutoAttach(); }; /** * Webfm.jsUpload constructor * 1st param is upload iframe url * 2nd param is id of redirected button object) * 3rd param is id of container of html repainted by ajax * 4th param is id of upload input field * TODO: fix progress throbber */ Webfm.jsUpload = function (uri, button, wrapper, hide) { // Note: these elements are replaced after an upload, so we re-select them // everytime they are needed. this.button = '#' + button; this.wrapper = '#' + wrapper; this.hide = '#' + hide; Drupal.redirectFormButton(uri, $(this.button).get(0), this); }; //Handler for the form redirection submission. Webfm.jsUpload.prototype.onsubmit = function() { var hide; Webfm.progressObj.show(Webfm.js_msg.work, "blue"); hide = this.hide; $(hide).fadeOut('slow'); }; //Handler for the form redirection completion. Webfm.jsUpload.prototype.oncomplete = function (data) { var div, hide, cp, replaceButton, listener; // Remove old form Drupal.freezeHeight(); // Avoid unnecessary scrolling $(this.wrapper).html(''); // Place HTML into temporary div div = document.createElement('div'); $(div).html(data.html); $(this.wrapper).append(div); //div with id='replace-options' present only in case of file overwrite this.confirm = Webfm.$('replace-options'); if(this.confirm) { hide = this.hide; $(hide).fadeOut('slow'); cp = this; this.confirm.id = 'replace-options'; replaceButton = Webfm.ce('input'); replaceButton.setAttribute('type', 'button'); replaceButton.setAttribute('value', Webfm.js_msg.submit); listener = Webfm.eventListenerAdd(Webfm.eventListeners, replaceButton, "click", function(e) {cp.submit(); Webfm.stopEvent(e); }); this.confirm.appendChild(replaceButton); this.confirm.file = data.file; } else { $(this.hide, div).fadeIn('slow'); webfmUploadAutoAttach(); } Drupal.unfreezeHeight(); Webfm.progressObj.hide(); Webfm.dirListObj.refresh(); if(typeof (Webfm.$('webfm-inline')) !== 'undefined' && Webfm.$('webfm-inline') !== null) { // attach file to node if inside node-edit if(typeof data.fid !== 'undefined' && data.fid !== null) { Webfm.menuAttach(null, data.fid); } } }; //Handler for the form redirection error. Webfm.jsUpload.prototype.onerror = function (error) { alert(Drupal.t("An error occurred:\n\n") + error); Webfm.progressObj.hide(); if(this.confirm) { Webfm.clearNodeById('replace-options'); } // Undo hide $(this.hide).css({ position: 'static', left: '0px' }); }; Webfm.jsUpload.prototype.submit = function() { var inputs, selection, i, url, postObj; inputs = []; selection = ''; inputs = this.confirm.getElementsByTagName('input'); for(i = 0; i < inputs.length; i++) { if(inputs[i].checked === true) { selection = i; break; } } if(typeof selection != 'undefined') { url = Webfm.ajaxUrl(); Webfm.progressObj.show(Webfm.js_msg.work, "blue"); postObj = { action: encodeURIComponent("version"), param0: encodeURIComponent(selection), param1: encodeURIComponent(this.confirm.file)}; Webfm.HTTPPost(url, this.callback, this, postObj); } }; Webfm.jsUpload.prototype.callback = function (string, xmlhttp, cp) { var parent, hide, result, elDiv; Webfm.progressObj.hide(); // Remove overwrite radios parent = cp.confirm.parentNode; parent.removeChild(parent.firstChild); hide = cp.hide; if(xmlhttp.status == 200) { result = Drupal.parseJson(string); if(result.status) { Webfm.dirListObj.refresh(); } cp.confirm.style.display = 'none'; // Insert ajax feedback before upload form elDiv = Webfm.ce('div'); if(result.status) { elDiv.className = 'upload-msg'; } else { elDiv.className = 'upload-msg-err'; } elDiv.appendChild(Webfm.ctn(result.data.msg)); $(hide).before($(elDiv)); // Undo hide Webfm.dbgObj.dbg("hide:", Webfm.dump(hide)); $(hide).css({ display: 'block' }); webfmUploadAutoAttach(); if(typeof (Webfm.$('webfm-inline')) != 'undefined' && Webfm.$('webfm-inline') !== null) { // attach file to node if inside node-edit if(typeof result.data.fid !== 'undefined' && result.data.fid !== null) { Webfm.menuAttach(null, result.data.fid); } } } else { Webfm.alrtObj.msg(Webfm.js_msg.ajaxerr); } }; /** * Webfm.list constructor * 1st param is object to append this list object to * 2nd param is base id of listing (multiple listing objects must have unique ids) * 3rd param is base id of file rows of table * 4th param sets styling for listing * 5th param enables drag and drop * 6th param is directory menu array * 7th param is file menu array */ Webfm.list = function (parent, id, type, class_name, dd_enable, dir_menu, file_menu) { var wl, node, elTable, elTableBody, elTr, elTd, elA, elImg, listener, elSpan; wl = this; this.id = id; this.type = type; this.dd_enable = dd_enable; this.url = Webfm.ajaxUrl(); this.sc_n = 0; this.sc_m = 0; this.sc_s = 0; this.content = ''; this.iconDir = getWebfmIconDir(); this.dir_menu = dir_menu; this.file_menu = file_menu; //directory cache hashtable (key= directory path, val= directory contents) this.cache = new Webfm.ht(); this.eventListeners = []; //Get the number of columns being displayed Webfm.numColumns = 0; if(Webfm.options.displayColumns.name) {Webfm.numColumns++;} if(Webfm.options.displayColumns.modified) {Webfm.numColumns++;} if(Webfm.options.displayColumns.size) {Webfm.numColumns++; } //if(getWebfmOwnerColumn() && Webfm.options.displayColumns.owner) {Webfm.numColumns++;} if(Webfm.options.displayColumns.owner) {Webfm.numColumns++;} node = Webfm.ce("div"); node.setAttribute('id', this.id); node.className = class_name; this.obj = node; elTable = Webfm.ce('table'); elTableBody = Webfm.ce('tbody'); //elTableBody.setAttribute('id', this.id + 'body'); this.body = elTableBody; // First Row elTr = Webfm.ce('tr'); elTr.setAttribute('id', 'webfm-top-tr'); // Refresh Icon elTd = Webfm.ce('td'); elTd.className = 'navi icon'; elA = Webfm.ce('a'); elA.setAttribute('href', '#'); elA.setAttribute('title', Webfm.js_msg.refresh); elImg = Webfm.ce('img'); elImg.setAttribute('src', this.iconDir + '/r.gif'); elImg.setAttribute('alt', Webfm.js_msg.refresh); elA.appendChild(elImg); elTd.appendChild(elA); elTr.appendChild(elTd); listener = Webfm.eventListenerAdd(Webfm.eventListeners, elA, "click", function(e) { wl.refresh(Webfm.current); Webfm.stopEvent(e); }); // Breadcrumb trail elTd = Webfm.ce('td'); elTd.colSpan = Webfm.numColumns < 2 ? 2 : Webfm.numColumns; elTd.setAttribute('id', 'webfm-bcrumb-td'); elTd.setAttribute('class', 'navi'); // Build breadcrumb trail inside span elSpan = Webfm.ce('span'); elSpan.setAttribute('id', this.id + 'bcrumb'); elTd.appendChild(elSpan); elTr.appendChild(elTd); elTableBody.appendChild(elTr); // Second Row elTr = Webfm.ce('tr'); this.secondRow = elTr; // icon column elTd = Webfm.ce('td'); elTd.className = 'head'; elTr.appendChild(elTd); // Sort dir/files column if(Webfm.options.displayColumns.name) { elTd = Webfm.ce('td'); if(Webfm.numColumns < 2 ) {elTd.colSpan = 2;} elTd.className = 'head'; elA = Webfm.ce('a'); elA.setAttribute('href', '#'); elA.setAttribute('title', Webfm.js_msg.sort); listener = Webfm.eventListenerAdd(Webfm.eventListeners, elA, "click", function(e) { wl.sc_n ^= 1; wl.loadList("n"); wl.sortIcon(e, wl.sc_n); Webfm.stopEvent(e); }); elImg = Webfm.ce('img'); elImg.setAttribute('alt', Webfm.js_msg.sort); elImg.setAttribute('src', this.iconDir + '/down.gif'); elA.appendChild(elImg); elA.appendChild(Webfm.ctn(Webfm.js_msg.column1)); elTd.appendChild(elA); elTr.appendChild(elTd); } // date/time column if(Webfm.options.displayColumns.modified) { elTd = Webfm.ce('td'); if(Webfm.numColumns < 2 ) {elTd.colSpan = 2;} elTd.className = 'head'; elA = Webfm.ce('a'); elA.setAttribute('href', '#'); listener = Webfm.eventListenerAdd(Webfm.eventListeners, elA, "click", function(e) { wl.sc_m ^= 1; wl.loadList("m"); wl.sortIcon(e, wl.sc_m); Webfm.stopEvent(e); }); elImg = Webfm.ce('img'); elImg.setAttribute('alt', Webfm.js_msg.sort); elImg.setAttribute('src', this.iconDir + '/down.gif'); elA.appendChild(elImg); elA.appendChild(Webfm.ctn(Webfm.js_msg.column2)); elTd.appendChild(elA); elTr.appendChild(elTd); } // size column if(Webfm.options.displayColumns.size) { elTd = Webfm.ce('td'); if(Webfm.numColumns < 2) {elTd.colSpan = 2;} elTd.className = 'head'; elA = Webfm.ce('a'); elA.setAttribute('href', '#'); listener = Webfm.eventListenerAdd(Webfm.eventListeners, elA, "click", function(e) { wl.sc_s ^= 1; wl.loadList("s"); wl.sortIcon(e, wl.sc_s); Webfm.stopEvent(e); }); elImg = Webfm.ce('img'); elImg.setAttribute('alt', Webfm.js_msg.sort); elImg.setAttribute('src', this.iconDir + '/down.gif'); elA.appendChild(elImg); elA.appendChild(Webfm.ctn(Webfm.js_msg.column3)); elTd.appendChild(elA); elTr.appendChild(elTd); } // owner column //if(getWebfmOwnerColumn() && Webfm.options.displayColumns.owner ) { if(Webfm.options.displayColumns.owner ) { elTd = Webfm.ce('td'); if(Webfm.numColumns < 2) {elTd.colSpan = 2;} elTd.className = 'head'; elA = Webfm.ce('a'); elA.setAttribute('href', '#'); listener = Webfm.eventListenerAdd(Webfm.eventListeners, elA, "click", function(e) { wl.sc_o ^= 1; wl.loadList("o"); wl.sortIcon(e, wl.sc_o); Webfm.stopEvent(e); }); elImg = Webfm.ce('img'); elImg.setAttribute('alt', Webfm.js_msg.sort); elImg.setAttribute('src', this.iconDir + '/down.gif'); elA.appendChild(elImg); elA.appendChild(Webfm.ctn(Webfm.js_msg.column4)); elTd.appendChild(elA); elTr.appendChild(elTd); } elTableBody.appendChild(elTr); elTable.appendChild(elTableBody); node.appendChild(elTable); parent.appendChild(node); }; Webfm.list.prototype.selectBC = function(event) { var el = event.target || window.event.srcElement; Webfm.selectDir(el.title); }; Webfm.list.prototype.listenerfn_bcrumb_click = function(cp) { var listenerfn = function(e) { cp.selectBC(e); Webfm.stopEvent(e); }; return listenerfn; }; Webfm.list.prototype.bcrumb = function() { var cp, i, pth, elA, listener, elSpan, l, adminPrefix, broot, bRoot; cp = this; pth = []; Webfm.clearNodeById(this.id + 'bcrumb'); elSpan = Webfm.$(this.id + 'bcrumb'); broot = []; if(Webfm.options.breadcrumbRoot) { l = this.content.current.indexOf(Webfm.options.breadcrumbRoot ); adminPrefix = this.content.current.substring(0, l); bRoot = adminPrefix + Webfm.options.breadcrumbRoot; broot = bRoot.split('/'); if(broot[0] === '') { broot.shift(); } broot.pop(); } for(i = 0; i < this.content.bcrumb.length - 1; i++) { pth.push(this.content.bcrumb[i]); if(this.content.bcrumb[i] == broot[i]) { continue; } elSpan.appendChild(Webfm.ctn(" / ")); // No breadcrumb link necessary for current directory elA = Webfm.ce('a'); elA.setAttribute('href', '#'); // join previous loop iterations to create path for title elA.setAttribute('title', "/" + pth.join("/")); elA.appendChild(Webfm.ctn(this.content.bcrumb[i])); //IE fix listener = Webfm.eventListenerAdd(Webfm.eventListeners, elA, "click", Webfm.list.prototype.listenerfn_bcrumb_click(cp)); elSpan.appendChild(elA); } elSpan.appendChild(Webfm.ctn(" / ")); elSpan.appendChild(Webfm.ctn(this.content.bcrumb[i])); }; Webfm.list.prototype.sortIcon = function (event, up_down) { var el = event.target || window.event.srcElement; if(el.firstChild) { el.firstChild.src = this.iconDir + '/' + (up_down ? "up" : "down") + '.gif'; } }; Webfm.list.prototype.refresh = function (path, rename_dir) { if(path === null || typeof (path) === 'undefined') { path = Webfm.current; } this.cache.remove(path); if(typeof rename_dir != 'undefined') { this.rename_dir = rename_dir; } this.fetch(path); }; Webfm.list.prototype.fetch = function (curr_dir) { var uploadpath, postObj; Webfm.alrtObj.msg(); if(curr_dir || (curr_dir = Webfm.current)) { Webfm.progressObj.show(Webfm.js_msg.work, "blue"); //update current dir if specific dir selected Webfm.current = curr_dir; Webfm.dbgObj.dbg('fetch: ', curr_dir); if(this.cache.containsKey(Webfm.current)) { Webfm.dbgObj.dbg('cache hit: ', Webfm.current); this.content = this.cache.get(Webfm.current); this.bcrumb(); this.loadList(); uploadpath = Webfm.$('edit-webfmuploadpath'); if(uploadpath) { uploadpath.value = Webfm.current; } Webfm.progressObj.hide(); } else { Webfm.admin = false; postObj = { action: encodeURIComponent("read"), param0: encodeURIComponent(curr_dir) }; Webfm.HTTPPost(this.url, this.callback, this, postObj); } } else { Webfm.dbgObj.dbg(Webfm.js_msg.curdirundef); } }; Webfm.list.prototype.callback = function (string, xmlhttp, cp) { var uploadpath, found, i; found = false; Webfm.progressObj.hide(); if(xmlhttp.status == 200) { cp.content = Drupal.parseJson(string); if(cp.content.status) { cp.cache.put(cp.content.current, cp.content); //Sets client permissions - server will always validate any action Webfm.admin = cp.content.admin; cp.bcrumb(); cp.loadList("n"); // Insert current directory path into upload form uploadpath = Webfm.$('edit-webfmuploadpath'); if(uploadpath) { uploadpath.value = cp.content.current; Webfm.dbgObj.dbg('uploadpath: ', uploadpath.value); } Webfm.current = cp.content.current; cp.adminCtl(Webfm.admin); if(cp.rename_dir) { found = false; for(i = 0; i < Webfm.dirListObj.dirrows.length; i++) { if(cp.dirrows[i].clickObj.title == "/" + cp.rename_dir) { found = true; break; } } if(found) { Webfm.menuRename(cp.dirrows[i]); } } } else { Webfm.alrtObj.str_arr(cp.content.data); } } else { Webfm.alrtObj.msg(Webfm.js_msg.ajaxerr); } }; //build admin icons for create dir and file db insertion //maintain 4 column table Webfm.list.prototype.adminCtl = function (admin) { var col_span, wl, elTd, elSpan, elA, elImg, listener; col_span = Webfm.numColumns < 2 ? 2 : Webfm.numColumns; //if(admin) { if(Webfm.usCreateDir("")) { //xl666 modification if(Webfm.$('webfm-bcrumb-td').colSpan == col_span) { wl = this; Webfm.$('webfm-bcrumb-td').colSpan = col_span - 1; // Create New Directory and allow db insertions elTd = Webfm.ce('td'); elTd.className = "ctls-td"; elSpan = Webfm.ce('span'); elSpan.id = this.id + "-ctls"; elA = Webfm.ce('a'); elA.title = Webfm.js_msg.newdir; elImg = Webfm.ce('img'); elImg.setAttribute('alt', Webfm.js_msg.newdir); elImg.setAttribute('src', this.iconDir + '/dn.gif'); elA.appendChild(elImg); listener = Webfm.eventListenerAdd(Webfm.eventListeners, elA, "click", function(e) { Webfm.stopEvent(e); wl.mkdir(); }); listener = Webfm.eventListenerAdd(Webfm.eventListeners, elA, "mouseover", function(e) { wl.hover(e, true, 0); }); listener = Webfm.eventListenerAdd(Webfm.eventListeners, elA, "mouseout", function(e) { wl.hover(e, false, 0); }); elSpan.appendChild(elA); if (admin) { elA = Webfm.ce('a'); elA.title = Webfm.js_msg.addtodb; elImg = Webfm.ce('img'); elImg.setAttribute('alt', Webfm.js_msg.addtodb); elImg.setAttribute('src', this.iconDir + '/add_loc.gif'); elA.appendChild(elImg); listener = Webfm.eventListenerAdd(Webfm.eventListeners, elA, "click", function(e) { Webfm.stopEvent(e); wl.enumLocal(); }); listener = Webfm.eventListenerAdd(Webfm.eventListeners, elA, "mouseover", function(e) { wl.hover(e, true); }); listener = Webfm.eventListenerAdd(Webfm.eventListeners, elA, "mouseout", function(e) { wl.hover(e, false); }); elSpan.appendChild(elA); elA = Webfm.ce('a'); elA.title = Webfm.js_msg.recursivecaddaddtodb; elImg = Webfm.ce('img'); elImg.setAttribute('alt', Webfm.js_msg.recursivecaddaddtodb); elImg.setAttribute('src', this.iconDir + '/add_recur.gif'); elA.appendChild(elImg); listener = Webfm.eventListenerAdd(Webfm.eventListeners, elA, "click", function(e) { Webfm.stopEvent(e); wl.enumRecur(); }); listener = Webfm.eventListenerAdd(Webfm.eventListeners, elA, "mouseover", function(e) { wl.hover(e, true); }); listener = Webfm.eventListenerAdd(Webfm.eventListeners, elA, "mouseout", function(e) { wl.hover(e, false); }); elSpan.appendChild(elA); } elTd.appendChild(elSpan); Webfm.$('webfm-top-tr').appendChild(elTd); } else { Webfm.$('webfm-bcrumb-td').colSpan = col_span - 1; } } else { Webfm.$('webfm-bcrumb-td').colSpan = col_span; } }; //IE does not understand 'this' inside event listener func Webfm.list.prototype.hover = function (event, state) { var el = event.target || window.event.srcElement; el.className = state ? 'selected' : ''; }; //Function to create a new directory Webfm.list.prototype.mkdir = function() { Webfm.alrtObj.msg(); Webfm.progressObj.show(Webfm.js_msg.work, "blue"); var postObj = { action: encodeURIComponent("mkdir"), param0: encodeURIComponent(this.content.current) }; Webfm.HTTPPost(this.url, this.mkdir_callback, this, postObj); }; Webfm.list.prototype.enumLocal = function() { if(Webfm.confirm(Webfm.js_msg.enum_local)) { Webfm.insert(this.content.current, "dir"); } }; Webfm.list.prototype.enumRecur = function() { if(Webfm.confirm(Webfm.js_msg.enum_recur)) { Webfm.insert(this.content.current, "recur"); } }; Webfm.list.prototype.mkdir_callback = function (string, xmlhttp, cp) { var result; Webfm.progressObj.hide(); if(xmlhttp.status == 200) { result = Drupal.parseJson(string); Webfm.dbgObj.dbg("mkdir data:", result.data); if(result.status) { cp.refresh(cp.content.current, result.data); if(Webfm.dirTreeObj) { //we just updated the listing - 2nd var must be false Webfm.dirTreeObj.fetch(true, false); } } else { Webfm.alrtObj.str_arr(result.data); } } else { Webfm.alrtObj.msg(Webfm.js_msg.ajaxerr); } }; Webfm.list.prototype.loadList = function (sortcol) { var i, filerow; this.c_dir = 0; this.c_fil = 0; //remove all rows beneath second row of listing table body while(this.secondRow.nextSibling) { this.body.removeChild(this.secondRow.nextSibling); } //clear event listeners for old listing Webfm.eventUnregister(this.eventListeners); // Build directory rows and append to table if(this.content.dirs.length) { this.dirrows = []; //IE hack since dirs have no size and no owner if(!(Webfm.browser.isIE && sortcol == "s") && sortcol != "o") { this.sortTable(this.content.dirs, sortcol); } for(i = 0; i < this.content.dirs.length; i++) { this.dirrows[i] = new Webfm.dirrow(this.body, this.content.dirs[i], i, this.dd_enable, this.dir_menu, this.eventListeners); } } // Build file rows and append to table // type determines file context menu if(this.content.files.length) { this.sortTable(this.content.files, sortcol); for(i = 0; i < this.content.files.length; i++) { filerow = new Webfm.filerow(this.body, this.content.files[i], this.type, i, this.dd_enable, this.file_menu, this.eventListeners); } } }; Webfm.list.prototype.sortTable = function (arr, key) { switch(key) { case "o": arr.sort(Webfm.sortByOwner); if(this.sc_o) { arr.reverse(); } break; case "s": arr.sort(Webfm.sortBySize); if(this.sc_s) { arr.reverse(); } break; case "m": arr.sort(Webfm.sortByModified); if(this.sc_m) { arr.reverse(); } break; case "n": arr.sort(Webfm.sortByName); if(this.sc_n) { arr.reverse(); } break; } }; /** * Webfm.dirrow constructor * 1st param is parent obj * 2nd param is dir object * 3rd param is unique number to append to id * 4th param enables drag and drop * 5th param is directory menu array * 6th param is event listener array for closure cleanup */ Webfm.dirrow = function (parent, dir, index, dd_enable, menu, eventListenerArr) { var dr, dc_id, elTr, elTd, elImg, owner, listener, size; dr = this; this.uid = dir.u; //xl666 modification this.draggable = dd_enable; this.iconDir = getWebfmIconDir(); //id used for drop container dc_id = 'webfm-dirlist' + index; elTr = Webfm.ce('tr'); this.element = elTr; this.element.className = 'dirrow'; elTr.setAttribute('id', dc_id); elTr.setAttribute('title', dir.p); //if(dd_enable && Webfm.admin) { if(dd_enable && (Webfm.admin || this.uid==getWebfmUid())) {//xl666 modification //Webfm.draggable must be created after title assigned to set current path this.dd = new Webfm.draggable(Webfm.dragCont, elTr, this.element.className); } else { this.draggable = false; } elTd = Webfm.ce('td'); elImg = Webfm.ce('img'); elImg.setAttribute('src', this.iconDir + '/d.gif'); elImg.setAttribute('id', dc_id + 'dd'); elImg.setAttribute('alt', Webfm.js_msg.u_dir); this.menu = menu; elTd.appendChild(elImg); elTr.appendChild(elTd); if(Webfm.options.displayColumns.name) { elTd = Webfm.ce('td'); if(Webfm.numColumns < 2) {elTd.colSpan = 2;} // Title of link = path this.clickObj = Webfm.ce('a'); this.clickObj.setAttribute('href', '#'); //title is path this.clickObj.setAttribute('title', dir.p); this.clickObj.appendChild(Webfm.ctn(dir.n)); elTd.appendChild(this.clickObj); elTr.appendChild(elTd); } if(Webfm.options.displayColumns.modified) { elTd = Webfm.ce('td'); if(Webfm.numColumns < 2) {elTd.colSpan = 2;} elTd.className = 'txt'; elTd.appendChild(Webfm.ctn(Webfm.convertunixtime(parseInt(dir.m, 10)))); elTr.appendChild(elTd); } if(Webfm.options.displayColumns.size) { elTd = Webfm.ce('td'); if(Webfm.numColumns < 2) {elTd.colSpan = 2;} elTd.className = 'txt'; if(dir.s) { size = Webfm.size(dir.s); elTd.appendChild(Webfm.ctn(size)); } elTr.appendChild(elTd); } // Add td if owner column enabled //if(getWebfmOwnerColumn() && Webfm.options.displayColumns.owner) { if(Webfm.options.displayColumns.owner) { elTd = Webfm.ce('td'); if(Webfm.numColumns < 2) {elTd.colSpan = 2;} elTd.className = 'txt'; // if(dir.o) { // owner = Webfm.ce(dir.o); if(dir.u) { // xl666 modification owner = dir.un; //xl666 modification elTd.appendChild(Webfm.ctn(owner)); } elTr.appendChild(elTd); } //mouse event listeners if(dd_enable) { listener = Webfm.eventListenerAdd(eventListenerArr, this.element, "mousedown", function(e) { Webfm.contextMenuObj.hideContextMenu(e); dr.select(e); }); } else { listener = Webfm.eventListenerAdd(eventListenerArr, this.element, "click", function(e) { Webfm.contextMenuObj.hideContextMenu(e); if(Webfm.renameActive === false) { Webfm.selectDir(dr.element.title); } }); } if(this.draggable) { listener = Webfm.eventListenerAdd(eventListenerArr, this.element, "mouseover", function() { dr.hover(dr.element, true); }); listener = Webfm.eventListenerAdd(eventListenerArr, this.element, "mouseout", function() { dr.hover(dr.element, false); }); } if(Webfm.browser.isOP) { listener = Webfm.eventListenerAdd(eventListenerArr, this.element, "mousedown", function(e) { if(e && e.button === 0 && e.altKey === true) { if(Webfm.renameActive === false) { Webfm.contextMenuObj.showContextMenu(e, dr); } Webfm.stopEvent(e); } }); } else { listener = Webfm.eventListenerAdd(eventListenerArr, this.element, "contextmenu", function(e) { if(Webfm.renameActive === false) { Webfm.contextMenuObj.showContextMenu(e, dr); } Webfm.stopEvent(e); }); } parent.appendChild(elTr); this.c_dir = this.c_dir + 1; }; Webfm.dirrow.prototype.hover = function (el, state) { if(state) { el.className += ' selected'; } else { el.className = el.className.split(' ', 1); } }; Webfm.dirrow.prototype.select = function (event) { var cp, rightclick; cp = this; if(Webfm.renameActive === true) { return false; } event = event || window.event; if(event.target || event.srcElement) { if(this.clickObj) { // Determine mouse button rightclick = Webfm.rclick(event); if(rightclick) { return false; } setTimeout(function() { //if click then no dragging... if(Webfm.dragging === false) { Webfm.selectDir(cp.element.title); } }, 200); } //passthrough if(typeof this.dd != "undefined") { this.dd.mouseButton(event); } } return false; }; /** * Webfm.filerow constructor * 1st param is parent obj * 2nd param is fileobject (see desc below) * 3rd param is base id name of file row * 4th param is unique number to append to id * 5th param enables drag and drop * 6th param is file menu array * 7th param is event listener array for closure cleanup * * fileobject elements: * id -> fid * n -> file name * p -> path (includes name) * s -> file size * m -> modified date * e -> mimetype extension * i -> image file. * w -> image width * h -> image height * un -> file owner user name */ Webfm.filerow = function (parent, fileObj, idtype, index, dd_enable, file_menu, eventListenerArr) { var fr, elTr, elTd, elImg, size, listener; fr = this; this.draggable = dd_enable; this.iconDir = getWebfmIconDir(); this.ext = fileObj.e; this.filepath = fileObj.p + '/' + fileObj.n; this.uid = fileObj.u; this.ftitle = null; this.funame = fileObj.un; if(typeof fileObj.ftitle != "undefined") { this.ftitle = fileObj.ftitle; } elTr = Webfm.ce('tr'); this.element = elTr; elTr.className = idtype + 'row'; //drag object id used for download type if(typeof fileObj.id == "undefined") { this.row_id = 'nodb' + index; } else { if(fileObj.id === 0) { this.row_id = idtype + index; } else { //TODO: fix - this causes repeat ids for attach rows! this.row_id = 'fid' + fileObj.id; } } elTr.setAttribute('id', this.row_id); //title of drag object is path for move elTr.setAttribute('title', this.filepath); if(dd_enable) { //Only admins or owner of file can move it if(Webfm.admin || fileObj.u == getWebfmUid()) { this.dd = new Webfm.draggable(Webfm.dragCont, elTr, elTr.className); } else { this.draggable = false; } } elTd = Webfm.ce('td'); elImg = Webfm.ce('img'); if(fileObj.i) { elImg.setAttribute('src', this.iconDir + '/i.gif'); } else { elImg.setAttribute('src', fr.getIconByExt()); } if((typeof fileObj.id == "undefined") || fileObj.id === 0 || fileObj.id === false) { // Make icon transparent if file not in db - TODO: fix for IE elImg.style.opacity = 0.25; elImg.style.filter = "alpha(opacity=25)"; } elImg.setAttribute('alt', Webfm.js_msg.u_file); this.menu = file_menu; elTd.appendChild(elImg); elTr.appendChild(elTd); if(Webfm.options.displayColumns.name ) { elTd = Webfm.ce('td'); if(Webfm.numColumns < 2) {elTd.colSpan = 2;} this.clickObj = Webfm.ce('a'); this.clickObj.setAttribute('href', '#'); if((typeof fileObj.id == "undefined") || fileObj.id === 0 || fileObj.id === false) { this.clickObj.setAttribute('title', this.filepath); } else { if(Webfm.browser.isOP) { this.clickObj.setAttribute('href', getBaseUrl() + "\/webfm_send\/" + fileObj.id); } this.clickObj.setAttribute('title', fileObj.id); } if(this.ftitle) { this.clickObj.appendChild(Webfm.ctn(fileObj.ftitle)); } else { this.clickObj.appendChild(Webfm.ctn(fileObj.n)); } elTd.appendChild(this.clickObj); elTr.appendChild(elTd); } if(Webfm.options.displayColumns.modified) { elTd = Webfm.ce('td'); if(Webfm.numColumns < 2) {elTd.colSpan = 2;} elTd.className = 'txt'; elTd.appendChild(Webfm.ctn(Webfm.convertunixtime(parseInt(fileObj.m, 10)))); elTr.appendChild(elTd); } if(Webfm.options.displayColumns.size) { elTd = Webfm.ce('td'); if(Webfm.numColumns < 2) {elTd.colSpan = 2;} elTd.className = 'txt'; size = Webfm.size(fileObj.s); elTd.appendChild(Webfm.ctn(size)); elTr.appendChild(elTd); } //owner field to row if(Webfm.options.displayColumns.owner) { //if(getWebfmOwnerColumn() && Webfm.options.displayColumns.owner) { elTd = Webfm.ce('td'); if(Webfm.numColumns < 2) {elTd.colSpan = 2;} elTd.className = 'txt'; elTd.appendChild(Webfm.ctn(fileObj.un)); elTr.appendChild(elTd); } //mouse event listeners if(dd_enable) { listener = Webfm.eventListenerAdd(eventListenerArr, this.element, "mousedown", function(e) { Webfm.contextMenuObj.hideContextMenu(e); fr.select(e); }); } else { listener = Webfm.eventListenerAdd(eventListenerArr, this.element, "click", function(e) { Webfm.contextMenuObj.hideContextMenu(e); if(Webfm.renameActive === false) { Webfm.selectFile(fr.clickObj.title, fr.element); } }); } if(this.draggable) { listener = Webfm.eventListenerAdd(eventListenerArr, this.element, "mouseover", function() { fr.hover(fr.element, true); }); listener = Webfm.eventListenerAdd(eventListenerArr, this.element, "mouseout", function() { fr.hover(fr.element, false); }); } if(Webfm.browser.isOP) { listener = Webfm.eventListenerAdd(eventListenerArr, this.element, "mouseup", function(e) { if(e && e.button === 0 && e.altKey === true) { if(Webfm.renameActive === false) { Webfm.contextMenuObj.showContextMenu(e, fr); Webfm.stopEvent(e); } } }); } else { listener = Webfm.eventListenerAdd(eventListenerArr, this.element, "contextmenu", function(e) { if(Webfm.renameActive === false) { Webfm.contextMenuObj.showContextMenu(e, fr); } Webfm.stopEvent(e); }); } parent.appendChild(elTr); this.c_fil = this.c_fil + 1; }; Webfm.filerow.prototype.hover = function (el, state) { if(state) { el.className += ' selected'; } else { el.className = el.className.split(' ', 1); } }; Webfm.filerow.prototype.select = function (event) { var cp, rightclick; cp = this; if(Webfm.renameActive === true) { return false; } event = event || window.event; if(event.target || event.srcElement) { if(this.clickObj) { // Determine mouse button rightclick = Webfm.rclick(event); if(rightclick) { return false; } setTimeout(function() { //if click then no dragging... if(Webfm.dragging === false) { //element id used for download method (webfm_send||direct http access) Webfm.selectFile(cp.clickObj.title, cp.element); } }, 200); } //passthrough if(typeof this.dd != "undefined") { this.dd.mouseButton(event); } } return false; }; Webfm.filerow.prototype.getIconByExt = function() { var ext, last, icon; // extension stored in file record of db fails - use pathname ext = this.ext; if(ext) { ext = ext.replace(/\//g, "_").toLowerCase(); } else { ext = this.filepath.toLowerCase(); last = ext.lastIndexOf("."); if(last != -1) { // "." found ext = ext.slice(last + 1); } else { ext = ""; } } icon = this.iconDir + '/' + (Webfm.icons["e" + ext] ? Webfm.icons["e" + ext] : "f") + '.gif'; return icon; }; /* * Webfm.treeBuilder constructor */ Webfm.treeBuilder = function (parent, root_menu, dir_menu) { this.parent = parent; this.root_menu = root_menu; this.dir_menu = dir_menu; this.trees = []; }; Webfm.treeBuilder.prototype.fetch = function (tree_refresh, list_refresh) { var url, postObj; url = Webfm.ajaxUrl(); this.tree_refresh = tree_refresh; this.list_refresh = list_refresh; Webfm.alrtObj.msg(); Webfm.progressObj.show(Webfm.js_msg.work, "blue"); postObj = { action: encodeURIComponent("readtrees") }; if(tree_refresh) { postObj.param0 = encodeURIComponent(true); } if(Webfm.current) { // Allow themers to request the current tree. postObj.param1 = encodeURIComponent(Webfm.current); } Webfm.admin = false; Webfm.HTTPPost(url, this.callback, this, postObj); }; Webfm.treeBuilder.prototype.callback = function (string, xmlhttp, cp) { var result, i; Webfm.progressObj.hide(); if(xmlhttp.status == 200) { result = Drupal.parseJson(string); //Webfm.dbgObj.dbg("trees fetch:", Webfm.dump(result)); if(result.status) { if(result.err) { Webfm.alrtObj.msg(result.err); } Webfm.admin = result.admin; // build directory trees from php associative array for(i in result.tree) { // Webfm.dbgObj.dbg("tree" + i, Webfm.dump(result.tree[i])); if(!cp.trees[i]) { cp.trees[i] = new Webfm.tree(cp.parent, i, cp.root_menu, cp.dir_menu); } cp.trees[i].fetch(cp.tree_refresh, false); } Webfm.dirListObj.refresh(result.current); } else { Webfm.alrtObj.msg(result.err); } } else { Webfm.alrtObj.msg(Webfm.js_msg.ajaxerr); } }; Webfm.tree_listenerfn_click = function (wt, b) { return function(e) { wt.exp(b); Webfm.stopEvent(e); }; }; /** * Webfm.tree constructor * 1st param is parent node to append this Webfm.tree object * 2nd param is index to append to base id of Webfm.tree object * 3rd param is root directory menu array * 4th param is non-root directory menu array */ Webfm.tree = function (parent, treeIdx, root_menu, dir_menu) { var wt, node, elA, listener, elImg, elSpan, i, elDiv; wt = this; this.id = 'dirtree' + treeIdx; this.treeIdx = treeIdx; this.icondir = getWebfmIconDir(); this.content = ''; this.expAllData = [['collapse', 'minus', 'block'], ['expand', 'plus', 'none']]; // Set tree exp/collapse behaviour on load (0 = expanded, 1 = collapsed) this.expAllIndex = 1; this.root_menu = root_menu; this.dir_menu = dir_menu; this.eventListeners = []; node = Webfm.ce("div"); node.setAttribute('id', this.id); node.className = 'dirtree'; //build tree and display elA = Webfm.ce('a'); elA.setAttribute('href', '#'); elA.setAttribute('title', Webfm.js_msg.refresh); listener = Webfm.eventListenerAdd(Webfm.eventListeners, elA, "click", function(e) { wt.fetch(true, ''); Webfm.stopEvent(e); }); elImg = Webfm.ce('img'); elImg.setAttribute('src', this.icondir + '/r.gif'); elImg.setAttribute('alt', Webfm.js_msg.refresh); elA.appendChild(elImg); node.appendChild(elA); elSpan = Webfm.ce("span"); elSpan.appendChild(Webfm.ctn(' ')); elSpan.setAttribute('id', this.id + 'Name'); node.appendChild(elSpan); // Expand/Collapse all folders buttons elSpan = Webfm.ce("span"); elSpan.setAttribute('id', this.id + 'exp'); for(i = 0; i < 2; i++) { elA = Webfm.ce('a'); elA.setAttribute('href', '#'); if(i) { elA.setAttribute('title', 'expand tree'); listener = Webfm.eventListenerAdd(Webfm.eventListeners, elA, "click", Webfm.tree_listenerfn_click(wt, 0)); } else { elA.setAttribute('title', 'collapse tree'); listener = Webfm.eventListenerAdd(Webfm.eventListeners, elA, "click", Webfm.tree_listenerfn_click(wt, 1)); } elImg = Webfm.ce('img'); elImg.setAttribute('alt', this.expAllData[i][0]); elImg.setAttribute('src', this.icondir + '/' + this.expAllData[i][1] + '.gif'); elA.appendChild(elImg); elSpan.appendChild(elA); } node.appendChild(elSpan); //container div for tree elDiv = Webfm.ce("div"); this.treeCont = elDiv; node.appendChild(elDiv); parent.appendChild(node); }; Webfm.tree.prototype.fetch = function (tree_refresh, list_refresh) { var url, postObj; url = Webfm.ajaxUrl(); // Reset ul count (0=root) this.treeUlCounter = 0; this.treeNodeCounter = 0; this.list_refresh = list_refresh; Webfm.alrtObj.msg(); Webfm.progressObj.show(Webfm.js_msg.work, "blue"); Webfm.dbgObj.dbg("tree fetch path:", this.treeIdx); postObj = { action: encodeURIComponent("readtree"), param0: encodeURIComponent(this.treeIdx) }; if(tree_refresh) { postObj.param1 = encodeURIComponent(true); } Webfm.HTTPPost(url, this.callback, this, postObj); }; Webfm.tree.prototype.callback = function (string, xmlhttp, cp) { var treeName, j; Webfm.progressObj.hide(); if(xmlhttp.status == 200) { cp.content = Drupal.parseJson(string); // Webfm.dbgObj.dbg("tree fetch:", Webfm.dump(cp.content)); //clear tree content while(cp.treeCont.hasChildNodes()) { cp.treeCont.removeChild(cp.treeCont.firstChild); } //clear event listeners for old tree content Webfm.eventUnregister(cp.eventListeners); //clear drop container array; Webfm.dropContainers = []; //update tree name treeName = Webfm.$(cp.id + 'Name'); treeName.removeChild(treeName.firstChild); //TODO: Is this break really correct? for(j in cp.content.tree) { //textnode = last directory of root path treeName.appendChild(Webfm.ctn(' ' + j.substring(j.lastIndexOf("/") + 1) + ' ' + Webfm.js_msg.tree)); break; } // Recursively build directory tree from php associative array cp.buildTreeRecur(cp.content.tree, cp.treeCont, ''); cp.init(); if(cp.list_refresh) { Webfm.dirListObj.refresh(cp.content.current); } } else { Webfm.alrtObj.msg(Webfm.js_msg.ajaxerr); } }; Webfm.tree.prototype.getpath = function() { return this.content.current; }; Webfm.tree.prototype.showHideNode = function (event) { var collapseIcon, ul; event = event || window.event; collapseIcon = event.target || event.srcElement; if(collapseIcon.style.visibility == 'hidden') { return; } ul = collapseIcon.parentNode.parentNode.getElementsByTagName('ul')[0]; if(collapseIcon.title == this.expAllData[0][0]) { collapseIcon.src = this.icondir + '/' + this.expAllData[1][1] + '.gif'; collapseIcon.alt = this.expAllData[1][0]; collapseIcon.title = this.expAllData[1][0]; ul.style.display = this.expAllData[1][2]; } else { collapseIcon.src = this.icondir + '/' + this.expAllData[0][1] + '.gif'; collapseIcon.alt = this.expAllData[0][0]; collapseIcon.title = this.expAllData[0][0]; ul.style.display = this.expAllData[0][2]; } }; Webfm.tree.prototype.buildTreeRecur_listenerfn_click = function (cp) { var listenerfn = function(e) { cp.showHideNode(e); Webfm.stopEvent(e); }; return listenerfn; }; Webfm.listenerfn_mouseoverout = function (cp, indicator) { var listenerfn = function(e) { cp.hover(e, indicator); }; return listenerfn; }; Webfm.listenerfn_mouseoverout_dir = function (cp, indicator) { var listenerfn = function(e) { cp.hoverDir(e, indicator); }; return listenerfn; }; Webfm.tree.prototype.buildTreeRecur = function (content, parent, input_path) { var cp, dc_id, elUl, sortDir, i, j, newpath, elLi, elDiv, elImg, listener, treeNode; cp = this; //php associative array is always a single member array with nested objects if(Webfm.isArray(content)) { this.buildTreeRecur(content[0], parent, ''); } else if(Webfm.isObject(content)) { if(input_path) { input_path += "/"; } elUl = Webfm.ce('ul'); if(this.treeUlCounter) { this.treeUlCounter = this.treeUlCounter + 1; } else { elUl.className = 'root-list'; this.treeUlCounter = this.treeUlCounter + 1; } // sort object here since php does not have a case-sensitive ksort sortDir = []; for(i in content) { if(content.hasOwnProperty(i)) { sortDir.push(i); } } if(sortDir.length) { sortDir.sort(Webfm.sortByKey); for(j = 0; j < sortDir.length; j = j + 1) { newpath = input_path + sortDir[j]; elLi = Webfm.ce('li'); dc_id = this.id + 'node' + this.treeNodeCounter; elLi.setAttribute('id', dc_id); elLi.setAttribute('title', newpath); elLi.className = "treenode"; elDiv = Webfm.ce('div'); elImg = Webfm.ce('img'); elImg.setAttribute('src', this.icondir + '/' + this.expAllData[this.expAllIndex][1] + '.gif'); elImg.setAttribute('alt', this.expAllData[this.expAllIndex][0]); elImg.setAttribute('title', this.expAllData[this.expAllIndex][0]); elDiv.appendChild(elImg); elLi.appendChild(elDiv); listener = Webfm.eventListenerAdd(this.eventListeners, elImg, "click", Webfm.tree.prototype.buildTreeRecur_listenerfn_click(cp)); treeNode = new Webfm.treeNode(elDiv, newpath, dc_id, elImg, this.treeNodeCounter ? this.dir_menu : this.root_menu, this.eventListeners); listener = Webfm.eventListenerAdd(this.eventListeners, elDiv, "mouseover", Webfm.listenerfn_mouseoverout(cp, true)); listener = Webfm.eventListenerAdd(this.eventListeners, elDiv, "mouseout", Webfm.listenerfn_mouseoverout(cp, false)); this.treeNodeCounter = this.treeNodeCounter + 1; this.buildTreeRecur(content[sortDir[j]], elLi, newpath); elUl.appendChild(elLi); } } // Always show root if(elUl.className == 'root-list') { elUl.style.display = 'block'; } else { elUl.style.display = this.expAllData[this.expAllIndex][2]; } parent.appendChild(elUl); } }; //IE does not understand 'this' inside event listener func Webfm.tree.prototype.hover = function (event, state) { var el; el = event.target || window.event.srcElement; if(state) { el.className = 'selected'; el.parentNode.className = 'selected'; // el.parentNode.className += ' selected'; } else { // var class_names = []; // class_names = el.parentNode.className.split(' '); // el.parentNode.className = class_names[0]; el.className = ''; el.parentNode.className = ''; } }; Webfm.tree.prototype.init = function() { // Determine if expand/collapse icon is present // Create event objects for each element var dirItems, subItems, i; dirItems = this.treeCont.getElementsByTagName('li'); if(dirItems.length) { for(i = 0; i < dirItems.length; i++) { subItems = dirItems[i].getElementsByTagName('ul'); if(!subItems.length) { // Hide collapse icon if no sub-directories dirItems[i].getElementsByTagName('img')[0].style.visibility = 'hidden'; } } } }; Webfm.tree.prototype.exp = function (expcol) { //clear tree while(this.treeCont.hasChildNodes()) { this.treeCont.removeChild(this.treeCont.firstChild); } // Rebuild dirtree ul/li objects from dirtree object this.expAllIndex = expcol; this.treeUlCounter = 0; this.treeNodeCounter = 0; this.buildTreeRecur(this.content.tree, this.treeCont, ''); this.init(); }; Webfm.treeNode = function (parent, path, id, expImg, menu, eventListenerArr) { var tn, icondir, elImg, nodeNumPos, root, listener; tn = this; icondir = getWebfmIconDir(); root = []; this.parent = parent; this.element = parent.parentNode; this.expClickObj = expImg; elImg = Webfm.ce('img'); elImg.setAttribute('id', id + 'dd'); elImg.setAttribute('src', icondir + '/d.gif'); parent.appendChild(elImg); this.clickObj = Webfm.ce('a'); this.clickObj.href = '#'; //anchor title is path this.clickObj.setAttribute('title', path); nodeNumPos = this.element.id.indexOf("node") + 4; if((this.element.id.substring(nodeNumPos) != "0") && Webfm.admin) { // root treenode isn't draggable this.dd = new Webfm.draggable(Webfm.dragCont, this.element, this.element.className); } root = path.split('/'); //textNode is last directory name of path string (used for root path) this.clickObj.appendChild(Webfm.ctn(root[root.length - 1])); parent.appendChild(this.clickObj); //mouse event listeners this.menu = menu; if(typeof this.dd != "undefined") { listener = Webfm.eventListenerAdd(eventListenerArr, parent, "mousedown", function(e) { Webfm.contextMenuObj.hideContextMenu(e); tn.select(e); }); } else { listener = Webfm.eventListenerAdd(eventListenerArr, parent, "click", function(e) { Webfm.selectDir(tn.clickObj.title); Webfm.stopEvent(e); }); } if(Webfm.browser.isOP) { listener = Webfm.eventListenerAdd(eventListenerArr, parent, "mouseup", function(e) { if(e && e.button === 0 && e.altKey === true) { if(Webfm.renameActive === false) { Webfm.contextMenuObj.showContextMenu(e, tn); } Webfm.stopEvent(e); } }); } else { listener = Webfm.eventListenerAdd(eventListenerArr, parent, "contextmenu", function(e) { if(Webfm.renameActive === false) { Webfm.contextMenuObj.showContextMenu(e, tn); } Webfm.stopEvent(e); }); } }; Webfm.treeNode.prototype.select = function (event) { var cp, rightclick; cp = this; // disable during rename if(Webfm.renameActive === true) { return false; } event = event || window.event; switch(event.target || event.srcElement) { case this.expClickObj: break; case this.clickObj: // Determine mouse button rightclick = Webfm.rclick(event); if(rightclick) { // oncontextmenu will handle this break; } setTimeout(function() { //if click then no dragging... if(Webfm.dragging === false) { Webfm.selectDir(cp.clickObj.title); } }, 200); if(typeof this.dd != "undefined") { this.dd.mouseButton(event); } break; //passthrough default: if(typeof this.dd != "undefined") { this.dd.mouseButton(event); } break; } return false; }; Webfm.selectDir = function (path) { Webfm.dirListObj.fetch(path); }; //File download Webfm.selectFile = function (path, el, as_file) { var fid, sent, pths, pluspath, fullpath, url, cache, i, iframeName, pane; //files not in db use file path in tr title for download //files inside webfm have 'fidxxx' as title fid = null; sent = false; pths = []; pths = el.title.split('/'); if(el.id.substring(0, 3) == 'fid' || el.id.substring(0, 3) == 'sid') { fid = el.id.substring(3); fullpath = 'webfm_send/' + path; if(as_file) { fullpath += '/1'; } } else { //replace / with ~ since server uses / as param delimiter pluspath = pths.join('~'); fullpath = 'webfm_send/' + encodeURIComponent(pluspath); } if(getWebfmCleanUrl()) { url = getBaseUrl() + '/' + fullpath; } else { url = '?q=' + fullpath; } if(as_file) { // Send download/open dialog window.location = url; } else { cache = Webfm.dirListObj.cache.get(Webfm.current); for(i in cache.files) { // Display downloaded image in iframe // check cache files[] array for path match and image type if(((cache.files[i].id == fid) || ((cache.files[i].p + '/' + cache.files[i].n) == path)) && cache.files[i].i) { // FF needs unique name per iframe - Webfm.zindex guaranteed unique // since incremented with each new pane iframeName = "dwnld" + Webfm.zindex; pane = new Webfm.pane(Webfm.viewCont, pths[pths.length - 1], "webfm-viewFile", null, 200, 200); // I hate using innerHTML but IE iframe requires this method: pane.content.innerHTML = ''; if(fid) { pane.headerMsg("fid:" + path); } pane.show(); sent = true; break; } } // Not an image - launch file in new browser instance if(!sent) { // window.open(url); window.location = url; } } }; /** * Webfm.context constructor */ Webfm.context = function (container) { Webfm.renameActive = false; this.container = container; this.eventListeners = this.container.eventListenerArr; }; Webfm.context.prototype.hideContextMenu = function (event) { // Hide context menu and restore document oncontextmenu handler this.container.obj.style.visibility = "hidden"; document.body.oncontextmenu = Webfm.oldOnContextMenu; }; Webfm.listenerfn_context_mousedown = function (cp, obj) { var listenerfn = function(e) { cp.selectMenu(e, obj); cp.hideContextMenu(e); Webfm.stopEvent(e); }; return listenerfn; }; //obj is treenode|filerow|dirrow Webfm.context.prototype.showContextMenu = function (event, obj) { var cp, listener, pos, j, elUl, elLi; cp = this; this.element = obj.element; this.clickObj = obj.clickObj; // Webfm.dbgObj.dbg('this.element.title:', this.element.title); document.body.oncontextmenu = function() { return false; }; event = event || window.event; pos = Drupal.mousePosition(event); // Remove any existing list in our contextMenu. this.container.destroy(); // Build menu ul and append to this.container if(obj.menu !== null || typeof obj.menu !== 'undefined' || obj.menu !== false) { elUl = Webfm.ce('ul'); for(j = 0; j < obj.menu.length; j = j + 1) { elLi = Webfm.ce('li'); //Run prepare function and return true if menuElement to appear in menu if(typeof obj.menu[j].prepFunc == 'function' && !obj.menu[j].prepFunc(obj)) { continue; } elLi.appendChild(Webfm.ctn(obj.menu[j].desc)); //menu selection is title of event elLi.id = 'webfm-cxtMenu' + j; listener = Webfm.eventListenerAdd(Webfm.eventListeners, elLi, "mousedown", Webfm.listenerfn_context_mousedown(cp, obj)); listener = Webfm.eventListenerAdd(Webfm.eventListeners, elLi, "mouseover", Webfm.listenerfn_mouseoverout(cp, true)); listener = Webfm.eventListenerAdd(Webfm.eventListeners, elLi, "mouseout", Webfm.listenerfn_mouseoverout(cp, false)); elUl.appendChild(elLi); } this.container.obj.appendChild(elUl); this.container.obj.style.visibility = "visible"; if(pos.x + this.container.obj.offsetWidth > (document.documentElement.offsetWidth - 20)) { pos.x = pos.x + (document.documentElement.offsetWidth - (pos.x + this.container.obj.offsetWidth)) - 20; } this.container.obj.style.left = pos.x + 'px'; this.container.obj.style.top = pos.y + 'px'; this.container.obj.style.display = 'block'; this.container.obj.style.zIndex = Webfm.zindex + 1; } listener = Webfm.eventListenerAdd(Webfm.eventListeners, document, "mousedown", function(e) { cp.hideContextMenu(e); }); return false; }; //IE does not understand 'this' inside event listener func Webfm.context.prototype.hover = function (event, state) { var el = event.target || window.event.srcElement; el.className = state ? 'selected' : ''; }; //Call Webfm.menuElement execute function Webfm.context.prototype.selectMenu = function (event, obj) { event = event || window.event; obj.menu[(event.target || event.srcElement).id.substring(13)].execFunc(obj); return false; }; Webfm.menuElement = function (desc, execFunc, prepFunc) { this.desc = desc; this.execFunc = execFunc; this.prepFunc = prepFunc; }; //obj is treenode|filerow|dirrow Webfm.menuElement.prototype.exec = function(obj) { this.execFunc(obj); }; Webfm.menuRemove = function(obj) { var url, path, postObj; url = Webfm.ajaxUrl(); if(typeof obj.ext != "undefined") { //directories don't have extension properties obj.is_file = true; } path = obj.element.title; obj.parentPath = path.substring(0, path.lastIndexOf("/")); if(Webfm.confirm(Webfm.js_msg.confirmdel0 + (obj.is_file ? Webfm.js_msg.file : Webfm.js_msg.dir) + " " + path + (obj.is_file ? "" : Webfm.js_msg.confirmdel1) + "?")) { Webfm.progressObj.show(Webfm.js_msg.work, "blue"); postObj = { action: encodeURIComponent("delete"), param0: encodeURIComponent(path) }; Webfm.HTTPPost(url, Webfm.ctxMenuCallback, obj, postObj); return false; } }; Webfm.menuMkdir = function(obj) { var url, path, postObj; url = Webfm.ajaxUrl(); obj.is_file = false; path = obj.element.title; obj.parentPath = path; Webfm.progressObj.show(Webfm.js_msg.work, "blue"); postObj = { action: encodeURIComponent("mkdir"), param0: encodeURIComponent(path) }; Webfm.HTTPPost(url, Webfm.ctxMenuMkdirCallback, obj, postObj); }; Webfm.menuRename = function(obj) { var listener; if(typeof obj.ext != "undefined") { //directories don't have extension properties obj.is_file = true; } obj.renInput = Webfm.ce('input'); obj.renInput.setAttribute('type', 'textfield'); obj.renInput.value = obj.clickObj.firstChild.nodeValue; //clone input element since Webfm.contextMenuObj isn't destroyed on DOM obj.tempInput = obj.renInput.cloneNode(true); obj.tempInput.setAttribute('autocomplete', 'off'); //FF focus bug obj.clickparent = obj.clickObj.parentNode; obj.clickparent.replaceChild(obj.tempInput, obj.clickObj); //no change (blur) - restore original textNode listener = Webfm.eventListenerAdd(Webfm.eventListeners, obj.tempInput, "blur", function(e) { Webfm.renameActive = false; obj.clickparent.replaceChild(obj.clickObj, obj.tempInput); Webfm.stopEvent(e); }); //listen for enter key up - swap names (illegal names are ignored on server and next list //refresh will restore the proper filename) listener = Webfm.eventListenerAdd(Webfm.eventListeners, obj.tempInput, "keydown", function(e) { if(Webfm.enter(e) && Webfm.renameActive === true) { Webfm.renameActive = false; Webfm.menuSwapname(obj); this.blur(); Webfm.stopEvent(e); } }); setTimeout(function() { obj.tempInput.focus(); Webfm.renameActive = true; }, 10); }; Webfm.menuSearch = function(obj) { Webfm.searchObj.createForm(obj.element.title); }; Webfm.menuSwapname = function(obj) { var url, oldpath, newpath, postObj; url = Webfm.ajaxUrl(); oldpath = obj.element.title; obj.parentPath = oldpath.substring(0, oldpath.lastIndexOf("/")); newpath = obj.parentPath + '/' + obj.tempInput.value; postObj = { action: encodeURIComponent("rename"), param0: encodeURIComponent(oldpath), param1: encodeURIComponent(newpath) }; Webfm.HTTPPost(url, Webfm.ctxMenuCallback, obj, postObj); return true; }; Webfm.menuGetMeta = function(obj) { var url, postObj; url = Webfm.ajaxUrl(); // Webfm.dbgObj.dbg("obj.clickObj.title:", obj.clickObj.title); Webfm.progressObj.show(Webfm.js_msg.work, "blue"); postObj = { action: encodeURIComponent("getmeta"), param0: encodeURIComponent(obj.clickObj.title) }; Webfm.HTTPPost(url, Webfm.ctxMenuMetaCallback, '', postObj); }; Webfm.menuAttach = function (obj, ma_fid) { var url, fid, i, postObj, attach_arr; url = Webfm.ajaxUrl(); attach_arr = []; if(obj === null || typeof obj === 'undefined' || obj === false) { fid = ma_fid; } else { fid = obj.clickObj.title; } //check that this file is not already attached attach_arr = Webfm.$(Webfm.attachFormInput).value.split(','); for(i = 0; i < attach_arr.length; i++) { if(fid == attach_arr[i]) { break; } } if(i == attach_arr.length) { Webfm.progressObj.show(Webfm.js_msg.work, "blue"); postObj = { action: encodeURIComponent("attachfile"), param0: encodeURIComponent(fid) }; Webfm.HTTPPost(url, Webfm.ctxMenuAttachCallback, '', postObj); Webfm.attach.noAttachments(false); } }; Webfm.menuDetach = function(obj) { var path, attach_arr, new_attach_arr, j, i, fid; Webfm.alrtObj.msg(); path = obj.element.title; if(Webfm.confirm(Webfm.js_msg.confirmdet + path + "?")) { // update table obj.element.parentNode.removeChild(obj.element); // update form input attach_arr = []; attach_arr = Webfm.$(Webfm.attachFormInput).value.split(','); new_attach_arr = []; j = 0; // tr elements use 'fid#' in 'title' field fid = obj.element.id.substring(3); for(i = 0; i < attach_arr.length; i++) { if(attach_arr[i] != fid) { j = j + 1; new_attach_arr[j] = attach_arr[i]; } } Webfm.$(Webfm.attachFormInput).value = new_attach_arr.join(','); if(!new_attach_arr.length) { Webfm.attach.noAttachments(true); } } }; Webfm.menuView = function(obj) { Webfm.selectFile(obj.clickObj.title, obj.element, false); }; Webfm.menuDownload = function(obj) { Webfm.selectFile(obj.clickObj.title, obj.element, true); }; Webfm.menuDbRem = function(obj) { var path, fid, url, postObj; path = obj.element.title; //strip 'fid' from front of id fid = obj.element.id.substring(3); if(Webfm.confirm(Webfm.js_msg.confirmdbrem0 + path + Webfm.js_msg.confirmdbrem1)) { url = Webfm.ajaxUrl(); Webfm.progressObj.show(Webfm.js_msg.work, "blue"); postObj = { action: encodeURIComponent("dbrem"), param0: encodeURIComponent(fid) }; // path for callback must be a directory - not a file path = path.substring(0, path.lastIndexOf("/")); Webfm.HTTPPost(url, Webfm.dbrem_callback, path, postObj); } return false; }; Webfm.menuGetPerm = function(obj) { var url, postObj; url = Webfm.ajaxUrl(); Webfm.progressObj.show(Webfm.js_msg.work, "blue"); postObj = { action: encodeURIComponent("getperm"), param0: encodeURIComponent(obj.clickObj.title) }; Webfm.HTTPPost(url, Webfm.ctxMenuPermCallback, '', postObj); }; Webfm.dbrem_callback = function (string, xmlhttp, path) { var result; Webfm.alrtObj.msg(); Webfm.progressObj.hide(); if(xmlhttp.status == 200) { result = Drupal.parseJson(string); Webfm.dbgObj.dbg("dbrem:", Webfm.dump(result)); if(result.status) { Webfm.dirListObj.refresh(path); } else { if(result.data) { Webfm.alrtObj.str_arr(result.data); } else { Webfm.alrtObj.msg("operation fail"); } } } else { Webfm.alrtObj.msg(Webfm.js_msg.ajaxerr); } }; Webfm.menuInsert = function(obj) { Webfm.insert(obj.element.title, "file"); }; Webfm.insert = function (path, type) { var url, postObj; url = Webfm.ajaxUrl(); Webfm.progressObj.show(Webfm.js_msg.work, "blue"); postObj = { action: encodeURIComponent("insert"), param0: encodeURIComponent(path), param1: encodeURIComponent(type) }; if(type == "file") { // path for callback must be a directory - not a file path = path.substring(0, path.lastIndexOf("/")); } Webfm.HTTPPost(url, Webfm.insert_callback, path, postObj); return false; }; Webfm.insert_callback = function (string, xmlhttp, path) { var result; Webfm.alrtObj.msg(); Webfm.progressObj.hide(); if(xmlhttp.status == 200) { result = Drupal.parseJson(string); Webfm.dbgObj.dbg("insert:", Webfm.dump(result)); if(result.status) { //if success, update fetch if(result.data.cnt) { Webfm.dirListObj.refresh(path); Webfm.alrtObj.msg(result.data.cnt + Webfm.js_msg.inserted); } if(result.data.errcnt) { Webfm.alrtObj.msg(result.data.errcnt + Webfm.js_msg.notinserted); Webfm.alrtObj.str_arr(result.data.err); } } else if(result.data.err) { Webfm.alrtObj.str_arr(result.data.err); } } else { Webfm.alrtObj.msg(Webfm.js_msg.ajaxerr); } }; Webfm.generateFileHref = function (obj, url) { var title, string; title = ''; if(typeof url == 'undefined') { url = getBaseUrl(); } if(typeof obj.ftitle != "undefined" && obj.ftitle !== null && obj.ftitle.length) { title = obj.ftitle; } else { title = obj.element.title.substring(obj.element.title.lastIndexOf("/") + 1); } if(getWebfmCleanUrl()) { string = "" + title + ""; } else { string = "" + title + ""; } return string; }; Webfm.menuPasteHref = function(obj) { var fileHref, myField, startPos, endPos, sel; fileHref = Webfm.generateFileHref(obj, Drupal.settings.basePath.replace(/\/$/, '')); myField = Webfm.lastarea; //IE support if(document.selection) { myField.focus(); sel = document.selection.createRange(); sel.text = fileHref; } //other browsers else if(myField.selectionStart || myField.selectionStart == '0') { startPos = myField.selectionStart; endPos = myField.selectionEnd; myField.value = myField.value.substring(0, startPos) + fileHref + myField.value.substring(endPos, myField.value.length); } else { myField.value += fileHref; } }; Webfm.menuAdmin = function() { return Webfm.admin; }; Webfm.menuFileUid = function(obj) { //determine if we are the owner of this file return ((Webfm.admin || obj.uid == getWebfmUid()) ? true : false); }; Webfm.usCreateDir=function(obj){ //xl666 new function if(canCreateDir() >= 1) return true; else return false; } Webfm.menuRenFileUid = function(obj) { if(Webfm.menuFileUid(obj)) { // Determine if name is a metadata title return (obj.ftitle === null); } return false; }; Webfm.menuFilePerm = function(obj) { // object must be file in db with user access if(Webfm.menuFidVal(obj)) { return Webfm.menuFileUid(obj); } return false; }; Webfm.menuAdminFidVal = function(obj) { if(Webfm.admin) { return Webfm.menuFidVal(obj); } return false; }; Webfm.menuAdminNoFidVal = function(obj) { if(Webfm.admin) { return Webfm.menuNoFidVal(obj); } return false; }; //menu prepFunc to determine if filerow has 'fid' as first 3 letters of id Webfm.menuFidVal = function(obj) { if(obj.element.id.substring(0, 3) == 'fid') { return true; } return false; }; Webfm.menuNoFidVal = function(obj) { if(obj.element.id.substring(0, 3) != 'fid') { return true; } return false; }; Webfm.confirm = function (text) { var agree = confirm(text); return agree ? true : false; }; /** * Context menu callbacks */ Webfm.ctxMenuAttachCallback = function (string, xmlhttp, cp) { var result, filerow, elInput; Webfm.progressObj.hide(); if(xmlhttp.status == 200) { result = Drupal.parseJson(string); // Webfm.dbgObj.dbg("attach:", Webfm.dump(result)); if(result.status) { Webfm.admin = result.admin; filerow = new Webfm.filerow(Webfm.attachObj.body, result.data, 'attach', '', true, Webfm.menuHT.get('det'), Webfm.attachObj.eventListeners); elInput = Webfm.$(Webfm.attachFormInput); elInput.setAttribute('value', (elInput.getAttribute('value') ? elInput.getAttribute('value') + ',' : '') + result.data.id); } else { Webfm.alrtObj.msg(result.data); } } else { Webfm.alrtObj.msg(Webfm.js_msg.ajaxerr); } }; Webfm.ctxMenuCallback = function (string, xmlhttp, obj, mkdir_flag) { var result; Webfm.progressObj.hide(); Webfm.alrtObj.msg(); if(xmlhttp.status == 200) { result = Drupal.parseJson(string); // Webfm.dbgObj.dbg("context:", Webfm.dump(result)); // Webfm.dbgObj.dbg("obj:", obj.droppath); if(result.status) { if(!obj.is_file && Webfm.dirTreeObj) { Webfm.dirTreeObj.fetch(true, false); } //if success, flush cache for updated fetch if(typeof mkdir_flag != "undefined") { Webfm.dirListObj.refresh(obj.parentPath, result.data); } else { Webfm.dirListObj.refresh(obj.parentPath); } } else if(result.data) { Webfm.alrtObj.str_arr(result.data); } else { Webfm.alrtObj.msg("operation fail"); } } else { Webfm.alrtObj.msg(Webfm.js_msg.ajaxerr); } }; Webfm.ctxMenuMkdirCallback = function (string, xmlhttp, obj) { var mkdir_flag = true; // fourth var to signal the listing to rename the new directory Webfm.ctxMenuCallback(string, xmlhttp, obj, mkdir_flag); }; Webfm.ctxMenuMetaCallback = function (string, xmlhttp, obj) { var result; Webfm.progressObj.hide(); if(xmlhttp.status == 200) { result = Drupal.parseJson(string); // Webfm.dbgObj.dbg("meta result:", Webfm.dump(result)); if(result.status) { Webfm.metaObj.createForm(result.data); } else { Webfm.alrtObj.msg(result.data); } } else { Webfm.alrtObj.msg(Webfm.js_msg.ajaxerr); } }; Webfm.ctxMenuPermCallback = function (string, xmlhttp, obj) { var result; Webfm.progressObj.hide(); if(xmlhttp.status == 200) { result = Drupal.parseJson(string); // Webfm.dbgObj.dbg("perm result:", Webfm.dump(result)); if(result.status) { Webfm.permObj.createForm(result.data); } else { Webfm.alrtObj.msg(result.data); } } else { Webfm.alrtObj.msg(Webfm.js_msg.ajaxerr); } }; /** * Webfm.perm constructor * 1st param is popup container obj * 2nd param is default startup width * 2nd param is default startup height */ Webfm.perm = function (container, width, height) { var elDiv, elForm, elTable, elTBody, elControls; elDiv = Webfm.ce('div'); elDiv.setAttribute('id', 'webfm-perm-form'); elForm = Webfm.ce('form'); elDiv.appendChild(elForm); elTable = Webfm.ce('table'); elForm.appendChild(elTable); elTBody = Webfm.ce('tbody'); elTable.appendChild(elTBody); elControls = Webfm.ce('div'); elForm.appendChild(elControls); this.obj = elDiv; this.container = container; this.form = elForm; this.tbody = elTBody; this.controls = elControls; this.width = width; this.height = height; this.eventListeners = this.container.eventListenerArr; }; Webfm.perm.prototype.createForm = function (data) { this.data = data; this.permit = (Webfm.admin || this.data.u == getWebfmUid()) ? true : false; //clear any permissions info this.resetForm(); //create new pane to house this perm object this.pane = new Webfm.pane(this.container, Webfm.js_msg.perm, "webfm-permPane", this.obj, this.width, this.height); //create permissions checkboxes this.fillFormData(); //create controls if owner has rights to file if(this.permit) { this.buildFormControls(); } else { //put read-only indicator in pane header this.pane.headerMsg("read-only"); } }; Webfm.perm.prototype.resetForm = function() { var tbody, controls; tbody = this.tbody; controls = this.controls; while(tbody.hasChildNodes()) { tbody.removeChild(tbody.firstChild); } while(controls.hasChildNodes()) { controls.removeChild(controls.firstChild); } }; Webfm.perm.prototype.fillFormData = function() { var elTr, elTd, i, j, check, elInput; for(j in this.data) { if(j != "p") { elTr = Webfm.ce('tr'); // label td elTd = Webfm.ce('td'); elTd.appendChild(Webfm.ctn(Webfm.permInfoHT.get(j) + ': ')); elTr.appendChild(elTd); // info td elTd = Webfm.ce('td'); elTd.appendChild(Webfm.ctn(this.data[j])); elTr.appendChild(elTd); this.tbody.appendChild(elTr); } } // Webfm.permKey keys correspond to permission bitfields for(i in Webfm.permKey) { elTr = Webfm.ce('tr'); // label td elTd = Webfm.ce('td'); elTd.appendChild(Webfm.ctn(Webfm.permHT.get(Webfm.permKey[i]) + ': ')); elTr.appendChild(elTd); // checkbox td elTd = Webfm.ce('td'); // use bitwise operator to determine permission bits check = (parseInt(Webfm.permKey[i], 10) & parseInt(this.data.p, 10)) > 0; if(this.permit) { elInput = Webfm.ce('input'); elInput.setAttribute('type', 'checkbox'); // checkbox name is used to build the new permission value elInput.setAttribute('name', Webfm.permKey[i]); if(check) { elInput.setAttribute('checked', check); } elTd.appendChild(elInput); } else { elTd.appendChild(Webfm.ctn(check ? "True" : "False")); } elTr.appendChild(elTd); this.tbody.appendChild(elTr); } }; //build perm control buttons Webfm.perm.prototype.buildFormControls = function() { var cp, submitButton, listener, resetButton; cp = this; submitButton = Webfm.ce('input'); submitButton.setAttribute('type', 'button'); submitButton.setAttribute('value', Webfm.js_msg.submit); submitButton.className = "perm-button"; listener = Webfm.eventListenerAdd(cp.eventListeners, submitButton, "click", function(e) { if(cp.submitPerm()) { cp.container.destroy(); } Webfm.stopEvent(e); }); this.controls.appendChild(submitButton); resetButton = Webfm.ce('input'); resetButton.setAttribute('type', 'button'); resetButton.setAttribute('value', Webfm.js_msg.reset); resetButton.className = "perm-button"; listener = Webfm.eventListenerAdd(cp.eventListeners, resetButton, "click", function(e) { cp.createForm(cp.data); Webfm.stopEvent(e); }); this.controls.appendChild(resetButton); }; Webfm.perm.prototype.submitPerm = function() { var url, inputs, output, i, postObj; url = Webfm.ajaxUrl(); inputs = []; output = 0; inputs = this.tbody.getElementsByTagName('input'); for(i = 0; i < inputs.length; i++) { // Build permission val from checkbox name if(inputs[i].checked) { output += parseInt(inputs[i].name, 10); } } Webfm.progressObj.show(Webfm.js_msg.work, "blue"); postObj = { action: encodeURIComponent("putperm"), param0: encodeURIComponent(this.data.id), param1: encodeURIComponent(output)}; Webfm.HTTPPost(url, this.submitPermcallback, this, postObj); }; Webfm.perm.prototype.submitPermcallback = function (string, xmlhttp, obj) { var result; Webfm.progressObj.hide(); if(xmlhttp.status == 200) { result = Drupal.parseJson(string); if(result.status) { //put confirmed result back into this.data for proper 'reset' obj.data.p = result.data.perm; // Webfm.dbgObj.dbg('new perm :', obj.data["p"]); } obj.pane.headerMsg(result.msg); } else { Webfm.alrtObj.msg(Webfm.js_msg.ajaxerr); } }; /** * Webfm.metadata constructor * 1st param is popup container obj * 2nd param is default startup width * 2nd param is default startup height */ Webfm.metadata = function (container, width, height) { var elDiv, elForm, elTable, elTBody, elControls; elDiv = Webfm.ce('div'); elDiv.setAttribute('id', 'webfm-meta-form'); elForm = Webfm.ce('form'); elDiv.appendChild(elForm); elTable = Webfm.ce('table'); elForm.appendChild(elTable); elTBody = Webfm.ce('tbody'); elTable.appendChild(elTBody); elControls = Webfm.ce('div'); elForm.appendChild(elControls); this.obj = elDiv; this.container = container; this.form = elForm; this.tbody = elTBody; this.controls = elControls; this.fid = null; this.width = width; this.height = height; this.eventListeners = this.container.eventListenerArr; }; Webfm.metadata.prototype.createForm = function (data) { this.data = data; //clear any metadata info this.resetForm(); //create new pane to house this metadata object this.pane = new Webfm.pane(this.container, Webfm.js_msg.metadata, "webfm-metaPane", this.obj, this.width, this.height); //create metadata fields this.fillFormData(); //create controls if owner has rights to file if(this.fid) { this.buildFormControls(); } else { //put read-only indicator in pane header this.pane.headerMsg("read-only"); } }; Webfm.metadata.prototype.resetForm = function() { var tbody, controls; tbody = this.tbody; while(tbody.hasChildNodes()) { tbody.removeChild(tbody.firstChild); } controls = this.controls; while(controls.hasChildNodes()) { controls.removeChild(controls.firstChild); } this.fid = null; }; Webfm.metadata.prototype.fillFormData = function() { var i, meta, elTr, elTd, elInput, elTextArea; if(typeof this.data.id != "undefined") { this.fid = this.data.id; } for(i in this.data) { meta = Webfm.metadataHT.get(i); elTr = Webfm.ce('tr'); // label td elTd = Webfm.ce('td'); elTd.appendChild(Webfm.ctn(meta.desc + ': ')); elTr.appendChild(elTd); // info td elTd = Webfm.ce('td'); if(this.fid && meta.edit) { if(meta.size == 256) { // textarea elTextArea = Webfm.ce('textarea'); elTextArea.setAttribute('name', i); elTextArea.cols = "40"; elTextArea.rows = "4"; elTextArea.value = decodeURI(this.data[i]); elTd.appendChild(elTextArea); } else { // textfield elInput = Webfm.ce('input'); elInput.setAttribute('type', 'textfield'); elInput.setAttribute('name', i); elInput.setAttribute('size', '40'); elInput.setAttribute('value', decodeURI(this.data[i])); elTd.appendChild(elInput); } } else { elTd.appendChild(Webfm.ctn(decodeURI(this.data[i]))); } elTr.appendChild(elTd); // validation td elTd = Webfm.ce('td'); elTd.appendChild(Webfm.ctn(String.fromCharCode(160))); //  elTr.appendChild(elTd); this.tbody.appendChild(elTr); } }; //build metadata control buttons Webfm.metadata.prototype.buildFormControls = function() { var cp, submitButton, listener, resetButton; cp = this; submitButton = Webfm.ce('input'); submitButton.setAttribute('type', 'button'); submitButton.setAttribute('value', Webfm.js_msg.submit); submitButton.className = "meta-button"; listener = Webfm.eventListenerAdd(cp.eventListeners, submitButton, "click", function(e) { if(cp.submitMeta()) { cp.container.destroy(); } Webfm.stopEvent(e); }); this.controls.appendChild(submitButton); resetButton = Webfm.ce('input'); resetButton.setAttribute('type', 'button'); resetButton.setAttribute('value', Webfm.js_msg.reset); resetButton.className = "meta-button"; listener = Webfm.eventListenerAdd(cp.eventListeners, resetButton, "click", function(e) { cp.createForm(cp.data); Webfm.stopEvent(e); }); this.controls.appendChild(resetButton); }; //Validate the length of input Webfm.metadata.prototype.validateMetaInput = function (elInput) { var len, data, err_msg; len = Webfm.metadataHT.get(elInput.name).size; //Webfm.dbgObj.dbg("validateMetaInput", elInput.name); if(len < 256) { data = Webfm.trim(elInput.value); if(data.length > len) { // Append error msg to validation td err_msg = Webfm.ctn(Webfm.js_msg.lengtherr); elInput.parentNode.nextSibling.style.color = 'red'; elInput.parentNode.nextSibling.appendChild(err_msg); setTimeout(function() { elInput.focus(); }, 10); return false; } else { // Remove any contents of validation td while(elInput.parentNode.nextSibling.hasChildNodes()) { elInput.parentNode.nextSibling.removeChild(elInput.parentNode.nextSibling.firstChild); } } } return true; }; Webfm.metadata.prototype.submitMeta = function() { var url, inputs, arr, textareas, input_num, i, postObj; url = Webfm.ajaxUrl(); inputs = []; arr = []; textareas = []; inputs = this.tbody.getElementsByTagName('input'); textareas = this.tbody.getElementsByTagName('textarea'); input_num = inputs.length; for(i = 0; i < input_num; i++) { if(!this.validateMetaInput(inputs[i])) { break; } } // All fields validated // TODO: Data format needs to be reworked (json?) if(i == input_num) { this.output = ""; for(i = 0; i < input_num; i++) { this.output += encodeURIComponent(inputs[i].name) + ":" + encodeURIComponent(Webfm.trim(inputs[i].value)) + ","; } for(i = 0; i < textareas.length; i++) { this.output += encodeURIComponent(textareas[i].name) + ":" + encodeURIComponent(Webfm.trim(textareas[i].value)) + ","; } if(this.output.length) { Webfm.progressObj.show(Webfm.js_msg.work, "blue"); //strip off final comma this.output = this.output.substring(0, this.output.length - 1); postObj = { action: encodeURIComponent("putmeta"), param0: encodeURIComponent(this.fid), param1: encodeURIComponent(this.output)}; Webfm.HTTPPost(url, this.submitMetacallback, this, postObj); } } else { alert(Webfm.js_msg.fix_input); } return false; }; Webfm.metadata.prototype.submitMetacallback = function (string, xmlhttp, obj) { var params, result, i, key, val; Webfm.progressObj.hide(); if(xmlhttp.status == 200) { result = Drupal.parseJson(string); // Webfm.dbgObj.dbg('submitMetacallback: ', Webfm.dump(result)); if(result.status) { //update data for reset button params = []; params = obj.output.split(','); for(i = 0; i < params.length; i++) { key = params[i].substring(0, params[i].indexOf(":")); val = params[i].substring(params[i].indexOf(":") + 1); obj.data[key] = val; } } obj.pane.headerMsg(result.data); } else { Webfm.alrtObj.msg(Webfm.js_msg.ajaxerr); } }; //Trim leading/trailing whitespace off string Webfm.trim = function (str) { return str.replace(/^\s+|\s+$/g, ''); }; /* * Webfm.attach constructor * param is parentId from hook_form_alter */ Webfm.attach = function (parentId) { var wa, elTable, elTableBody, elTr, elTd; wa = this; this.id = parentId; this.attached = ''; this.eventListeners = []; elTable = Webfm.ce('table'); elTableBody = Webfm.ce('tbody'); //attached file rows are appended to this div this.body = elTableBody; //Header elTr = Webfm.ce('tr'); // icon column elTd = Webfm.ce('td'); elTd.className = 'head'; elTr.appendChild(elTd); // Sort dir/files column elTd = Webfm.ce('td'); elTd.className = 'head'; elTd.appendChild(Webfm.ctn(Webfm.js_msg.attachtitle)); elTr.appendChild(elTd); // date/time column elTd = Webfm.ce('td'); elTd.className = 'head'; elTd.appendChild(Webfm.ctn(Webfm.js_msg.column2)); elTr.appendChild(elTd); // file size column elTd = Webfm.ce('td'); elTd.className = 'head'; elTd.appendChild(Webfm.ctn(Webfm.js_msg.column3)); elTr.appendChild(elTd); // owner column elTd = Webfm.ce('td'); elTd.className = 'head'; elTd.appendChild(Webfm.ctn(Webfm.js_msg.column4)); elTr.appendChild(elTd); elTableBody.appendChild(elTr); elTable.appendChild(elTableBody); Webfm.$(parentId).appendChild(elTable); }; //Turn on/off no attachments display as needed. Webfm.attach.noAttachments = function (show) { if(show) { $('#webfm-attach').append( '
' + Webfm.js_msg.noattachments + '
'); } else { $('#webfm-no-attachments').remove(); } }; Webfm.attach.prototype.fetch = function() { var url, node_url, postObj, fids; url = Webfm.ajaxUrl(); // action attribute of node-edit form contains the node number if(Webfm.$('node-form')) { node_url = Webfm.$('node-form').action; } if(Webfm.$('comment-form')) { node_url = Webfm.$('comment-form').action; } Webfm.progressObj.show(Webfm.js_msg.work, "blue"); postObj = { action: encodeURIComponent("attach"), param0: encodeURIComponent(node_url) }; // If we are in a preview/validate, the fids are still stored in the form. // Pass them to webfm_ajax to reload them. fids = Webfm.$(Webfm.attachFormInput).value; if(fids.length !== 0) { postObj.param1 = encodeURIComponent(fids); } Webfm.HTTPPost(url, this.callback, this, postObj); }; Webfm.attach.prototype.callback = function (string, xmlhttp, obj) { var result, elInput, attach_arr, i, filerow, j; Webfm.progressObj.hide(); if(xmlhttp.status == 200) { result = Drupal.parseJson(string); // Webfm.dbgObj.dbg("attach.fetch:", Webfm.dump(result)); if(result.status) { if(result.data.length) { Webfm.admin = result.admin; elInput = Webfm.$(Webfm.attachFormInput); attach_arr = []; attach_arr = Webfm.$(Webfm.attachFormInput).value.split(','); for(i = 0; i < result.data.length; i++) { filerow = new Webfm.filerow(obj.body, result.data[i], 'attach', '', true, Webfm.menuHT.get('det'), obj.eventListeners); // Don't add if it already exists. // Note that values are kept in the form for preview/failed validate. for(j = 0; j < attach_arr.length; j = j + 1) { if(result.data[i].id == attach_arr[j]) { break; } } if(j == attach_arr.length) { elInput.setAttribute('value', (elInput.getAttribute('value') ? elInput.getAttribute('value') + ',' : '') + result.data[i].id); } } } else { Webfm.attach.noAttachments(true); } } else { Webfm.alrtObj.msg(result.data); } } else { Webfm.alrtObj.msg(Webfm.js_msg.ajaxerr); } }; /** * Webfm.search constructor * 1st param is popup container obj * 2nd param is default startup width * 2nd param is default startup height */ Webfm.search = function (container, width, height) { var elDiv, elForm, elResults; elDiv = Webfm.ce('div'); elDiv.setAttribute('id', 'webfm-search'); elForm = Webfm.ce('form'); elDiv.appendChild(elForm); elResults = Webfm.ce('div'); elDiv.appendChild(elResults); this.obj = elDiv; this.container = container; this.form = elForm; this.results = elResults; this.width = width; this.height = height; this.iconDir = getWebfmIconDir(); this.eventListeners = this.container.eventListenerArr; }; Webfm.search.prototype.resetForm = function() { var form = this.form; while(form.hasChildNodes()) { form.removeChild(form.firstChild); } }; Webfm.search.prototype.resetResults = function() { var results = this.results; while(results.hasChildNodes()) { results.removeChild(results.firstChild); } }; Webfm.search.prototype.createForm = function (source) { var cp, pane, elInput, listener, searchButton; cp = this; this.source = source; //clear any metadata info this.resetForm(); cp.resetResults(); //create new pane to house this metadata object pane = new Webfm.pane(this.container, Webfm.js_msg.searchtitle, "webfm-searchPane", this.obj, this.width, this.height); //put search path in header pane.headerMsg(source); //create search fields elInput = Webfm.ce('input'); elInput.setAttribute('type', 'textfield'); elInput.setAttribute('size', '30'); setTimeout(function() { elInput.focus(); }, 10); listener = Webfm.eventListenerAdd(this.eventListeners, elInput, "keydown", function(e) { if(Webfm.enter(e)) { cp.submit(elInput.value); elInput.blur(); Webfm.stopEvent(e); } }); this.form.appendChild(elInput); searchButton = Webfm.ce('input'); searchButton.setAttribute('type', 'button'); searchButton.setAttribute('value', Webfm.js_msg.search); listener = Webfm.eventListenerAdd(this.eventListeners, searchButton, "click", function(e) { cp.submit(elInput.value); Webfm.stopEvent(e); }); this.form.appendChild(searchButton); pane.show(); }; Webfm.search.prototype.submit = function (value) { var url, postObj; url = Webfm.ajaxUrl(); Webfm.progressObj.show(Webfm.js_msg.work, "blue"); postObj = { action: encodeURIComponent("search"), param0: encodeURIComponent(this.source), param1: encodeURIComponent(value) }; Webfm.HTTPPost(url, this.callback, this, postObj); }; Webfm.listenerfn_search_click_dir = function (cp) { var listenerfn = function(e) { cp.selectDir(e); Webfm.stopEvent(e); }; return listenerfn; }; Webfm.listenerfn_search_click = function (cp) { var listenerfn = function(e) { cp.selectFile(e); Webfm.stopEvent(e); }; return listenerfn; }; Webfm.search.prototype.callback = function (string, xmlhttp, cp) { var result, searchList, i, elLi, elImg, listener, elA, no_match; Webfm.progressObj.hide(); if(xmlhttp.status == 200) { cp.resetResults(); //build ul of search results result = Drupal.parseJson(string); if(result.files.length) { searchList = Webfm.ce('ul'); for(i = (result.files.length - 1); i >= 0; i = i - 1) { elLi = Webfm.ce('li'); elImg = Webfm.ce('img'); elImg.setAttribute('src', cp.iconDir + '/d.gif'); elImg.setAttribute('alt', Webfm.js_msg.u_dir); //title is path to directory elImg.setAttribute('title', result.files[i].p); listener = Webfm.eventListenerAdd(cp.eventListeners, elImg, "click", Webfm.listenerfn_search_click_dir(cp)); listener = Webfm.eventListenerAdd(cp.eventListeners, elImg, "mouseover", Webfm.listenerfn_mouseoverout_dir(cp, true)); listener = Webfm.eventListenerAdd(cp.eventListeners, elImg, "mouseout", Webfm.listenerfn_mouseoverout_dir(cp, false)); elLi.appendChild(elImg); elLi.appendChild(Webfm.ctn(' ')); elA = Webfm.ce('a'); elA.setAttribute('href', '#'); if(result.files[i].id) { //first three letters of id must be 'sid' for selectFile //tooltip indicates if file is downloadable elA.setAttribute('id', 'sid' + result.files[i].id); elA.setAttribute('title', Webfm.js_msg.filedwld); listener = Webfm.eventListenerAdd(cp.eventListeners, elA, "click", Webfm.listenerfn_search_click(cp)); } else { elA.setAttribute('title', Webfm.js_msg.nofiledwld); } elA.appendChild(Webfm.ctn(result.files[i].n)); elLi.appendChild(elA); searchList.appendChild(elLi); } cp.results.appendChild(searchList); } else { no_match = Webfm.ctn(Webfm.js_msg.nomatch); cp.results.style.color = 'red'; cp.results.appendChild(no_match); } } else { Webfm.alrtObj.msg(Webfm.js_msg.ajaxerr); } }; //IE does not understand 'this' inside event listener func Webfm.search.prototype.hoverDir = function (event, state) { var el = event.target || window.event.srcElement; el.src = this.iconDir + (state ? '/open.gif' : '/d.gif'); }; Webfm.search.prototype.selectDir = function (event) { var el = event.target || window.event.srcElement; Webfm.selectDir(el.title); }; Webfm.search.prototype.selectFile = function (event) { var el = event.target || window.event.srcElement; Webfm.selectFile(el.id.substring(3), el, true); }; /* * debug constructor * 1st param is popup container obj * 2nd param is default startup width * 2nd param is default startup height */ Webfm.debug = function (container, width, height) { var dbgButton, cp, cacheCont, report, listener; dbgButton = ''; //id from webfm_main() dbgButton = Webfm.$("webfm-debug-link"); this.enable = dbgButton; if(dbgButton) { this.container = container; this.eventListeners = this.container.eventListenerArr; this.width = width; this.height = height; cp = this; //create cache popup cacheCont = new Webfm.popup("webfm-cacheCont"); this.cacheCont = cacheCont; report = Webfm.ce('div'); this.report = report; //attach popup creation to [debug] link listener = Webfm.eventListenerAdd(Webfm.eventListeners, dbgButton, "click", function() { cp.show(); }); } }; Webfm.debug.prototype.dbg = function (title, msg) { var elSpan, elBr; if(this.enable) { //put latest msg at top (less scrolling) elBr = Webfm.ce('br'); this.report.insertBefore(elBr, this.report.firstChild); if(msg) { this.report.insertBefore(Webfm.ctn(msg), this.report.firstChild); } if(title) { elSpan = Webfm.ce('span'); elSpan.className = 'g'; elSpan.appendChild(Webfm.ctn(title)); this.report.insertBefore(elSpan, this.report.firstChild); } } }; Webfm.debug.prototype.clear = function() { if(this.enable) { Webfm.alrtObj.msg(); while(this.report.hasChildNodes()) { this.report.removeChild(this.report.firstChild); } this.cacheCont.destroy(); } }; Webfm.debug.prototype.show = function() { var elDiv, pane, cp, elControls, elClear, listener, elCache, report; if(this.enable) { elDiv = Webfm.ce('div'); elDiv.setAttribute('id', 'webfm-debug'); this.obj = elDiv; //create new pane to house this metadata object pane = new Webfm.pane(this.container, Webfm.js_msg.debugtitle, "webfm-debugPane", this.obj, this.width, this.height); cp = this; elControls = Webfm.ce('div'); this.controls = elControls; elClear = Webfm.ce('input'); elClear.setAttribute('type', 'button'); elClear.setAttribute('value', Webfm.js_msg.clear); elClear.className = "dbg-button"; listener = Webfm.eventListenerAdd(this.eventListeners, elClear, "click", function() { cp.clear(); }); this.controls.appendChild(elClear); elCache = Webfm.ce('input'); elCache.setAttribute('type', 'button'); elCache.setAttribute('value', Webfm.js_msg.cache); elCache.className = "dbg-button"; listener = Webfm.eventListenerAdd(this.eventListeners, elCache, "click", function(e) { cp.showCache(); Webfm.stopEvent(e); }); this.controls.appendChild(elCache); this.obj.appendChild(elControls); report = this.report; this.obj.appendChild(report); } }; Webfm.debug.prototype.showCache = function() { var dump, pane; if(this.enable) { //create new pane to house this metadata object dump = Webfm.ctn(Webfm.dump(Webfm.dirListObj.cache.dump())); pane = new Webfm.pane(this.cacheCont, Webfm.js_msg.cachetitle, "webfm-cachePane", dump, this.width, this.height); pane.show(); } }; /** * Progress indicator */ Webfm.progress = function (parent, id) { var elSpan = Webfm.ce('span'); this.id = id; this.flag = false; elSpan.setAttribute('id', this.id); parent.appendChild(elSpan); }; Webfm.progress.prototype.hide = function() { if(this.flag) { this.flag = false; Webfm.clearNodeById(this.id); } }; Webfm.progress.prototype.show = function (x, y) { var prog, elSpan; if(!this.flag) { this.flag = true; prog = Webfm.$(this.id); elSpan = Webfm.ce('span'); elSpan.style.backgroundColor = y; elSpan.appendChild(Webfm.ctn(x)); prog.appendChild(elSpan); prog.style.visibility = 'visible'; } }; /** * Alert indicator */ Webfm.alert = function (parent, id) { var elDiv; this.id = id; elDiv = Webfm.ce('div'); this.node = elDiv; elDiv.setAttribute('id', id); parent.appendChild(elDiv); }; Webfm.alert.prototype.msg = function (msg) { var elSpan; if(!msg) { Webfm.clearNodeById(this.id); } else { elSpan = Webfm.ce('span'); elSpan.className = 'alertspan'; elSpan.appendChild(Webfm.ctn(msg)); this.node.appendChild(elSpan); this.lf(); } }; Webfm.alert.prototype.lf = function() { var elBr = Webfm.ce('br'); this.node.appendChild(elBr); }; /* * Display an array of strings alert */ Webfm.alert.prototype.str_arr = function (arr) { var i; if(typeof arr == 'function') { return; } else if(Webfm.isArray(arr)) { for(i = 0; i < arr.length; i++) { this.str_arr(arr[i]); } } if(typeof arr == 'string') { this.msg(arr); } }; /** * Webfm.popup constructor */ Webfm.popup = function (Id) { var elDiv; this.id = Id; elDiv = Webfm.ce('div'); elDiv.id = Id; //id for css elDiv.style.cssText = 'position:absolute;display:none;'; document.body.appendChild(elDiv); this.obj = elDiv; //vars used for storing position info for contained object (pane) this.width = null; this.content_height = null; this.top = null; this.left = null; this.eventListenerArr = []; }; Webfm.popup.prototype.getScrollY = function() { var scrY = 0; if(typeof window.pageYOffset == 'number') { scrY = window.pageYOffset; } else if(document.body && document.body.scrollTop) { scrY = document.body.scrollTop; } else if(document.documentElement && document.documentElement.scrollTop) { scrY = document.documentElement.scrollTop; } return scrY; }; Webfm.popup.prototype.getObjectOffset = function (event, element, comp) { var objPos, mousePos; objPos = this.objPosition(element, comp); mousePos = Drupal.mousePosition(event); return {x: mousePos.x - objPos.x, y: mousePos.y - objPos.y}; }; Webfm.popup.prototype.objPosition = function (element, comp) { var curleft, curtop; curleft = 0; curtop = 0; if(element.offsetParent) { do { curleft += element.offsetLeft; curtop += element.offsetTop; } while(element = element.offsetParent); // jslint identifies this as an error - it is not! } // IE must compensate for relative positioning in css if(Webfm.browser.isIE && comp) { curleft += parseInt(getWebfmIEListOffset(), 10); if(comp == 'tree') { curleft += parseInt(getWebfmIETreeOffset(), 10); } } return { x: curleft, y: curtop }; }; Webfm.popup.prototype.destroy = function() { //cleanup event closures for this popup Webfm.eventUnregister(this.eventListenerArr); while(this.obj.hasChildNodes()) { this.obj.removeChild(this.obj.firstChild); } document.onmousemove = null; document.onmouseup = null; this.obj.style.display = 'none'; }; Webfm.popup.prototype.isEmpty = function() { return (!this.obj.hasChildNodes()); }; /** * Webfm.pane constructor * 1st param is popup container obj * 2nd param is title displayed in pane header * 3rd param is this obj id * 4th param is content appended to this obj content div * 5th param is default startup width * 6th param is default startup height */ Webfm.pane = function (popupCont, title, paneId, content, paneWidth, contentHeight) { var cp, body_scroll_top, body_height, body_scroll_left, body_width, iconDir, pane, header, elTitle, elMsg, elA, listener, elImg, contentContainer, footer, elResize; cp = this; this.popupCont = popupCont; body_scroll_top = this.popupCont.getScrollY(); body_height = Webfm.browser.isIE ? document.documentElement.clientHeight : window.innerHeight; // locate pane in centre of screen only if drag container not already in use if((!popupCont.width) || (!popupCont.content_height) || (!popupCont.top) || (!popupCont.left)) { body_scroll_left = Webfm.browser.isIE ? document.documentElement.scrollLeft : window.pageXOffset; body_width = Webfm.browser.isIE ? document.documentElement.clientWidth : window.innerWidth; this.popupCont.width = paneWidth; this.popupCont.content_height = contentHeight; this.popupCont.top = body_scroll_top + (body_height - contentHeight) / 2; this.popupCont.left = body_scroll_left + (body_width - paneWidth) / 2; } //Compensate pane position for vertical scroll that places it out of view if((body_scroll_top + body_height) < this.popupCont.top) { this.popupCont.top = body_scroll_top + (body_height - contentHeight) / 2; } if((body_scroll_top) > this.popupCont.top + this.popupCont.content_height) { this.popupCont.top = body_scroll_top + (body_height - contentHeight) / 2; } // Set top of drag popup and empty any contents this.popupCont.obj.style.top = this.popupCont.top + "px"; this.popupCont.obj.style.left = this.popupCont.left + "px"; this.popupCont.destroy(); // Pane container div iconDir = getWebfmIconDir(); pane = Webfm.ce('div'); this.pane = pane; pane.id = paneId; pane.className = "webfm-pane"; pane.style.width = this.popupCont.width + "px"; this.popupCont.obj.appendChild(this.pane); // pane header header = Webfm.ce('div'); this.header = header; header.id = pane.id + '-header'; header.className = "webfm-pane-header"; elTitle = Webfm.ce('div'); elTitle.appendChild(Webfm.ctn(title)); elTitle.className = "webfm-pane-title"; header.appendChild(elTitle); elMsg = Webfm.ce('div'); this.msg = elMsg; elMsg.className = "webfm-pane-msg"; header.appendChild(elMsg); cp = this; listener = Webfm.eventListenerAdd(Webfm.eventListeners, header, "mousedown", function(e) { cp.dragStart(e, 1); }); elA = Webfm.ce('a'); elA.setAttribute('href', '#'); elA.setAttribute('title', Webfm.js_msg.close); elA.className = "webfm-pane-close"; elImg = Webfm.ce('img'); elImg.setAttribute('src', iconDir + '/x.gif'); elImg.setAttribute('alt', Webfm.js_msg.close); elA.appendChild(elImg); header.appendChild(elA); listener = Webfm.eventListenerAdd(Webfm.eventListeners, elA, "click", function(e) { cp.popupCont.destroy(); Webfm.stopEvent(e); }); pane.appendChild(header); // pane content contentContainer = Webfm.ce('div'); this.content = contentContainer; contentContainer.id = pane.id + '-content'; contentContainer.className = "webfm-pane-content"; contentContainer.style.height = this.popupCont.content_height + "px"; pane.appendChild(contentContainer); // pane footer footer = Webfm.ce('div'); this.footer = footer; footer.className = "webfm-pane-footer"; elResize = Webfm.ce('a'); elResize.setAttribute('href', '#'); elResize.setAttribute('title', Webfm.js_msg.resize); elResize.className = "webfm-pane-resize"; elImg = Webfm.ce('img'); elImg.setAttribute('src', iconDir + '/resize.gif'); elImg.setAttribute('alt', Webfm.js_msg.resize); elResize.appendChild(elImg); footer.appendChild(elResize); listener = Webfm.eventListenerAdd(Webfm.eventListeners, elResize, "mousedown", function(e) { cp.dragStart(e, 0); }); pane.appendChild(footer); if(content) { this.fill(content); } }; Webfm.pane.prototype.dragStart = function (event, move) { var cp; cp = this; Webfm.dragging = true; event = event || window.event; // Hide content - mousing over visible iframe can cause problems this.content.style.visibility = "hidden"; this.popupCont.obj.style.zIndex = Webfm.zindex + 1; if(move == 1) { //Offset of cursor position form top/left corner of drag object on mousedown this.offset = this.popupCont.getObjectOffset(event, this.header); document.onmousemove = function(e) { cp.drag(e); }; document.onmouseup = function(e) { cp.dragEnd(e); }; this.drag(event); } else { //Start position of cursor on mousedown this.initPos = Drupal.mousePosition(event); //Start width and height of pane content on mousedown this.width = parseInt(this.pane.offsetWidth, 10); this.height = parseInt(this.content.offsetHeight, 10); document.onmousemove = function(e) { cp.resize(e); }; document.onmouseup = function(e) { cp.resizeEnd(e); }; Webfm.scrollVal = this.popupCont.getScrollY(); this.resize(event); } }; Webfm.pane.prototype.drag = function (event) { var pos, x, y, scroll; event = event || window.event; pos = Drupal.mousePosition(event); x = pos.x - this.offset.x; y = pos.y - this.offset.y; scroll = this.popupCont.getScrollY();//Scroll page if near top or bottom edge. Hardcoded values if(typeof window.innerHeight == 'number') { if(pos.y > (window.innerHeight + scroll - 35)) { window.scrollBy(0, 20); } else if(pos.y - scroll < (25)) { window.scrollBy(0, -20); } } else if(document.documentElement && document.documentElement.clientHeight) { if(pos.y > (document.documentElement.clientHeight + scroll - 35)) { window.scrollBy(0, 20); } else if(pos.y - scroll < (25)) { window.scrollBy(0, -20); } } // Move our drag container to wherever the mouse is (adjusted by mouseOffset) this.popupCont.obj.style.top = y + 'px'; this.popupCont.obj.style.left = x + 'px'; // Prevent selection of textnodes Webfm.stopEvent(event); }; Webfm.pane.prototype.resize = function (event) { var pos, x, y; event = event || window.event; // Calculate distance from start position pos = Drupal.mousePosition(event); x = this.width + (pos.x - this.initPos.x); y = this.height + (pos.y - this.initPos.y); // Adjust pane width and height css with min size constraint this.pane.style.width = Math.max(x, 100) + "px"; this.content.style.height = Math.max(y, 100) + "px"; // Prevent selection of textnodes Webfm.stopEvent(event); }; Webfm.pane.prototype.dragEnd = function (event) { // Store popup container top/left position global vars this.popupCont.top = parseInt(this.popupCont.obj.style.top, 10); this.popupCont.left = parseInt(this.popupCont.obj.style.left, 10); this.end(event); }; Webfm.pane.prototype.resizeEnd = function (event) { // Store popup container width/height size global vars this.popupCont.width = parseInt(this.pane.style.width, 10); this.popupCont.content_height = parseInt(this.content.style.height, 10); this.end(event); // counter browser scrolling setTimeout(function() { window.scrollTo(0, Webfm.scrollVal); }, 1); }; Webfm.pane.prototype.end = function (event) { this.content.style.visibility = "visible"; Webfm.dragging = false; document.onmousemove = null; document.onmouseup = null; Webfm.stopEvent(event); }; Webfm.pane.prototype.headerMsg = function (string) { while(this.msg.hasChildNodes()) { this.msg.removeChild(this.msg.firstChild); } this.msg.appendChild(Webfm.ctn(string)); }; Webfm.pane.prototype.fill = function (content) { if(content) { this.content.appendChild(content); } this.show(); }; Webfm.pane.prototype.clear = function() { while(this.content.hasChildNodes()) { this.content.removeChild(this.content.firstChild); } while(this.msg.hasChildNodes()) { this.msg.removeChild(this.content.firstChild); } }; Webfm.pane.prototype.hide = function() { this.popupCont.obj.style.display = 'none'; }; Webfm.pane.prototype.show = function() { this.popupCont.obj.style.zIndex = Webfm.zindex + 1; this.popupCont.obj.style.display = 'block'; }; /** * Webfm.draggable constructor */ Webfm.draggable = function (popupCont, element, d_class) { this.dragCont = popupCont; this.element = element; this.curpath = element.title; this.isTree = d_class.substring(0, 4) == 'tree'; this.isDir = (d_class == 'dirrow') || this.isTree; this.isAttach = d_class == 'attachrow'; this.icondir = getWebfmIconDir(); this.comp = this.isTree ? 'tree' : 'list'; }; Webfm.draggable.prototype.mouseButton = function (event) { var rightclick; event = event || window.event; // Determine mouse button rightclick = Webfm.rclick(event); if(!rightclick && event.altKey === false) { this.dragStart(event); } }; Webfm.draggable.prototype.dragStart = function (event) { var cp; Webfm.dragging = true; // Destroy all contents in popup container. this.dragCont.destroy(); cp = this; document.onmousemove = function(e) { cp.drag(e); }; document.onmouseup = function(e) { cp.dragEnd(e); }; // Make transparent this.element.style.opacity = 0.5; // Process this.drag(event); }; Webfm.draggable.prototype.drag = function (event) { var cp, elDiv, dirListRows, dirListCont, k, class_names, droptarget, cont_pos, skip, droppath, curtemp, droptemp, children, dirTreeCont, j, pos, x, y, scroll, container, att_table_body, attachRows, prevNode, nextNode, curr, i, att_pos; cp = this; event = event || window.event; //Build Webfm.dropContainers array //The dragStart flag ensures that the following executes once only at the //beginning of a drag-drop if(!Webfm.dragStart) { Webfm.dragStart = true; //copy dragged element into drag container and make visible this.offset = this.dragCont.getObjectOffset(event, this.element, this.comp); if(Webfm.browser.isIE && !this.isTree) { /* IE cannot clone table rows */ elDiv = Webfm.ce('div'); elDiv.setAttribute('id', 'webfm-ieDD'); elDiv.appendChild(this.element.getElementsByTagName('img')[0].cloneNode(false)); elDiv.appendChild(this.element.getElementsByTagName('a')[0].firstChild.cloneNode(false)); this.dragCont.obj.appendChild(elDiv); } else { this.dragCont.obj.appendChild(this.element.cloneNode(true)); } this.dragCont.obj.style.display = 'block'; this.dragCont.obj.style.zIndex = Webfm.zindex + 1; Webfm.dropContainers = []; // Build list drop container array if(!this.isAttach) { dirListRows = Webfm.dirListObj.obj.getElementsByTagName('tr'); dirListCont = []; for(k = 0; k < dirListRows.length; k = k + 1) { if(dirListRows[k].className == 'dirrow') { dirListCont.push(dirListRows[k]); } } if(dirListCont.length) { for(i = 0; i < dirListCont.length; i++) { // DragDrop element is folder icon droptarget = dirListCont[i]; cont_pos = this.dragCont.objPosition(droptarget, this.comp); skip = false; droppath = dirListCont[i].title; if(this.curpath == droppath) { continue; } if(this.isTree) { curtemp = []; curtemp = this.curpath.split('/'); droptemp = []; droptemp = droppath.split('/'); // Test if drop path is beneath the drag path for(j = 0; j < curtemp.length; j = j + 1) { if(curtemp[j] != droptemp[j]) { break; } } if(j == curtemp.length) { skip = true; } else { // Test if drop path is directly above drag path (already a subdir) for(j = 0; j < droptemp.length; j = j + 1) { if(curtemp[j] != droptemp[j]) { break; } } if((j == droptemp.length) && (curtemp.length == j + 1)) { skip = true; } } } if(skip === false) { // Valid drop container container = { id: dirListCont[i].id, x: cont_pos.x, y: cont_pos.y, w: droptarget.offsetWidth, h: droptarget.offsetHeight }; Webfm.dropContainers.push(container); } } } dirTreeCont = ''; dirTreeCont = Webfm.$("webfm-tree"); if(dirTreeCont) { //reuse var for container list dirTreeCont = Webfm.$("webfm-tree").getElementsByTagName('li'); if(dirTreeCont.length) { // Build tree drop container array for(i = 0; i < dirTreeCont.length; i++) { // DragDrop element is folder icon droptarget = dirTreeCont[i].getElementsByTagName('div')[0]; cont_pos = this.dragCont.objPosition(droptarget, this.comp); skip = false; if(this.isTree) { // Prevent a directory drop onto itself or its direct parent li (already a sub-directory) if((dirTreeCont[i] != this.element) && (dirTreeCont[i] != this.element.parentNode.parentNode)) { children = this.element.getElementsByTagName('li'); // Prevent a directory drop into a sub-directory for(j = 0; j < children.length; j = j + 1) { if(children[j] == dirTreeCont[i]) { skip = true; } } } else { skip = true; } } else { droppath = dirTreeCont[i].title; // A regex would be preferable here if(this.curpath != droppath) { curtemp = []; curtemp = this.curpath.split('/'); droptemp = []; droptemp = droppath.split('/'); // Test if drop path is beneath the drag path for(j = 0; j < curtemp.length; j = j + 1) { if(curtemp[j] != droptemp[j]) { break; } } if(j == curtemp.length) { skip = true; } else { // Test if drop path is directly above drag path (already a subdir) for(j = 0; j < droptemp.length; j = j + 1) { if(curtemp[j] != droptemp[j]) { break; } } if((j == droptemp.length) && (curtemp.length == j + 1)) { skip = true; } } } else { skip = true; } } if(skip === false) { // Valid drop container - add to array of drop containers container = { id: dirTreeCont[i].id, x: cont_pos.x, y: cont_pos.y, w: droptarget.offsetWidth, h: droptarget.offsetHeight }; Webfm.dropContainers.push(container); } } } } } else { // attachment container is attach table body droptarget = Webfm.attachObj.body; cont_pos = this.dragCont.objPosition(droptarget, this.comp); Webfm.attachContainer = { x: cont_pos.x, y: cont_pos.y, w: droptarget.offsetWidth, h: droptarget.offsetHeight }; } } pos = Drupal.mousePosition(event); x = pos.x; //- this.offset.x; y = pos.y; // - this.offset.y; scroll = this.dragCont.getScrollY();//Scroll page if near top or bottom edge. Hardcoded values if(typeof window.innerHeight == 'number') { if(pos.y > (window.innerHeight + scroll - 35)) { window.scrollBy(0, 20); } else if(pos.y - scroll < (25)) { window.scrollBy(0, -20); } } else if(document.documentElement && document.documentElement.clientHeight) { if(pos.y > (document.documentElement.clientHeight + scroll - 35)) { window.scrollBy(0, 20); } else if(pos.y - scroll < (25)) { window.scrollBy(0, -20); } } // move our drag container to wherever the mouse is (adjusted by mouseOffset) this.dragCont.obj.style.top = y + 'px'; this.dragCont.obj.style.left = x + 'px'; if(!this.isAttach) { Webfm.activeDropCont = null; if(Webfm.dropContainers.length) { // Compare mouse position to every drop container for(i = 0; i < Webfm.dropContainers.length; i++) { if((Webfm.dropContainers[i].x < pos.x) && (Webfm.dropContainers[i].y < pos.y) && ((Webfm.dropContainers[i].w + Webfm.dropContainers[i].x) > pos.x) && ((Webfm.dropContainers[i].h + Webfm.dropContainers[i].y) > pos.y)) { // Found a valid drop container - Highlight selection Webfm.activeDropCont = Webfm.$(Webfm.dropContainers[i].id); Webfm.$(Webfm.dropContainers[i].id + 'dd').src = this.icondir + '/open.gif'; Webfm.$(Webfm.dropContainers[i].id).className += ' selected'; } else { // De-highlight container Webfm.$(Webfm.dropContainers[i].id + 'dd').src = this.icondir + '/d.gif'; class_names = []; class_names = Webfm.$(Webfm.dropContainers[i].id).className.split(' '); Webfm.$(Webfm.dropContainers[i].id).className = class_names[0]; } } } } else { // Ignore all movement outside of the attach table if((Webfm.attachContainer.x < pos.x) && (Webfm.attachContainer.y < pos.y) && ((Webfm.attachContainer.w + Webfm.attachContainer.x) > pos.x) && ((Webfm.attachContainer.h + Webfm.attachContainer.y) > pos.y)) { // In attach container att_table_body = Webfm.attachObj.body; attachRows = att_table_body.getElementsByTagName('TR'); prevNode = ''; nextNode = ''; curr = false; // Start at 1 since first row is header for(i = 1; i < attachRows.length; i++) { if(this.element.id != attachRows[i].id) { att_pos = this.dragCont.objPosition(attachRows[i], this.comp); if((att_pos.y + (attachRows[i].offsetHeight / 2)) < pos.y) { if(curr === true) { prevNode = attachRows[i]; } } else if((att_pos.y + (attachRows[i].offsetHeight / 2)) > pos.y) { if(curr === false) { nextNode = attachRows[i]; } } } else { curr = true; } } if(prevNode) { att_table_body.insertBefore(prevNode, this.element); } else if(nextNode) { att_table_body.insertBefore(this.element, nextNode); } } } //prevent selection of textnodes Webfm.stopEvent(event); }; Webfm.draggable.prototype.dragEnd = function (event) { var class_names, url, postObj, elInput, attachRows, i, fid; event = event || window.event; // Restore opacity this.element.style.opacity = 1.0; Webfm.dragging = false; Webfm.dragStart = false; this.dragCont.obj.style.display = 'none'; Webfm.stopEvent(event); if(!this.isAttach) { // Move dragged object if a valid drop container if(Webfm.activeDropCont) { this.droppath = Webfm.activeDropCont.title; // De-highlight container Webfm.$(Webfm.activeDropCont.id + 'dd').src = this.icondir + '/d.gif'; class_names = []; class_names = Webfm.activeDropCont.className.split(' '); Webfm.activeDropCont.className = class_names[0]; url = Webfm.ajaxUrl(); Webfm.progressObj.show(Webfm.js_msg.work, "blue"); postObj = { action: encodeURIComponent("move"), param0: encodeURIComponent(this.curpath), param1: encodeURIComponent(this.droppath) }; Webfm.HTTPPost(url, this.callback, this, postObj); Webfm.activeDropCont = null; } } else { // Put the current order of attachments into the form in preparation for submit elInput = Webfm.$('edit-attachlist'); attachRows = Webfm.attachObj.body.getElementsByTagName('tr'); elInput.setAttribute('value', ''); // Ignore 1st row (header) for(i = 1; i < attachRows.length; i++) { fid = attachRows[i].id.substring(3); elInput.setAttribute('value', (elInput.getAttribute('value') ? elInput.getAttribute('value') + ',':'') + fid); } } // Empty drag container + uncapture mouse. document.onmousemove = null; document.onmouseup = null; this.dragCont.destroy(); }; Webfm.draggable.prototype.callback = function (string, xmlhttp, cp) { var result; Webfm.progressObj.hide(); Webfm.alrtObj.msg(); if(xmlhttp.status == 200) { result = Drupal.parseJson(string); //Webfm.dbgObj.dbg("move result:", Webfm.dump(result)); if(result.status) { //flush cache for target dir and source dir of object Webfm.dirListObj.cache.remove(cp.droppath); Webfm.dirListObj.cache.remove(cp.curpath.substring(0, cp.curpath.lastIndexOf("/"))); //update tree if directory is moved if(cp.isDir) { Webfm.dirTreeObj.fetch(true); } if(!cp.isTree) { //listing draggable - update current listing by removing dropped item cp.element.parentNode.removeChild(cp.element); } else { //tree draggable - update target directory Webfm.dirListObj.fetch(cp.droppath); } } if(result.data) { Webfm.alrtObj.str_arr(result.data); } else { Webfm.alrtObj.msg(Webfm.js_msg.moveerr); } } else { Webfm.alrtObj.msg(Webfm.js_msg.ajaxerr); } }; /** * Event Handler adapted from http://ajaxcookbook.org (Creative Commons Attribution 2.5) */ Webfm.eventListenerAdd = function (listener_arr, instance, eventName, listener) { var listenerFn, event; listenerFn = listener; if(instance.addEventListener) { instance.addEventListener(eventName, listenerFn, false); } else if(instance.attachEvent) { listenerFn = function() { listener(window.event); }; instance.attachEvent("on" + eventName, listenerFn); } else { throw new Error("Event registration not supported"); } event = { instance: instance, name: eventName, listener: listenerFn }; listener_arr.push(event); return event; }; Webfm.eventListenerRemove = function (event, listener_arr) { var i, instance; i = 0; instance = event.instance; if(instance.removeEventListener) { instance.removeEventListener(event.name, event.listener, false); } else if(instance.detachEvent) { instance.detachEvent("on" + event.name, event.listener); } for(i = 0; i < listener_arr.length; i++) { if(listener_arr[i] == event) { listener_arr.splice(i, 1); break; } } }; //remove local event listeners Webfm.eventUnregister = function (listener_arr) { while(listener_arr.length > 0) { Webfm.eventListenerRemove(listener_arr[0], listener_arr); } listener_arr = []; }; //remove global events at window.onunload Webfm.eventUnregisterWebfm = function() { while(Webfm.eventListeners.length > 0) { Webfm.eventListenerRemove(Webfm.eventListeners[0], Webfm.eventListeners); } Webfm.eventListeners = []; }; /** * Helper Functions */ Webfm.$ = function (id) { return document.getElementById(id); }; Webfm.ctn = function (textNodeContents) { var textNode = document.createTextNode(textNodeContents); return textNode; }; Webfm.ce = function (elementName) { var element; elementName = elementName.toLowerCase(); element = document.createElement(elementName); return element; }; /** * Creates an HTTP POST request and sends the response to the callback function * * Note: passing null or undefined for 'object' makes the request fail in Opera 8. * Pass an empty string instead. */ Webfm.HTTPPost = function (uri, callbackFunction, callbackParameter, object) { var xmlHttp, bAsync, toSend, i; bAsync = true; toSend = ''; if(window.XMLHttpRequest) { // If IE7, Mozilla, Safari, etc: Use native object xmlHttp = new XMLHttpRequest(); } else { if(window.ActiveXObject) { // ...otherwise, use the ActiveX control for IE5.x and IE6 xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } } if(!callbackFunction) { bAsync = false; } xmlHttp.open('POST', uri, bAsync); if(typeof object == 'object') { xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xmlHttp.setRequestHeader("X-Requested-With", "XMLHttpRequest"); for(i in object) { toSend += (toSend ? '&' : '') + i + '=' + encodeURIComponent(object[i]); } } else { toSend = object; } xmlHttp.send(toSend); if(bAsync) { xmlHttp.onreadystatechange = function() { if(xmlHttp.readyState == 4) { callbackFunction(Webfm.trim(xmlHttp.responseText), xmlHttp, callbackParameter); } }; return xmlHttp; } else { return Webfm.trim(xmlHttp.responseText); } }; /** * Prevents an event from propagating. */ Webfm.stopEvent = function (event) { event = event || window.event; if(event.preventDefault) { event.preventDefault(); event.stopPropagation(); } else { event.returnValue = false; event.cancelBubble = true; } }; //the getModUrl() is used by contrib modules for custom ajax Webfm.ajaxUrl = function() { var path = getBaseUrl() + "/?q="; path += (typeof getModUrl == "undefined") ? "webfm_js" : getModUrl(); return path; }; //Empty all child nodes Webfm.clearNodeById = function (elementId) { var node = Webfm.$(elementId); while(node.hasChildNodes()) { node.removeChild(node.firstChild); } }; //Sort methods Webfm.sortByName = function (a, b) { var x, y; if(typeof a.ftitle != "undefined") { x = a.ftitle.toLowerCase(); } else { x = a.n.toLowerCase(); } if(typeof b.ftitle != "undefined") { y = b.ftitle.toLowerCase(); } else { y = b.n.toLowerCase(); } return ((x < y) ? -1 : ((x > y) ? 1 : 0)); }; Webfm.sortBySize = function (a, b) { var x, y; x = parseInt(parseFloat(a.s), 10); y = parseInt(parseFloat(b.s), 10); return x - y; }; Webfm.sortByModified = function (a, b) { var x, y; x = a.m; y = b.m; return ((x < y) ? -1 : ((x > y) ? 1 : 0)); }; Webfm.sortByOwner = function (a, b) { var x, y; if(typeof a.funame != "undefined") { x = a.funame.toLowerCase(); } else { x = a.un.toLowerCase(); } if(typeof b.funame != "undefined") { y = b.funame.toLowerCase(); } else { y = b.un.toLowerCase(); } return ((x < y) ? -1 : ((x > y) ? 1 : 0)); }; Webfm.sortByKey = function (a, b) { var x, y; x = a.toLowerCase(); y = b.toLowerCase(); return ((x < y) ? -1 : ((x > y) ? 1 : 0)); }; //Build date stamp Webfm.convertunixtime = function (unixtime) { var c_date, c_min, c_hours, c_day, c_mon, c_year, format; // unix date format doesn't have millisec component c_date = new Date(unixtime * 1000); c_min = c_date.getMinutes(); c_hours = c_date.getHours(); c_day = c_date.getDate(); c_mon = c_date.getMonth() + 1; c_year = c_date.getFullYear(); c_min = Webfm.doubleDigit(c_min); c_hours = Webfm.doubleDigit(c_hours); c_day = Webfm.doubleDigit(c_day); c_mon = Webfm.doubleDigit(c_mon); if(c_year > 1999) { c_year -= 2000; } else { c_year -= 1900; } c_year = Webfm.doubleDigit(c_year); // Get day/month order from db variable format = getWebfmDateFormat(); if(format == 1) { return c_day + "/" + c_mon + "/" + c_year + " " + c_hours + ":" + c_min; } else { return c_mon + "/" + c_day + "/" + c_year + " " + c_hours + ":" + c_min; } }; Webfm.doubleDigit = function (num) { return (num < 10) ? "0" + num : num; }; Webfm.size = function (sz) { var size, units; size = sz; if(size < 1024) { units = " B"; } else { size = parseInt(size >> 10, 10); if(size < 1024) { units = " KB"; } else { size = parseInt(size >> 10, 10); if(size < 1024) { units = " MB"; } else { size = parseInt(size >> 10, 10); if(size < 1024) { units = " GB"; } else { size = parseInt(size >> 10, 10); units = " TB"; } } } } return size + units; }; Webfm.enter = function (event) { var code; event = event || window.event; if(event.keyCode) { code = event.keyCode; } else if(event.which) { code = event.which; } return (code == 13) ? true : false; }; Webfm.rclick = function (event) { var rightclick; if(event.which) { rightclick = (event.which == 3); } else { if(event.button) { rightclick = (event.button == 2); } } return rightclick; }; //Dump debug function //return a string version of a thing, without name. //calls recursive function to actually traverse content. Webfm.dump = function (content, txt_arr) { if(txt_arr == 'undefined') { txt_arr = false; } return Webfm.dumpRecur(content, 0, true, txt_arr) + "\n"; }; //recursive function traverses content, returns string version of thing //content: what to dump. //indent: how far to indent. //neednl: true if need newline, false if not Webfm.dumpRecur = function (content, indent, neednl, txt_arr) { var out, inside, i; out = ""; if(typeof content == 'function') { return 'function'; } else if(Webfm.isArray(content)) { // handle real arrays in brackets if(neednl) { out += "\n" + Webfm.dumpSpaces(indent); } if(!txt_arr) { out += "[ "; } inside = false; for(i = 0; i < content.length; i++) { if(inside) { out += " \n" + Webfm.dumpSpaces(indent + 1); } else { inside = true; } out += Webfm.dumpRecur(content[i], indent + 1, false, txt_arr); } out += "\n" + Webfm.dumpSpaces(indent); if(!txt_arr) { out += "]"; } } else if(Webfm.isObject(content)) { // handle objects by association if(neednl) { out += "\n" + Webfm.dumpSpaces(indent); } if(!txt_arr) { out += "{ "; } inside = false; for(i in content) { if(content.hasOwnProperty(i)) { if(inside) { out += " \n" + Webfm.dumpSpaces(indent + 1); } else { inside = true; } out += "'" + i + "':" + Webfm.dumpRecur(content[i], indent + 1, true, txt_arr); } } out += "\n" + Webfm.dumpSpaces(indent); if(!txt_arr) { out += "}"; } } else if(typeof content == 'string') { out += "'" + content + "'"; } else { out += content; } return out; }; //print n groups of two spaces for indent Webfm.dumpSpaces = function (n) { var out, i; out = ''; for(i = 0; i < n; i++) { out += ' '; } return out; }; Webfm.isArray = function (array) { return (array && array.constructor == Array); }; Webfm.isObject = function (object) { return (object && object.constructor == Object); }; //Unregister all global listener events window.onunload = Webfm.eventUnregisterWebfm; ///////////////////////////////////////////////////////ADD IN LEGACY DRUPAL JS FUNCTIONS USED BY WEBFM//////////////////////////////////////////////// /** * Redirects a button's form submission to a hidden iframe and displays the result * in a given wrapper. The iframe should contain a call to * window.parent.iframeHandler() after submission. */ Drupal.redirectFormButton = function (uri, button, handler) { var action, target, response, iframe; // Trap the button button.onmouseover = button.onfocus = function() { button.onclick = function() { // Create target iframe Drupal.createIframe(); // Prepare variables for use in anonymous function. button = this; action = button.form.action; target = button.form.target; // Redirect form submission to iframe this.form.action = uri; this.form.target = 'redirect-target'; handler.onsubmit(); // Set iframe handler for later window.iframeHandler = function() { iframe = $('#redirect-target').get(0); // Restore form submission button.form.action = action; button.form.target = target; // Get response from iframe body try { response = (iframe.contentWindow || iframe.contentDocument || iframe).document.body.innerHTML; // Firefox 1.0.x hack: Remove (corrupted) control characters response = response.replace(/[\f\n\r\t]/g, ' '); if(window.opera) { // Opera-hack: it returns innerHTML sanitized. response = response.replace(/"/g, '"'); } } catch (e) { response = null; } response = Drupal.parseJson(response); // Check response code if(response.status === 0) { handler.onerror(response.data); return; } handler.oncomplete(response.data); return true; }; return true; }; }; button.onmouseout = button.onblur = function() { button.onclick = null; }; }; /** * Create an invisible iframe for form submissions. */ Drupal.createIframe = function() { var div, iframe; if($('#redirect-holder').size()) { return; } // Note: some browsers require the literal name/id attributes on the tag, // some want them set through JS. We do both. window.iframeHandler = function() {}; div = document.createElement('div'); div.id = 'redirect-holder'; $(div).html(''); iframe = div.firstChild; $(iframe).attr({ name: 'redirect-target', id: 'redirect-target' }); $(iframe).css({ position: 'absolute', height: '1px', width: '1px', visibility: 'hidden' }); $('body').append(div); }; /** * Delete the invisible iframe */ Drupal.deleteIframe = function() { $('#redirect-holder').remove(); }; /** * Returns the position of the mouse cursor based on the event object passed */ Drupal.mousePosition = function(e) { if(Webfm.browser.isIE) { return { x: e.clientX + document.documentElement.scrollLeft, y: e.clientY + document.documentElement.scrollTop }; } else { return { x: e.pageX, y: e.pageY }; } };