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();
35 var weekStartIsMonday = true;
38 var allDocumentElements = null;
40 var userDefaults = null;
41 var userSettings = null;
43 /* a W3C compliant document.all */
44 function getAllScopeElements(scope) {
45 var elements = new Array();
47 for (var i = 0; i < scope.childNodes.length; i++)
48 if (typeof(scope.childNodes[i]) == "object"
49 && scope.childNodes[i].tagName
50 && scope.childNodes[i].tagName != '')
52 elements.push(scope.childNodes[i]);
53 var childElements = getAllElements(scope.childNodes[i]);
54 if (childElements.length > 0)
55 elements.push(childElements);
61 function getAllElements(scope) {
68 && allDocumentElements != null)
69 elements = allDocumentElements;
72 elements = getAllScopeElements(scope);
73 if (scope == document)
74 allDocumentElements = elements;
81 http://www.robertnyman.com/2005/11/07/the-ultimate-getelementsbyclassname/ */
82 function getElementsByClassName2(_tag, _class, _scope) {
83 var regexp, classes, elements, element, returnElements;
85 _scope = _scope || document;
87 elements = (!_tag || _tag == "*"
88 ? getAllElements(null)
89 : _scope.getElementsByTagName(_tag));
92 classes = _class.split(/\s+/);
93 regexp = new RegExp("(^|\s+)("+ classes.join("|") +")(\s+|$)","i");
96 for(var i = 0; element = elements[i]; i++) {
97 if (regexp.test(element.className)) {
98 returnElements.push(element);
101 return returnElements;
107 function createElement(tagName, id, classes, attributes, htmlAttributes,
109 var newElement = $(document.createElement(tagName));
111 newElement.setAttribute("id", id);
113 if (typeof(classes) == "string")
114 newElement.addClassName(classes);
116 for (var i = 0; i < classes.length; i++)
117 newElement.addClassName(classes[i]);
120 for (var i in attributes)
121 newElement[i] = attributes[i];
123 for (var i in htmlAttributes)
124 newElement.setAttribute(i, attributes[i]);
126 parentNode.appendChild(newElement);
128 return $(newElement);
131 function ml_stripActionInURL(url) {
132 if (url[url.length - 1] != '/') {
135 i = url.lastIndexOf("/");
136 if (i != -1) url = url.substring(0, i);
138 if (url[url.length - 1] != '/') // ensure trailing slash
143 function URLForFolderID(folderID) {
144 var folderInfos = folderID.split(":");
146 if (folderInfos.length > 1) {
147 url = UserFolderURL + "../" + folderInfos[0];
148 if (folderInfos[1][0] != '/')
150 url += folderInfos[1];
153 url = ApplicationBaseURL + folderInfos[0];
155 if (url[url.length-1] == '/')
156 url = url.substr(0, url.length-1);
161 function extractEmailAddress(mailTo) {
165 = /([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;
166 if (emailre.test(mailTo)) {
167 emailre.exec(mailTo);
174 function extractEmailName(mailTo) {
177 var tmpMailTo = mailTo.replace("<", "<");
178 tmpMailTo = tmpMailTo.replace(">", ">");
180 var emailNamere = /([ ]+)?(.+)\ </;
181 if (emailNamere.test(tmpMailTo)) {
182 emailNamere.exec(tmpMailTo);
183 emailName = RegExp.$2;
189 function sanitizeMailTo(dirtyMailTo) {
190 var emailName = extractEmailName(dirtyMailTo);
191 var email = "" + extractEmailAddress(dirtyMailTo);
194 if (emailName && emailName.length > 0)
195 mailto = emailName + ' <' + email + '>';
202 function openUserFolderSelector(callback, type) {
203 var urlstr = ApplicationBaseURL;
204 if (urlstr[urlstr.length-1] != '/')
206 urlstr += ("../../" + UserLogin + "/Contacts/userFolders");
207 var w = window.open(urlstr, "User Selector",
208 "width=322,height=250,resizable=1,scrollbars=0");
210 w.userFolderCallback = callback;
211 w.userFolderType = type;
215 function openMailComposeWindow(url) {
216 var w = window.open(url, null,
217 "width=680,height=520,resizable=1,scrollbars=1,toolbar=0,"
218 + "location=0,directories=0,status=0,menubar=0"
225 function openMailTo(senderMailTo) {
226 var mailto = sanitizeMailTo(senderMailTo);
227 if (mailto.length > 0)
228 openMailComposeWindow(ApplicationBaseURL
229 + "/../Mail/compose?mailto=" + mailto);
231 return false; /* stop following the link */
234 function createHTTPClient() {
235 // http://developer.apple.com/internet/webcontent/xmlhttpreq.html
236 if (typeof XMLHttpRequest != "undefined")
237 return new XMLHttpRequest();
239 try { return new ActiveXObject("Msxml2.XMLHTTP"); }
241 try { return new ActiveXObject("Microsoft.XMLHTTP"); }
247 function appendDifferentiator(url) {
248 var url_nocache = url;
249 var position = url.indexOf('?', 0);
254 url_nocache += 'differentiator=' + Math.floor(Math.random()*50000);
259 function triggerAjaxRequest(url, callback, userdata) {
260 var http = createHTTPClient();
262 activeAjaxRequests += 1;
263 document.animTimer = setTimeout("checkAjaxRequestsState();", 200);
264 //url = appendDifferentiator(url);
267 http.open("POST", url, true);
269 http.onreadystatechange
271 //log ("state changed (" + http.readyState + "): " + url);
273 if (http.readyState == 4
274 && activeAjaxRequests > 0) {
276 http.callbackData = userdata;
279 activeAjaxRequests -= 1;
280 checkAjaxRequestsState();
284 activeAjaxRequests -= 1;
285 checkAjaxRequestsState();
286 log("AJAX Request, Caught Exception: " + e.name);
294 log("triggerAjaxRequest: error creating HTTP Client!");
300 function checkAjaxRequestsState() {
301 var toolbar = document.getElementById("toolbar");
303 if (activeAjaxRequests > 0
304 && !document.busyAnim) {
305 var anim = document.createElement("img");
307 document.busyAnim = anim;
308 anim.id = "progressIndicator";
309 anim.src = ResourcesURL + "/busy.gif";
310 anim.setStyle({ visibility: "hidden" });
311 toolbar.appendChild(anim);
312 anim.setStyle({ visibility: "visible" });
314 else if (activeAjaxRequests == 0
316 && document.busyAnim.parentNode) {
317 document.busyAnim.parentNode.removeChild(document.busyAnim);
318 document.busyAnim = null;
323 function isSafari() {
324 //var agt = navigator.userAgent.toLowerCase();
325 //var is_safari = ((agt.indexOf('safari')!=-1)&&(agt.indexOf('mac')!=-1))?true:false;
327 return (navigator.vendor == "Apple Computer, Inc.");
330 function isHttpStatus204(status) {
331 return (status == 204 || // Firefox
332 (isSafari() && typeof(status) == 'undefined') || // Safari
333 status == 1223); // IE
336 function getTarget(event) {
337 event = event || window.event;
339 return event.target; // W3C DOM
341 return event.srcElement; // IE
344 function preventDefault(event) {
345 if (event.preventDefault)
346 event.preventDefault(); // W3C DOM
348 event.returnValue = false; // IE
351 function resetSelection(win) {
353 if (win && win.getSelection) {
354 t = win.getSelection().toString();
355 win.getSelection().removeAllRanges();
360 function refreshOpener() {
361 if (window.opener && !window.opener.closed) {
362 window.opener.location.reload();
368 function parseQueryString() {
369 var queryArray, queryDict
370 var key, value, s, idx;
371 queryDict.length = 0;
373 queryDict = new Array();
374 queryArray = location.search.substr(1).split('&');
375 for (var i in queryArray) {
376 if (!queryArray[i]) continue ;
378 idx = s.indexOf("=");
384 key = s.substr(0, idx);
385 value = unescape(s.substr(idx + 1));
388 if (typeof queryDict[key] == 'undefined')
391 queryDict[key] = value;
396 function generateQueryString(queryDict) {
398 for (var key in queryDict) {
403 s = s + key + "=" + escape(queryDict[key]);
408 function getQueryParaArray(s) {
409 if (s.charAt(0) == "?") s = s.substr(1, s.length - 1);
413 function getQueryParaValue(s, name) {
416 t = getQueryParaArray(s);
417 for (var i = 0; i < t.length; i++) {
420 if (s.indexOf(name) != 0)
423 s = s.substr(name.length, s.length - name.length);
424 return decodeURIComponent(s);
429 /* opener callback */
431 function triggerOpenerCallback() {
432 /* this code has some issue if the folder has no proper trailing slash! */
433 if (window.opener && !window.opener.closed) {
436 t = getQueryParaValue(window.location.search, "openerurl=");
437 cburl = window.opener.location.href;
438 if (cburl[cburl.length - 1] != "/") {
439 cburl = cburl.substr(0, cburl.lastIndexOf("/") + 1);
442 window.opener.location.href = cburl;
446 /* selection mechanism */
448 function deselectAll(parent) {
449 for (var i = 0; i < parent.childNodes.length; i++) {
450 var node = parent.childNodes.item(i);
451 if (node.nodeType == 1)
456 function isNodeSelected(node) {
457 return $(node).hasClassName('_selected');
460 function acceptMultiSelect(node) {
461 var response = false;
462 var attribute = node.getAttribute('multiselect');
464 log("node '" + node.getAttribute("id")
465 + "' is still using old-stylemultiselect!");
466 response = (attribute.toLowerCase() == 'yes');
469 response = node.multiselect;
474 function onRowClick(event) {
475 var node = getTarget(event);
477 if (node.tagName == 'TD')
478 node = node.parentNode;
479 var startSelection = $(node.parentNode).getSelectedNodes();
480 if (event.shiftKey == 1
481 && (acceptMultiSelect(node.parentNode)
482 || acceptMultiSelect(node.parentNode.parentNode))) {
483 if (isNodeSelected(node) == true) {
489 $(node.parentNode).deselectAll();
493 if (startSelection != $(node.parentNode).getSelectedNodes()) {
494 var parentNode = node.parentNode;
495 if (parentNode.tagName == 'TBODY')
496 parentNode = parentNode.parentNode;
497 //log("onRowClick: parentNode = " + parentNode.tagName);
498 // parentNode is UL or TABLE
499 if (document.createEvent) {
500 var onSelectionChangeEvent;
502 onSelectionChangeEvent = document.createEvent("UIEvents");
504 onSelectionChangeEvent = document.createEvent("Events");
505 onSelectionChangeEvent.initEvent("mousedown", true, true);
506 parentNode.dispatchEvent(onSelectionChangeEvent);
508 else if (document.createEventObject) {
509 parentNode.fireEvent("onmousedown");
518 // var acceptClick = false;
520 function popupMenu(event, menuId, target) {
521 document.menuTarget = target;
523 if (document.currentPopupMenu)
524 hideMenu(document.currentPopupMenu);
526 var popup = $(menuId);
527 var menuTop = event.pageY;
528 var menuLeft = event.pageX;
529 var heightDiff = (window.innerHeight
530 - (menuTop + popup.offsetHeight));
532 menuTop += heightDiff;
534 var leftDiff = (window.innerWidth
535 - (menuLeft + popup.offsetWidth));
537 menuLeft -= popup.offsetWidth;
539 popup.setStyle({ top: menuTop + "px",
540 left: menuLeft + "px",
541 visibility: "visible" });
543 document.currentPopupMenu = popup;
544 Event.observe(document.body, "click", onBodyClickMenuHandler);
546 preventDefault(event);
549 function getParentMenu(node) {
550 var currentNode, menuNode;
554 var menure = new RegExp("(^|\s+)menu(\s+|$)", "i");
556 while (menuNode == null
558 if (menure.test(currentNode.className))
559 menuNode = currentNode;
561 currentNode = currentNode.parentNode;
566 function onBodyClickMenuHandler(event) {
567 document.body.menuTarget = null;
568 hideMenu(document.currentPopupMenu);
569 Event.stopObserving(document.body, "click", onBodyClickMenuHandler);
571 preventDefault(event);
574 function hideMenu(menuNode) {
577 if (menuNode.submenu) {
578 hideMenu(menuNode.submenu);
579 menuNode.submenu = null;
582 menuNode.setStyle({ visibility: "hidden" });
584 if (menuNode.parentMenuItem) {
585 menuNode.parentMenuItem.setAttribute('class', 'submenu');
586 menuNode.parentMenuItem = null;
587 menuNode.parentMenu.setAttribute('onmousemove', null);
588 menuNode.parentMenu.submenuItem = null;
589 menuNode.parentMenu.submenu = null;
590 menuNode.parentMenu = null;
593 if (document.initEvent) {
594 var onhideEvent = document.createEvent("UIEvents");
595 onhideEvent.initEvent("hideMenu", false, true);
596 menuNode.dispatchEvent(onhideEvent);
598 else if (document.createEventObject) {
599 // TODO: add support for IE
603 function onMenuEntryClick(event) {
604 var node = event.target;
606 id = getParentMenu(node).menuTarget;
607 // log("clicked " + id + "/" + id.tagName);
612 function parseQueryParameters(url) {
613 var parameters = new Array();
615 var params = url.split("?")[1];
617 var pairs = params.split("&");
618 for (var i = 0; i < pairs.length; i++) {
619 var pair = pairs[i].split("=");
620 parameters[pair[0]] = pair[1];
627 function initLogConsole() {
628 var logConsole = $("logConsole");
630 logConsole.highlighted = false;
631 Event.observe(logConsole, "dblclick", onLogDblClick, false);
632 logConsole.innerHTML = "";
633 Event.observe(window, "keydown", onBodyKeyDown);
637 function onBodyKeyDown(event) {
638 if (event.keyCode == 27) {
640 preventDefault(event);
644 function onLogDblClick(event) {
645 var logConsole = $("logConsole");
646 logConsole.innerHTML = "";
649 function toggleLogConsole(event) {
650 var logConsole = $("logConsole");
651 var display = '' + logConsole.style.display;
652 if (display.length == 0) {
653 logConsole.setStyle({ display: 'block' });
655 logConsole.setStyle({ display: '' });
658 preventDefault(event);
661 function log(message) {
664 while (logWindow.opener)
665 logWindow = logWindow.opener;
667 var logConsole = logWindow.document.getElementById("logConsole");
669 logConsole.highlighted = !logConsole.highlighted;
670 var logMessage = message.replace("<", "<", "g");
671 logMessage = logMessage.replace(" ", " ", "g");
672 logMessage = logMessage.replace("\r\n", "<br />\n", "g");
673 logMessage = logMessage.replace("\n", "<br />\n", "g");
674 logMessage += '<br />' + "\n";
675 if (logConsole.highlighted)
676 logMessage = '<div class="highlighted">' + logMessage + '</div>';
677 logConsole.innerHTML += logMessage;
681 function backtrace() {
682 var func = backtrace.caller;
683 var str = "backtrace:\n";
689 str += " " + func.name;
691 str += " (" + this + ")";
694 str += "[anonymous]\n";
704 function dropDownSubmenu(event) {
706 if (this.submenu && this.submenu != "") {
707 log ("submenu: " + this.submenu);
708 var submenuNode = $(this.submenu);
709 var parentNode = getParentMenu(node);
710 if (parentNode.submenu)
711 hideMenu(parentNode.submenu);
712 submenuNode.parentMenuItem = node;
713 submenuNode.parentMenu = parentNode;
714 parentNode.submenuItem = node;
715 parentNode.submenu = submenuNode;
717 var menuTop = (node.offsetTop - 2);
719 var heightDiff = (window.innerHeight
720 - (menuTop + submenuNode.offsetHeight));
722 menuTop += heightDiff;
724 var menuLeft = parentNode.offsetWidth - 3;
725 if (window.innerWidth
726 < (menuLeft + submenuNode.offsetWidth
727 + parentNode.cascadeLeftOffset()))
728 menuLeft = - submenuNode.offsetWidth + 3;
730 parentNode.setAttribute('onmousemove', 'checkDropDown(event);');
731 node.setAttribute('class', 'submenu-selected');
732 submenuNode.setStyle({ top: menuTop + "px",
733 left: menuLeft + "px",
734 visibility: "visible" });
738 function checkDropDown(event) {
739 var parentMenu = getParentMenu(event.target);
740 var submenuItem = parentMenu.submenuItem;
742 var menuX = event.clientX - parentMenu.cascadeLeftOffset();
743 var menuY = event.clientY - parentMenu.cascadeTopOffset();
744 var itemX = submenuItem.offsetLeft;
745 var itemY = submenuItem.offsetTop - 75;
748 && menuX < itemX + submenuItem.offsetWidth
750 || menuY > (itemY + submenuItem.offsetHeight))) {
751 hideMenu(parentMenu.submenu);
752 parentMenu.submenu = null;
753 parentMenu.submenuItem = null;
754 parentMenu.setAttribute('onmousemove', null);
760 function popupSearchMenu(event) {
761 var menuId = this.getAttribute("menuid");
762 relX = event.pageX - $(this).cascadeLeftOffset();
763 relY = event.pageY - $(this).cascadeTopOffset();
765 if (event.button == 0
767 event.cancelBubble = true;
768 event.returnValue = false;
770 if (document.currentPopupMenu)
771 hideMenu(document.currentPopupMenu);
773 var popup = $(menuId);
774 popup.setStyle({ top: this.offsetHeight + "px",
775 left: (this.offsetLeft + 3) + "px",
776 visibility: "visible" });
778 document.currentPopupMenu = popup;
779 Event.observe(document.body, "click", onBodyClickMenuHandler);
783 function setSearchCriteria(event) {
784 searchValue = $("searchValue");
785 searchCriteria = $("searchCriteria");
787 searchValue.setAttribute("ghost-phrase", this.innerHTML);
788 searchCriteria.value = this.getAttribute('id');
791 function checkSearchValue(event) {
792 var form = event.target;
793 var searchValue = $("searchValue");
794 var ghostPhrase = searchValue.getAttribute('ghost-phrase');
796 if (searchValue.value == ghostPhrase)
797 searchValue.value = "";
800 function onSearchChange() {
801 log ("onSearchChange()...");
804 function configureSearchField() {
805 var searchValue = $("searchValue");
807 Event.observe(searchValue, "mousedown",
808 onSearchMouseDown.bindAsEventListener(searchValue));
809 Event.observe(searchValue, "click",
810 popupSearchMenu.bindAsEventListener(searchValue));
811 Event.observe(searchValue, "blur",
812 onSearchBlur.bindAsEventListener(searchValue));
813 Event.observe(searchValue, "focus",
814 onSearchFocus.bindAsEventListener(searchValue));
815 Event.observe(searchValue, "keydown",
816 onSearchKeyDown.bindAsEventListener(searchValue));
819 function onSearchMouseDown(event) {
820 var superNode = this.parentNode.parentNode.parentNode;
821 relX = (event.pageX - superNode.offsetLeft - this.offsetLeft);
822 relY = (event.pageY - superNode.offsetTop - this.offsetTop);
825 event.cancelBubble = true;
826 event.returnValue = false;
830 function onSearchFocus() {
831 ghostPhrase = this.getAttribute("ghost-phrase");
832 if (this.value == ghostPhrase) {
834 this.setAttribute("modified", "");
839 this.setStyle({ color: "#000" });
842 function onSearchBlur(event) {
843 var ghostPhrase = this.getAttribute("ghost-phrase");
844 // log ("search blur: '" + this.value + "'");
846 this.setAttribute("modified", "");
847 this.setStyle({ color: "#aaa" });
848 this.value = ghostPhrase;
849 } else if (this.value == ghostPhrase) {
850 this.setAttribute("modified", "");
851 this.setStyle({ color: "#aaa" });
853 this.setAttribute("modified", "yes");
854 this.setStyle({ color: "#000" });
858 function onSearchKeyDown(event) {
860 clearTimeout(this.timer);
862 this.timer = setTimeout("onSearchFormSubmit()", 1000);
865 function onSearchFormSubmit(event) {
866 var searchValue = $("searchValue");
867 var searchCriteria = $("searchCriteria");
869 search["criteria"] = searchCriteria.value;
870 search["value"] = searchValue.value;
872 refreshCurrentFolder();
875 function initCriteria() {
876 var searchCriteria = $("searchCriteria");
877 var searchValue = $("searchValue");
879 var searchOptions = $("searchOptions").childNodesWithTag("li");
880 if (searchOptions.length > 0) {
881 var firstChild = searchOptions[0];
882 searchCriteria.value = $(firstChild).getAttribute('id');
883 searchValue.setAttribute('ghost-phrase', firstChild.innerHTML);
884 if (searchValue.value == '') {
885 searchValue.value = firstChild.innerHTML;
886 searchValue.setAttribute("modified", "");
887 searchValue.setStyle({ color: "#aaa" });
892 /* toolbar buttons */
893 function popupToolbarMenu(node, menuId) {
894 if (document.currentPopupMenu)
895 hideMenu(document.currentPopupMenu);
897 var popup = $(menuId);
898 var top = node.top + node.offsetHeight - 2;
899 popup.setStyle({ top: top + "px",
900 left: node.cascadeLeftOffset() + "px",
901 visibility: "visible" });
903 document.currentPopupMenu = popup;
904 Event.observe(document.body, "click", onBodyClickMenuHandler);
907 /* contact selector */
909 function folderSubscriptionCallback(http) {
910 if (http.readyState == 4) {
911 if (http.status == 204) {
912 if (http.callbackData)
913 http.callbackData["method"](http.callbackData["data"]);
916 window.alert(labels["Unable to subscribe to that folder!"].decodeEntities());
917 document.subscriptionAjaxRequest = null;
920 log ("ajax fuckage");
923 function subscribeToFolder(refreshCallback, refreshCallbackData) {
924 var folderData = refreshCallbackData["folder"].split(":");
925 var username = folderData[0];
926 var folderPath = folderData[1];
927 if (username != UserLogin) {
928 var url = (UserFolderURL + "../" + username
929 + folderPath + "/subscribe");
930 if (document.subscriptionAjaxRequest) {
931 document.subscriptionAjaxRequest.aborted = true;
932 document.subscriptionAjaxRequest.abort();
934 var rfCbData = { method: refreshCallback, data: refreshCallbackData };
935 document.subscriptionAjaxRequest = triggerAjaxRequest(url,
936 folderSubscriptionCallback,
940 window.alert(labels["You cannot subscribe to a folder that you own!"]
944 function folderUnsubscriptionCallback(http) {
945 if (http.readyState == 4) {
946 if (http.status == 204) {
947 if (http.callbackData)
948 http.callbackData["method"](http.callbackData["data"]);
951 window.alert(labels["Unable to unsubscribe from that folder!"].decodeEntities());
952 document.unsubscriptionAjaxRequest = null;
956 function unsubscribeFromFolder(folder, refreshCallback, refreshCallbackData) {
957 if (document.body.hasClassName("popup")) {
958 window.opener.unsubscribeFromFolder(folder, refreshCallback,
959 refreshCallbackData);
962 var folderData = folder.split(":");
963 var username = folderData[0];
964 var folderPath = folderData[1];
965 if (username != UserLogin) {
966 var url = (UserFolderURL + "../" + username
967 + "/" + folderPath + "/unsubscribe");
968 if (document.unsubscriptionAjaxRequest) {
969 document.unsubscriptionAjaxRequest.aborted = true;
970 document.unsubscriptionAjaxRequest.abort();
972 var rfCbData = { method: refreshCallback, data: refreshCallbackData };
973 document.unsubscriptionAjaxRequest
974 = triggerAjaxRequest(url, folderUnsubscriptionCallback,
978 window.alert(labels["You cannot unsubscribe from a folder that you own!"].decodeEntities());
982 function listRowMouseDownHandler(event) {
983 preventDefault(event);
987 function initTabs() {
988 var containers = document.getElementsByClassName("tabsContainer");
989 for (var x = 0; x < containers.length; x++) {
990 var container = containers[x];
992 for (var i = 0; i < container.childNodes.length; i++) {
993 if (container.childNodes[i].tagName == 'UL') {
998 var nodes = container.childNodes[firstTab].childNodes;
1001 for (var i = 0; i < nodes.length; i++) {
1002 var currentNode = nodes[i];
1003 if (currentNode.tagName == 'LI') {
1006 Event.observe(currentNode, "mousedown",
1007 onTabMouseDown.bindAsEventListener(currentNode));
1008 Event.observe(currentNode, "click",
1009 onTabClick.bindAsEventListener(currentNode));
1010 //$(currentNode.getAttribute("target")).hide();
1014 nodes[firstTab].addClassName("first");
1015 nodes[firstTab].addClassName("active");
1016 container.activeTab = nodes[firstTab];
1018 var target = $(nodes[firstTab].getAttribute("target"));
1019 target.addClassName("active");
1024 function initMenus() {
1025 var menus = getMenus();
1027 for (var menuID in menus) {
1028 var menuDIV = $(menuID);
1030 initMenu(menuDIV, menus[menuID]);
1035 function initMenu(menuDIV, callbacks) {
1036 var lis = $(menuDIV.childNodesWithTag("ul")[0]).childNodesWithTag("li");
1037 for (var j = 0; j < lis.length; j++) {
1039 Event.observe(node, "mousedown", listRowMouseDownHandler, false);
1040 var callback = callbacks[j];
1042 if (typeof(callback) == "string") {
1043 if (callback == "-")
1044 node.addClassName("separator");
1046 node.submenu = callback;
1047 node.addClassName("submenu");
1048 Event.observe(node, "mouseover", dropDownSubmenu);
1052 Event.observe(node, "mouseup",
1053 $(callback).bindAsEventListener(node));
1056 node.addClassName("disabled");
1060 function onTabMouseDown(event) {
1061 event.cancelBubble = true;
1062 preventDefault(event);
1065 function openExternalLink(anchor) {
1069 function openAclWindow(url) {
1070 var w = window.open(url, "aclWindow",
1071 "width=420,height=300,resizable=1,scrollbars=1,toolbar=0,"
1072 + "location=0,directories=0,status=0,menubar=0"
1073 + ",copyhistory=0");
1080 function getUsersRightsWindowHeight() {
1081 return usersRightsWindowHeight;
1084 function getUsersRightsWindowWidth() {
1085 return usersRightsWindowWidth;
1088 function getTopWindow() {
1089 var topWindow = null;
1090 var currentWindow = window;
1091 while (!topWindow) {
1092 if (currentWindow.document.body.hasClassName("popup")
1093 && currentWindow.opener)
1094 currentWindow = currentWindow.opener;
1096 topWindow = currentWindow;
1102 function onTabClick(event) {
1103 var node = getTarget(event); // LI element
1105 var target = node.getAttribute("target");
1107 var container = node.parentNode.parentNode;
1108 var oldTarget = container.activeTab.getAttribute("target");
1109 var content = $(target);
1110 var oldContent = $(oldTarget);
1112 oldContent.removeClassName("active");
1113 container.activeTab.removeClassName("active"); // previous LI
1114 container.activeTab = node;
1115 container.activeTab.addClassName("active"); // current LI
1116 content.addClassName("active");
1118 // Prototype alternative
1120 //oldContent.removeClassName("active");
1121 //container.activeTab.removeClassName("active"); // previous LI
1122 //container.activeTab = node;
1123 //container.activeTab.addClassName("active"); // current LI
1125 //container.activeTab.hide();
1126 //oldContent.hide();
1129 //container.activeTab = node;
1130 //container.activeTab.show();
1135 function enableAnchor(anchor) {
1136 var classStr = '' + anchor.getAttribute("class");
1137 var position = classStr.indexOf("_disabled", 0);
1138 if (position > -1) {
1139 var disabledHref = anchor.getAttribute("disabled-href");
1141 anchor.setAttribute("href", disabledHref);
1142 var disabledOnclick = anchor.getAttribute("disabled-onclick");
1143 if (disabledOnclick)
1144 anchor.setAttribute("onclick", disabledOnclick);
1145 anchor.removeClassName("_disabled");
1146 anchor.setAttribute("disabled-href", null);
1147 anchor.setAttribute("disabled-onclick", null);
1148 anchor.disabled = 0;
1153 function disableAnchor(anchor) {
1154 var classStr = '' + anchor.getAttribute("class");
1155 var position = classStr.indexOf("_disabled", 0);
1157 var href = anchor.getAttribute("href");
1159 anchor.setAttribute("disabled-href", href);
1160 var onclick = anchor.getAttribute("onclick");
1162 anchor.setAttribute("disabled-onclick", onclick);
1163 anchor.addClassName("_disabled");
1164 anchor.setAttribute("href", "#");
1165 anchor.setAttribute("onclick", "return false;");
1166 anchor.disabled = 1;
1172 var hD = "0123456789abcdef";
1173 var h = hD.substr(d & 15, 1);
1177 h = hD.substr(d & 15, 1) + h;
1183 function indexColor(number) {
1189 var colorTable = new Array(1, 1, 1);
1191 var currentValue = number;
1193 while (currentValue) {
1194 if (currentValue & 1)
1195 colorTable[index]++;
1203 + d2h((256 / colorTable[2]) - 1)
1204 + d2h((256 / colorTable[1]) - 1)
1205 + d2h((256 / colorTable[0]) - 1));
1211 function loadPreferences() {
1212 var url = UserFolderURL + "jsonDefaults";
1213 var http = createHTTPClient();
1214 http.open("GET", url, false);
1216 if (http.status == 200)
1217 userDefaults = http.responseText.evalJSON(true);
1219 url = UserFolderURL + "jsonSettings";
1220 http.open("GET", url, false);
1222 if (http.status == 200)
1223 userSettings = http.responseText.evalJSON(true);
1226 function onLoadHandler(event) {
1228 queryParameters = parseQueryParameters('' + window.location);
1229 if (!$(document.body).hasClassName("popup")) {
1232 configureSearchField();
1236 configureDragHandles();
1237 configureSortableTableHeaders();
1238 configureLinkBanner();
1239 var progressImage = $("progressIndicator");
1241 progressImage.parentNode.removeChild(progressImage);
1242 Event.observe(document.body, "contextmenu", onBodyClickContextMenu);
1245 function onBodyClickContextMenu(event) {
1246 preventDefault(event);
1249 function configureSortableTableHeaders() {
1250 var headers = document.getElementsByClassName("sortableTableHeader");
1251 for (var i = 0; i < headers.length; i++) {
1252 var header = headers[i];
1253 var anchor = $(header).childNodesWithTag("a")[0];
1255 Event.observe(anchor, "click",
1256 onHeaderClick.bindAsEventListener(anchor));
1260 function onLinkBannerClick() {
1261 activeAjaxRequests++;
1262 checkAjaxRequestsState();
1265 function onPreferencesClick(event) {
1266 var urlstr = UserFolderURL + "preferences";
1267 var w = window.open(urlstr, "User Preferences",
1268 "width=430,height=250,resizable=0,scrollbars=0");
1272 preventDefault(event);
1275 function configureLinkBanner() {
1276 var linkBanner = $("linkBanner");
1278 var anchors = linkBanner.childNodesWithTag("a");
1279 for (var i = 0; i < 2; i++) {
1280 Event.observe(anchors[i], "mousedown", listRowMouseDownHandler);
1281 Event.observe(anchors[i], "click", onLinkBannerClick);
1283 Event.observe(anchors[3], "mousedown", listRowMouseDownHandler);
1284 Event.observe(anchors[3], "click", onPreferencesClick);
1285 if (anchors.length > 4)
1286 Event.observe(anchors[4], "click", toggleLogConsole);
1290 addEvent(window, 'load', onLoadHandler);
1292 function parent$(element) {
1293 return this.opener.document.getElementById(element);
1297 function refreshCurrentFolder() {
1300 function configureDragHandles() {
1303 function getMenus() {
1306 function onHeaderClick(event) {
1307 window.alert("generic headerClick");