/* -*- Mode: java; tab-width: 2; c-label-minimum-indentation: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
Copyright (C) 2005 SKYRIX Software AG
Copyright (C) 2006-2010 Inverse
This file is part of SOGo
SOGo is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
SOGo is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public
License along with SOGo; see the file COPYING. If not, write to the
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
/* some generic JavaScript code for SOGo */
var logConsole;
var logWindow = null;
var queryParameters;
var menus = new Array();
var search = {};
var sorting = {};
var lastClickedRow = -1;
// logArea = null;
var allDocumentElements = null;
// Alarms
var nextAlarm = null;
var Alarms = new Array();
// Ajax requests counts
var activeAjaxRequests = 0;
var removeFolderRequestCount = 0;
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 URLForFolderID(folderID) {
var folderInfos = folderID.split(":");
var url;
if (folderInfos.length > 1) {
url = UserFolderURL + "../" + encodeURI(folderInfos[0]);
if (!(folderInfos[0].endsWith('/')
|| folderInfos[1].startsWith('/')))
url += '/';
url += folderInfos[1];
}
else {
var folderInfo = folderInfos[0];
if (ApplicationBaseURL.endsWith('/')
&& folderInfo.startsWith('/'))
folderInfo = folderInfo.substr(1);
url = ApplicationBaseURL + encodeURI(folderInfo);
}
if (url[url.length-1] == '/')
url = url.substr(0, url.length-1);
return url;
}
function extractEmailAddress(mailTo) {
var email = "";
var emailre
= /(([a-zA-Z0-9\._-]+)*[a-zA-Z0-9_-]+@([a-zA-Z0-9\._-]+)*[a-zA-Z0-9_-]+)/;
if (emailre.test(mailTo)) {
emailre.exec(mailTo);
email = RegExp.$1;
}
return email;
}
function extractEmailName(mailTo) {
var emailName = "";
var tmpMailTo = mailTo.replace("<", "<");
tmpMailTo = tmpMailTo.replace(">", ">");
var emailNamere = /([ ]+)?(.+)\ ;
if (emailNamere.test(tmpMailTo)) {
emailNamere.exec(tmpMailTo);
emailName = RegExp.$2;
}
return emailName;
}
function extractSubject(mailTo) {
var subject = "";
var subjectre = /\?subject=([^&]+)/;
if (subjectre.test(mailTo)) {
subjectre.exec(mailTo);
subject = RegExp.$1;
}
return subject;
}
function sanitizeMailTo(dirtyMailTo) {
var emailName = extractEmailName(dirtyMailTo);
var email = extractEmailAddress(dirtyMailTo);
var mailto = "";
if (emailName && emailName.length > 0)
mailto = emailName + ' <' + email + '>';
else
mailto = email;
return mailto;
}
function sanitizeWindowName(dirtyWindowName) {
// IE is picky about the characters used for the window name.
return dirtyWindowName.replace(/[\s\.\/\-\@]/g, "_");
}
function openUserFolderSelector(callback, type) {
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 (!wId)
wId = "_blank";
else
wId = sanitizeWindowName(wId);
var w = window.open(url, wId,
"width=450,height=530,resizable=0,location=0");
w.focus();
return w;
}
function openMailComposeWindow(url, wId) {
var parentWindow = this;
if (!wId)
wId = "_blank";
else
wId = sanitizeWindowName(wId);
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 addresses = senderMailTo.split(",");
var sanitizedAddresses = new Array();
var subject = extractSubject(senderMailTo);
for (var i = 0; i < addresses.length; i++) {
var sanitizedAddress = sanitizeMailTo(addresses[i]);
if (sanitizedAddress.length > 0)
sanitizedAddresses.push(sanitizedAddress);
}
var mailto = sanitizedAddresses.join(",");
if (mailto.length > 0)
openMailComposeWindow(ApplicationBaseURL
+ "../Mail/compose?mailto=" + encodeURI(mailto)
+ ((subject.length > 0)?"?subject=" + encodeURI(subject):""));
return false; /* stop following the link */
}
function deleteDraft(url) {
/* this is called by UIxMailEditor with window.opener */
new Ajax.Request(url, {
asynchronous: false,
method: 'post',
onFailure: function(transport) {
log("draftDeleteCallback: problem during ajax request: " + transport.status);
}
});
}
function refreshFolderByType(type) {
/* this is called by UIxMailEditor with window.opener */
if (Mailer && Mailer.currentMailboxType == type)
refreshCurrentFolder();
}
function createHTTPClient() {
return new XMLHttpRequest();
}
function onAjaxRequestStateChange(http) {
try {
if (http.readyState == 4
&& activeAjaxRequests > 0) {
if (!http.aborted)
http.callback(http);
activeAjaxRequests--;
checkAjaxRequestsState();
http.onreadystatechange = Prototype.emptyFunction;
http.callback = Prototype.emptyFunction;
http.callbackData = null;
}
}
catch(e) {
activeAjaxRequests--;
checkAjaxRequestsState();
http.onreadystatechange = Prototype.emptyFunction;
http.callback = Prototype.emptyFunction;
http.callbackData = null;
log("AJAX Request, Caught Exception: " + e.name);
log(e.message);
if (e.fileName) {
if (e.lineNumber)
log("at " + e.fileName + ": " + e.lineNumber);
else
log("in " + e.fileName);
}
log(backtrace());
log("request url was '" + http.url + "'");
}
}
/* taken from Lightning */
function getContrastingTextColor(bgColor) {
var calcColor = bgColor.substring(1);
var red = parseInt(calcColor.substring(0, 2), 16);
var green = parseInt(calcColor.substring(2, 4), 16);
var blue = parseInt(calcColor.substring(4, 6), 16);
// Calculate the brightness (Y) value using the YUV color system.
var brightness = (0.299 * red) + (0.587 * green) + (0.114 * blue);
// Consider all colors with less than 56% brightness as dark colors and
// use white as the foreground color, otherwise use black.
return ((brightness < 144) ? "white" : "black");
}
function triggerAjaxRequest(url, callback, userdata, content, headers) {
var http = createHTTPClient();
if (http) {
activeAjaxRequests++;
document.animTimer = setTimeout("checkAjaxRequestsState();", 250);
http.open("POST", url, true);
http.url = url;
http.callback = callback;
http.callbackData = userdata;
http.onreadystatechange = function() { onAjaxRequestStateChange(http);};
// = function() {
// // log ("state changed (" + http.readyState + "): " + url);
// };
var hasContentLength = false;
if (headers) {
for (var i in headers) {
if (i.toLowerCase() == "content-length")
hasContentLength = true;
http.setRequestHeader(i, headers[i]);
}
} /*
if (!hasContentLength) {
var cLength = "0";
if (content)
cLength = "" + content.length;
http.setRequestHeader("Content-Length", "" + cLength);
} */
http.send(content ? content : "");
}
else {
log("triggerAjaxRequest: error creating HTTP Client!");
}
return http;
}
function startAnimation(parent, nextNode) {
var anim = $("progressIndicator");
if (!anim) {
anim = createElement("img", "progressIndicator", null,
{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 progressImage = $("progressIndicator");
if (activeAjaxRequests > 0
&& !progressImage) {
var toolbar = $("toolbar");
if (toolbar)
startAnimation(toolbar);
}
else if (!activeAjaxRequests
&& progressImage)
progressImage.parentNode.removeChild(progressImage);
}
function isMac() {
return (navigator.platform.indexOf('Mac') > -1);
}
function isWindows() {
return (navigator.platform.indexOf('Win') > -1);
}
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.") || (navigator.userAgent.toLowerCase().indexOf('konqueror') != -1);
}
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) {
if (event.preventDefault)
event.preventDefault(); // W3C DOM
else
event.returnValue = false; // IE
}
}
function resetSelection(win) {
var t = "";
if (win && win.getSelection) {
t = win.getSelection().toString();
win.getSelection().removeAllRanges();
}
return t;
}
function refreshOpener() {
if (window.opener && !window.opener.closed) {
window.opener.location.reload();
}
}
/* selection mechanism */
function eventIsLeftClick(event) {
var isLeftClick = true;
if (isMac() && isSafari()) {
if (event.ctrlKey == 1)
isLeftClick = false; // Control-click is equivalent to right-click under Mac OS X
else if (event.metaKey == 1) // Command-click
isLeftClick = true;
else
isLeftClick = Event.isLeftClick(event);
}
else {
isLeftClick = event.isLeftClick();
}
return isLeftClick;
}
function deselectAll(parent) {
for (var i = 0; i < parent.childNodes.length; i++) {
var node = parent.childNodes.item(i);
if (node.nodeType == 1)
$(node).deselect();
}
}
function isNodeSelected(node) {
return $(node).hasClassName('_selected');
}
function acceptMultiSelect(node) {
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 response;
}
function onRowClick(event) {
var node = Event.element(event);
var rowIndex = null;
if (node.tagName != 'TD' && node.tagName != 'LI')
node = this;
if (node.tagName == 'TD') {
node = node.parentNode; // select TR
}
if (node.tagName == '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;
if (list) {
var items = list.childNodesWithTag("li");
for (var i = 0; i < items.length; i++) {
if (items[i] == node) {
rowIndex = i;
break;
}
}
}
else
// No parent; stop here
return true;
}
var initialSelection = $(node.parentNode).getSelectedNodes();
if (initialSelection.length > 0
&& initialSelection.indexOf(node) >= 0
&& !eventIsLeftClick(event))
// Ignore non primary-click (ie right-click) inside current selection
return true;
if ((event.shiftKey == 1 || (isMac() && event.metaKey == 1) || (!isMac() && event.ctrlKey == 1))
&& (lastClickedRow >= 0)
&& (acceptMultiSelect(node.parentNode)
|| acceptMultiSelect(node.parentNode.parentNode))) {
if (event.shiftKey) {
$(node.parentNode).selectRange(lastClickedRow, rowIndex);
} else if (isNodeSelected(node)) {
$(node).deselect();
rowIndex = null;
} else {
$(node).selectElement();
}
// At this point, should empty content of 3-pane view
} else {
// Single line selection
$(node.parentNode).deselectAll();
$(node).selectElement();
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");
}
}
if (rowIndex != null)
lastClickedRow = rowIndex;
return true;
}
/* popup menus */
function popupMenu(event, menuId, target) {
document.menuTarget = target;
if (document.currentPopupMenu)
hideMenu(document.currentPopupMenu);
var popup = $(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.pointerY(event) + deltaY;
var menuLeft = Event.pointerX(event) + deltaX;
var heightDiff = ((window.height() + deltaY)
- (menuTop + popup.offsetHeight + 1));
if (heightDiff < 0)
menuTop += heightDiff;
var leftDiff = ((window.width() + deltaX)
- (menuLeft + popup.offsetWidth));
if (leftDiff < 0)
menuLeft -= (popup.offsetWidth + 1);
var isVisible = true;
if (popup.prepareVisibility)
if (!popup.prepareVisibility())
isVisible = false;
Event.stop(event);
if (isVisible) {
popup.setStyle({ top: menuTop + "px",
left: menuLeft + "px",
visibility: "visible" });
document.currentPopupMenu = popup;
$(document.body).observe("click", onBodyClickMenuHandler);
}
}
function getParentMenu(node) {
var currentNode, menuNode;
menuNode = null;
currentNode = node;
var menure = new RegExp("(^|\s+)menu(\s+|$)", "i");
while (menuNode == null
&& currentNode)
if (menure.test(currentNode.className))
menuNode = currentNode;
else
currentNode = currentNode.parentNode;
return menuNode;
}
function onBodyClickMenuHandler(event) {
hideMenu(document.currentPopupMenu);
document.body.stopObserving("click", onBodyClickMenuHandler);
document.body.stopObserving("mouseup", onBodyClickMenuHandler);
document.currentPopupMenu = null;
if (event)
preventDefault(event);
}
function onMenuClickHandler(event) {
if (!this.hasClassName("disabled"))
this.menuCallback.apply(this, [event]);
}
function hideMenu(menuNode) {
var onHide;
if (!menuNode)
return;
if (menuNode.submenu) {
hideMenu(menuNode.submenu);
menuNode.submenu = null;
}
menuNode.setStyle({ visibility: "hidden" });
if (menuNode.parentMenuItem) {
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.submenuItem = null;
menuNode.parentMenu.submenu = null;
menuNode.parentMenu = null;
}
$(menuNode).fire("mousedown");
}
function onMenuEntryClick(event) {
var node = event.target;
id = getParentMenu(node).menuTarget;
return false;
}
/* query string */
function generateQueryString(queryDict) {
var s = "";
for (var key in queryDict) {
var value = queryDict[key];
if (typeof(value) == "string"
|| typeof(value) == "number") {
if (s.length == 0)
s = "?";
else
s = s + "&";
s = s + key + "=" + escape(value);
}
}
return s;
}
function parseQueryParameters(url) {
var parameters = new Array();
var params = url.split("?")[1];
if (params) {
var pairs = params.split("&");
for (var i = 0; i < pairs.length; i++) {
var pair = pairs[i].split("=");
parameters[pair[0]] = pair[1];
}
}
return parameters;
}
function initLogConsole() {
var logConsole = $("logConsole");
if (logConsole) {
logConsole.highlighted = false;
logConsole.observe("dblclick", onLogDblClick, false);
logConsole.update();
Event.observe(window, "keydown", onBodyKeyDown);
}
}
function onBodyKeyDown(event) {
if (event.keyCode == Event.KEY_ESC) {
toggleLogConsole();
preventDefault(event);
}
}
function toggleLogConsole(event) {
var logConsole = $("logConsole");
var display = '' + logConsole.style.display;
if (display.length == 0) {
logConsole.setStyle({ display: 'block' });
} else {
logConsole.setStyle({ display: '' });
}
if (event)
preventDefault(event);
}
function log(message) {
if (!logWindow) {
logWindow = window;
while (logWindow.opener)
logWindow = logWindow.opener;
}
var logConsole = logWindow.document.getElementById("logConsole");
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 = '