X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=UI%2FWebServerResources%2Fgeneric.js;h=ce7a12ed45171a4c42d9c14348d16ee1f19d6cc7;hb=c6c01229291a89caf24a6a11b25bcdefee5f6246;hp=89cce21d5d12a715159f04f15c3096c9f9eb87e9;hpb=e37a86b6eb86fcda7a82dfe12e60d97327d866b8;p=scalable-opengroupware.org diff --git a/UI/WebServerResources/generic.js b/UI/WebServerResources/generic.js index 89cce21d..ce7a12ed 100644 --- a/UI/WebServerResources/generic.js +++ b/UI/WebServerResources/generic.js @@ -20,8 +20,6 @@ */ /* some generic JavaScript code for SOGo */ -// TODO: replace things with Prototype where applicable - /* generic stuff */ var logConsole; @@ -29,11 +27,24 @@ var logWindow = null; var queryParameters; -var activeAjaxRequests = 0; +var menus = new Array(); +var search = {}; +var sorting = {}; + +var lastClickedRow = -1; + +var weekStartIsMonday = true; // logArea = null; var allDocumentElements = null; +var userDefaults = null; +var userSettings = null; + +// Ajax requests counts +var activeAjaxRequests = 0; +var removeFolderRequestCount = 0; + /* a W3C compliant document.all */ function getAllScopeElements(scope) { var elements = new Array(); @@ -98,6 +109,30 @@ function getElementsByClassName2(_tag, _class, _scope) { } } +function createElement(tagName, id, classes, attributes, htmlAttributes, + parentNode) { + var newElement = $(document.createElement(tagName)); + if (id) + newElement.setAttribute("id", id); + if (classes) { + if (typeof(classes) == "string") + newElement.addClassName(classes); + else + for (var i = 0; i < classes.length; i++) + newElement.addClassName(classes[i]); + } + if (attributes) + for (var i in attributes) + newElement[i] = attributes[i]; + if (htmlAttributes) + for (var i in htmlAttributes) + newElement.setAttribute(i, htmlAttributes[i]); + if (parentNode) + parentNode.appendChild(newElement); + + return $(newElement); +} + function ml_stripActionInURL(url) { if (url[url.length - 1] != '/') { var i; @@ -111,21 +146,22 @@ function ml_stripActionInURL(url) { } function URLForFolderID(folderID) { - var folderInfos = folderID.split(":"); - var url; - if (folderInfos.length > 1) { - url = UserFolderURL + "../" + folderInfos[0]; - if (folderInfos[1][0] != '/') - url += '/'; - url += folderInfos[1]; - } - else - url = ApplicationBaseURL + folderInfos[0]; + var folderInfos = folderID.split(":"); + var url; + if (folderInfos.length > 1) { + url = UserFolderURL + "../" + folderInfos[0]; + if (!(folderInfos[0].endsWith('/') + || folderInfos[1].startsWith('/'))) + url += '/'; + url += folderInfos[1]; + } + else + url = ApplicationBaseURL + folderInfos[0]; - if (url[url.length-1] == '/') - url = url.substr(0, url.length-1); + if (url[url.length-1] == '/') + url = url.substr(0, url.length-1); - return url; + return url; } function extractEmailAddress(mailTo) { @@ -144,19 +180,22 @@ function extractEmailAddress(mailTo) { function extractEmailName(mailTo) { var emailName = ""; - var emailNamere = /(.+)\ "); + var emailNamere = /([ ]+)?(.+)\ 0) mailto = emailName + ' <' + email + '>'; @@ -167,34 +206,61 @@ function sanitizeMailTo(dirtyMailTo) { } function openUserFolderSelector(callback, type) { - var urlstr = ApplicationBaseURL; - if (urlstr[urlstr.length-1] != '/') - urlstr += '/'; - urlstr += ("../../" + UserLogin + "/Contacts/userFolders"); - var w = window.open(urlstr, "User Selector", - "width=322,height=250,resizable=1,scrollbars=0"); - w.opener = window; - w.userFolderCallback = callback; - w.userFolderType = type; - w.focus(); -} - -function openMailComposeWindow(url) { - var w = window.open(url, null, + var urlstr = ApplicationBaseURL; + if (! urlstr.endsWith('/')) + urlstr += '/'; + urlstr += ("../../" + UserLogin + "/Contacts/userFolders"); + var w = window.open(urlstr, "_blank", + "width=322,height=250,resizable=1,scrollbars=0,location=0"); + w.opener = window; + window.userFolderCallback = callback; + window.userFolderType = type; + w.focus(); +} + +function openContactWindow(url, wId) { + if (typeof wId == "undefined") + wId = "_blank"; + else { + var r = new RegExp("[\.\/-]", "g"); + wId = wId.replace(r, "_"); + } + + var w = window.open(url, wId, + "width=450,height=600,resizable=0,location=0"); + w.focus(); + + return w; +} + +function openMailComposeWindow(url, wId) { + var parentWindow = this; + + if (typeof wId == "undefined") + wId = "_blank"; + else { + var r = new RegExp("[\.\/-]", "g"); + wId = wId.replace(r, "_"); + if (document.body.hasClassName("popup")) + parentWindow = window.opener; + } + + var w = parentWindow.open(url, wId, "width=680,height=520,resizable=1,scrollbars=1,toolbar=0," + "location=0,directories=0,status=0,menubar=0" + ",copyhistory=0"); + w.focus(); return w; } -function openMailTo(senderMailto) { - var mailto = sanitizeMailTo(senderMailto); +function openMailTo(senderMailTo) { + var mailto = sanitizeMailTo(senderMailTo); if (mailto.length > 0) openMailComposeWindow(ApplicationBaseURL - + "/../Mail/compose?mailto=" + mailto); + + "../Mail/compose?mailto=" + mailto); return false; /* stop following the link */ } @@ -203,7 +269,7 @@ function createHTTPClient() { // http://developer.apple.com/internet/webcontent/xmlhttpreq.html if (typeof XMLHttpRequest != "undefined") return new XMLHttpRequest(); - + try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { } try { return new ActiveXObject("Microsoft.XMLHTTP"); } @@ -212,63 +278,126 @@ function createHTTPClient() { return null; } +function appendDifferentiator(url) { + var url_nocache = url; + var position = url.indexOf('?', 0); + if (position < 0) + url_nocache += '?'; + else + url_nocache += '&'; + url_nocache += 'differentiator=' + Math.floor(Math.random()*50000); + + return url_nocache; +} + function triggerAjaxRequest(url, callback, userdata) { var http = createHTTPClient(); activeAjaxRequests += 1; - document.animTimer = setTimeout("checkAjaxRequestsState();", 200); + document.animTimer = setTimeout("checkAjaxRequestsState();", 50); + //url = appendDifferentiator(url); if (http) { + http.open("POST", url, true); + http.url = url; http.onreadystatechange = function() { -// log ("state changed (" + http.readyState + "): " + url); - try { - if (http.readyState == 4 - && activeAjaxRequests > 0) { - if (!http.aborted) { - http.callbackData = userdata; - callback(http); - } - activeAjaxRequests -= 1; - checkAjaxRequestsState(); - } - } - catch( e ) { - activeAjaxRequests -= 1; - checkAjaxRequestsState(); - log("AJAX Request, Caught Exception: " + e.name); - log(e.message); - } - }; - http.url = url; - http.open("GET", url, true); - http.send(""); +// log ("state changed (" + http.readyState + "): " + url); + try { + if (http.readyState == 4 + && activeAjaxRequests > 0) { + if (!http.aborted) { + if (userdata) + http.callbackData = userdata; + callback(http); + } + activeAjaxRequests -= 1; + checkAjaxRequestsState(); + } + } + catch( e ) { + activeAjaxRequests -= 1; + checkAjaxRequestsState(); + log("AJAX Request, Caught Exception: " + e.name); + log(e.message); + log(backtrace()); + } + }; + http.send(null); + } + else { + log("triggerAjaxRequest: error creating HTTP Client!"); } return http; } +function startAnimation(parent, nextNode) { + var anim = $("progressIndicator"); + if (anim) return anim; + + anim = document.createElement("img"); + anim = $(anim); + anim.id = "progressIndicator"; + anim.src = ResourcesURL + "/busy.gif"; + anim.setStyle({ visibility: "hidden" }); + if (nextNode) + parent.insertBefore(anim, nextNode); + else + parent.appendChild(anim); + anim.setStyle({ visibility: "visible" }); + + return anim; +} + function checkAjaxRequestsState() { var toolbar = document.getElementById("toolbar"); if (toolbar) { if (activeAjaxRequests > 0 && !document.busyAnim) { - var anim = document.createElement("img"); - document.busyAnim = anim; - anim.id = "progressIndicator"; - anim.src = ResourcesURL + "/busy.gif"; - anim.style.visibility = "hidden;"; - toolbar.appendChild(anim); - anim.style.visibility = "visible;"; + document.busyAnim = startAnimation(toolbar); } else if (activeAjaxRequests == 0 - && document.busyAnim) { + && document.busyAnim + && document.busyAnim.parentNode) { document.busyAnim.parentNode.removeChild(document.busyAnim); document.busyAnim = null; } } } +function isSafari3() { + return (navigator.appVersion.indexOf("Version") > -1); +} + +function isSafari() { + //var agt = navigator.userAgent.toLowerCase(); + //var is_safari = ((agt.indexOf('safari')!=-1)&&(agt.indexOf('mac')!=-1))?true:false; + + return (navigator.vendor == "Apple Computer, Inc."); +} + +function isHttpStatus204(status) { + return (status == 204 || // Firefox + (isSafari() && typeof(status) == 'undefined') || // Safari + status == 1223); // IE +} + +function getTarget(event) { + event = event || window.event; + if (event.target) + return event.target; // W3C DOM + else + return event.srcElement; // IE +} + +function preventDefault(event) { + if (event.preventDefault) + event.preventDefault(); // W3C DOM + else + event.returnValue = false; // IE +} + function resetSelection(win) { var t = ""; if (win && win.getSelection) { @@ -288,7 +417,7 @@ function refreshOpener() { function parseQueryString() { var queryArray, queryDict - var key, value, s, idx; + var key, value, s, idx; queryDict.length = 0; queryDict = new Array(); @@ -326,143 +455,132 @@ function generateQueryString(queryDict) { return s; } -function getQueryParaArray(s) { - if (s.charAt(0) == "?") s = s.substr(1, s.length - 1); - return s.split("&"); -} - -function getQueryParaValue(s, name) { - var t; - - t = getQueryParaArray(s); - for (var i = 0; i < t.length; i++) { - var s = t[i]; - - if (s.indexOf(name) != 0) - continue; - - s = s.substr(name.length, s.length - name.length); - return decodeURIComponent(s); - } - return null; -} - -/* opener callback */ - -function triggerOpenerCallback() { - /* this code has some issue if the folder has no proper trailing slash! */ - if (window.opener && !window.opener.closed) { - var t, cburl; - - t = getQueryParaValue(window.location.search, "openerurl="); - cburl = window.opener.location.href; - if (cburl[cburl.length - 1] != "/") { - cburl = cburl.substr(0, cburl.lastIndexOf("/") + 1); - } - cburl = cburl + t; - window.opener.location.href = cburl; - } -} - /* selection mechanism */ function deselectAll(parent) { for (var i = 0; i < parent.childNodes.length; i++) { var node = parent.childNodes.item(i); if (node.nodeType == 1) - node.deselect(); + $(node).deselect(); } } function isNodeSelected(node) { - var classStr = '' + node.getAttribute('class'); - var position = classStr.indexOf('_selected', 0); - - return (position > -1); + return $(node).hasClassName('_selected'); } function acceptMultiSelect(node) { - var accept = ('' + node.getAttribute('multiselect')).toLowerCase(); + var response = false; + var attribute = node.getAttribute('multiselect'); + if (attribute && attribute.length > 0) { + log("node '" + node.getAttribute("id") + + "' is still using old-stylemultiselect!"); + response = (attribute.toLowerCase() == 'yes'); + } + else + response = node.multiselect; - return (accept == 'yes'); + return response; } function onRowClick(event) { - var node = event.target; + var node = getTarget(event); + var rowIndex = null; - if (node.tagName == 'TD') - node = node.parentNode; + if (node.tagName == 'TD') { + node = node.parentNode; // select TR + rowIndex = node.rowIndex - $(node).up('table').down('thead').getElementsByTagName('tr').length; + } + else if (node.tagName == 'LI') { + // Find index of clicked row + var list = node.parentNode; + var items = list.childNodesWithTag("li"); + for (var i = 0; i < items.length; i++) { + if (items[i] == node) { + rowIndex = i; + break; + } + } + } - var startSelection = node.parentNode.getSelectedNodes(); - if (event.shiftKey == 1 + var initialSelection = $(node.parentNode).getSelectedNodes(); + if ((event.shiftKey == 1 || event.ctrlKey == 1) + && (lastClickedRow >= 0) && (acceptMultiSelect(node.parentNode) || acceptMultiSelect(node.parentNode.parentNode))) { - if (isNodeSelected(node) == true) { - node.deselect(); + if (event.shiftKey) + $(node.parentNode).selectRange(lastClickedRow, rowIndex); + else if (isNodeSelected(node) == true) { + $(node).deselect(); } else { - node.select(); + $(node).select(); } + // At this point, should empty content of 3-pane view } else { - deselectAll(node.parentNode); - node.select(); - } - - if (startSelection != node.parentNode.getSelectedNodes()) { - var parentNode = node.parentNode; - if (parentNode instanceof HTMLTableSectionElement) - parentNode = parentNode.parentNode; - var onSelectionChangeEvent = document.createEvent("UIEvents"); - onSelectionChangeEvent.initEvent("selectionchange", true, true); - parentNode.dispatchEvent(onSelectionChangeEvent); + // Single line selection + $(node.parentNode).deselectAll(); + $(node).select(); + + if (initialSelection != $(node.parentNode).getSelectedNodes()) { + // Selection has changed; fire mousedown event + var parentNode = node.parentNode; + if (parentNode.tagName == 'TBODY') + parentNode = parentNode.parentNode; + parentNode.fire("mousedown"); + } } + lastClickedRow = rowIndex; + + return true; } /* popup menus */ -var bodyOnClick = ""; // var acceptClick = false; -function onMenuClick(event, menuId) { - var node = event.target; +function popupMenu(event, menuId, target) { + document.menuTarget = target; if (document.currentPopupMenu) - hideMenu(event, document.currentPopupMenu); + hideMenu(document.currentPopupMenu); + + var popup = $(menuId); - var popup = document.getElementById(menuId); + var deltaX = 0; + var deltaY = 0; + + var pageContent = $("pageContent"); + if (popup.parentNode.tagName != "BODY") { + var offset = pageContent.cascadeLeftOffset(); + deltaX = -($(popup.parentNode).cascadeLeftOffset() - offset); + offset = pageContent.cascadeTopOffset(); + deltaY = -($(popup.parentNode).cascadeTopOffset() - offset); + } - var menuTop = event.pageY; - var menuLeft = event.pageX; - var heightDiff = (window.innerHeight + var menuTop = Event.pointerY(event) + deltaY; + var menuLeft = Event.pointerX(event) + deltaX; + var heightDiff = (window.height() - (menuTop + popup.offsetHeight)); if (heightDiff < 0) menuTop += heightDiff; - - var leftDiff = (window.innerWidth + + var leftDiff = (window.width() - (menuLeft + popup.offsetWidth)); if (leftDiff < 0) menuLeft -= popup.offsetWidth; - popup.style.top = menuTop + "px;"; - popup.style.left = menuLeft + "px;"; - popup.style.visibility = "visible;"; - setupMenuTarget(popup, node); + if (popup.prepareVisibility) + popup.prepareVisibility(); + + popup.setStyle({ top: menuTop + "px", + left: menuLeft + "px", + visibility: "visible" }); - bodyOnClick = "" + document.body.getAttribute("onclick"); - document.body.setAttribute("onclick", "onBodyClick(event);"); document.currentPopupMenu = popup; - event.cancelBubble = true; - event.returnValue = false; - - return false; -} + $(document.body).observe("click", onBodyClickMenuHandler); -function setupMenuTarget(menu, target) { - menu.menuTarget = target; - var menus = document.getElementsByClassName("menu", menu); - for (var i = 0; i < menus.length; i++) { - menus[i].menuTarget = target; - } + preventDefault(event); } function getParentMenu(node) { @@ -482,43 +600,44 @@ function getParentMenu(node) { return menuNode; } -function onBodyClick(event) { - document.currentPopupMenu.menuTarget = null; - hideMenu(event, document.currentPopupMenu); - document.body.setAttribute("onclick", bodyOnClick); +function onBodyClickMenuHandler(event) { + hideMenu(document.currentPopupMenu); + document.body.stopObserving("click", onBodyClickMenuHandler); - return false; + if (event) + preventDefault(event); } -function hideMenu(event, menuNode) { +function hideMenu(menuNode) { var onHide; -// log('hiding menu "' + menuNode.getAttribute('id') + '"'); if (menuNode.submenu) { - hideMenu(event, menuNode.submenu); + hideMenu(menuNode.submenu); menuNode.submenu = null; } - menuNode.style.visibility = "hidden"; + menuNode.setStyle({ visibility: "hidden" }); if (menuNode.parentMenuItem) { - menuNode.parentMenuItem.setAttribute('class', 'submenu'); + menuNode.parentMenuItem.stopObserving("mouseover",onMouseEnteredSubmenu); + menuNode.stopObserving("mouseover", onMouseEnteredSubmenu); + menuNode.parentMenuItem.stopObserving("mouseout", onMouseLeftSubmenu); + menuNode.stopObserving("mouseout", onMouseLeftSubmenu); + menuNode.parentMenu.stopObserving("mouseover", onMouseEnteredParentMenu); + $(menuNode.parentMenuItem).removeClassName("submenu-selected"); + menuNode.parentMenuItem.mouseInside = false; menuNode.parentMenuItem = null; - menuNode.parentMenu.setAttribute('onmousemove', null); menuNode.parentMenu.submenuItem = null; menuNode.parentMenu.submenu = null; menuNode.parentMenu = null; } - var onhideEvent = document.createEvent("UIEvents"); - onhideEvent.initEvent("hideMenu", false, true); - menuNode.dispatchEvent(onhideEvent); + $(menuNode).fire("mousedown"); } -function onMenuEntryClick(event, menuId) { +function onMenuEntryClick(event) { var node = event.target; id = getParentMenu(node).menuTarget; -// log("clicked " + id + "/" + id.tagName); return false; } @@ -541,18 +660,17 @@ function parseQueryParameters(url) { function initLogConsole() { var logConsole = $("logConsole"); if (logConsole) { - logConsole.addEventListener("dblclick", onLogDblClick, false); - logConsole.innerHTML = ""; - node = document.getElementsByTagName('body')[0]; - node.addEventListener("keydown", onBodyKeyDown, true); + logConsole.highlighted = false; + logConsole.observe("dblclick", onLogDblClick, false); + logConsole.update(); + Event.observe(window, "keydown", onBodyKeyDown); } } function onBodyKeyDown(event) { if (event.keyCode == 27) { toggleLogConsole(); - event.cancelBubble = true; - event.returnValue = false; + preventDefault(event); } } @@ -565,13 +683,12 @@ function toggleLogConsole(event) { var logConsole = $("logConsole"); var display = '' + logConsole.style.display; if (display.length == 0) { - logConsole.style.display = 'block;'; + logConsole.setStyle({ display: 'block' }); } else { - logConsole.style.display = ''; + logConsole.setStyle({ display: '' }); } - event.cancelBubble = true; - event.returnValue = false; - event.preventDefault(); + if (event) + preventDefault(event); } function log(message) { @@ -581,95 +698,105 @@ function log(message) { logWindow = logWindow.opener; } var logConsole = logWindow.document.getElementById("logConsole"); - if (logConsole) - logConsole.innerHTML += message.replace("<", "<") + '
' + "\n"; + if (logConsole) { + logConsole.highlighted = !logConsole.highlighted; + if (message == '\c') { + logConsole.innerHTML = ""; + return; + } + var logMessage = message.replace("<", "<", "g"); + logMessage = logMessage.replace(" ", " ", "g"); + logMessage = logMessage.replace("\r\n", "
\n", "g"); + logMessage = logMessage.replace("\n", "
\n", "g"); + logMessage += '
' + "\n"; + if (logConsole.highlighted) + logMessage = '
' + logMessage + '
'; + logConsole.innerHTML += logMessage; + } } function backtrace() { - var func = backtrace.caller; - var str = "backtrace:
"; + var func = backtrace.caller; + var str = "backtrace:\n"; - while (func) - { + while (func) + { if (func.name) - { - str += " " + func.name; - if (this) + { + str += " " + func.name; + if (this) str += " (" + this + ")"; - } + } else - str += "[anonymous]\n"; + str += "[anonymous]\n"; - str += "
"; + str += "\n"; func = func.caller; - } - str += "--\n"; + } + str += "--\n"; - return str; + return str; } -function dropDownSubmenu(event) { - var node = event.target; - var submenu = node.getAttribute("submenu"); - if (submenu && submenu != "") { - var submenuNode = document.getElementById(submenu); - var parentNode = getParentMenu(node); +function popupSubmenu(event) { + if (this.submenu && this.submenu != "") { + var submenuNode = $(this.submenu); + var parentNode = getParentMenu(this); if (parentNode.submenu) - hideMenu(event, parentNode.submenu); - submenuNode.parentMenuItem = node; + hideMenu(parentNode.submenu); + submenuNode.parentMenuItem = this; submenuNode.parentMenu = parentNode; - parentNode.submenuItem = node; + parentNode.submenuItem = this; parentNode.submenu = submenuNode; - - var menuTop = (node.offsetTop - 2); - - var heightDiff = (window.innerHeight - - (menuTop + submenuNode.offsetHeight)); - if (heightDiff < 0) - menuTop += heightDiff; - - var menuLeft = parentNode.offsetWidth - 3; - if (window.innerWidth - < (menuLeft + submenuNode.offsetWidth - + parentNode.cascadeLeftOffset())) - menuLeft = -submenuNode.offsetWidth + 3; - - parentNode.setAttribute('onmousemove', 'checkDropDown(event);'); - node.setAttribute('class', 'submenu-selected'); - submenuNode.style.top = menuTop + "px;"; - submenuNode.style.left = menuLeft + "px;"; - submenuNode.style.visibility = "visible;"; + + if (submenuNode.prepareVisibility) + submenuNode.prepareVisibility(); + + var menuTop = (parentNode.offsetTop - 1 + + this.offsetTop); + if (window.height() + < (menuTop + submenuNode.offsetHeight) + && submenuNode.offsetHeight < window.height()) + menuTop -= submenuNode.offsetHeight - this.offsetHeight - 4; + var menuLeft = (parentNode.offsetLeft + parentNode.offsetWidth - 3); + if (window.width() + < (menuLeft + submenuNode.offsetWidth)) + menuLeft = parentNode.offsetLeft - submenuNode.offsetWidth + 3; + + this.mouseInside = true; + this.observe("mouseover", onMouseEnteredSubmenu); + submenuNode.observe("mouseover", onMouseEnteredSubmenu); + this.observe("mouseout", onMouseLeftSubmenu); + submenuNode.observe("mouseout", onMouseLeftSubmenu); + parentNode.observe("mouseover", onMouseEnteredParentMenu); + $(this).addClassName("submenu-selected"); + submenuNode.setStyle({ top: menuTop + "px", + left: menuLeft + "px", + visibility: "visible" }); + preventDefault(event); } } -function checkDropDown(event) { - var parentMenu = getParentMenu(event.target); - var submenuItem = parentMenu.submenuItem; - if (submenuItem) { - var menuX = event.clientX - parentMenu.cascadeLeftOffset(); - var menuY = event.clientY - parentMenu.cascadeTopOffset(); - var itemX = submenuItem.offsetLeft; - var itemY = submenuItem.offsetTop - 75; - - if (menuX >= itemX - && menuX < itemX + submenuItem.offsetWidth - && (menuY < itemY - || menuY > (itemY + submenuItem.offsetHeight))) { - hideMenu(event, parentMenu.submenu); - parentMenu.submenu = null; - parentMenu.submenuItem = null; - parentMenu.setAttribute('onmousemove', null); - } - } +function onMouseEnteredParentMenu(event) { + if (this.submenuItem && !this.submenuItem.mouseInside) + hideMenu(this.submenu); +} + +function onMouseEnteredSubmenu(event) { + $(this).mouseInside = true; +} + +function onMouseLeftSubmenu(event) { + $(this).mouseInside = false; } /* search field */ function popupSearchMenu(event) { - var node = event.target; - var menuId = this.getAttribute("menuid"); - relX = event.pageX - node.cascadeLeftOffset(); - relY = event.pageY - node.cascadeTopOffset(); + var offset = Position.cumulativeOffset(this); + + relX = Event.pointerX(event) - offset[0]; + relY = Event.pointerY(event) - offset[1]; if (event.button == 0 && relX < 24) { @@ -677,26 +804,30 @@ function popupSearchMenu(event) { event.returnValue = false; if (document.currentPopupMenu) - hideMenu(event, document.currentPopupMenu); + hideMenu(document.currentPopupMenu); - var popup = document.getElementById(menuId); - popup.style.top = node.offsetHeight + "px"; - popup.style.left = (node.offsetLeft + 3) + "px"; - popup.style.visibility = "visible"; + var popup = $(menuId); + offset = Position.positionedOffset(this); + popup.setStyle({ top: this.offsetHeight + "px", + left: (offset[0] + 3) + "px", + visibility: "visible" }); - bodyOnClick = "" + document.body.getAttribute("onclick"); - document.body.setAttribute("onclick", "onBodyClick('" + menuId + "');"); document.currentPopupMenu = popup; + $(document.body).observe("click", onBodyClickMenuHandler); } } function setSearchCriteria(event) { - searchValue = $("searchValue"); - searchCriteria = $("searchCriteria"); + var searchValue = $("searchValue"); + var searchCriteria = $("searchCriteria"); + + searchValue.setAttribute("ghost-phrase", this.innerHTML); + searchCriteria.value = this.getAttribute('id'); - var node = event.target; - searchValue.setAttribute("ghost-phrase", node.innerHTML); - searchCriteria = node.getAttribute('id'); + if (this.parentNode.chosenNode) + this.parentNode.chosenNode.removeClassName("_chosen"); + this.addClassName("_chosen"); + this.parentNode.chosenNode = this; } function checkSearchValue(event) { @@ -712,15 +843,35 @@ function onSearchChange() { log ("onSearchChange()..."); } +function configureSearchField() { + var searchValue = $("searchValue"); + var searchOptions = $("searchOptions"); + + if (!searchValue) return; + + searchValue.observe("click", popupSearchMenu); + searchValue.observe("blur", onSearchBlur); + searchValue.observe("focus", onSearchFocus); + searchValue.observe("keydown", onSearchKeyDown); + searchValue.observe("mousedown", onSearchMouseDown); + + if (!searchOptions) return; + + // Set the checkmark to the first option + var firstOption = searchOptions.down('li'); + firstOption.addClassName("_chosen"); + searchOptions.chosenNode = firstOption; +} + function onSearchMouseDown(event) { - var superNode = this.parentNode.parentNode.parentNode; - relX = (event.pageX - superNode.offsetLeft - this.offsetLeft); - relY = (event.pageY - superNode.offsetTop - this.offsetTop); + var superNode = this.parentNode.parentNode.parentNode; + relX = (Event.pointerX(event) - superNode.offsetLeft - this.offsetLeft); + relY = (Event.pointerY(event) - superNode.offsetTop - this.offsetTop); - if (relY < 24) { - event.cancelBubble = true; - event.returnValue = false; - } + if (relY < 24) { + event.cancelBubble = true; + event.returnValue = false; + } } function onSearchFocus() { @@ -732,22 +883,23 @@ function onSearchFocus() { this.select(); } - this.style.color = "#000"; + this.setStyle({ color: "#000" }); } function onSearchBlur(event) { var ghostPhrase = this.getAttribute("ghost-phrase"); -// log ("search blur: '" + this.value + "'"); + if (!this.value) { this.setAttribute("modified", ""); - this.style.color = "#aaa"; + this.setStyle({ color: "#aaa" }); this.value = ghostPhrase; + refreshCurrentFolder(); } else if (this.value == ghostPhrase) { this.setAttribute("modified", ""); - this.style.color = "#aaa"; + this.setStyle({ color: "#aaa" }); } else { this.setAttribute("modified", "yes"); - this.style.color = "#000"; + this.setStyle({ color: "#000" }); } } @@ -758,128 +910,152 @@ function onSearchKeyDown(event) { this.timer = setTimeout("onSearchFormSubmit()", 1000); } +function onSearchFormSubmit(event) { + var searchValue = $("searchValue"); + var searchCriteria = $("searchCriteria"); + var ghostPhrase = searchValue.getAttribute('ghost-phrase'); + + if (searchValue.value == ghostPhrase) return; + + search["criteria"] = searchCriteria.value; + search["value"] = searchValue.value; + + refreshCurrentFolder(); +} + function initCriteria() { var searchCriteria = $("searchCriteria"); var searchValue = $("searchValue"); - var firstOption; - var searchOptions = $("searchOptions"); - if (searchOptions) { - firstOption = searchOptions.childNodes[1]; - searchCriteria.value = firstOption.getAttribute('id'); - searchValue.setAttribute('ghost-phrase', firstOption.innerHTML); + if (!searchValue) return; + + var searchOptions = $("searchOptions").childNodesWithTag("li"); + if (searchOptions.length > 0) { + var firstChild = searchOptions[0]; + searchCriteria.value = $(firstChild).getAttribute('id'); + searchValue.setAttribute('ghost-phrase', firstChild.innerHTML); if (searchValue.value == '') { - searchValue.value = firstOption.innerHTML; + searchValue.value = firstChild.innerHTML; searchValue.setAttribute("modified", ""); - searchValue.style.color = "#aaa"; + searchValue.setStyle({ color: "#aaa" }); } } } /* toolbar buttons */ -function popupToolbarMenu(event, menuId) { - var toolbar = $("toolbar"); - var node = event.target; - if (node.tagName != 'A') - node = node.getParentWithTagName("a"); - node = node.childNodesWithTag("span")[0]; - - if (event.button == 0) { - event.cancelBubble = true; - event.returnValue = false; - - if (document.currentPopupMenu) - hideMenu(event, document.currentPopupMenu); - - var popup = document.getElementById(menuId); - var top = node.offsetTop + node.offsetHeight - 2; - popup.style.top = top + "px"; - popup.style.left = node.cascadeLeftOffset() + "px"; - popup.style.visibility = "visible"; - - bodyOnClick = "" + document.body.getAttribute("onclick"); - document.body.setAttribute("onclick", "onBodyClick('" + menuId + "');"); - document.currentPopupMenu = popup; - } +function popupToolbarMenu(node, menuId) { + if (document.currentPopupMenu) + hideMenu(document.currentPopupMenu); + + var popup = $(menuId); + var top = ($(node).getStyle('top') || 0) + node.offsetHeight - 2; + popup.setStyle({ top: top + "px", + left: $(node).cascadeLeftOffset() + "px", + visibility: "visible" }); + + document.currentPopupMenu = popup; + $(document.body).observe("click", onBodyClickMenuHandler); } /* contact selector */ function folderSubscriptionCallback(http) { - if (http.readyState == 4) { - if (http.status == 204) { - if (http.callbackData) - http.callbackData["method"](http.callbackData["data"]); - } - else - window.alert(labels["Unable to subscribe to that folder!"].decodeEntities()); - document.subscriptionAjaxRequest = null; - } - else - log ("ajax fuckage"); + if (http.readyState == 4) { + if (isHttpStatus204(http.status)) { + if (http.callbackData) + http.callbackData["method"](http.callbackData["data"]); + } + else + window.alert(clabels["Unable to subscribe to that folder!"]); + document.subscriptionAjaxRequest = null; + } + else + log ("folderSubscriptionCallback Ajax error"); } function subscribeToFolder(refreshCallback, refreshCallbackData) { - var folderData = refreshCallbackData["folder"].split(":"); - var username = folderData[0]; - var folderPath = folderData[1]; - if (username != UserLogin) { - var url = (UserFolderURL + "../" + username - + folderPath + "/subscribe"); - if (document.subscriptionAjaxRequest) { - document.subscriptionAjaxRequest.aborted = true; - document.subscriptionAjaxRequest.abort(); - } - var rfCbData = { method: refreshCallback, data: refreshCallbackData }; - document.subscriptionAjaxRequest = triggerAjaxRequest(url, - folderSubscriptionCallback, - rfCbData); - } - else - window.alert(labels["You cannot subscribe to a folder that you own!"] - .decodeEntities()); + var folderData = refreshCallbackData["folder"].split(":"); + var username = folderData[0]; + var folderPath = folderData[1]; + if (username != UserLogin) { + var url = (UserFolderURL + "../" + username + + folderPath + "/subscribe"); + if (document.subscriptionAjaxRequest) { + document.subscriptionAjaxRequest.aborted = true; + document.subscriptionAjaxRequest.abort(); + } + + var rfCbData = { method: refreshCallback, data: refreshCallbackData }; + document.subscriptionAjaxRequest = triggerAjaxRequest(url, + folderSubscriptionCallback, + rfCbData); + } + else + refreshCallbackData["window"].alert(clabels["You cannot subscribe to a folder that you own!"]); } function folderUnsubscriptionCallback(http) { - if (http.readyState == 4) { - if (http.status == 204) { - if (http.callbackData) - http.callbackData["method"](http.callbackData["data"]); - } - else - window.alert(labels["Unable to unsubscribe from that folder!"].decodeEntities()); - document.unsubscriptionAjaxRequest = null; - } + if (http.readyState == 4) { + removeFolderRequestCount--; + if (isHttpStatus204(http.status)) { + if (http.callbackData) + http.callbackData["method"](http.callbackData["data"]); + } + else + window.alert(clabels["Unable to unsubscribe from that folder!"]); + } } function unsubscribeFromFolder(folder, refreshCallback, refreshCallbackData) { - if (document.body.hasClassName("popup")) { - window.opener.unsubscribeFromFolder(folder, refreshCallback, - refreshCallbackData); - } - else { - var folderData = folder.split(":"); - var username = folderData[0]; - var folderPath = folderData[1]; - if (username != UserLogin) { - var url = (UserFolderURL + "../" + username - + "/" + folderPath + "/unsubscribe"); - if (document.unsubscriptionAjaxRequest) { - document.unsubscriptionAjaxRequest.aborted = true; - document.unsubscriptionAjaxRequest.abort(); - } - var rfCbData = { method: refreshCallback, data: refreshCallbackData }; - document.unsubscriptionAjaxRequest - = triggerAjaxRequest(url, folderUnsubscriptionCallback, - rfCbData); - } - else - window.alert(labels["You cannot unsubscribe from a folder that you own!"].decodeEntities()); - } + if (document.body.hasClassName("popup")) { + window.opener.unsubscribeFromFolder(folder, refreshCallback, + refreshCallbackData); + } + else { + var folderData = folder.split("_"); + var username = folderData[0]; + var folderPath = folderData[1]; + if (username.startsWith('/')) + username = username.substring(1); + if (username != UserLogin) { + var url = (ApplicationBaseURL + folder + "/unsubscribe"); + removeFolderRequestCount++; + var rfCbData = { method: refreshCallback, data: refreshCallbackData }; + triggerAjaxRequest(url, folderUnsubscriptionCallback, rfCbData); + } + else + window.alert(clabels["You cannot unsubscribe from a folder that you own!"]); + } +} + +function accessToSubscribedFolder(serverFolder) { + var folder; + + var parts = serverFolder.split(":"); + if (parts.length > 1) { + var paths = parts[1].split("/"); + folder = "/" + parts[0] + "_" + paths[2]; + } + else + folder = serverFolder; + + return folder; +} + +function getSubscribedFolderOwner(serverFolder) { + var owner; + + var parts = serverFolder.split(":"); + if (parts.length > 1) { + owner = parts[0]; + } + + return owner; } function listRowMouseDownHandler(event) { - event.preventDefault(); + preventDefault(event); + //Event.stop(event); } /* tabs */ @@ -887,16 +1063,24 @@ function initTabs() { var containers = document.getElementsByClassName("tabsContainer"); for (var x = 0; x < containers.length; x++) { var container = containers[x]; - var nodes = container.childNodes[1].childNodes; - - var firstTab; + var firstTab = null; + for (var i = 0; i < container.childNodes.length; i++) { + if (container.childNodes[i].tagName == 'UL') { + if (!firstTab) + firstTab = i; + } + } + var nodes = container.childNodes[firstTab].childNodes; + + firstTab = null; for (var i = 0; i < nodes.length; i++) { - if (nodes[i] instanceof HTMLLIElement) { - if (!firstTab) { - firstTab = i; - } - nodes[i].addEventListener("mousedown", onTabMouseDown, true); - nodes[i].addEventListener("click", onTabClick, true); + var currentNode = nodes[i]; + if (currentNode.tagName == 'LI') { + if (!firstTab) + firstTab = i; + $(currentNode).observe("mousedown", onTabMouseDown); + $(currentNode).observe("click", onTabClick); + //$(currentNode.getAttribute("target")).hide(); } } @@ -906,31 +1090,50 @@ function initTabs() { var target = $(nodes[firstTab].getAttribute("target")); target.addClassName("active"); + //target.show(); } } -function initMenusNamed(menuDivNames) { - for (var i = 0; i < menuDivNames.length; i++) { - var menuDIV = $(menuDivNames[i]); - if (menuDIV) - initMenu(menuDIV); - else - log("menu named '" + menuDivNames[i] + "' not found"); +function initMenus() { + var menus = getMenus(); + if (menus) { + for (var menuID in menus) { + var menuDIV = $(menuID); + if (menuDIV) + initMenu(menuDIV, menus[menuID]); + } } } -function initMenu(menuDIV) { - var lis = menuDIV.childNodesWithTag("ul")[0].childNodesWithTag("li"); - for (var j = 0; j < lis.length; j++) - lis[j].addEventListener("mousedown", listRowMouseDownHandler, false); - var subMenus = menuDIV.childNodesWithTag("div"); - for (var i = 0; i < subMenus.length; i++) - initMenu(subMenus[i]); +function initMenu(menuDIV, callbacks) { + var lis = $(menuDIV.childNodesWithTag("ul")[0]).childNodesWithTag("li"); + for (var j = 0; j < lis.length; j++) { + var node = $(lis[j]); + node.observe("mousedown", listRowMouseDownHandler, false); + var callback = callbacks[j]; + if (callback) { + if (typeof(callback) == "string") { + if (callback == "-") + node.addClassName("separator"); + else { + node.submenu = callback; + node.addClassName("submenu"); + node.observe("mouseover", popupSubmenu); + } + } + else { + node.observe("mouseup", onBodyClickMenuHandler); + node.observe("click", callback); + } + } + else + node.addClassName("disabled"); + } } function onTabMouseDown(event) { event.cancelBubble = true; - event.preventDefault(); + preventDefault(event); } function openExternalLink(anchor) { @@ -939,7 +1142,7 @@ function openExternalLink(anchor) { function openAclWindow(url) { var w = window.open(url, "aclWindow", - "width=300,height=300,resizable=1,scrollbars=1,toolbar=0," + "width=420,height=300,resizable=1,scrollbars=1,toolbar=0," + "location=0,directories=0,status=0,menubar=0" + ",copyhistory=0"); w.opener = window; @@ -949,29 +1152,29 @@ function openAclWindow(url) { } function getUsersRightsWindowHeight() { - return usersRightsWindowHeight; + return usersRightsWindowHeight; } function getUsersRightsWindowWidth() { - return usersRightsWindowWidth; + return usersRightsWindowWidth; } function getTopWindow() { - var topWindow = null; - var currentWindow = window; - while (!topWindow) { - if (currentWindow.document.body.hasClassName("popup") - && currentWindow.opener) - currentWindow = currentWindow.opener; - else - topWindow = currentWindow; - } + var topWindow = null; + var currentWindow = window; + while (!topWindow) { + if (currentWindow.document.body.hasClassName("popup") + && currentWindow.opener) + currentWindow = currentWindow.opener; + else + topWindow = currentWindow; + } - return topWindow; + return topWindow; } function onTabClick(event) { - var node = event.target; + var node = getTarget(event); // LI element var target = node.getAttribute("target"); @@ -981,10 +1184,24 @@ function onTabClick(event) { var oldContent = $(oldTarget); oldContent.removeClassName("active"); - container.activeTab.removeClassName("active"); + container.activeTab.removeClassName("active"); // previous LI container.activeTab = node; - container.activeTab.addClassName("active"); + container.activeTab.addClassName("active"); // current LI content.addClassName("active"); + + // Prototype alternative + + //oldContent.removeClassName("active"); + //container.activeTab.removeClassName("active"); // previous LI + //container.activeTab = node; + //container.activeTab.addClassName("active"); // current LI + + //container.activeTab.hide(); + //oldContent.hide(); + //content.show(); + + //container.activeTab = node; + //container.activeTab.show(); return false; } @@ -1048,12 +1265,12 @@ function indexColor(number) { var currentValue = number; var index = 0; while (currentValue) { - if (currentValue & 1) - colorTable[index]++; - if (index == 3) - index = 0; - currentValue >>= 1; - index++; + if (currentValue & 1) + colorTable[index]++; + if (index == 3) + index = 0; + currentValue >>= 1; + index++; } color = ("#" @@ -1065,31 +1282,57 @@ function indexColor(number) { return color; } -var onLoadHandler = function (event) { +function loadPreferences() { + var url = UserFolderURL + "jsonDefaults"; + var http = createHTTPClient(); + http.open("GET", url, false); + http.send(""); + if (http.status == 200) { + if (http.responseText.length > 0) + userDefaults = http.responseText.evalJSON(true); + else + userDefaults = {}; + } + + url = UserFolderURL + "jsonSettings"; + http.open("GET", url, false); + http.send(""); + if (http.status == 200) { + if (http.responseText.length > 0) + userSettings = http.responseText.evalJSON(true); + else + userSettings = {}; + } +} + +function onLoadHandler(event) { + if (typeof UserLogin != "undefined") + loadPreferences(); queryParameters = parseQueryParameters('' + window.location); - if (!document.body.hasClassName("popup")) { + if (!$(document.body).hasClassName("popup")) { initLogConsole(); - initializeMenus(); - initCriteria(); } + initCriteria(); + configureSearchField(); + initMenus(); initTabs(); configureDragHandles(); - configureSortableTableHeaders(); configureLinkBanner(); var progressImage = $("progressIndicator"); if (progressImage) progressImage.parentNode.removeChild(progressImage); + $(document.body).observe("contextmenu", onBodyClickContextMenu); +} + +function onBodyClickContextMenu(event) { + preventDefault(event); } -function configureSortableTableHeaders() { - var headers = document.getElementsByClassName("sortableTableHeader"); +function configureSortableTableHeaders(table) { + var headers = $(table).getElementsByClassName("sortableTableHeader"); for (var i = 0; i < headers.length; i++) { - var anchor = headers[i].childNodesWithTag("a")[0]; - if (!anchor.link) { - anchor.link = anchor.getAttribute("href"); - anchor.href = "#"; - anchor.addEventListener("click", onHeaderClick, true); - } + var header = headers[i]; + $(header).observe("click", onHeaderClick); } } @@ -1098,37 +1341,85 @@ function onLinkBannerClick() { checkAjaxRequestsState(); } +function onPreferencesClick(event) { + var urlstr = UserFolderURL + "preferences"; + var w = window.open(urlstr, "_blank", + "width=430,height=250,resizable=0,scrollbars=0,location=0"); + w.opener = window; + w.focus(); + + preventDefault(event); +} + function configureLinkBanner() { var linkBanner = $("linkBanner"); if (linkBanner) { var anchors = linkBanner.childNodesWithTag("a"); - for (var i = 0; i < 2; i++) { - anchors[i].addEventListener("mousedown", listRowMouseDownHandler, - false); - anchors[i].addEventListener("click", onLinkBannerClick, false); + for (var i = 1; i < 3; i++) { + $(anchors[i]).observe("mousedown", listRowMouseDownHandler); + $(anchors[i]).observe("click", onLinkBannerClick); } - if (anchors.length > 3) - anchors[3].addEventListener("click", toggleLogConsole, true); + $(anchors[4]).observe("mousedown", listRowMouseDownHandler); + $(anchors[4]).observe("click", onPreferencesClick); + if (anchors.length > 5) + $(anchors[5]).observe("click", toggleLogConsole); } } -if (window.addEventListener) { - window.addEventListener('load', onLoadHandler, false); -} else if (document.addEventListener) { - document.addEventListener('load', onLoadHandler, false); +/* folder creation */ +function createFolder(name, okCB, notOkCB) { + if (name) { + if (document.newFolderAjaxRequest) { + document.newFolderAjaxRequest.aborted = true; + document.newFolderAjaxRequest.abort(); + } + var url = ApplicationBaseURL + "/createFolder?name=" + name; + document.newFolderAjaxRequest + = triggerAjaxRequest(url, createFolderCallback, + {name: name, + okCB: okCB, + notOkCB: notOkCB}); + } +} + +function createFolderCallback(http) { + if (http.readyState == 4) { + var data = http.callbackData; + if (http.status == 201) { + if (data.okCB) + data.okCB(data.name, "/" + http.responseText, UserLogin); + } + else { + if (data.notOkCB) + data.notOkCB(name); + else + log("ajax problem:" + http.status); + } + } +} + +function onFinalLoadHandler(event) { + var safetyNet = $("javascriptSafetyNet"); + if (safetyNet) + safetyNet.parentNode.removeChild(safetyNet); +} + +FastInit.addOnLoad(onLoadHandler); + +function parent$(element) { + return this.opener.document.getElementById(element); } /* stubs */ +function refreshCurrentFolder() { +} + function configureDragHandles() { } -function initializeMenus() { +function getMenus() { } function onHeaderClick(event) { window.alert("generic headerClick"); } - -function parent$(element) { - return window.opener.document.getElementById(element); -}