2 Copyright (C) 2005 SKYRIX Software AG
4 This file is part of OpenGroupware.org.
6 OGo is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 OGo is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with OGo; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21 /* some generic JavaScript code for SOGo */
30 var activeAjaxRequests = 0;
31 var menus = new Array();
33 var weekStartIsMonday = true;
36 var allDocumentElements = null;
38 /* a W3C compliant document.all */
39 function getAllScopeElements(scope) {
40 var elements = new Array();
42 for (var i = 0; i < scope.childNodes.length; i++)
43 if (typeof(scope.childNodes[i]) == "object"
44 && scope.childNodes[i].tagName
45 && scope.childNodes[i].tagName != '')
47 elements.push(scope.childNodes[i]);
48 var childElements = getAllElements(scope.childNodes[i]);
49 if (childElements.length > 0)
50 elements.push(childElements);
56 function getAllElements(scope) {
63 && allDocumentElements != null)
64 elements = allDocumentElements;
67 elements = getAllScopeElements(scope);
68 if (scope == document)
69 allDocumentElements = elements;
76 http://www.robertnyman.com/2005/11/07/the-ultimate-getelementsbyclassname/ */
77 function getElementsByClassName2(_tag, _class, _scope) {
78 var regexp, classes, elements, element, returnElements;
80 _scope = _scope || document;
82 elements = (!_tag || _tag == "*"
83 ? getAllElements(null)
84 : _scope.getElementsByTagName(_tag));
87 classes = _class.split(/\s+/);
88 regexp = new RegExp("(^|\s+)("+ classes.join("|") +")(\s+|$)","i");
91 for(var i = 0; element = elements[i]; i++) {
92 if (regexp.test(element.className)) {
93 returnElements.push(element);
96 return returnElements;
102 function ml_stripActionInURL(url) {
103 if (url[url.length - 1] != '/') {
106 i = url.lastIndexOf("/");
107 if (i != -1) url = url.substring(0, i);
109 if (url[url.length - 1] != '/') // ensure trailing slash
114 function URLForFolderID(folderID) {
115 var folderInfos = folderID.split(":");
117 if (folderInfos.length > 1) {
118 url = UserFolderURL + "../" + folderInfos[0];
119 if (folderInfos[1][0] != '/')
121 url += folderInfos[1];
124 url = ApplicationBaseURL + folderInfos[0];
126 if (url[url.length-1] == '/')
127 url = url.substr(0, url.length-1);
132 function extractEmailAddress(mailTo) {
136 = /([a-zA-Z0-9]+[a-zA-Z0-9\._-]+[a-zA-Z0-9]+@[a-zA-Z0-9]+[a-zA-Z0-9\._-]+[a-zA-Z0-9]+)/g;
137 if (emailre.test(mailTo)) {
138 emailre.exec(mailTo);
145 function extractEmailName(mailTo) {
148 var tmpMailTo = mailTo.replace("<", "<");
149 tmpMailTo = tmpMailTo.replace(">", ">");
151 var emailNamere = /([ ]+)?(.+)\ </;
152 if (emailNamere.test(tmpMailTo)) {
153 emailNamere.exec(tmpMailTo);
154 emailName = RegExp.$2;
160 function sanitizeMailTo(dirtyMailTo) {
161 var emailName = extractEmailName(dirtyMailTo);
162 var email = "" + extractEmailAddress(dirtyMailTo);
165 if (emailName && emailName.length > 0)
166 mailto = emailName + ' <' + email + '>';
173 function openUserFolderSelector(callback, type) {
174 var urlstr = ApplicationBaseURL;
175 if (urlstr[urlstr.length-1] != '/')
177 urlstr += ("../../" + UserLogin + "/Contacts/userFolders");
178 var w = window.open(urlstr, "User Selector",
179 "width=322,height=250,resizable=1,scrollbars=0");
181 w.userFolderCallback = callback;
182 w.userFolderType = type;
186 function openMailComposeWindow(url) {
187 var w = window.open(url, null,
188 "width=680,height=520,resizable=1,scrollbars=1,toolbar=0,"
189 + "location=0,directories=0,status=0,menubar=0"
196 function openMailTo(senderMailTo) {
197 var mailto = sanitizeMailTo(senderMailTo);
198 if (mailto.length > 0)
199 openMailComposeWindow(ApplicationBaseURL
200 + "/../Mail/compose?mailto=" + mailto);
202 return false; /* stop following the link */
205 function createHTTPClient() {
206 // http://developer.apple.com/internet/webcontent/xmlhttpreq.html
207 if (typeof XMLHttpRequest != "undefined")
208 return new XMLHttpRequest();
210 try { return new ActiveXObject("Msxml2.XMLHTTP"); }
212 try { return new ActiveXObject("Microsoft.XMLHTTP"); }
218 function appendDifferentiator(url) {
219 var url_nocache = url;
220 var position = url.indexOf('?', 0);
225 url_nocache += 'differentiator=' + Math.floor(Math.random()*50000);
230 function triggerAjaxRequest(url, callback, userdata) {
231 var http = createHTTPClient();
233 activeAjaxRequests += 1;
234 document.animTimer = setTimeout("checkAjaxRequestsState();", 200);
235 //url = appendDifferentiator(url);
238 http.open("POST", url, true);
240 http.onreadystatechange
242 //log ("state changed (" + http.readyState + "): " + url);
244 if (http.readyState == 4
245 && activeAjaxRequests > 0) {
247 http.callbackData = userdata;
250 activeAjaxRequests -= 1;
251 checkAjaxRequestsState();
255 activeAjaxRequests -= 1;
256 checkAjaxRequestsState();
257 log("AJAX Request, Caught Exception: " + e.name);
265 log("triggerAjaxRequest: error creating HTTP Client!");
271 function checkAjaxRequestsState() {
272 var toolbar = document.getElementById("toolbar");
274 if (activeAjaxRequests > 0
275 && !document.busyAnim) {
276 var anim = document.createElement("img");
278 document.busyAnim = anim;
279 anim.id = "progressIndicator";
280 anim.src = ResourcesURL + "/busy.gif";
281 anim.setStyle({ visibility: "hidden" });
282 toolbar.appendChild(anim);
283 anim.setStyle({ visibility: "visible" });
285 else if (activeAjaxRequests == 0
287 && document.busyAnim.parentNode) {
288 document.busyAnim.parentNode.removeChild(document.busyAnim);
289 document.busyAnim = null;
294 function isSafari() {
295 //var agt = navigator.userAgent.toLowerCase();
296 //var is_safari = ((agt.indexOf('safari')!=-1)&&(agt.indexOf('mac')!=-1))?true:false;
298 return (navigator.vendor == "Apple Computer, Inc.");
301 function isHttpStatus204(status) {
302 return (status == 204 || // Firefox
303 (isSafari() && typeof(status) == 'undefined') || // Safari
304 status == 1223); // IE
307 function getTarget(event) {
308 event = event || window.event;
310 return event.target; // W3C DOM
312 return event.srcElement; // IE
315 function preventDefault(event) {
316 if (event.preventDefault)
317 event.preventDefault(); // W3C DOM
319 event.returnValue = false; // IE
322 function resetSelection(win) {
324 if (win && win.getSelection) {
325 t = win.getSelection().toString();
326 win.getSelection().removeAllRanges();
331 function refreshOpener() {
332 if (window.opener && !window.opener.closed) {
333 window.opener.location.reload();
339 function parseQueryString() {
340 var queryArray, queryDict
341 var key, value, s, idx;
342 queryDict.length = 0;
344 queryDict = new Array();
345 queryArray = location.search.substr(1).split('&');
346 for (var i in queryArray) {
347 if (!queryArray[i]) continue ;
349 idx = s.indexOf("=");
355 key = s.substr(0, idx);
356 value = unescape(s.substr(idx + 1));
359 if (typeof queryDict[key] == 'undefined')
362 queryDict[key] = value;
367 function generateQueryString(queryDict) {
369 for (var key in queryDict) {
374 s = s + key + "=" + escape(queryDict[key]);
379 function getQueryParaArray(s) {
380 if (s.charAt(0) == "?") s = s.substr(1, s.length - 1);
384 function getQueryParaValue(s, name) {
387 t = getQueryParaArray(s);
388 for (var i = 0; i < t.length; i++) {
391 if (s.indexOf(name) != 0)
394 s = s.substr(name.length, s.length - name.length);
395 return decodeURIComponent(s);
400 /* opener callback */
402 function triggerOpenerCallback() {
403 /* this code has some issue if the folder has no proper trailing slash! */
404 if (window.opener && !window.opener.closed) {
407 t = getQueryParaValue(window.location.search, "openerurl=");
408 cburl = window.opener.location.href;
409 if (cburl[cburl.length - 1] != "/") {
410 cburl = cburl.substr(0, cburl.lastIndexOf("/") + 1);
413 window.opener.location.href = cburl;
417 /* selection mechanism */
419 function deselectAll(parent) {
420 for (var i = 0; i < parent.childNodes.length; i++) {
421 var node = parent.childNodes.item(i);
422 if (node.nodeType == 1)
427 function isNodeSelected(node) {
428 return $(node).hasClassName('_selected');
431 function acceptMultiSelect(node) {
432 var response = false;
433 var attribute = node.getAttribute('multiselect');
435 log("node '" + node.getAttribute("id")
436 + "' is still using old-stylemultiselect!");
437 response = (attribute.toLowerCase() == 'yes');
440 response = node.multiselect;
445 function onRowClick(event) {
446 var node = getTarget(event);
448 if (node.tagName == 'TD')
449 node = node.parentNode;
450 var startSelection = $(node.parentNode).getSelectedNodes();
451 if (event.shiftKey == 1
452 && (acceptMultiSelect(node.parentNode)
453 || acceptMultiSelect(node.parentNode.parentNode))) {
454 if (isNodeSelected(node) == true) {
460 $(node.parentNode).deselectAll();
464 if (startSelection != $(node.parentNode).getSelectedNodes()) {
465 var parentNode = node.parentNode;
466 if (parentNode.tagName == 'TBODY')
467 parentNode = parentNode.parentNode;
468 //log("onRowClick: parentNode = " + parentNode.tagName);
469 // parentNode is UL or TABLE
470 if (document.createEvent) {
471 var onSelectionChangeEvent;
473 onSelectionChangeEvent = document.createEvent("UIEvents");
475 onSelectionChangeEvent = document.createEvent("Events");
476 onSelectionChangeEvent.initEvent("mousedown", true, true);
477 parentNode.dispatchEvent(onSelectionChangeEvent);
479 else if (document.createEventObject) {
480 parentNode.fireEvent("onmousedown");
489 // var acceptClick = false;
491 function popupMenu(event, menuId, target) {
492 document.menuTarget = target;
494 if (document.currentPopupMenu)
495 hideMenu(event, document.currentPopupMenu);
497 var popup = $(menuId);
498 var menuTop = event.pageY;
499 var menuLeft = event.pageX;
500 var heightDiff = (window.innerHeight
501 - (menuTop + popup.offsetHeight));
503 menuTop += heightDiff;
505 var leftDiff = (window.innerWidth
506 - (menuLeft + popup.offsetWidth));
508 menuLeft -= popup.offsetWidth;
510 popup.setStyle({ top: menuTop + "px",
511 left: menuLeft + "px",
512 visibility: "visible" });
514 document.currentPopupMenu = popup;
515 Event.observe(document.body, "click", onBodyClickMenuHandler);
517 preventDefault(event);
520 function getParentMenu(node) {
521 var currentNode, menuNode;
525 var menure = new RegExp("(^|\s+)menu(\s+|$)", "i");
527 while (menuNode == null
529 if (menure.test(currentNode.className))
530 menuNode = currentNode;
532 currentNode = currentNode.parentNode;
537 function onBodyClickMenuHandler(event) {
538 document.body.menuTarget = null;
539 hideMenu(event, document.currentPopupMenu);
540 Event.stopObserving(document.body, "click", onBodyClickMenuHandler);
542 preventDefault(event);
545 function hideMenu(event, menuNode) {
548 // log('hiding menu "' + menuNode.getAttribute('id') + '"');
549 if (menuNode.submenu) {
550 hideMenu(event, menuNode.submenu);
551 menuNode.submenu = null;
554 menuNode.setStyle({ visibility: "hidden" });
556 if (menuNode.parentMenuItem) {
557 menuNode.parentMenuItem.setAttribute('class', 'submenu');
558 menuNode.parentMenuItem = null;
559 menuNode.parentMenu.setAttribute('onmousemove', null);
560 menuNode.parentMenu.submenuItem = null;
561 menuNode.parentMenu.submenu = null;
562 menuNode.parentMenu = null;
565 if (document.initEvent) {
566 var onhideEvent = document.createEvent("UIEvents");
567 onhideEvent.initEvent("hideMenu", false, true);
568 menuNode.dispatchEvent(onhideEvent);
570 else if (document.createEventObject) {
571 // TODO: add support for IE
575 function onMenuEntryClick(event) {
576 var node = event.target;
578 id = getParentMenu(node).menuTarget;
579 // log("clicked " + id + "/" + id.tagName);
584 function parseQueryParameters(url) {
585 var parameters = new Array();
587 var params = url.split("?")[1];
589 var pairs = params.split("&");
590 for (var i = 0; i < pairs.length; i++) {
591 var pair = pairs[i].split("=");
592 parameters[pair[0]] = pair[1];
599 function initLogConsole() {
600 var logConsole = $("logConsole");
602 logConsole.highlighted = false;
603 Event.observe(logConsole, "dblclick", onLogDblClick, false);
604 logConsole.innerHTML = "";
605 Event.observe(window, "keydown", onBodyKeyDown);
609 function onBodyKeyDown(event) {
610 if (event.keyCode == 27) {
612 preventDefault(event);
616 function onLogDblClick(event) {
617 var logConsole = $("logConsole");
618 logConsole.innerHTML = "";
621 function toggleLogConsole(event) {
622 var logConsole = $("logConsole");
623 var display = '' + logConsole.style.display;
624 if (display.length == 0) {
625 logConsole.setStyle({ display: 'block' });
627 logConsole.setStyle({ display: '' });
630 preventDefault(event);
633 function log(message) {
636 while (logWindow.opener)
637 logWindow = logWindow.opener;
639 var logConsole = logWindow.document.getElementById("logConsole");
641 logConsole.highlighted = !logConsole.highlighted;
642 var logMessage = message.replace("<", "<", "g");
643 logMessage = logMessage.replace(" ", " ", "g");
644 logMessage = logMessage.replace("\r\n", "<br />\n", "g");
645 logMessage = logMessage.replace("\n", "<br />\n", "g");
646 logMessage += '<br />' + "\n";
647 if (logConsole.highlighted)
648 logMessage = '<div class="highlighted">' + logMessage + '</div>';
649 logConsole.innerHTML += logMessage;
653 function backtrace() {
654 var func = backtrace.caller;
655 var str = "backtrace:\n";
661 str += " " + func.name;
663 str += " (" + this + ")";
666 str += "[anonymous]\n";
676 function dropDownSubmenu(event) {
678 if (this.submenu && this.submenu != "") {
679 log ("submenu: " + this.submenu);
680 var submenuNode = $(this.submenu);
681 var parentNode = getParentMenu(node);
682 if (parentNode.submenu)
683 hideMenu(event, parentNode.submenu);
684 submenuNode.parentMenuItem = node;
685 submenuNode.parentMenu = parentNode;
686 parentNode.submenuItem = node;
687 parentNode.submenu = submenuNode;
689 var menuTop = (node.offsetTop - 2);
691 var heightDiff = (window.innerHeight
692 - (menuTop + submenuNode.offsetHeight));
694 menuTop += heightDiff;
696 var menuLeft = parentNode.offsetWidth - 3;
697 if (window.innerWidth
698 < (menuLeft + submenuNode.offsetWidth
699 + parentNode.cascadeLeftOffset()))
700 menuLeft = - submenuNode.offsetWidth + 3;
702 parentNode.setAttribute('onmousemove', 'checkDropDown(event);');
703 node.setAttribute('class', 'submenu-selected');
704 submenuNode.setStyle({ top: menuTop + "px",
705 left: menuLeft + "px",
706 visibility: "visible" });
710 function checkDropDown(event) {
711 var parentMenu = getParentMenu(event.target);
712 var submenuItem = parentMenu.submenuItem;
714 var menuX = event.clientX - parentMenu.cascadeLeftOffset();
715 var menuY = event.clientY - parentMenu.cascadeTopOffset();
716 var itemX = submenuItem.offsetLeft;
717 var itemY = submenuItem.offsetTop - 75;
720 && menuX < itemX + submenuItem.offsetWidth
722 || menuY > (itemY + submenuItem.offsetHeight))) {
723 hideMenu(event, parentMenu.submenu);
724 parentMenu.submenu = null;
725 parentMenu.submenuItem = null;
726 parentMenu.setAttribute('onmousemove', null);
732 function popupSearchMenu(event) {
733 var node = getTarget(event);
735 var menuId = this.getAttribute("menuid");
736 relX = event.pageX - node.cascadeLeftOffset();
737 relY = event.pageY - node.cascadeTopOffset();
739 if (event.button == 0
741 event.cancelBubble = true;
742 event.returnValue = false;
744 if (document.currentPopupMenu)
745 hideMenu(event, document.currentPopupMenu);
747 var popup = document.getElementById(menuId);
748 popup.setStyle({ top: node.offsetHeight + "px",
749 left: (node.offsetLeft + 3) + "px",
750 visibility: "visible" });
752 document.currentPopupMenu = popup;
753 Event.observe(document.body, "click", onBodyClickMenuHandler);
757 function setSearchCriteria(event) {
758 searchValue = $("searchValue");
759 searchCriteria = $("searchCriteria");
761 searchValue.setAttribute("ghost-phrase", this.innerHTML);
762 // searchCriteria = this.getAttribute('id');
765 function checkSearchValue(event) {
766 var form = event.target;
767 var searchValue = $("searchValue");
768 var ghostPhrase = searchValue.getAttribute('ghost-phrase');
770 if (searchValue.value == ghostPhrase)
771 searchValue.value = "";
774 function onSearchChange() {
775 log ("onSearchChange()...");
778 function onSearchMouseDown(event) {
779 var superNode = this.parentNode.parentNode.parentNode;
780 relX = (event.pageX - superNode.offsetLeft - this.offsetLeft);
781 relY = (event.pageY - superNode.offsetTop - this.offsetTop);
784 event.cancelBubble = true;
785 event.returnValue = false;
789 function onSearchFocus() {
790 ghostPhrase = this.getAttribute("ghost-phrase");
791 if (this.value == ghostPhrase) {
793 this.setAttribute("modified", "");
798 this.setStyle({ color: "#000" });
801 function onSearchBlur(event) {
802 var ghostPhrase = this.getAttribute("ghost-phrase");
803 // log ("search blur: '" + this.value + "'");
805 this.setAttribute("modified", "");
806 this.setStyle({ color: "#aaa" });
807 this.value = ghostPhrase;
808 } else if (this.value == ghostPhrase) {
809 this.setAttribute("modified", "");
810 this.setStyle({ color: "#aaa" });
812 this.setAttribute("modified", "yes");
813 this.setStyle({ color: "#000" });
817 function onSearchKeyDown(event) {
819 clearTimeout(this.timer);
821 this.timer = setTimeout("onSearchFormSubmit()", 1000);
824 function initCriteria() {
825 var searchCriteria = $("searchCriteria");
826 var searchValue = $("searchValue");
829 var searchOptions = $("searchOptions");
832 $A(searchOptions.childNodes).each(function (item) {
833 if (item.tagName == 'LI') {
837 searchCriteria.value = firstOption.getAttribute('id');
838 searchValue.setAttribute('ghost-phrase', firstOption.innerHTML);
839 if (searchValue.value == '') {
840 searchValue.value = firstOption.innerHTML;
841 searchValue.setAttribute("modified", "");
842 searchValue.setStyle({ color: "#aaa" });
847 /* toolbar buttons */
848 function popupToolbarMenu(event, menuId) {
849 var toolbar = $("toolbar");
850 var node = getTarget(event);
851 if (node.tagName != 'A')
852 node = node.getParentWithTagName("a");
853 node = node.childNodesWithTag("span")[0];
855 if (event.button == 0) {
856 event.cancelBubble = true;
857 event.returnValue = false;
859 if (document.currentPopupMenu)
860 hideMenu(event, document.currentPopupMenu);
862 var popup = document.getElementById(menuId);
863 var top = node.offsetTop + node.offsetHeight - 2;
864 popup.setStyle({ top: top + "px",
865 left: node.cascadeLeftOffset() + "px",
866 visibility: "visible" });
868 document.currentPopupMenu = popup;
869 Event.observe(document.body, "click", onBodyClickMenuHandler);
873 /* contact selector */
875 function folderSubscriptionCallback(http) {
876 if (http.readyState == 4) {
877 if (http.status == 204) {
878 if (http.callbackData)
879 http.callbackData["method"](http.callbackData["data"]);
882 window.alert(labels["Unable to subscribe to that folder!"].decodeEntities());
883 document.subscriptionAjaxRequest = null;
886 log ("ajax fuckage");
889 function subscribeToFolder(refreshCallback, refreshCallbackData) {
890 var folderData = refreshCallbackData["folder"].split(":");
891 var username = folderData[0];
892 var folderPath = folderData[1];
893 if (username != UserLogin) {
894 var url = (UserFolderURL + "../" + username
895 + folderPath + "/subscribe");
896 if (document.subscriptionAjaxRequest) {
897 document.subscriptionAjaxRequest.aborted = true;
898 document.subscriptionAjaxRequest.abort();
900 var rfCbData = { method: refreshCallback, data: refreshCallbackData };
901 document.subscriptionAjaxRequest = triggerAjaxRequest(url,
902 folderSubscriptionCallback,
906 window.alert(labels["You cannot subscribe to a folder that you own!"]
910 function folderUnsubscriptionCallback(http) {
911 if (http.readyState == 4) {
912 if (http.status == 204) {
913 if (http.callbackData)
914 http.callbackData["method"](http.callbackData["data"]);
917 window.alert(labels["Unable to unsubscribe from that folder!"].decodeEntities());
918 document.unsubscriptionAjaxRequest = null;
922 function unsubscribeFromFolder(folder, refreshCallback, refreshCallbackData) {
923 if (document.body.hasClassName("popup")) {
924 window.opener.unsubscribeFromFolder(folder, refreshCallback,
925 refreshCallbackData);
928 var folderData = folder.split(":");
929 var username = folderData[0];
930 var folderPath = folderData[1];
931 if (username != UserLogin) {
932 var url = (UserFolderURL + "../" + username
933 + "/" + folderPath + "/unsubscribe");
934 if (document.unsubscriptionAjaxRequest) {
935 document.unsubscriptionAjaxRequest.aborted = true;
936 document.unsubscriptionAjaxRequest.abort();
938 var rfCbData = { method: refreshCallback, data: refreshCallbackData };
939 document.unsubscriptionAjaxRequest
940 = triggerAjaxRequest(url, folderUnsubscriptionCallback,
944 window.alert(labels["You cannot unsubscribe from a folder that you own!"].decodeEntities());
948 function listRowMouseDownHandler(event) {
949 preventDefault(event);
953 function initTabs() {
954 var containers = document.getElementsByClassName("tabsContainer");
955 for (var x = 0; x < containers.length; x++) {
956 var container = containers[x];
958 for (var i = 0; i < container.childNodes.length; i++) {
959 if (container.childNodes[i].tagName == 'UL') {
964 var nodes = container.childNodes[firstTab].childNodes;
967 for (var i = 0; i < nodes.length; i++) {
968 var currentNode = nodes[i];
969 if (currentNode.tagName == 'LI') {
972 Event.observe(currentNode, "mousedown",
973 onTabMouseDown.bindAsEventListener(currentNode));
974 Event.observe(currentNode, "click",
975 onTabClick.bindAsEventListener(currentNode));
976 //$(currentNode.getAttribute("target")).hide();
980 nodes[firstTab].addClassName("first");
981 nodes[firstTab].addClassName("active");
982 container.activeTab = nodes[firstTab];
984 var target = $(nodes[firstTab].getAttribute("target"));
985 target.addClassName("active");
990 function initMenus() {
991 var menus = getMenus();
993 for (var menuID in menus) {
994 var menuDIV = $(menuID);
996 initMenu(menuDIV, menus[menuID]);
1001 function initMenu(menuDIV, callbacks) {
1002 var lis = $(menuDIV.childNodesWithTag("ul")[0]).childNodesWithTag("li");
1003 for (var j = 0; j < lis.length; j++) {
1005 Event.observe(node, "mousedown", listRowMouseDownHandler, false);
1006 var callback = callbacks[j];
1008 if (typeof(callback) == "string") {
1009 if (callback == "-")
1010 node.addClassName("separator");
1012 node.submenu = callback;
1013 node.addClassName("submenu");
1014 Event.observe(node, "mouseover", dropDownSubmenu);
1018 Event.observe(node, "mouseup",
1019 $(callback).bindAsEventListener(node));
1022 node.addClassName("disabled");
1026 function onTabMouseDown(event) {
1027 event.cancelBubble = true;
1028 preventDefault(event);
1031 function openExternalLink(anchor) {
1035 function openAclWindow(url) {
1036 var w = window.open(url, "aclWindow",
1037 "width=420,height=300,resizable=1,scrollbars=1,toolbar=0,"
1038 + "location=0,directories=0,status=0,menubar=0"
1039 + ",copyhistory=0");
1046 function getUsersRightsWindowHeight() {
1047 return usersRightsWindowHeight;
1050 function getUsersRightsWindowWidth() {
1051 return usersRightsWindowWidth;
1054 function getTopWindow() {
1055 var topWindow = null;
1056 var currentWindow = window;
1057 while (!topWindow) {
1058 if (currentWindow.document.body.hasClassName("popup")
1059 && currentWindow.opener)
1060 currentWindow = currentWindow.opener;
1062 topWindow = currentWindow;
1068 function onTabClick(event) {
1069 var node = getTarget(event); // LI element
1071 var target = node.getAttribute("target");
1073 var container = node.parentNode.parentNode;
1074 var oldTarget = container.activeTab.getAttribute("target");
1075 var content = $(target);
1076 var oldContent = $(oldTarget);
1078 oldContent.removeClassName("active");
1079 container.activeTab.removeClassName("active"); // previous LI
1080 container.activeTab = node;
1081 container.activeTab.addClassName("active"); // current LI
1082 content.addClassName("active");
1084 // Prototype alternative
1086 //oldContent.removeClassName("active");
1087 //container.activeTab.removeClassName("active"); // previous LI
1088 //container.activeTab = node;
1089 //container.activeTab.addClassName("active"); // current LI
1091 //container.activeTab.hide();
1092 //oldContent.hide();
1095 //container.activeTab = node;
1096 //container.activeTab.show();
1101 function enableAnchor(anchor) {
1102 var classStr = '' + anchor.getAttribute("class");
1103 var position = classStr.indexOf("_disabled", 0);
1104 if (position > -1) {
1105 var disabledHref = anchor.getAttribute("disabled-href");
1107 anchor.setAttribute("href", disabledHref);
1108 var disabledOnclick = anchor.getAttribute("disabled-onclick");
1109 if (disabledOnclick)
1110 anchor.setAttribute("onclick", disabledOnclick);
1111 anchor.removeClassName("_disabled");
1112 anchor.setAttribute("disabled-href", null);
1113 anchor.setAttribute("disabled-onclick", null);
1114 anchor.disabled = 0;
1119 function disableAnchor(anchor) {
1120 var classStr = '' + anchor.getAttribute("class");
1121 var position = classStr.indexOf("_disabled", 0);
1123 var href = anchor.getAttribute("href");
1125 anchor.setAttribute("disabled-href", href);
1126 var onclick = anchor.getAttribute("onclick");
1128 anchor.setAttribute("disabled-onclick", onclick);
1129 anchor.addClassName("_disabled");
1130 anchor.setAttribute("href", "#");
1131 anchor.setAttribute("onclick", "return false;");
1132 anchor.disabled = 1;
1138 var hD = "0123456789abcdef";
1139 var h = hD.substr(d & 15, 1);
1143 h = hD.substr(d & 15, 1) + h;
1149 function indexColor(number) {
1155 var colorTable = new Array(1, 1, 1);
1157 var currentValue = number;
1159 while (currentValue) {
1160 if (currentValue & 1)
1161 colorTable[index]++;
1169 + d2h((256 / colorTable[2]) - 1)
1170 + d2h((256 / colorTable[1]) - 1)
1171 + d2h((256 / colorTable[0]) - 1));
1177 function onLoadHandler(event) {
1178 queryParameters = parseQueryParameters('' + window.location);
1179 if (!$(document.body).hasClassName("popup")) {
1185 configureDragHandles();
1186 configureSortableTableHeaders();
1187 configureLinkBanner();
1188 var progressImage = $("progressIndicator");
1190 progressImage.parentNode.removeChild(progressImage);
1191 Event.observe(document.body, "contextmenu", onBodyClickContextMenu);
1194 function onBodyClickContextMenu(event) {
1195 preventDefault(event);
1198 function configureSortableTableHeaders() {
1199 var headers = document.getElementsByClassName("sortableTableHeader");
1200 for (var i = 0; i < headers.length; i++) {
1201 var header = headers[i];
1202 var anchor = $(header).childNodesWithTag("a")[0];
1204 Event.observe(anchor, "click",
1205 onHeaderClick.bindAsEventListener(anchor));
1209 function onLinkBannerClick() {
1210 activeAjaxRequests++;
1211 checkAjaxRequestsState();
1214 function configureLinkBanner() {
1215 var linkBanner = $("linkBanner");
1217 var anchors = linkBanner.childNodesWithTag("a");
1218 for (var i = 0; i < 2; i++) {
1219 Event.observe(anchors[i], "mousedown", listRowMouseDownHandler);
1220 Event.observe(anchors[i], "click", onLinkBannerClick);
1222 if (anchors.length > 3)
1223 Event.observe(anchors[3], "click", toggleLogConsole);
1227 addEvent(window, 'load', onLoadHandler);
1230 function configureDragHandles() {
1233 function getMenus() {
1236 function onHeaderClick(event) {
1237 window.alert("generic headerClick");
1240 function parent$(element) {
1241 return this.opener.document.getElementById(element);