You are viewing a plain text version of this content. The canonical link for it is here.
Posted to xap-commits@incubator.apache.org by mt...@apache.org on 2006/08/16 20:18:12 UTC
svn commit: r432019 [6/7] - in /incubator/xap/trunk/dist: dojo.js xapcore.js
zimbra.js
Added: incubator/xap/trunk/dist/zimbra.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/dist/zimbra.js?rev=432019&view=auto
==============================================================================
--- incubator/xap/trunk/dist/zimbra.js (added)
+++ incubator/xap/trunk/dist/zimbra.js Wed Aug 16 13:18:11 2006
@@ -0,0 +1,31843 @@
+function launch() {
+ // DBG = new AjxDebug( AjxDebug.NONE, null, false );
+}
+// AjxCore.addOnloadListener( launch );
+
+// Basename: /msgs/I18nMsg
+function I18nMsg(){}
+
+I18nMsg["currencyCode"] = "USD";
+I18nMsg["currencySymbol"] = "$";
+I18nMsg["eraAD"] = "AD";
+I18nMsg["eraBC"] = "BC";
+I18nMsg["firstDayOfWeek"] = "1";
+I18nMsg["formatDateFull"] = "EEEE, MMMM d, yyyy";
+I18nMsg["formatDateLong"] = "MMMM d, yyyy";
+I18nMsg["formatDateMedium"] = "MMM d, yyyy";
+I18nMsg["formatDateShort"] = "M/d/yy";
+I18nMsg["formatDateTime"] = "{0} {1}";
+I18nMsg["formatNumber"] = "#,##0.###";
+I18nMsg["formatNumberCurrency"] = "\u00a4#,##0.00;(\u00a4#,##0.00)";
+I18nMsg["formatNumberInteger"] = "#,##0";
+I18nMsg["formatNumberPercent"] = "#,##0%";
+I18nMsg["formatTimeFull"] = "h:mm:ss a z";
+I18nMsg["formatTimeLong"] = "h:mm:ss a z";
+I18nMsg["formatTimeMedium"] = "h:mm:ss a";
+I18nMsg["formatTimeShort"] = "h:mm a";
+I18nMsg["monthAprLong"] = "April";
+I18nMsg["monthAprMedium"] = "Apr";
+I18nMsg["monthAugLong"] = "August";
+I18nMsg["monthAugMedium"] = "Aug";
+I18nMsg["monthDecLong"] = "December";
+I18nMsg["monthDecMedium"] = "Dec";
+I18nMsg["monthFebLong"] = "February";
+I18nMsg["monthFebMedium"] = "Feb";
+I18nMsg["monthJanLong"] = "January";
+I18nMsg["monthJanMedium"] = "Jan";
+I18nMsg["monthJulLong"] = "July";
+I18nMsg["monthJulMedium"] = "Jul";
+I18nMsg["monthJunLong"] = "June";
+I18nMsg["monthJunMedium"] = "Jun";
+I18nMsg["monthMarLong"] = "March";
+I18nMsg["monthMarMedium"] = "Mar";
+I18nMsg["monthMayLong"] = "May";
+I18nMsg["monthMayMedium"] = "May";
+I18nMsg["monthNovLong"] = "November";
+I18nMsg["monthNovMedium"] = "Nov";
+I18nMsg["monthOctLong"] = "October";
+I18nMsg["monthOctMedium"] = "Oct";
+I18nMsg["monthSepLong"] = "September";
+I18nMsg["monthSepMedium"] = "Sep";
+I18nMsg["numberInfinity"] = "\u221e";
+I18nMsg["numberNaN"] = "\ufffd";
+I18nMsg["numberSeparatorDecimal"] = ".";
+I18nMsg["numberSeparatorGrouping"] = ",";
+I18nMsg["numberSeparatorMoneyDecimal"] = ".";
+I18nMsg["numberSignMinus"] = "-";
+I18nMsg["numberSignPerMill"] = "\u2030";
+I18nMsg["numberSignPercent"] = "%";
+I18nMsg["numberZero"] = "0";
+I18nMsg["periodAm"] = "AM";
+I18nMsg["periodPm"] = "PM";
+I18nMsg["timezoneMapAfrica/Algiers"] = "(GMT+01.00) West Central Africa";
+I18nMsg["timezoneMapAfrica/Cairo"] = "(GMT+02.00) Cairo";
+I18nMsg["timezoneMapAfrica/Casablanca"] = "(GMT) Casablanca / Monrovia";
+I18nMsg["timezoneMapAfrica/Harare"] = "(GMT+02.00) Harare / Pretoria";
+I18nMsg["timezoneMapAfrica/Nairobi"] = "(GMT+03.00) Nairobi";
+I18nMsg["timezoneMapAmerica/Bogota"] = "(GMT-05.00) Bogota / Lima / Quito";
+I18nMsg["timezoneMapAmerica/Buenos_Aires"] = "(GMT-03.00) Buenos Aires / Georgetown";
+I18nMsg["timezoneMapAmerica/Caracas"] = "(GMT-04.00) Caracas / La Paz";
+I18nMsg["timezoneMapAmerica/Godthab"] = "(GMT-03.00) Greenland";
+I18nMsg["timezoneMapAmerica/Santiago"] = "(GMT-04.00) Santiago";
+I18nMsg["timezoneMapAsia/Aqtobe"] = "(GMT+05.00) Ekaterinburg";
+I18nMsg["timezoneMapAsia/Baghdad"] = "(GMT+03.00) Baghdad";
+I18nMsg["timezoneMapAsia/Baku"] = "(GMT+04.00) Baku / Tbilisi / Yerevan";
+I18nMsg["timezoneMapAsia/Bangkok"] = "(GMT+07.00) Bangkok / Hanoi / Jakarta";
+I18nMsg["timezoneMapAsia/Calcutta"] = "(GMT+05.30) Chennai / Kolkata / Mumbai / New Delhi";
+I18nMsg["timezoneMapAsia/Colombo"] = "(GMT+06.00) Sri Jayawardenepura";
+I18nMsg["timezoneMapAsia/Dhaka"] = "(GMT+06.00) Astana / Dhaka";
+I18nMsg["timezoneMapAsia/Hong_Kong"] = "(GMT+08.00) Beijing / Chongqing / Hong Kong / Urumqi";
+I18nMsg["timezoneMapAsia/Irkutsk"] = "(GMT+08.00) Irkutsk / Ulaan Bataar";
+I18nMsg["timezoneMapAsia/Jerusalem"] = "(GMT+02.00) Jerusalem";
+I18nMsg["timezoneMapAsia/Kabul"] = "(GMT+04.30) Kabul";
+I18nMsg["timezoneMapAsia/Karachi"] = "(GMT+05.00) Islamabad / Karachi / Tashkent";
+I18nMsg["timezoneMapAsia/Katmandu"] = "(GMT+05.45) Kathmandu";
+I18nMsg["timezoneMapAsia/Krasnoyarsk"] = "(GMT+07.00) Krasnoyarsk";
+I18nMsg["timezoneMapAsia/Kuala_Lumpur"] = "(GMT+08.00) Kuala Lumpur / Singaporev";
+I18nMsg["timezoneMapAsia/Kuwait"] = "(GMT+03.00) Kuwait / Riyadh";
+I18nMsg["timezoneMapAsia/Magadan"] = "(GMT+11.00) Magadan / Solomon Is. / New Calenodia";
+I18nMsg["timezoneMapAsia/Muscat"] = "(GMT+04.00) Abu Dhabi / Muscat";
+I18nMsg["timezoneMapAsia/Novosibirsk"] = "(GMT+06.00) Almaty / Novosibirsk";
+I18nMsg["timezoneMapAsia/Rangoon"] = "(GMT+06.30) Rangoon";
+I18nMsg["timezoneMapAsia/Seoul"] = "(GMT+09.00) Seoul";
+I18nMsg["timezoneMapAsia/Taipei"] = "(GMT+08.00) Taipei";
+I18nMsg["timezoneMapAsia/Tehran"] = "(GMT+03.30) Tehran";
+I18nMsg["timezoneMapAsia/Tokyo"] = "(GMT+09.00) Osaka / Sapporo / Tokyo";
+I18nMsg["timezoneMapAsia/Vladivostok"] = "(GMT+10.00) Vladivostok";
+I18nMsg["timezoneMapAsia/Yakutsk"] = "(GMT+09.00) Yakutsk";
+I18nMsg["timezoneMapAtlantic/Azores"] = "(GMT-01.00) Azores";
+I18nMsg["timezoneMapAtlantic/Cape_Verde"] = "(GMT-01.00) Cape Verde Is.";
+I18nMsg["timezoneMapAustralia/Adelaide"] = "(GMT+09.30) Adelaide";
+I18nMsg["timezoneMapAustralia/Brisbane"] = "(GMT+10.00) Brisbane";
+I18nMsg["timezoneMapAustralia/Darwin"] = "(GMT+09.30) Darwin";
+I18nMsg["timezoneMapAustralia/Hobart"] = "(GMT+10.00) Hobart";
+I18nMsg["timezoneMapAustralia/Perth"] = "(GMT+08.00) Perth";
+I18nMsg["timezoneMapAustralia/Sydney"] = "(GMT+10.00) Canberra / Melbourne / Sydney";
+I18nMsg["timezoneMapBrazil/East"] = "(GMT-03.00) Brasilia";
+I18nMsg["timezoneMapCanada/Eastern"] = "(GMT-04.00) Atlantic Time (Canada)";
+I18nMsg["timezoneMapCanada/Newfoundland"] = "(GMT-03.30) Newfoundlan";
+I18nMsg["timezoneMapCanada/Saskatchewan"] = "(GMT-06.00) Saskatchewan";
+I18nMsg["timezoneMapEurope/Athens"] = "(GMT+02.00) Athens / Beirut / Istanbul / Minsk";
+I18nMsg["timezoneMapEurope/Berlin"] = "(GMT+01.00) Amsterdam / Berlin / Bern / Rome / Stockholm / Vienna";
+I18nMsg["timezoneMapEurope/London"] = "(GMT) Greenwich Mean Time - Dublin / Edinburgh / Lisbon / London";
+I18nMsg["timezoneMapEurope/Moscow"] = "(GMT+03.00) Moscow / St. Petersburg / Volgograd";
+I18nMsg["timezoneMapPacific/Auckland"] = "(GMT+12.00) Auckland / Wellington";
+I18nMsg["timezoneMapPacific/Fiji"] = "(GMT+12.00) Fiji / Kamchatka / Marshall Is.";
+I18nMsg["timezoneMapPacific/Guam"] = "(GMT+10.00) Guam / Port Moresby";
+I18nMsg["timezoneMapPacific/Midway"] = "(GMT-11.00) Midway Island / Samoa";
+I18nMsg["timezoneMapPacific/Tongatapu"] = "(GMT+13.00) Nuku'alofa";
+I18nMsg["timezoneMapUS/Alaska"] = "(GMT-09.00) Alaska";
+I18nMsg["timezoneMapUS/Arizona"] = "(GMT-07.00) Arizona";
+I18nMsg["timezoneMapUS/Central"] = "(GMT-06.00) Central Time (US & Canada)";
+I18nMsg["timezoneMapUS/East-Indiana"] = "(GMT-05.00) Indiana (East)";
+I18nMsg["timezoneMapUS/Eastern"] = "(GMT-05.00) Eastern Time (US & Canada)";
+I18nMsg["timezoneMapUS/Hawaii"] = "(GMT-10.00) Hawaii";
+I18nMsg["timezoneMapUS/Mountain"] = "(GMT-07.00) Mountain Time (US & Canada)";
+I18nMsg["timezoneMapUS/Pacific"] = "(GMT-08.00) Pacific Time (US & Canada) / Tijuana";
+I18nMsg["timezoneNameAfrica/Algiers"] = "Central European Time";
+I18nMsg["timezoneNameAfrica/Cairo"] = "Eastern European Time";
+I18nMsg["timezoneNameAfrica/Casablanca"] = "Western European Time";
+I18nMsg["timezoneNameAfrica/Harare"] = "Central African Time";
+I18nMsg["timezoneNameAfrica/Nairobi"] = "Eastern African Time";
+I18nMsg["timezoneNameAmerica/Bogota"] = "Colombia Time";
+I18nMsg["timezoneNameAmerica/Buenos_Aires"] = "Argentine Time";
+I18nMsg["timezoneNameAmerica/Caracas"] = "Venezuela Time";
+I18nMsg["timezoneNameAmerica/Godthab"] = "Western Greenland Time";
+I18nMsg["timezoneNameAmerica/Santiago"] = "Chile Time";
+I18nMsg["timezoneNameAsia/Aqtobe"] = "Aqtobe Time";
+I18nMsg["timezoneNameAsia/Baghdad"] = "Arabia Standard Time";
+I18nMsg["timezoneNameAsia/Baku"] = "Azerbaijan Time";
+I18nMsg["timezoneNameAsia/Bangkok"] = "Indochina Time";
+I18nMsg["timezoneNameAsia/Calcutta"] = "India Standard Time";
+I18nMsg["timezoneNameAsia/Colombo"] = "Sri Lanka Time";
+I18nMsg["timezoneNameAsia/Dhaka"] = "Bangladesh Time";
+I18nMsg["timezoneNameAsia/Hong_Kong"] = "Hong Kong Time";
+I18nMsg["timezoneNameAsia/Irkutsk"] = "Irkutsk Time";
+I18nMsg["timezoneNameAsia/Jerusalem"] = "Israel Standard Time";
+I18nMsg["timezoneNameAsia/Kabul"] = "Afghanistan Time";
+I18nMsg["timezoneNameAsia/Karachi"] = "Pakistan Time";
+I18nMsg["timezoneNameAsia/Katmandu"] = "Nepal Time";
+I18nMsg["timezoneNameAsia/Krasnoyarsk"] = "Krasnoyarsk Time";
+I18nMsg["timezoneNameAsia/Kuala_Lumpur"] = "Malaysia Time";
+I18nMsg["timezoneNameAsia/Kuwait"] = "Arabia Standard Time";
+I18nMsg["timezoneNameAsia/Magadan"] = "Magadan Time";
+I18nMsg["timezoneNameAsia/Muscat"] = "Gulf Standard Time";
+I18nMsg["timezoneNameAsia/Novosibirsk"] = "Novosibirsk Time";
+I18nMsg["timezoneNameAsia/Rangoon"] = "Myanmar Time";
+I18nMsg["timezoneNameAsia/Seoul"] = "Korea Standard Time";
+I18nMsg["timezoneNameAsia/Taipei"] = "China Standard Time";
+I18nMsg["timezoneNameAsia/Tehran"] = "Iran Standard Time";
+I18nMsg["timezoneNameAsia/Tokyo"] = "Japan Standard Time";
+I18nMsg["timezoneNameAsia/Vladivostok"] = "Vladivostok Time";
+I18nMsg["timezoneNameAsia/Yakutsk"] = "Yakutsk Time";
+I18nMsg["timezoneNameAtlantic/Azores"] = "Azores Time";
+I18nMsg["timezoneNameAtlantic/Cape_Verde"] = "Cape Verde Time";
+I18nMsg["timezoneNameAustralia/Adelaide"] = "Central Standard Time (South Australia)";
+I18nMsg["timezoneNameAustralia/Brisbane"] = "Eastern Standard Time (Queensland)";
+I18nMsg["timezoneNameAustralia/Darwin"] = "Central Standard Time (Northern Territory)";
+I18nMsg["timezoneNameAustralia/Hobart"] = "Eastern Standard Time (Tasmania)";
+I18nMsg["timezoneNameAustralia/Perth"] = "Western Standard Time (Australia)";
+I18nMsg["timezoneNameAustralia/Sydney"] = "Eastern Standard Time (New South Wales)";
+I18nMsg["timezoneNameBrazil/East"] = "Brazil Time";
+I18nMsg["timezoneNameCanada/Eastern"] = "Eastern Standard Time";
+I18nMsg["timezoneNameCanada/Newfoundland"] = "Newfoundland Standard Time";
+I18nMsg["timezoneNameCanada/Saskatchewan"] = "Central Standard Time";
+I18nMsg["timezoneNameEurope/Athens"] = "Eastern European Time";
+I18nMsg["timezoneNameEurope/Berlin"] = "Central European Time";
+I18nMsg["timezoneNameEurope/London"] = "Greenwich Mean Time";
+I18nMsg["timezoneNameEurope/Moscow"] = "Moscow Standard Time";
+I18nMsg["timezoneNamePacific/Auckland"] = "New Zealand Standard Time";
+I18nMsg["timezoneNamePacific/Fiji"] = "Fiji Time";
+I18nMsg["timezoneNamePacific/Guam"] = "Chamorro Standard Time";
+I18nMsg["timezoneNamePacific/Midway"] = "Samoa Standard Time";
+I18nMsg["timezoneNamePacific/Tongatapu"] = "Tonga Time";
+I18nMsg["timezoneNameUS/Alaska"] = "Alaska Standard Time";
+I18nMsg["timezoneNameUS/Arizona"] = "Mountain Standard Time";
+I18nMsg["timezoneNameUS/Central"] = "Central Standard Time";
+I18nMsg["timezoneNameUS/East-Indiana"] = "Eastern Standard Time";
+I18nMsg["timezoneNameUS/Eastern"] = "Eastern Standard Time";
+I18nMsg["timezoneNameUS/Hawaii"] = "Hawaii Standard Time";
+I18nMsg["timezoneNameUS/Mountain"] = "Mountain Standard Time";
+I18nMsg["timezoneNameUS/Pacific"] = "Pacific Standard Time";
+I18nMsg["weekdayFriLong"] = "Friday";
+I18nMsg["weekdayFriMedium"] = "Fri";
+I18nMsg["weekdayMonLong"] = "Monday";
+I18nMsg["weekdayMonMedium"] = "Mon";
+I18nMsg["weekdaySatLong"] = "Saturday";
+I18nMsg["weekdaySatMedium"] = "Sat";
+I18nMsg["weekdaySunLong"] = "Sunday";
+I18nMsg["weekdaySunMedium"] = "Sun";
+I18nMsg["weekdayThuLong"] = "Thursday";
+I18nMsg["weekdayThuMedium"] = "Thu";
+I18nMsg["weekdayTueLong"] = "Tuesday";
+I18nMsg["weekdayTueMedium"] = "Tue";
+I18nMsg["weekdayWedLong"] = "Wednesday";
+I18nMsg["weekdayWedMedium"] = "Wed";
+
+// Basename: /msgs/AjxMsg
+function AjxMsg(){}
+
+AjxMsg["XfnumberLessThanMin"] = "Value must be greater than or equal to {0}.";
+AjxMsg["_close"] = "Close";
+AjxMsg["_finish"] = "Finish";
+AjxMsg["_next"] = "Next";
+AjxMsg["_prev"] = "Previous";
+AjxMsg["add"] = "Add";
+AjxMsg["addAll"] = "Add All";
+AjxMsg["ago"] = "ago";
+AjxMsg["cancel"] = "Cancel";
+AjxMsg["cancelRequest"] = "Cancel Request";
+AjxMsg["confirmTitle"] = "Confirmation";
+AjxMsg["criticalMsg"] = "Critical";
+AjxMsg["dateParsing2DigitStartYear"] = "1936";
+AjxMsg["day"] = "day";
+AjxMsg["days"] = "days";
+AjxMsg["detail"] = "Detail";
+AjxMsg["didNotMatchChoice"] = "Value '$0' did not match any values for this type.";
+AjxMsg["dismiss"] = "Dismiss";
+AjxMsg["first"] = "first";
+AjxMsg["formatCalDate"] = "EEE, MMM d";
+AjxMsg["formatCalDateFull"] = "EEEE, MMMM d, yyyy";
+AjxMsg["formatCalDateLong"] = "EEEE, MMMM d";
+AjxMsg["formatCalDay"] = "M/d ";
+AjxMsg["formatCalMonth"] = "MMMM yyyy";
+AjxMsg["formatDateMediumNoYear"] = "MMM dd ";
+AjxMsg["fourth"] = "fourth";
+AjxMsg["hour"] = "hour";
+AjxMsg["hours"] = "hours";
+AjxMsg["infoMsg"] = "Informational";
+AjxMsg["invalidDateString"] = "Date value must be entered in the form: MM/DD/YYYY or \"today\", \"yesterday\" or \"tomorrow\".";
+AjxMsg["invalidDatetimeString"] = "Date format not understood.";
+AjxMsg["invalidTimeString"] = "Time value must be entered in the form: HH:MM[:SS] [AM|PM]";
+AjxMsg["last"] = "last";
+AjxMsg["minute"] = "minute";
+AjxMsg["minutes"] = "minutes";
+AjxMsg["month"] = "month";
+AjxMsg["monthAprShort"] = "A";
+AjxMsg["monthAugShort"] = "A";
+AjxMsg["monthDecShort"] = "D";
+AjxMsg["monthFebShort"] = "F";
+AjxMsg["monthJanShort"] = "J";
+AjxMsg["monthJulShort"] = "J";
+AjxMsg["monthJunShort"] = "J";
+AjxMsg["monthMarShort"] = "M";
+AjxMsg["monthMayShort"] = "M";
+AjxMsg["monthNovShort"] = "N";
+AjxMsg["monthOctShort"] = "O";
+AjxMsg["monthSepShort"] = "S";
+AjxMsg["months"] = "months";
+AjxMsg["no"] = "No";
+AjxMsg["noResults"] = "No results found.";
+AjxMsg["notANumber"] = "Value must be a number.";
+AjxMsg["notAString"] = "Value must be a text string.";
+AjxMsg["notAnInteger"] = "Value must be an integer.";
+AjxMsg["numberFractionExceeded"] = "Fractional digits exceeds total of {0}.";
+AjxMsg["numberLessThanEqualMin"] = "Value must be greater than {0}.";
+AjxMsg["numberLessThanMin"] = "Value must be greater than or equal to {0}.";
+AjxMsg["numberMoreThanEqualMax"] = "Value must be less than {0}.";
+AjxMsg["numberMoreThanMax"] = "Value must be less than or equal to {0}.";
+AjxMsg["numberMustBeNon0Percent"] = "Value must be a percentage between 1 and 100";
+AjxMsg["numberTotalExceeded"] = "Whole digits exceeds total of {0}.";
+AjxMsg["ok"] = "OK";
+AjxMsg["remove"] = "Remove";
+AjxMsg["removeAll"] = "Remove All";
+AjxMsg["second"] = "second";
+AjxMsg["seconds"] = "seconds";
+AjxMsg["stringLenWrong"] = "Value must be exactly {0} characters long.";
+AjxMsg["stringMismatch"] = "Value did not match valid values.";
+AjxMsg["stringTooLong"] = "Value must be no more than {0} characters long.";
+AjxMsg["stringTooShort"] = "Value must be at least {0} characters long.";
+AjxMsg["third"] = "third";
+AjxMsg["today"] = "today";
+AjxMsg["tomorrow"] = "tomorrow";
+AjxMsg["valueIsRequired"] = "Value is required";
+AjxMsg["warningMsg"] = "Warning";
+AjxMsg["week"] = "week";
+AjxMsg["weekdayFriShort"] = "F";
+AjxMsg["weekdayMonShort"] = "M";
+AjxMsg["weekdaySatShort"] = "S";
+AjxMsg["weekdaySunShort"] = "S";
+AjxMsg["weekdayThuShort"] = "T";
+AjxMsg["weekdayTueShort"] = "T";
+AjxMsg["weekdayWedShort"] = "W";
+AjxMsg["weeks"] = "weeks";
+AjxMsg["workInProgress"] = "Work In Progress";
+AjxMsg["xFnumberMoreThanMax"] = "Value must be less than or equal to {0}.";
+AjxMsg["xformDateTimeFormat"] = "{0,date} at {0,time}";
+AjxMsg["xformRepeatAdd"] = "+";
+AjxMsg["xformRepeatRemove"] = "-";
+AjxMsg["year"] = "year";
+AjxMsg["years"] = "years";
+AjxMsg["yes"] = "Yes";
+AjxMsg["yesterday"] = "yesterday";
+
+/*
+* Conventions
+*
+* - Classes that start with "Dwt" have a corollary Javascript object.
+* - Use one line if there is only one selector and one declaration. Otherwise, indent each declaration on its own line.
+* - Group selectors to avoid repetition of styles, as appropriate (ie group within a section). That means you may have
+* to look at more than one definition to figure out all the applicable styles, but it lets you give the styles a
+* hierarchy. That way, you're more likely to need to change a style in just one place.
+* - Use shorthand styles when possible (font, margin, padding, etc).
+* - When grouping selectors that correspond to our Javascript objects, show inheritance by using a different line for
+* each level of inheritance. CSS doesn't care about our object hierarchy, but doing that enhances readability.
+* - Use decimal RGB values for colors that don't have names.
+* - Modifiers are lower case, whether they're a class (eg .activated) or tacked on (eg -selected).
+*
+* Classes are laid out in the following general order:
+* - HTML elements
+* - General app stuff (shell, overlays, banner)
+* - Widgets that tend toward abstract (minimal subclassing), such as tool tips and sashes
+* - Heavier use widgets such as buttons and dialogs
+* - General widget stuff, then specialized subclasses
+* - List views, with common stuff first
+* - Other views (lots of them)
+* - Miscellaneous stuff that multiple apps might use (objects, autocomplete)
+* - Modifiers
+*
+* Many of the Dwt widgets don't have corresponding classes here, since they are only subclassed. If you create and
+* display one of those widgets, you'll have to add a class for it.
+*/
+
+/*
+* HTML elements - use for global declarations
+*/
+
+/* Global ELEMENT declarations */
+
+function ExMsg() {}
+/*
+* ***** BEGIN LICENSE BLOCK *****
+* Version: MPL 1.1
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 ("License"); you may not use this file except in
+* compliance with the License. You may obtain a copy of the License at
+* http://www.zimbra.com/license
+*
+* Software distributed under the License is distributed on an "AS IS"
+* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+* the License for the specific language governing rights and limitations
+* under the License.
+*
+* The Original Code is: Zimbra AJAX Toolkit.
+*
+* The Initial Developer of the Original Code is Zimbra, Inc.
+* Portions created by Zimbra are Copyright (C) 2005 Zimbra, Inc.
+* All Rights Reserved.
+*
+* Contributor(s):
+*
+* ***** END LICENSE BLOCK *****
+*/
+
+
+function AjxEnv() {
+}
+
+AjxEnv._inited = false;
+
+
+AjxEnv.reset = function () {
+ AjxEnv.browserVersion = -1;
+ AjxEnv.geckoDate = 0;
+ AjxEnv.mozVersion = -1;
+ AjxEnv.isMac = false;
+ AjxEnv.isWindows = false;
+ AjxEnv.isLinux = false;
+ AjxEnv.isNav = false;
+ AjxEnv.isIE = false;
+ AjxEnv.isNav4 = false;
+ AjxEnv.trueNs = true;
+ AjxEnv.isNav6 = false;
+ AjxEnv.isNav6up = false;
+ AjxEnv.isNav7 = false;
+ AjxEnv.isIE3 = false;
+ AjxEnv.isIE4 = false;
+ AjxEnv.isIE4up = false;
+ AjxEnv.isIE5 = false;
+ AjxEnv.isIE5_5 = false;
+ AjxEnv.isIE5up = false;
+ AjxEnv.isIE5_5up = false;
+ AjxEnv.isIE6 = false;
+ AjxEnv.isIE6up = false;
+ AjxEnv.isNormalResolution = false;
+ AjxEnv.ieScaleFactor = 1;
+ AjxEnv.isFirefox = false;
+ AjxEnv.isFirefox1up = false;
+ AjxEnv.isFirefox1_5up = false;
+ AjxEnv.isMozilla = false;
+ AjxEnv.isMozilla1_4up = false;
+ AjxEnv.isSafari = false;
+ AjxEnv.isGeckoBased = false;
+ AjxEnv.isOpera = false;
+ AjxEnv.useTransparentPNGs = false;
+
+ // screen resolution - ADD MORE RESOLUTION CHECKS AS NEEDED HERE:
+ AjxEnv.is800x600orLower = screen.width <= 800 && screen.height <= 600;
+};
+
+AjxEnv.parseUA = function (userAgent) {
+ var agt = userAgent.toLowerCase();
+ var agtArr = agt.split(" ");
+ var i = 0;
+ var index = -1;
+ var token = null;
+ var isSpoofer = false;
+ var isWebTv = false;
+ var isHotJava = false;
+ var beginsWithMozilla = false;
+ var isCompatible = false;
+ if (agtArr != null) {
+ if ( (index = agtArr[0].search(/^\s*mozilla\//) )!= -1){
+ beginsWithMozilla = true;
+ AjxEnv.browserVersion = parseFloat(agtArr[0].substring(index + 8));
+ AjxEnv.isNav = true;
+ }
+ for ( ; i < agtArr.length; ++i ){
+ token = agtArr[i];
+ if (token.indexOf('compatible') != -1 ) {
+ isCompatible = true;
+ AjxEnv.isNav = false;
+ } else if ((token.indexOf('opera')) != -1){
+ AjxEnv.isOpera = true;
+ AjxEnv.isNav = false;
+ AjxEnv.browserVersion = parseFloat(agtArr[i+1]);
+ } else if ((token.indexOf('spoofer')) != -1){
+ isSpoofer = true;
+ AjxEnv.isNav = false;
+ } else if ((token.indexOf('webtv')) != -1) {
+ isWebTv = true;
+ AjxEnv.isNav = false;
+ } else if ((token.indexOf('hotjava')) != -1) {
+ isHotJava = true;
+ AjxEnv.isNav = false;
+ } else if ((index = token.indexOf('msie')) != -1) {
+ AjxEnv.isIE = true;
+ AjxEnv.browserVersion = parseFloat(agtArr[i+1]);
+ } else if ((index = token.indexOf('gecko/')) != -1){
+ AjxEnv.isGeckoBased = true;
+ AjxEnv.geckoDate = parseFloat(token.substr(index + 6));
+ } else if ((index = token.indexOf('rv:')) != -1){
+ AjxEnv.mozVersion = parseFloat(token.substr(index + 3));
+ AjxEnv.browserVersion = AjxEnv.mozVersion;
+ } else if ((index = token.indexOf('firefox/')) != -1){
+ AjxEnv.isFirefox = true;
+ AjxEnv.browserVersion = parseFloat(token.substr(index + 8));
+ } else if ((index = token.indexOf('netscape6/')) != -1){
+ AjxEnv.trueNs = true;
+ AjxEnv.browserVersion = parseFloat(token.substr(index + 10));
+ } else if ((index = token.indexOf('netscape/')) != -1){
+ AjxEnv.trueNs = true;
+ AjxEnv.browserVersion = parseFloat(token.substr(index + 9));
+ } else if ((index = token.indexOf('safari/')) != -1){
+ AjxEnv.isSafari = true;
+ AjxEnv.browserVersion = parseFloat(token.substr(index + 7));
+ } else if (token.indexOf('windows') != -1){
+ AjxEnv.isWindows = true;
+ } else if ((token.indexOf('macintosh') != -1) ||
+ (token.indexOf('mac_') != -1)){
+ AjxEnv.isMac = true;
+ } else if (token.indexOf('linux') != -1){
+ AjxEnv.isLinux = true;
+ }
+ }
+ // Note: Opera and WebTV spoof Navigator.
+ // We do strict client detection.
+ AjxEnv.isNav = (beginsWithMozilla && !isSpoofer && !isCompatible &&
+ !AjxEnv.isOpera && !isWebTv && !isHotJava &&
+ !AjxEnv.isSafari);
+
+ AjxEnv.isIE = (AjxEnv.isIE && !AjxEnv.isOpera);
+
+ AjxEnv.isNav4 = (AjxEnv.isNav && (AjxEnv.browserVersion == 4) &&
+ (!AjxEnv.isIE));
+ AjxEnv.isNav6 = (AjxEnv.isNav && AjxEnv.trueNs &&
+ (AjxEnv.browserVersion >=6.0) &&
+ (AjxEnv.browserVersion < 7.0));
+ AjxEnv.isNav6up = (AjxEnv.isNav && AjxEnv.trueNs &&
+ (AjxEnv.browserVersion >= 6.0));
+ AjxEnv.isNav7 = (AjxEnv.isNav && AjxEnv.trueNs &&
+ (AjxEnv.browserVersion == 7.0));
+
+ AjxEnv.isIE3 = (AjxEnv.isIE && (AjxEnv.browserVersion < 4));
+ AjxEnv.isIE4 = (AjxEnv.isIE && (AjxEnv.browserVersion == 4) &&
+ (AjxEnv.browserVersion == 4.0));
+ AjxEnv.isIE4up = (AjxEnv.isIE && (AjxEnv.browserVersion >= 4));
+ AjxEnv.isIE5 = (AjxEnv.isIE && (AjxEnv.browserVersion == 4) &&
+ (AjxEnv.browserVersion == 5.0));
+ AjxEnv.isIE5_5 = (AjxEnv.isIE && (AjxEnv.browserVersion == 4) &&
+ (AjxEnv.browserVersion == 5.5));
+ AjxEnv.isIE5up = (AjxEnv.isIE && (AjxEnv.browserVersion >= 5.0));
+ AjxEnv.isIE5_5up =(AjxEnv.isIE && (AjxEnv.browserVersion >= 5.5));
+ AjxEnv.isIE6 = (AjxEnv.isIE && (AjxEnv.browserVersion == 6.0));
+ AjxEnv.isIE6up = (AjxEnv.isIE && (AjxEnv.browserVersion >= 6.0));
+
+ AjxEnv.isMozilla = ((AjxEnv.isNav && AjxEnv.mozVersion &&
+ AjxEnv.isGeckoBased && (AjxEnv.geckoDate != 0)));
+ AjxEnv.isMozilla1_4up = (AjxEnv.isMozilla && (AjxEnv.mozVersion >= 1.4));
+ AjxEnv.isFirefox = ((AjxEnv.isMozilla && AjxEnv.isFirefox));
+ AjxEnv.isFirefox1up = (AjxEnv.isFirefox && AjxEnv.browserVersion >= 1.0);
+ AjxEnv.isFirefox1_5up = (AjxEnv.isFirefox && AjxEnv.browserVersion >= 1.5);
+
+ }
+ // setup some global setting we can check for high resolution
+ if (AjxEnv.isIE){
+ AjxEnv.isNormalResolution = true;
+ AjxEnv.ieScaleFactor = screen.deviceXDPI / screen.logicalXDPI;
+ if (AjxEnv.ieScaleFactor > 1) {
+ AjxEnv.isNormalResolution = false;
+ }
+ }
+ // show transparent PNGs on platforms that support them well
+ // (eg: all but IE and Linux)
+ // MOW: having trouble getting safari to render transparency for shadows, skipping there, too
+ AjxEnv.useTransparentPNGs = !AjxEnv.isIE && !AjxEnv.isLinux && !AjxEnv.isSafari;
+ AjxEnv._inited = !AjxEnv.isIE;
+};
+
+AjxEnv.reset();
+AjxEnv.parseUA(navigator.userAgent);
+
+// COMPATIBILITY
+
+// Safari doesn't support string.replace(/regexp/, function);
+if (AjxEnv.isSafari) {
+ if (!String.prototype._AjxOldReplace) {
+ String.prototype._AjxOldReplace = String.prototype.replace;
+ String.prototype.replace = function(re, val) {
+ if (typeof val != "function")
+ return this._AjxOldReplace(re, val);
+ else {
+ // TODO: investigate if it's possible to use the array.join approach
+ var str = this.slice(0), v, l, a;
+ while (a = re.exec(str)) {
+ v = val.apply(null, a);
+ l = a[0].length;
+ re.lastIndex -= l - v.length;
+ str = str.substr(0, a.index) + v + str.substr(a.index + l);
+ if (!re.global)
+ break;
+ }
+ return str;
+ }
+ };
+ }
+}
+/*
+* ***** BEGIN LICENSE BLOCK *****
+* Version: MPL 1.1
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 ("License"); you may not use this file except in
+* compliance with the License. You may obtain a copy of the License at
+* http://www.zimbra.com/license
+*
+* Software distributed under the License is distributed on an "AS IS"
+* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+* the License for the specific language governing rights and limitations
+* under the License.
+*
+* The Original Code is: Zimbra AJAX Toolkit.
+*
+* The Initial Developer of the Original Code is Zimbra, Inc.
+* Portions created by Zimbra are Copyright (C) 2005 Zimbra, Inc.
+* All Rights Reserved.
+*
+* Contributor(s):
+*
+* ***** END LICENSE BLOCK *****
+*/
+
+
+/**
+ * AjxUtil - static class with some utility methods. This is where to
+ * put things when no other class wants them.
+ *
+ * 12/3/2004 At this point, it only needs AjxEnv to be loaded.
+ */
+function AjxUtil () {
+};
+
+AjxUtil.FLOAT_RE = /^[+\-]?((\d+(\.\d*)?)|((\d*\.)?\d+))([eE][+\-]?\d+)?$/;
+AjxUtil.NOTFLOAT_RE = /[^\d\.]/;
+AjxUtil.NOTINT_RE = /[^0-9]+/;
+AjxUtil.LIFETIME_FIELD = /^([0-9])+([dhms])?$/;
+
+AjxUtil.isSpecified = function(aThing) { return ((aThing !== void 0) && (aThing !== null)); };
+AjxUtil.isUndefined = function(aThing) { return (aThing === void 0); };
+AjxUtil.isNull = function(aThing) { return (aThing === null); };
+AjxUtil.isBoolean = function(aThing) { return (typeof(aThing) == 'boolean'); };
+AjxUtil.isString = function(aThing) { return (typeof(aThing) == 'string'); };
+AjxUtil.isNumber = function(aThing) { return (typeof(aThing) == 'number'); };
+AjxUtil.isObject = function(aThing) { return ((typeof(aThing) == 'object') && (aThing !== null)); };
+AjxUtil.isArray = function(aThing) { return AjxUtil.isInstance(aThing, Array); };
+AjxUtil.isFunction = function(aThing) { return (typeof(aThing) == 'function'); };
+AjxUtil.isDate = function(aThing) { return AjxUtil.isInstance(aThing, Date); };
+AjxUtil.isLifeTime = function(aThing) { return AjxUtil.LIFETIME_FIELD.test(aThing); };
+AjxUtil.isNumeric = function(aThing) { return (!isNaN(parseFloat(aThing)) && AjxUtil.FLOAT_RE.test(aThing) && !AjxUtil.NOTFLOAT_RE.test(aThing)); };
+AjxUtil.isLong = function(aThing) { return (AjxUtil.isNumeric(aThing) && !AjxUtil.NOTINT_RE.test(aThing)); };
+AjxUtil.isNonNegativeLong = function(aThing) { return (AjxUtil.isNumeric(aThing) && AjxUtil.isLong(aThing) && (parseFloat(aThing) >= 0)); };
+
+
+// REVISIT: Should do more precise checking. However, there are names in
+// common use that do not follow the RFC patterns (e.g. domain
+// names that start with digits).
+AjxUtil.IP_ADDRESS_RE = /^\d{1,3}(\.\d{1,3}){3}(\.\d{1,3}\.\d{1,3})?$/;
+AjxUtil.DOMAIN_NAME_SHORT_RE = /^[A-Za-z0-9\-]{2,}$/;
+AjxUtil.DOMAIN_NAME_FULL_RE = /^[A-Za-z0-9\-]{2,}(\.[A-Za-z0-9\-]{2,}){1,}$/;
+AjxUtil.HOST_NAME_RE = /^[A-Za-z0-9\-]{2,}(\.[A-Za-z0-9\-]{2,})*$/;
+AjxUtil.HOST_NAME_WITH_PORT_RE = /^[A-Za-z0-9\-]{2,}(\.[A-Za-z0-9\-]{2,})*:([0-9])+$/;
+AjxUtil.EMAIL_SHORT_RE = /^[^@\s]+$/;
+AjxUtil.EMAIL_FULL_RE = /^[^@\s]+@[A-Za-z0-9\-]{2,}(\.[A-Za-z0-9\-]{2,})*$/;
+AjxUtil.EMAIL_RE = /^([a-zA-Z0-9_\-])+((\.)?([a-zA-Z0-9_\-])+)*@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
+AjxUtil.SHORT_URL_RE = /^[A-Za-z0-9]{2,}:\/\/[A-Za-z0-9\-]{2,}(\.[A-Za-z0-9\-]{2,})*(:([0-9])+)*$/;
+AjxUtil.IP_SHORT_URL_RE = /^[A-Za-z0-9]{2,}:\/\/\d{1,3}(\.\d{1,3}){3}(\.\d{1,3}\.\d{1,3})?(:([0-9])+)*$/;
+
+AjxUtil.isIpAddress = function(s) { return AjxUtil.IP_ADDR_RE.test(s); };
+AjxUtil.isDomain = function(s) { return AjxUtil.DOMAIN_RE.test(s); };
+AjxUtil.isHostName = function(s) { return AjxUtil.HOST_NAME_RE.test(s); };
+AjxUtil.isDomainName =
+function(s, shortMatch) {
+ return shortMatch
+ ? AjxUtil.DOMAIN_NAME_SHORT_RE.test(s)
+ : AjxUtil.DOMAIN_NAME_FULL_RE.test(s);
+};
+
+AjxUtil.isEmailAddress =
+function(s, nameOnly) {
+ return nameOnly
+ ? AjxUtil.EMAIL_SHORT_RE.test(s)
+ : AjxUtil.EMAIL_FULL_RE.test(s);
+};
+
+AjxUtil.SIZE_GIGABYTES = "GB";
+AjxUtil.SIZE_MEGABYTES = "MB";
+AjxUtil.SIZE_KILOBYTES = "KB";
+AjxUtil.SIZE_BYTES = "B";
+
+/**
+ * Formats a size (in bytes) to the largest whole unit. For example,
+ * AjxUtil.formatSize(302132199) returns "288 MB".
+ *
+ * @param size The size (in bytes) to be formatted.
+ * @param round True to round to nearest integer. Default is true.
+ * @param fractions Number of fractional digits to display, if not rounding.
+ * Trailing zeros after the decimal point are trimmed.
+ */
+AjxUtil.formatSize =
+function(size, round, fractions) {
+ if (round == null) round = true;
+ if (fractions == null) fractions = 20; // max allowed for toFixed is 20
+
+ var units = AjxUtil.SIZE_BYTES;
+ if (size >= 1073741824) {
+ size /= 1073741824;
+ units = AjxUtil.SIZE_GIGABYTES;
+ }
+ else if (size >= 1048576) {
+ size /= 1048576;
+ units = AjxUtil.SIZE_MEGABYTES;
+ }
+ else if (size > 1023) {
+ size /= 1024;
+ units = AjxUtil.SIZE_KILOBYTES;
+ }
+
+ var formattedSize = round ? Math.round(size) : size.toFixed(fractions).replace(/\.?0+$/,"");
+ var formattedUnits = ' '+units;
+
+ return formattedSize + formattedUnits;
+};
+
+/**
+ * Formats a size (in bytes) to a specific unit. Since the unit size is
+ * known, the unit is not shown in the returned string. For example,
+ * AjxUtil.formatSizeForUnit(302132199, AjxUtil.SIZE_MEGABYTES, false, 2)
+ * returns "288.13".
+ *
+ * @param size The size (in bytes) to be formatted.
+ * @param units The unit of measure.
+ * @param round True to round to nearest integer. Default is true.
+ * @param fractions Number of fractional digits to display, if not rounding.
+ * Trailing zeros after the decimal point are trimmed.
+ */
+AjxUtil.formatSizeForUnits =
+function(size, units, round, fractions) {
+ if (units == null) units = AjxUtil.SIZE_BYTES;
+ if (round == null) round = true;
+ if (fractions == null) fractions = 20; // max allowed for toFixed is 20
+
+ switch (units) {
+ case AjxUtil.SIZE_GIGABYTES: { size /= 1073741824; break; }
+ case AjxUtil.SIZE_MEGABYTES: { size /= 1048576; break; }
+ case AjxUtil.SIZE_KILOBYTES: { size /= 1024; break; }
+ }
+
+ var formattedSize = round ? Math.round(size) : size.toFixed(fractions).replace(/\.?0+$/,"");
+ return formattedSize;
+};
+
+/**
+ * Performs the opposite of AjxUtil.formatSize in that this function takes a
+ * formatted size.
+ *
+ * @param units Unit constant: "GB", "MB", "KB", "B". Must be specified
+ * unless the formatted size ends with the size marker, in
+ * which case the size marker in the formattedSize param
+ * overrides this parameter.
+ */
+AjxUtil.parseSize =
+function(formattedSize, units) {
+ // NOTE: Take advantage of fact that parseFloat ignores bad chars
+ // after numbers
+ var size = parseFloat(formattedSize.replace(/^\s*/,""));
+
+ var marker = /[GMK]?B$/i;
+ var result = marker.exec(formattedSize);
+ if (result) {
+ //alert("units: "+units+", result[0]: '"+result[0]+"'");
+ units = result[0].toUpperCase();
+ }
+
+ switch (units) {
+ case AjxUtil.SIZE_GIGABYTES: size *= 1073741824; break;
+ case AjxUtil.SIZE_MEGABYTES: size *= 1048576; break;
+ case AjxUtil.SIZE_KILOBYTES: size *= 1024; break;
+ }
+
+ //alert("AjxUtil#parseSize: formattedSize="+formattedSize+", size="+size);
+ return size;
+};
+
+AjxUtil.isInstance =
+function(aThing, aClass) {
+ return !!(aThing && aThing.constructor && (aThing.constructor === aClass));
+};
+
+AjxUtil.assert =
+function(aCondition, aMessage) {
+ if (!aCondition && AjxUtil.onassert) AjxUtil.onassert(aMessage);
+};
+
+AjxUtil.onassert =
+function(aMessage) {
+ // Create an exception object and set the message
+ var myException = new Object();
+ myException.message = aMessage;
+
+ // Compile a stack trace
+ var myStack = new Array();
+ if (AjxEnv.isIE5_5up) {
+ // On IE, the caller chain is on the arguments stack
+ var myTrace = arguments.caller;
+ while (myTrace) {
+ myStack[myStack.length] = myTrace.callee;
+ myTrace = myTrace.caller;
+ }
+ } else {
+ try {
+ var myTrace = arguments.callee.caller;
+ while (myTrace) {
+ myStack[myStack.length] = myTrace;
+ if (myStack.length > 2) break;
+ myTrace = myTrace.caller;
+ }
+ } catch (e) {
+ }
+ }
+ myException.stack = myStack;
+
+ // Alert with the message and a description of the stack
+ var stackString = '';
+ var MAX_LEN = 170;
+ for (var i = 1; i < myStack.length; i++) {
+ if (i > 1) stackString += '\n';
+ if (i < 11) {
+ var fs = myStack[i].toString();
+ if (fs.length > MAX_LEN) {
+ fs = fs.substr(0,MAX_LEN) + '...';
+ fs = fs.replace(/\n/g, '');
+ }
+ stackString += i + ': ' + fs;
+ } else {
+ stackString += '(' + (myStack.length - 11) + ' frames follow)';
+ break;
+ }
+ }
+ alert('assertion:\n\n' + aMessage + '\n\n---- Call Stack ---\n' + stackString);
+
+ // Now throw the exception
+ throw myException;
+};
+
+AjxUtil.NODE_REPEATS = new Object();
+AjxUtil.NODE_REPEATS["folder"] = true;
+AjxUtil.NODE_REPEATS["search"] = true;
+AjxUtil.NODE_REPEATS["tag"] = true;
+AjxUtil.NODE_REPEATS["pref"] = true;
+AjxUtil.NODE_REPEATS["attr"] = true;
+AjxUtil.NODE_REPEATS["c"] = true;
+AjxUtil.NODE_REPEATS["m"] = true;
+AjxUtil.NODE_REPEATS["cn"] = true;
+AjxUtil.NODE_REPEATS["e"] = true;
+AjxUtil.NODE_REPEATS["a"] = true;
+AjxUtil.NODE_REPEATS["mbx"] = true;
+//AjxUtil.NODE_REPEATS["mp"] = true; // only when parent is "mp"
+// these really shouldn't repeat
+AjxUtil.NODE_REPEATS["prefs"] = true;
+AjxUtil.NODE_REPEATS["attrs"] = true;
+AjxUtil.NODE_REPEATS["tags"] = true;
+
+AjxUtil.NODE_IS_ATTR = new Object();
+AjxUtil.NODE_IS_ATTR["authToken"] = true;
+AjxUtil.NODE_IS_ATTR["lifetime"] = true;
+AjxUtil.NODE_IS_ATTR["sessionId"] = true;
+AjxUtil.NODE_IS_ATTR["name"] = true;
+AjxUtil.NODE_IS_ATTR["quotaUsed"] = true;
+AjxUtil.NODE_IS_ATTR["su"] = true;
+AjxUtil.NODE_IS_ATTR["fr"] = true;
+AjxUtil.NODE_IS_ATTR["mid"] = true;
+//AjxUtil.NODE_IS_ATTR["content"] = true; // only when parent is "note"
+
+AjxUtil.NODE_CONTENT = new Object();
+AjxUtil.NODE_CONTENT["pref"] = true;
+AjxUtil.NODE_CONTENT["attr"] = true;
+AjxUtil.NODE_CONTENT["a"] = true;
+
+// IE doesn't define Node type constants
+AjxUtil.ELEMENT_NODE = 1;
+AjxUtil.TEXT_NODE = 3;
+
+/**
+* Convert an XML node to the equivalent JS. Traverses the node's
+* children recursively.
+* <p>
+* NOTE: This method has not been extensively tested and likely needs
+* work.
+*
+* @param node [Element] XML node
+* @param omitName [boolean] if true, don't include node name in output
+*/
+AjxUtil.xmlToJs =
+function(node, omitName) {
+
+ if (node.nodeType == AjxUtil.TEXT_NODE)
+ return ['"', node.data, '"'].join("");
+
+ var name = node.name ? node.name : node.localName;
+ if (node.nodeType == AjxUtil.ELEMENT_NODE) {
+ // if only child is text, no need for enclosing {}
+ var hasTextNode = (node.childNodes && node.childNodes.length == 1 &&
+ (node.childNodes[0].nodeType == AjxUtil.TEXT_NODE));
+ var text;
+ if (omitName) {
+ text = "{";
+ } else if (hasTextNode) {
+ text = [name, ":"].join("");
+ } else {
+ text = [name, ":{"].join("");
+ }
+ var needComma = false;
+ if (node.attributes) {
+ for (var i = 0; i < node.attributes.length; i++) {
+ var attr = node.attributes[i];
+ if (attr.name == "xmlns") continue;
+ if (needComma) text += ",";
+ var value = AjxUtil.isNumeric(attr.value) ? attr.value : AjxUtil.jsEncode(attr.value);
+ text = [text, attr.name, ':', value].join("");
+ needComma = true;
+ }
+ }
+ if (node.hasChildNodes()) {
+ var cnodes = new Object();
+ var hasChild = false;
+ for (var i = 0; i < node.childNodes.length; i++) {
+ var child = node.childNodes[i];
+ var cname = child.name ? child.name : child.localName;
+ var isAttr = AjxUtil.NODE_IS_ATTR[cname] ||
+ (name == "content" && parent.name == "note");
+ if (isAttr) {
+ if (needComma) text += ",";
+ text = [text, cname, ':', AjxUtil.jsEncode(child.textContent)].join("");
+ needComma = true;
+ } else {
+ if (!cnodes[cname])
+ cnodes[cname] = new Array();
+ cnodes[cname].push(child);
+ hasChild = true;
+ }
+ }
+ if (hasChild && needComma) {text += ","; needComma = false;}
+ for (var cname in cnodes) {
+ if (needComma) {
+ text += ",";
+ needComma = false;
+ }
+ var repeats = AjxUtil.NODE_REPEATS[cname] ||
+ (cname == "mp" && name == "mp");
+ if (repeats) text += cname + ":[";
+ var clist = cnodes[cname];
+ for (var i = 0; i < clist.length; i++) {
+ if (needComma) text += ",";
+ text += AjxUtil.xmlToJs(clist[i], repeats);
+ needComma = true;
+ }
+ if (repeats) text += "]";
+ }
+ }
+ if (!hasTextNode) text += "}";
+ }
+
+ return text;
+}
+
+AjxUtil.JS_CHAR_ENCODINGS = [
+ "\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005", "\\u0006", "\\u0007",
+ "\\b", "\\t", "\\n", "\\u000B", "\\f", "\\r", "\\u000E", "\\u000F",
+ "\\u0010", "\\u0011", "\\u0012", "\\u0013", "\\u0014", "\\u0015", "\\u0016", "\\u0017",
+ "\\u0018", "\\u0019", "\\u001A", "\\u001B", "\\u001C", "\\u001D", "\\u001E", "\\u001F"
+];
+
+AjxUtil.jsEncode =
+function(string) {
+
+ if (!string) return "\"\"";
+
+ var text = '"';
+ for (var i = 0; i < string.length; i++) {
+ var c = string.charAt(i);
+ switch (c) {
+ case '\\': case '"': case '/':
+ text += '\\' + c;
+ break;
+ default:
+ var code = string.charCodeAt(i);
+ text += (code < 32) ? AjxUtil.JS_CHAR_ENCODINGS[code] : c;
+ }
+ }
+ text += '"';
+ return text;
+};
+
+AjxUtil.getInnerText =
+function(node) {
+ if (AjxEnv.isIE)
+ return node.innerText;
+
+ function f(n) {
+ if (n) {
+ if (n.nodeType == 3 /* TEXT_NODE */)
+ return n.data;
+ if (n.nodeType == 1 /* ELEMENT_NODE */) {
+ if (/^br$/i.test(n.tagName))
+ return "\r\n";
+ var str = "";
+ for (var i = n.firstChild; i; i = i.nextSibling)
+ str += f(i);
+ return str;
+ }
+ }
+ return "";
+ };
+ return f(node);
+};
+
+/**
+ * This method returns a proxy for the specified object. This is useful when
+ * you want to modify properties of an object and want to keep those values
+ * separate from the values in the original object. You can then iterate
+ * over the proxy's properties and use the <code>hasOwnProperty</code>
+ * method to determine if the property is a new value in the proxy.
+ * <p>
+ * <strong>Note:</strong>
+ * A reference to the original object is stored in the proxy as the "_object_"
+ * property.
+ *
+ * @param object [object] The object to proxy.
+ * @param level [number] The number of property levels deep to proxy.
+ * Defaults to zero.
+ */
+AjxUtil.createProxy =
+function(object, level) {
+ var proxy;
+ var proxyCtor = function(){}; // bug #6517 (Safari doesnt like 'new Function')
+ proxyCtor.prototype = object;
+ if (object instanceof Array) {
+ proxy = new Array();
+ var cnt = object.length;
+ for(var ix = 0; ix < cnt; ix++) {
+ proxy[ix] = object[ix];
+ }
+ } else {
+ proxy = new proxyCtor;
+ }
+
+ if (level) {
+ for (var prop in object) {
+ if (typeof object[prop] == "object")
+ proxy[prop] = AjxUtil.createProxy(object[prop], level - 1);
+ }
+ }
+
+ proxy._object_ = object;
+ return proxy;
+};
+
+/**
+* Returns a copy of a list with empty members removed.
+*
+* @param list [array] original list
+*/
+AjxUtil.collapseList =
+function(list) {
+ var newList = [];
+ for (var i = 0; i < list.length; i++)
+ if (list[i])
+ newList.push(list[i]);
+ return newList;
+};
+/*
+* ***** BEGIN LICENSE BLOCK *****
+* Version: MPL 1.1
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 ("License"); you may not use this file except in
+* compliance with the License. You may obtain a copy of the License at
+* http://www.zimbra.com/license
+*
+* Software distributed under the License is distributed on an "AS IS"
+* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+* the License for the specific language governing rights and limitations
+* under the License.
+*
+* The Original Code is: Zimbra AJAX Toolkit.
+*
+* The Initial Developer of the Original Code is Zimbra, Inc.
+* Portions created by Zimbra are Copyright (C) 2005 Zimbra, Inc.
+* All Rights Reserved.
+*
+* Contributor(s):
+*
+* ***** END LICENSE BLOCK *****
+*/
+
+
+function AjxCore() {}
+
+AjxCore._objectIds = [null];
+
+
+AjxCore.assignId =
+function(anObject) {
+ var myId = AjxCore._objectIds.length;
+ AjxCore._objectIds[myId]= anObject;
+ return myId;
+};
+
+AjxCore.unassignId =
+function(anId) {
+ AjxCore._objectIds[anId]= null;
+};
+
+AjxCore.objectWithId =
+function(anId) {
+ return AjxCore._objectIds[anId];
+};
+
+/**
+ * Adds a listener to an element, for the given event name.
+ */
+AjxCore.addListener =
+function(eventSource, eventName, action) {
+ eventSource = AjxCore._getEventSource(eventSource);
+ var listenerStruct = AjxCore._getListenerStruct(eventSource, eventName, true);
+ listenerStruct.list[listenerStruct.list.length] = action;
+};
+
+/**
+ * sets a one time event handler for the given eventName.
+ */
+AjxCore.setEventHandler =
+function(eventSource, eventName, action) {
+ eventSource = AjxCore._getEventSource(eventSource);
+ var listenerStruct = AjxCore._getListenerStruct(eventSource, eventName, true);
+ listenerStruct.single = action;
+};
+
+/**
+ * removes a listener for a given event
+ */
+AjxCore.removeListener =
+function(eventSource, eventName, action) {
+ eventSource = AjxCore._getEventSource(eventSource);
+ var listenerStruct = AjxCore._getListenerStruct(eventSource, eventName);
+
+ if (listenerStruct) {
+ var listenerList = listenerStruct.list;
+ for (var i = 0; i < listenerList.length; i++) {
+ if (listenerList[i] == action)
+ listenerList[i] = null;
+ }
+ }
+};
+
+/**
+ * removes all listeners for a given eventName, and source
+ */
+AjxCore.removeAllListeners =
+function(eventSource, eventName) {
+ eventSource = AjxCore._getEventSource(eventSource);
+ var listenerStruct = AjxCore._getListenerStruct(eventSource, eventName);
+
+ if (listenerStruct) {
+ var listenerList = listenerStruct.list;
+ for (var i = 0; i < listenerList.length; i++)
+ listenerList[i] = null;
+ }
+ AjxCore.unassignId(listenerStruct.id);
+};
+
+/**
+ * notifies listeners of the event. This only needs to be called if
+ * the event is not a standard DOM event. Those types of event callbacks
+ * will be triggered by their event handlers
+ */
+AjxCore.notifyListeners =
+function(eventSource, eventName, arg1) {
+ eventSource = AjxCore._getEventSource(eventSource);
+ var listenerStruct = AjxCore._getListenerStruct(eventSource, eventName)
+ if (listenerStruct)
+ eventSource[eventName](arg1);
+};
+
+AjxCore._getEventSource =
+function(eventSource) {
+ if (typeof(eventSource) == 'string')
+ eventSource = document.getElementById(eventSource);
+ return eventSource;
+};
+
+AjxCore.getListenerStruct =
+function (eventSource, eventName) {
+ return AjxCore._getListenerStruct(eventSource, eventName);
+};
+
+/**
+ * gets the existing struct for the eventSource, or creates a new one.
+ */
+AjxCore._getListenerStruct =
+function(eventSource, eventName, create) {
+ var listenerStruct = null;
+ if (eventSource[eventName]) {
+ var id = eventSource[eventName]._lsListenerStructId;
+ listenerStruct = AjxCore.objectWithId(id);
+ } else if (create) {
+ listenerStruct = AjxCore._setupListener(eventSource, eventName);
+ }
+
+ return listenerStruct;
+};
+
+/**
+ * Creates a listener struct
+ */
+AjxCore._setupListener =
+function(eventSource, eventName, id) {
+ var listenerStruct = new Object();
+ listenerStruct.list = new Array();
+ listenerStruct.single = null;
+ var id = listenerStruct.id = AjxCore.assignId(listenerStruct);
+ var handler = AjxCore._createListenerClosure(id);
+ eventSource[eventName] = handler;
+ eventSource[eventName]._lsListenerStructId = id;
+
+ return listenerStruct;
+};
+
+AjxCore._createListenerClosure =
+function(id) {
+ var closure = function(arg1) {
+ var listenerStruct = AjxCore.objectWithId(id);
+ var listenerList = listenerStruct.list;
+ for (var i = 0; i < listenerList.length; i++) {
+ var callback = listenerList[i];
+ if (callback) {
+ if (typeof(callback) == 'string') {
+ eval(callback);
+ } else {
+ // handle AjxListener callbacks as well as simple functions
+ if (callback.handleEvent) {
+ callback.handleEvent(arg1, this);
+ } else {
+ callback(arg1, this);
+ }
+ }
+ }
+ }
+ if (listenerStruct.single) {
+ var callback = listenerStruct.single;
+ if (typeof(callback) == 'string') {
+ eval(callback);
+ } else {
+ return callback.handleEvent
+ ? callback.handleEvent(arg1, this)
+ : callback(arg1, this);
+ }
+ }
+ }
+ return closure;
+};
+
+/**
+ * Convenience method for adding onload listeners
+ */
+AjxCore.addOnloadListener =
+function(action) {
+ if (window.onload && (!window.onload._lsListenerStructId)) {
+ var priorListener = window.onload;
+ window.onload = null;
+ AjxCore.addListener(window, "onload", priorListener);
+ }
+
+ AjxCore.addListener(window, "onload", action);
+};
+
+/**
+ * Convenience method for adding onunload listeners
+ */
+AjxCore.addOnunloadListener =
+function(action) {
+ if (window.onunload && (!window.onunload._lsListenerStructId)) {
+ var priorListener = window.onunload;
+ window.onunload = null;
+ AjxCore.addListener(window, "onunload", priorListener);
+ }
+
+ AjxCore.addListener(window, "onunload", action);
+};
+/*
+* ***** BEGIN LICENSE BLOCK *****
+* Version: MPL 1.1
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 ("License"); you may not use this file except in
+* compliance with the License. You may obtain a copy of the License at
+* http://www.zimbra.com/license
+*
+* Software distributed under the License is distributed on an "AS IS"
+* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+* the License for the specific language governing rights and limitations
+* under the License.
+*
+* The Original Code is: Zimbra AJAX Toolkit.
+*
+* The Initial Developer of the Original Code is Zimbra, Inc.
+* Portions created by Zimbra are Copyright (C) 2005 Zimbra, Inc.
+* All Rights Reserved.
+*
+* Contributor(s):
+*
+* ***** END LICENSE BLOCK *****
+*/
+
+
+/* Represents a SOAP Fault
+*
+* Public attributes:
+*
+* - faultCode: The SOAP fault code
+* - reason: Reason string
+* - errorCode: server error code
+*/
+function AjxSoapFault(faultEl) {
+ if (arguments.length == 0) return;
+ var prefix = faultEl.prefix;
+ var codeStr = prefix + ":Code";
+ var reasonStr = prefix + ":Reason";
+ var detailStr = prefix + ":Detail"
+ // We will assume a correctly formatted Fault element
+ for (var i = 0; i < faultEl.childNodes.length; i++) {
+ var childNode = faultEl.childNodes[i];
+ if (childNode.nodeName == codeStr) {
+ var faultCode = childNode.firstChild.firstChild.nodeValue;
+ if (faultCode == (prefix + ":VersionMismatch"))
+ this.faultCode = AjxSoapFault.VERSION_MISMATCH;
+ else if (faultCode == (prefix + ":MustUnderstand"))
+ this.faultCode = AjxSoapFault.MUST_UNDERSTAND;
+ else if (faultCode == (prefix + ":DataEncodingUnknown"))
+ this.faultCode = AjxSoapFault.DATA_ENCODING_UNKNOWN;
+ else if (faultCode == (prefix + ":Sender"))
+ this.faultCode = AjxSoapFault.SENDER;
+ else if (faultCode == (prefix + ":Receiver"))
+ this.faultCode = AjxSoapFault.RECEIVER;
+ else
+ this.faultCode = AjxSoapFault.UNKNOWN;
+ } else if (childNode.nodeName == reasonStr) {
+ this.reason = childNode.firstChild.firstChild.nodeValue;
+ } else if (childNode.nodeName == detailStr) {
+ this.errorCode = childNode.firstChild.firstChild.firstChild.nodeValue;
+ }
+ }
+}
+
+AjxSoapFault.prototype.toString =
+function() {
+ return "AjxSoapFault";
+}
+
+AjxSoapFault.SENDER = -1;
+AjxSoapFault.RECEIVER = -2;
+AjxSoapFault.VERSION_MISMATCH = -3;
+AjxSoapFault.MUST_UNDERSTAND = -4;
+AjxSoapFault.DATA_ENCODING_UNKNOWN = -5;
+AjxSoapFault.UNKNOWN = -6;
+/*
+* ***** BEGIN LICENSE BLOCK *****
+* Version: MPL 1.1
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 ("License"); you may not use this file except in
+* compliance with the License. You may obtain a copy of the License at
+* http://www.zimbra.com/license
+*
+* Software distributed under the License is distributed on an "AS IS"
+* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+* the License for the specific language governing rights and limitations
+* under the License.
+*
+* The Original Code is: Zimbra AJAX Toolkit.
+*
+* The Initial Developer of the Original Code is Zimbra, Inc.
+* Portions created by Zimbra are Copyright (C) 2005 Zimbra, Inc.
+* All Rights Reserved.
+*
+* Contributor(s):
+*
+* ***** END LICENSE BLOCK *****
+*/
+
+
+function AjxCookie() {
+}
+
+AjxCookie.prototype.toString =
+function() {
+ return "AjxCookie";
+}
+
+AjxCookie.getCookie =
+function(doc, name) {
+ var arg = name + "=";
+ var alen = arg.length;
+ var clen = doc.cookie.length;
+ var cookie = doc.cookie;
+ var i = 0;
+ while (i < clen) {
+ var j = i + alen;
+ if (cookie.substring(i, j) == arg) {
+ var endstr = cookie.indexOf (";", j);
+ if (endstr == -1)
+ endstr = cookie.length;
+ return unescape(cookie.substring(j, endstr));
+ }
+ i = cookie.indexOf(" ", i) + 1;
+ if (i == 0)
+ break;
+ }
+ return null;
+}
+
+AjxCookie.setCookie =
+function(doc, name, value, expires, path, domain, secure) {
+ doc.cookie = name + "=" + escape (value) +
+ ((expires) ? "; expires=" + expires.toGMTString() : "") +
+ ((path) ? "; path=" + path : "") +
+ ((domain) ? "; domain=" + domain : "") +
+ ((secure) ? "; secure" : "");
+}
+
+AjxCookie.deleteCookie =
+function (doc, name, path, domain) {
+ doc.cookie = name + "=" +
+ ((path) ? "; path=" + path : "") +
+ ((domain) ? "; domain=" + domain : "") + "; expires=Fri, 31 Dec 1999 23:59:59 GMT";
+}
+/*
+* ***** BEGIN LICENSE BLOCK *****
+* Version: MPL 1.1
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 ("License"); you may not use this file except in
+* compliance with the License. You may obtain a copy of the License at
+* http://www.zimbra.com/license
+*
+* Software distributed under the License is distributed on an "AS IS"
+* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+* the License for the specific language governing rights and limitations
+* under the License.
+*
+* The Original Code is: Zimbra AJAX Toolkit.
+*
+* The Initial Developer of the Original Code is Zimbra, Inc.
+* Portions created by Zimbra are Copyright (C) 2005 Zimbra, Inc.
+* All Rights Reserved.
+*
+* Contributor(s):
+*
+* ***** END LICENSE BLOCK *****
+*/
+
+
+function AjxSoapException(msg, code, method, detail) {
+ AjxException.call(this, msg, code, method, detail);
+}
+
+AjxSoapException.prototype.toString =
+function() {
+ return "AjxSoapException";
+}
+
+AjxSoapException.prototype = new AjxException;
+AjxSoapException.prototype.constructor = AjxSoapException;
+
+AjxSoapException.INTERNAL_ERROR = "INTERNAL_ERROR";
+AjxSoapException.INVALID_PDU = "INVALID_PDU";
+AjxSoapException.ELEMENT_EXISTS = "ELEMENT_EXISTS";
+/*
+* ***** BEGIN LICENSE BLOCK *****
+* Version: MPL 1.1
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 ("License"); you may not use this file except in
+* compliance with the License. You may obtain a copy of the License at
+* http://www.zimbra.com/license
+*
+* Software distributed under the License is distributed on an "AS IS"
+* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+* the License for the specific language governing rights and limitations
+* under the License.
+*
+* The Original Code is: Zimbra AJAX Toolkit.
+*
+* The Initial Developer of the Original Code is Zimbra, Inc.
+* Portions created by Zimbra are Copyright (C) 2005 Zimbra, Inc.
+* All Rights Reserved.
+*
+* Contributor(s):
+*
+* ***** END LICENSE BLOCK *****
+*/
+
+
+/**
+* Creates a callback which consists of at least a function reference, and possibly also
+* an object to call it from.
+* @constructor
+* @class
+* This class represents a callback function which can be called standalone, or from a
+* given object. What the callback takes as arguments and what it returns are left to the
+* client.
+*
+* @author Conrad Damon
+* @param obj [Object] the object to call the function from
+* @param func [function] the callback function
+* @param args [primitive or Array] default arguments
+*/
+function AjxCallback(obj, func, args) {
+ if (arguments.length == 0) return;
+
+ this.obj = obj;
+ this.func = func;
+ this.args = args;
+}
+
+AjxCallback.prototype.toString =
+function() {
+ return "AjxCallback";
+}
+
+/**
+* Runs the callback function, from within the object if there is one. The
+* called function passed arguments are the concatenation of the argument
+* array passed to this object's constructor and the argument array passed
+* to the <code>run</code> method. Whatever the called function returns is
+* returned to the caller.
+*
+* @param arg1 The first argument which will be appended to the argument
+* array passed to this object's constructor. Any number of
+* arguments may be passed to the <code>run</code> method.
+*/
+AjxCallback.prototype.run =
+function(/* arg1 ... argN */) {
+ // combine original args with new ones
+ var args = [];
+
+ // sometimes we want to pass a null or false argument, so simply
+ // checking for if (this.args) won't do.
+ if (typeof this.args != "undefined") {
+ if (this.args instanceof Array)
+ // NOTE: We must NOT use this.args directly if this method's
+ // params are gonna be pushed onto the array because it
+ // will change the original args!
+ args = arguments.length > 0 ? args.concat(this.args) : this.args;
+ else
+ args.push(this.args);
+ }
+
+ for (var i = 0; i < arguments.length; ++i)
+ args.push(arguments[i]);
+
+ // invoke function
+ return this.func.apply(this.obj || window, args);
+};
+
+/**
+ * The following function is what an AjxCallback should be *all* about. It
+ * returns a plain function that will call your supplied "func" in the context
+ * of "obj" and pass to it, in this order, any additional arguments that you
+ * pass to simpleClosure and the arguments that were passed to it at the call
+ * time.
+ *
+ * An example should do:
+ *
+ * div.onclick = AjxCallback.simpleClosure(this.handler, this, "some data");
+ * ...
+ * this.handler = function(data, event) {
+ * // event will be passed for DOM2 compliant browsers
+ * // and data is "some data"
+ * };
+ *
+ * [this is one of the most useful functions I ever wrote :D -mihai@zimbra.com]
+ */
+AjxCallback.simpleClosure = function(func, obj) {
+ var args = [];
+ for (var i = 2; i < arguments.length; ++i)
+ args.push(arguments[i]);
+ return function() {
+ var args2 = [];
+ for (var i = 0; i < arguments.length; ++i)
+ args2.push(arguments[i]);
+ func.apply(obj || this, args.concat(args2));
+ };
+};
+/*
+* ***** BEGIN LICENSE BLOCK *****
+* Version: MPL 1.1
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 ("License"); you may not use this file except in
+* compliance with the License. You may obtain a copy of the License at
+* http://www.zimbra.com/license
+*
+* Software distributed under the License is distributed on an "AS IS"
+* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+* the License for the specific language governing rights and limitations
+* under the License.
+*
+* The Original Code is: Zimbra AJAX Toolkit.
+*
+* The Initial Developer of the Original Code is Zimbra, Inc.
+* Portions created by Zimbra are Copyright (C) 2005 Zimbra, Inc.
+* All Rights Reserved.
+*
+* Contributor(s):
+*
+* ***** END LICENSE BLOCK *****
+*/
+
+
+/**
+ * This requires an "owner" which is the object that owns the full set of items, implmenting:
+ * getItemCount() to return the number of items
+ * getItem(index) to return the item at a given index.
+ *
+ * And optionally implementing
+ * itemSelectionChanged(item, index, isSelected) which is called
+ * for each item that is selected or deselected
+ * selectionChanged() which is called after a batch of items have
+ * been selected or deselected with select()
+ *
+ */
+
+AjxSelectionManager = function(anOwner) {
+ this._owner = anOwner;
+};
+
+// -----------------------------------------------------------
+// Constants
+// -----------------------------------------------------------
+
+// Actions for select()
+AjxSelectionManager.SELECT_ONE_CLEAR_OTHERS = 0;
+AjxSelectionManager.TOGGLE_ONE_LEAVE_OTHERS = 1;
+AjxSelectionManager.SELECT_TO_ANCHOR = 2;
+AjxSelectionManager.DESELECT_ALL = 3;
+AjxSelectionManager.SELECT_ALL = 4;
+
+// -----------------------------------------------------------
+// API Methods
+// -----------------------------------------------------------
+
+/**
+ * returns an AjxVector
+ */
+AjxSelectionManager.prototype.getItems = function() {
+ if (this._selectedItems == null) {
+ this._selectedItems = this._createItemsCollection();
+ }
+ return this._selectedItems;
+};
+
+/**
+ * returns the number of selected items
+ */
+AjxSelectionManager.prototype.getLength = function() {
+ return this.getItems().length;
+};
+
+/**
+ * returns the anchor, unless nothing is selected
+ */
+AjxSelectionManager.prototype.getAnchor = function() {
+ if (this._anchor == null) {
+ var items = this.getItems();
+ if (items.length > 0) {
+ this._anchor = items[0];
+ }
+ }
+ return this._anchor;
+};
+
+/**
+ * The cursor probably changes when the users navigates with
+ * the keyboard. This returns the item that is currently the cursor,
+ * and null if nothing is selected.
+ */
+AjxSelectionManager.prototype.getCursor = function() {
+ if (this._cursor == null) {
+ this._cursor = this.getAnchor();
+ }
+ return this._cursor;
+};
+
+
+/**
+ * Returns true if the given item is selected.
+ */
+AjxSelectionManager.prototype.isSelected = function(item) {
+ return this.getItems().binarySearch(item) != -1;
+};
+
+AjxSelectionManager.prototype.selectOneItem = function(item) {
+ this.select(item, AjxSelectionManager.SELECT_ONE_CLEAR_OTHERS);
+};
+
+AjxSelectionManager.prototype.toggleItem = function(item) {
+ this.select(item, AjxSelectionManager.TOGGLE_ONE_LEAVE_OTHERS);
+};
+
+AjxSelectionManager.prototype.selectFromAnchorToItem = function(item) {
+ this.select(item, AjxSelectionManager.SELECT_TO_ANCHOR);
+};
+
+AjxSelectionManager.prototype.deselectAll = function() {
+ this.select(null, AjxSelectionManager.DESELECT_ALL);
+};
+
+AjxSelectionManager.prototype.selectAll = function() {
+ this.select(null, AjxSelectionManager.SELECT_ALL);
+};
+
+
+/**
+ * This method will notify the owner of any changes by calling
+ * itemSelectionChanged() (if the owner defines it) for each item whose
+ * selection changes and also by calling selectionChanged() (if the
+ * owner defines it) once at the end, if anything changed selection.
+ *
+ */
+AjxSelectionManager.prototype.select = function(item, action) {
+
+ // Update the anchor and cursor, if necessary
+ this._setAnchorAndCursor(item, action);
+
+ // save off the old set of selected items
+ var oldItems = this._selectedItems;
+ var oldItemsCount = (oldItems == null) ? 0 : oldItems.length;
+
+ // create a fresh set of selected items
+ this._selectedItems = null;
+ this._selectedItems = this._createItemsCollection();
+
+ // Now update the selection
+ var itemCount = this._owner.getItemCount();
+ var needsSort = false;
+ var selectionChanged = false;
+ var selecting = false;
+ for (var i = 0; i < itemCount; ++i) {
+ var testItem = this._owner.getItem(i);
+ var oldSelectionExists = this._isItemOldSelection(testItem, oldItems);
+ var newSelectionExists = oldSelectionExists;
+
+ switch (action) {
+ case AjxSelectionManager.SELECT_TO_ANCHOR:
+ if (this._anchor == null) {
+ // If we have no anchor, let it be the first item
+ // in the list
+ this._anchor = testItem;
+ }
+ var atEdge = (testItem == this._anchor || testItem == item);
+ var changed = false;
+ // mark the beginning of the selection for the iteration
+ if (!selecting && atEdge) {
+ selecting = true;
+ changed = true;
+ }
+ newSelectionExists = selecting;
+ // mark the end of the selection if we're there
+ if ((!changed || this._anchor == item)
+ && selecting && atEdge) {
+ selecting = false;
+ }
+
+ break;
+ case AjxSelectionManager.SELECT_ONE_CLEAR_OTHERS:
+ newSelectionExists = (testItem == item);
+ break;
+ case AjxSelectionManager.TOGGLE_ONE_LEAVE_OTHERS:
+ if (testItem == item) {
+ newSelectionExists = !oldSelectionExists ;
+ }
+ break;
+ case AjxSelectionManager.DESELECT_ALL:
+ newSelectionExists = false;
+ break;
+ case AjxSelectionManager.SELECT_ALL:
+ newSelectionExists = true;
+ break;
+ }
+
+ if (newSelectionExists) {
+ this._selectedItems.add(testItem);
+ needsSort = (this._selectedItems.length > 1);
+ }
+
+ if ( newSelectionExists != oldSelectionExists) {
+ // Something changed so notify the owner.
+ if (this._owner.itemSelectionChanged != null) {
+ this._owner.itemSelectionChanged(testItem,
+ i, newSelectionExists);
+ }
+ selectionChanged = true;
+ }
+ }
+ selectionChanged = selectionChanged || (oldItemsCount !=
+ this._selectedItems.length);
+
+ if (needsSort) this._selectedItems.sort();
+
+ if (selectionChanged && this._owner.selectionChanged != null) {
+ this._owner.selectionChanged(item);
+ }
+};
+
+/**
+ * Remove an item from the selection managers selected items
+ * collection if it exists.
+ */
+AjxSelectionManager.prototype.removeItem = function(item) {
+ if (this._selectedItems) {
+ var index = this._selectedItems.binarySearch(item);
+ if (index > -1) this._selectedItems.removeAt(index);
+ }
+};
+
+// -----------------------------------------------------------
+// Internal Methods
+// -----------------------------------------------------------
+
+/**
+ * Creates an array suitable for use as the sorted list of selected
+ * items and returns it.
+ */
+AjxSelectionManager.prototype._createItemsCollection = function() {
+ return new AjxVector();
+};
+
+AjxSelectionManager.prototype._isItemOldSelection = function (testItem, oldItems) {
+ var ret = false;
+ if (oldItems) {
+ var oldSelectionIndex = oldItems.binarySearch(testItem);
+ if (oldSelectionIndex > -1) {
+ oldItems.removeAt(oldSelectionIndex);
+ }
+ ret = (oldSelectionIndex != -1);
+ }
+ return ret;
+};
+
+AjxSelectionManager.prototype._setAnchorAndCursor = function (item, action) {
+ switch (action) {
+ case AjxSelectionManager.SELECT_TO_ANCHOR:
+ this._cursor = item;
+ break;
+ case AjxSelectionManager.SELECT_ONE_CLEAR_OTHERS:
+ this._anchor = item;
+ this._cursor = item;
+ break;
+ case AjxSelectionManager.TOGGLE_ONE_LEAVE_OTHERS:
+ this._anchor = item;
+ this._cursor = item;
+ break;
+ case AjxSelectionManager.DESELECT_ALL:
+ this._anchor = null;
+ this._cursor = null;
+ break;
+ case AjxSelectionManager.SELECT_ALL:
+ return;
+ }
+};
+/*
+* ***** BEGIN LICENSE BLOCK *****
+* Version: MPL 1.1
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 ("License"); you may not use this file except in
+* compliance with the License. You may obtain a copy of the License at
+* http://www.zimbra.com/license
+*
+* Software distributed under the License is distributed on an "AS IS"
+* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+* the License for the specific language governing rights and limitations
+* under the License.
+*
+* The Original Code is: Zimbra AJAX Toolkit.
+*
+* The Initial Developer of the Original Code is Zimbra, Inc.
+* Portions created by Zimbra are Copyright (C) 2005 Zimbra, Inc.
+* All Rights Reserved.
+*
+* Contributor(s):
+*
+* ***** END LICENSE BLOCK *****
+*/
+
+
+// Don't directly instantiate SoapDoc, use one of the create factory methods instead
+function AjxSoapDoc() {
+}
+
+AjxSoapDoc.prototype.toString =
+function() {
+ return "AjxSoapDoc";
+};
+
+AjxSoapDoc._SOAP_URI = "http://www.w3.org/2003/05/soap-envelope";
+// AjxSoapDoc._SOAP_URI = "http://schemas.xmlsoap.org/soap/envelope/";
+AjxSoapDoc._XMLNS_URI = "http://www.w3.org/2000/xmlns";
+
+AjxSoapDoc.create =
+function(method, namespace, namespaceId, soapURI) {
+ var sd = new AjxSoapDoc();
+ sd._xmlDoc = AjxXmlDoc.create();
+ var d = sd._xmlDoc.getDoc();
+ var envEl = d.createElement("soap:Envelope");
+
+ if (!soapURI)
+ soapURI = AjxSoapDoc._SOAP_URI;
+ envEl.setAttribute("xmlns:soap", soapURI);
+
+ d.appendChild(envEl);
+
+ var bodyEl = d.createElement("soap:Body");
+ envEl.appendChild(bodyEl);
+
+ sd._methodEl = d.createElement(method);
+ if (namespaceId == null)
+ sd._methodEl.setAttribute("xmlns", namespace);
+ else
+ sd._methodEl.setAttribute("xmlns:" + namespaceId, namespace);
+
+ bodyEl.appendChild(sd._methodEl);
+ return sd;
+};
+
+AjxSoapDoc.createFromDom =
+function(doc) {
+ var sd = new AjxSoapDoc();
+ sd._xmlDoc = AjxXmlDoc.createFromDom(doc);
+ sd._methodEl = sd._check(sd._xmlDoc);
+ return sd;
+};
+
+AjxSoapDoc.createFromXml =
+function(xml) {
+ var sd = new AjxSoapDoc();
+ sd._xmlDoc = AjxXmlDoc.createFromXml(xml);
+ sd._methodEl = sd._check(sd._xmlDoc);
+ return sd;
+};
+
+AjxSoapDoc.element2FaultObj =
+function(el) {
+ // If the element is not a SOAP fault, then return null
+ var faultEl = el.firstChild;
+ // Safari is bad at handling namespaces
+ if (!AjxEnv.isSafari) {
+ if (faultEl != null && faultEl.namespaceURI != AjxSoapDoc._SOAP_URI || faultEl.nodeName != (el.prefix + ":Fault"))
+ return null;
+ } else {
+ if (faultEl != null && faultEl.nodeName != (el.prefix + ":Fault"))
+ return null;
+ }
+ return new AjxSoapFault(faultEl);
+};
+
+AjxSoapDoc.prototype.setMethodAttribute =
+function(name, value) {
+ this._methodEl.setAttribute(name, value);
+};
+
+/**
+ * Creates arguments to pass within the envelope. "value" can be a JS object
+ * or a scalar (string, number, etc.).
+ *
+ * When "value" is a JS object, set() will call itself recursively in order to
+ * create a complex data structure. Don't pass a "way-too-complicated" object
+ * ("value" should only contain references to simple JS objects, or better put,
+ * hashes--don't include a reference to the "window" object as it will kill
+ * your browser).
+ *
+ * Example:
+ *
+ * soapDoc.set("user_auth", {
+ * user_name : "foo",
+ * password : "bar"
+ * });
+ *
+ * will create an XML like this under the method tag:
+ *
+ * <user_auth>
+ * <user_name>foo</user_name>
+ * <password>bar</password>
+ * </user_auth>
+ *
+ * Of course, nesting other hashes is allowed and will work as expected.
+ *
+ * NOTE: you can pass null for "name", in which case "value" is expected to be
+ * an object whose properties will be created directly under the method el.
+ */
+AjxSoapDoc.prototype.set =
+function(name, value, parent) {
+ var doc = this.getDoc();
+ var p = name
+ ? doc.createElement(name)
+ : doc.createDocumentFragment();
+
+ if (value != null) {
+ if (typeof value == "object") {
+ for (i in value)
+ this.set(i, value[i], p);
+ } else {
+ if (AjxEnv.isSafari) value = AjxStringUtil.xmlEncode(value);
+ p.appendChild(doc.createTextNode(value));
+ }
+ }
+ if (!parent)
+ parent = this._methodEl;
+ return parent.appendChild(p);
+};
+
+AjxSoapDoc.prototype.getMethod =
+function() {
+ return this._methodEl;
+};
+
+AjxSoapDoc.prototype.createHeaderElement =
+function() {
+ var d = this._xmlDoc.getDoc();
+ var envEl = d.firstChild;
+ var header = this.getHeader();
+ if (header != null) {
+ throw new AjxSoapException("SOAP header already exists", AjxSoapException.ELEMENT_EXISTS, "AjxSoapDoc.prototype.createHeaderElement");
+ }
+ header = d.createElement("soap:Header")
+ envEl.insertBefore(header, envEl.firstChild);
+ return header;
+};
+
+AjxSoapDoc.prototype.getHeader =
+function() {
+ // would love to use getElementsByTagNameNS, but IE does not support it
+ var d = this._xmlDoc.getDoc();
+ var nodeList = AjxEnv.isIE
+ ? (d.getElementsByTagName(d.firstChild.prefix + ":Header"))
+ : (d.getElementsByTagNameNS(AjxSoapDoc._SOAP_URI, "Header"));
+
+ return nodeList ? nodeList[0] : null;
+};
+
+AjxSoapDoc.prototype.getBody =
+function() {
+ // would love to use getElementsByTagNameNS, but IE does not support it
+ var d = this._xmlDoc.getDoc();
+ var nodeList = AjxEnv.isIE
+ ? (d.getElementsByTagName(d.firstChild.prefix + ":Body"))
+ : (d.getElementsByTagNameNS(AjxSoapDoc._SOAP_URI, "Body"));
+
+ return nodeList ? nodeList[0] : null;
+};
+
+AjxSoapDoc.prototype.getByTagName =
+function(type) {
+ if (type.indexOf(":") == -1)
+ type = "soap:" + type;
+
+ var a = this.getDoc().getElementsByTagName(type);
+
+ if (a.length == 1) return a[0];
+ else if (a.length > 0) return a;
+ else return null;
+};
+
+// gimme a header, no exceptions.
+AjxSoapDoc.prototype.ensureHeader =
+function() {
+ return (this.getByTagName("Header") || this.createHeaderElement());
+};
+
+AjxSoapDoc.prototype.getDoc =
+function() {
+ return this._xmlDoc.getDoc();
+};
+
+AjxSoapDoc.prototype.getXml =
+function() {
+ return AjxEnv.isSafari
+ ? (AjxXmlDoc.getXml(this._xmlDoc.getDoc()))
+ : this._xmlDoc.getDoc().xml;
+};
+
+// Very simple checking of soap doc. Should be made more comprehensive
+AjxSoapDoc.prototype._check =
+function(xmlDoc) {
+ var doc = xmlDoc.getDoc();
+ if (doc.childNodes.length != 1)
+ throw new AjxSoapException("Invalid SOAP PDU", AjxSoapException.INVALID_PDU, "AjxSoapDoc.createFromXml:1");
+
+ // Check to make sure we have a soap envelope
+ var el = doc.firstChild;
+
+ // Safari is bad at handling namespaces
+ if (!AjxEnv.isSafari) {
+ if (el.namespaceURI != AjxSoapDoc._SOAP_URI ||
+ el.nodeName != (el.prefix + ":Envelope") ||
+ (el.childNodes.length < 1 || el.childNodes.length > 2))
+ {
+ DBG.println("<font color=red>XML PARSE ERROR on RESPONSE:</font>");
+ DBG.printRaw(doc.xml);
+ throw new AjxSoapException("Invalid SOAP PDU", AjxSoapException.INVALID_PDU, "AjxSoapDoc.createFromXml:2");
+ }
+ } else {
+ if (el.nodeName != (el.prefix + ":Envelope"))
+ throw new AjxSoapException("Invalid SOAP PDU", AjxSoapException.INVALID_PDU, "AjxSoapDoc.createFromXml:2");
+ }
+};
+/*
+* ***** BEGIN LICENSE BLOCK *****
+* Version: MPL 1.1
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 ("License"); you may not use this file except in
+* compliance with the License. You may obtain a copy of the License at
+* http://www.zimbra.com/license
+*
+* Software distributed under the License is distributed on an "AS IS"
+* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+* the License for the specific language governing rights and limitations
+* under the License.
+*
+* The Original Code is: Zimbra AJAX Toolkit.
+*
+* The Initial Developer of the Original Code is Zimbra, Inc.
+* Portions created by Zimbra are Copyright (C) 2005 Zimbra, Inc.
+* All Rights Reserved.
+*
+* Contributor(s):
+*
+* ***** END LICENSE BLOCK *****
+*/
+
+
+/**
+* Creates a new AjxRpcRequest. The request object is an ActiveX object
+* for IE, and an XMLHttpRequest object otherwise.
+* @constructor
+* @class
+* This class represents an XML HTTP request, hiding differences between
+* browsers. The internal request object depends on the browser.
+*
+* @param id [string] unique ID for this request
+* @param ctxt [_RpcCtxt] owning context
+**/
+function AjxRpcRequest(id, ctxt) {
+ if (!AjxRpcRequest._inited)
+ AjxRpcRequest._init();
+
+ this.id = id;
+ this.ctxt = ctxt;
+ if (AjxEnv.isIE) {
+ this._httpReq = new ActiveXObject(AjxRpcRequest._msxmlVers);
+ } else if (AjxEnv.isSafari || AjxEnv.isNav) {
+ this._httpReq = new XMLHttpRequest();
+ }
+};
+
+AjxRpcRequest._inited = false;
+AjxRpcRequest._msxmlVers = null;
+
+AjxRpcRequest.prototype.toString =
+function() {
+ return "AjxRpcRequest";
+};
+
+/**
+* Sends this request to the target URL. If there is a callback, the request is
+* performed asynchronously.
+*
+* @param requestStr [string] HTTP request string/document
+* @param serverUrl [string] request target
+* @param requestHeaders [Array]* HTTP request headers
+* @param callback [AjxCallback]* callback (for async requests)
+* @param useGet [boolean]* if true use GET method, else use POST
+*/
+AjxRpcRequest.prototype.invoke =
+function(requestStr, serverUrl, requestHeaders, callback, useGet, timeout) {
+
+ var asyncMode = (callback != null);
+
+ // exception here will be caught by AjxRpc.invoke
+ this._httpReq.open((useGet) ? "get" : "post", serverUrl, asyncMode);
+
+ if (asyncMode) {
+ this._callback = callback;
+ var tempThis = this;
+ DBG.println(AjxDebug.DBG3, "Async RPC request");
+ this._httpReq.onreadystatechange = function(ev) {AjxRpcRequest._handleResponse(tempThis, callback);};
+ } else {
+ // IE appears to run handler even on sync requests, so we need to clear it
+ this._httpReq.onreadystatechange = function(ev) {};
+ }
+
+ if (requestHeaders) {
+ for (var i in requestHeaders) {
+ this._httpReq.setRequestHeader(i, requestHeaders[i]);
+ DBG.println(AjxDebug.DBG3, "Async RPC request: Add header " + i + " - " + requestHeaders[i]);
+ }
+ }
+
+ this._httpReq.send(requestStr);
+ if (asyncMode) {
+ return this.id;
+ } else {
+ if (this._httpReq.status == 200) {
+ return {text: this._httpReq.responseText, xml: this._httpReq.responseXML, success: true};
+ } else {
+ return {text: this._httpReq.responseText, xml: this._httpReq.responseXML, success: false, status: this._httpReq.status};
+ }
+ }
+};
+
+/*
+* Handler that runs when an asynchronous response has been received. It runs a
+* callback to initiate the response handling.
+*
+* @param req [AjxRpcRequest] request that generated the response
+* @param callback [AjxCallback] callback to run after response is received
+*/
+AjxRpcRequest._handleResponse =
+function(req, callback) {
+ if (!req) {
+ // If IE receives a 500 error, the object reference can be lost
+ DBG.println(AjxDebug.DBG1, "Async RPC request: Lost request object!!!");
+ callback.run( {text: null, xml: null, success: false, status: 500} );
+ return;
+ }
+
+ DBG.println(AjxDebug.DBG3, "Async RPC request: ready state = " + req._httpReq.readyState);
+ if (req._httpReq.readyState == 4) {
+ if (DBG.getDebugLevel() >= AjxDebug.DBG3)
+ DBG.println("Async RPC request: HTTP status = " + req._httpReq.status);
+ if (req._httpReq.status == 200) {
+ callback.run( {text: req._httpReq.responseText, xml: req._httpReq.responseXML, success: true} );
+ } else {
+ callback.run( {text: req._httpReq.responseText, xml: req._httpReq.responseXML, success: false, status: req._httpReq.status} );
+ }
+ req.ctxt.busy = false;
+ }
+};
+
+AjxRpcRequest.prototype.cancel =
+function() {
+ DBG.println(AjxDebug.DBG1, "Aborting HTTP request");
+ this._httpReq.abort();
+};
+
+AjxRpcRequest._init =
+function() {
+ if (AjxEnv.isIE) {
+ var msxmlVers = ["MSXML2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"];
+ for (var i = 0; i < msxmlVers.length; i++) {
+ try {
+ // search for the xml version on user's machine
+ var x = new ActiveXObject(msxmlVers[i]);
+ AjxRpcRequest._msxmlVers = msxmlVers[i];
+ break;
+ } catch (ex) {
+ // do nothing
+ }
+ }
+ if (AjxRpcRequest._msxmlVers == null)
+ throw new AjxException("MSXML not installed", AjxException.INTERNAL_ERROR, "AjxRpc._init");
+ }
+ AjxRpcRequest._inited = true;
+};
+/*
+* ***** BEGIN LICENSE BLOCK *****
+* Version: MPL 1.1
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 ("License"); you may not use this file except in
+* compliance with the License. You may obtain a copy of the License at
+* http://www.zimbra.com/license
+*
+* Software distributed under the License is distributed on an "AS IS"
+* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+* the License for the specific language governing rights and limitations
+* under the License.
+*
+* The Original Code is: Zimbra AJAX Toolkit.
+*
+* The Initial Developer of the Original Code is Zimbra, Inc.
+* Portions created by Zimbra are Copyright (C) 2005 Zimbra, Inc.
+* All Rights Reserved.
+*
+* Contributor(s):
+*
+* ***** END LICENSE BLOCK *****
+*/
+
+
+function DwtHtmlEditorStateEvent(init) {
+ if (arguments.length == 0) return;
+ DwtEvent.call(this, true);
+ this.reset();
+}
+
+DwtHtmlEditorStateEvent.prototype = new DwtEvent;
+DwtHtmlEditorStateEvent.prototype.constructor = DwtHtmlEditorStateEvent;
+
+DwtHtmlEditorStateEvent.prototype.toString =
+function() {
+ return "DwtHtmlEditorStateEvent";
+}
+
+DwtHtmlEditorStateEvent.prototype.reset =
+function() {
+ this.isBold = null;
+ this.isItalic = null;
+ this.isUnderline = null;
+ this.isStrikeThru = null;
+ this.isSuperscript = null;
+ this.isSubscript = null;
+ this.isOrderedList = null;
+ this.isNumberedList = null;
+ this.fontName = null;
+ this.fontSize = null;
+ this.style = null;
+ this.backgroundColor = null;
+ this.color = null;
+ this.justification = null;
+ this.direction = null;
+}
+/*
+* ***** BEGIN LICENSE BLOCK *****
+* Version: MPL 1.1
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 ("License"); you may not use this file except in
+* compliance with the License. You may obtain a copy of the License at
+* http://www.zimbra.com/license
+*
+* Software distributed under the License is distributed on an "AS IS"
+* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+* the License for the specific language governing rights and limitations
+* under the License.
+*
+* The Original Code is: Zimbra AJAX Toolkit.
+*
+* The Initial Developer of the Original Code is Zimbra, Inc.
+* Portions created by Zimbra are Copyright (C) 2005 Zimbra, Inc.
+* All Rights Reserved.
+*
+* Contributor(s):
+*
+* ***** END LICENSE BLOCK *****
+*/
+
+
+function DwtKeyEvent() {
+ DwtUiEvent.call(this, true);
+ this.reset(true);
+}
+
+
+DwtKeyEvent.KEY_END_OF_TEXT = 0x03;
+DwtKeyEvent.KEY_TAB = 0x09;
+DwtKeyEvent.KEY_RETURN = 0x0D;
+DwtKeyEvent.KEY_ENTER = 0x0D;
+DwtKeyEvent.KEY_ESCAPE = 0x1B;
+
+DwtKeyEvent.prototype = new DwtUiEvent;
+DwtKeyEvent.prototype.constructor = DwtKeyEvent;
+
+DwtKeyEvent.prototype.toString =
+function() {
+ return "DwtKeyEvent";
+}
+
+DwtKeyEvent.isKeyEvent =
+function(ev) {
+ return (ev.type.search(/^key/i) != -1);
+}
+
+DwtKeyEvent.isKeyPressEvent =
+function(ev) {
+ return (AjxEnv.isIE && ev.type == "keydown") || (ev.type == "keypress");
+}
+
+DwtKeyEvent.prototype.reset =
+function(dontCallParent) {
+ if (!dontCallParent)
+ DwtUiEvent.prototype.reset.call(this);
+ this.keyCode = 0;
+ this.charCode = 0;
+}
+
+
+DwtKeyEvent.prototype.setFromDhtmlEvent =
+function(ev) {
+ ev = DwtUiEvent.prototype.setFromDhtmlEvent.call(this, ev);
+ this.charCode = (ev.charCode) ? ev.charCode : ev.keyCode;
+ this.keyCode = ev.keyCode;
+}
+
+DwtKeyEvent.getCharCode =
+function(ev) {
+ ev = DwtUiEvent.getEvent(ev);
+ return AjxEnv.isSafari ? ev.keyCode : (ev.charCode || ev.keyCode);
+}
+
+DwtKeyEvent.copy =
+function(dest, src) {
+ DwtUiEvent.copy(dest, src);
+ dest.charCode = src.charCode;
+ dest.keyCode = src.keyCode;
+}
+/*
+* ***** BEGIN LICENSE BLOCK *****
+* Version: MPL 1.1
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 ("License"); you may not use this file except in
+* compliance with the License. You may obtain a copy of the License at
+* http://www.zimbra.com/license
+*
+* Software distributed under the License is distributed on an "AS IS"
+* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+* the License for the specific language governing rights and limitations
+* under the License.
+*
+* The Original Code is: Zimbra AJAX Toolkit.
+*
+* The Initial Developer of the Original Code is Zimbra, Inc.
+* Portions created by Zimbra are Copyright (C) 2005 Zimbra, Inc.
+* All Rights Reserved.
+*
+* Contributor(s):
+*
+* ***** END LICENSE BLOCK *****
+*/
+
+
+function DwtListView(parent, className, posStyle, headerList, noMaximize) {
+
+ if (arguments.length == 0) return;
+ className = className || "DwtListView";
+ DwtComposite.call(this, parent, className, posStyle);
+
+ if (headerList) {
+ var htmlElement = this.getHtmlElement();
+
+ this._listColDiv = document.createElement("div");
+ this._listColDiv.id = Dwt.getNextId();
+ this._listColDiv.className = "DwtListView-ColHeader";
+ htmlElement.appendChild(this._listColDiv);
+
+ this._listDiv = document.createElement("div");
+ this._listDiv.id = Dwt.getNextId();
+ this._listDiv.className = "DwtListView-Rows";
+ htmlElement.appendChild(this._listDiv);
+
+ // setup vars needed for sorting
+ this._bSortAsc = false;
+ this._currentColId = null;
+ this._sortingEnabled = true;
+ } else {
+ this.setScrollStyle(DwtControl.SCROLL); // auto scroll
+ }
+
+ this._setMouseEventHdlrs();
+ this.setCursor("default");
+
+ this._listenerMouseOver = new AjxListener(this, this._mouseOverListener);
+ this._listenerMouseOut = new AjxListener(this, this._mouseOutListener);
+ this._listenerMouseDown = new AjxListener(this, this._mouseDownListener);
+ this._listenerMouseUp = new AjxListener(this, this._mouseUpListener);
+ this._listenerMouseMove = new AjxListener(this, this._mouseMoveListener);
+ this._listenerDoubleClick = new AjxListener(this, this._doubleClickListener);
+ this.addListener(DwtEvent.ONMOUSEOVER, this._listenerMouseOver);
+ this.addListener(DwtEvent.ONMOUSEOUT, this._listenerMouseOut);
+ this.addListener(DwtEvent.ONMOUSEDOWN, this._listenerMouseDown);
+ this.addListener(DwtEvent.ONMOUSEUP, this._listenerMouseUp);
+ this.addListener(DwtEvent.ONMOUSEMOVE, this._listenerMouseMove);
+ this.addListener(DwtEvent.ONDBLCLICK, this._listenerDoubleClick);
+
+ this._evtMgr = new AjxEventMgr();
+ this._selectedItems = new AjxVector();
+ this._selAnchor = null;
+ this._selEv = new DwtSelectionEvent(true);
+ this._actionEv = new DwtListViewActionEvent(true);
+ this._stateChangeEv = new DwtEvent(true);
+ this._headerList = headerList;
+ this._noMaximize = noMaximize;
+ this._parentEl = this._headerList ? this._listDiv : this.getHtmlElement();
+
+ this._list = null;
+ this._offset = 0;
+ this._headerColCreated = false;
+ this._firstSelIndex = -1;
+
+ this.setMultiSelect(true);
+}
+
+DwtListView.ITEM_SELECTED = 1;
+DwtListView.ITEM_DESELECTED = 2;
+DwtListView.ITEM_DBL_CLICKED = 3;
+DwtListView._LAST_REASON = 3;
+
+DwtListView._TOOLTIP_DELAY = 250;
+
+DwtListView.HEADERITEM_HEIGHT = 24;
+DwtListView.HEADERITEM_ARROW = "arr--";
+DwtListView.HEADER_ID = "crr--";
+DwtListView.HEADERITEM_LABEL = "drr--";
+
+DwtListView.TYPE_HEADER_ITEM = "1";
+DwtListView.TYPE_LIST_ITEM = "2";
+DwtListView.TYPE_HEADER_SASH = "3";
+
+DwtListView.DEFAULT_LIMIT = 25;
+DwtListView.MAX_REPLENISH_THRESHOLD = 10;
+DwtListView.MIN_COLUMN_WIDTH = 10;
+DwtListView.COL_MOVE_THRESHOLD = 3;
+
+DwtListView.prototype = new DwtComposite;
+DwtListView.prototype.constructor = DwtListView;
+
+DwtListView.prototype.toString =
+function() {
+ return "DwtListView";
+}
+
+DwtListView.prototype.setEnabled =
+function(enabled) {
+ DwtComposite.prototype.setEnabled.call(this, enabled);
+ // always remove listeners to avoid adding listeners multiple times
+ this.removeListener(DwtEvent.ONMOUSEOVER, this._listenerMouseOver);
+ this.removeListener(DwtEvent.ONMOUSEOUT, this._listenerMouseOut);
+ this.removeListener(DwtEvent.ONMOUSEDOWN, this._listenerMouseDown);
+ this.removeListener(DwtEvent.ONMOUSEUP, this._listenerMouseUp);
+ this.removeListener(DwtEvent.ONMOUSEMOVE, this._listenerMouseMove);
+ this.removeListener(DwtEvent.ONDBLCLICK, this._listenerDoubleClick);
+ // now re-add listeners, if needed
+ if (enabled) {
+ this.addListener(DwtEvent.ONMOUSEOVER, this._listenerMouseOver);
+ this.addListener(DwtEvent.ONMOUSEOUT, this._listenerMouseOut);
+ this.addListener(DwtEvent.ONMOUSEDOWN, this._listenerMouseDown);
+ this.addListener(DwtEvent.ONMOUSEUP, this._listenerMouseUp);
+ this.addListener(DwtEvent.ONMOUSEMOVE, this._listenerMouseMove);
+ this.addListener(DwtEvent.ONDBLCLICK, this._listenerDoubleClick);
+ }
+ // modify selection classes
+ var selection = this.getSelectedItems();
+ if (selection) {
+ var elements = selection.getArray();
+ for (var i = 0; i < elements.length; i++) {
+ var element = elements[i];
+ element.className = enabled
+ ? Dwt.getAttr(element, "_selectedStyleClass")
+ : Dwt.getAttr(element, "_selectedDisabledStyleClass");
+ }
+ }
+}
+
+DwtListView.prototype.createHeaderHtml =
+function(defaultColumnSort) {
+
+ // does this list view have headers or have they already been created?
+ if (!this._headerList || this._headerColCreated)
+ return;
+
+ var idx = 0;
+ var htmlArr = new Array();
+ this._headerTableId = DwtListView.HEADER_ID + Dwt.getNextId();
+
+ htmlArr[idx++] = "<table id='" + this._headerTableId + "' cellpadding=0 cellspacing=0 border=0 height=100%";
+ htmlArr[idx++] = this._noMaximize ? ">" : " width=100%>";
+ htmlArr[idx++] = "<tr>";
+ for (i = 0; i < this._headerList.length; i++) {
+ var headerCol = this._headerList[i];
+ if (!headerCol._visible)
+ continue;
+
+ htmlArr[idx++] = "<td id='" + headerCol._id + "' class='";
+ htmlArr[idx++] = headerCol._id == this._currentColId
+ ? "DwtListView-Column DwtListView-ColumnActive'"
+ : "DwtListView-Column'";
+ htmlArr[idx++] = headerCol._width ? " width=" + headerCol._width + ">" : ">";
+ // must add a div to force clipping :(
+ htmlArr[idx++] = "<div";
+ htmlArr[idx++] = headerCol._width ? (" style='width: " + (headerCol._width+2) + "'>") : ">";
+
+ // add new table for icon/label/sorting arrow
+ htmlArr[idx++] = "<table border=0 cellpadding=0 cellspacing=0 width=100%><tr>";
+ if (headerCol._iconInfo) {
+ htmlArr[idx++] = "<td><center>";
+ htmlArr[idx++] = AjxImg.getImageHtml(headerCol._iconInfo);
+ htmlArr[idx++] = "</center></td>";
+ }
+
+ if (headerCol._label)
+ htmlArr[idx++] = "<td id='" + DwtListView.HEADERITEM_LABEL + headerCol._id + "'> " + headerCol._label + "</td>";
+
+ if (headerCol._sortable) {
+ var arrowIcon = this._bSortAsc ? "ColumnUpArrow" : "ColumnDownArrow";
+ var id = DwtListView.HEADERITEM_ARROW + headerCol._id;
+ if (headerCol._sortable == defaultColumnSort) {
+ this._currentColId = headerCol._id;
+ htmlArr[idx++] = "<td width=10 id='" + id + "'>" + AjxImg.getImageHtml(arrowIcon) + "</td>";
+ } else {
+ htmlArr[idx++] = "<td width=10 id='" + id + "'>" + AjxImg.getImageHtml(arrowIcon, "visibility:hidden") + "</td>";
+ }
+ }
+
+ // ALWAYS add "sash" separators
+ htmlArr[idx++] = "<td width=4>";
+ htmlArr[idx++] = "<table align=right border=0 cellpadding=0 cellspacing=0 width=2 height=100%><tr>";
+ htmlArr[idx++] = "<td class='DwtListView-Sash'><div style='width: 1px; height: " + (DwtListView.HEADERITEM_HEIGHT-2) + "px; background-color: #8A8A8A'></div></td>";
+ htmlArr[idx++] = "<td class='DwtListView-Sash'><div style='width: 1px; height: " + (DwtListView.HEADERITEM_HEIGHT-2) + "px; background-color: #FFFFFF'></div></td>";
+ htmlArr[idx++] = "</tr></table>";
+ htmlArr[idx++] = "</td>";
+
+ htmlArr[idx++] = "</tr></table>";
+ htmlArr[idx++] = "</div></td>";
+ }
+ htmlArr[idx++] = "</tr>";
+ htmlArr[idx++] = "</table>";
+
+ this._listColDiv.innerHTML = htmlArr.join("");
+
+ // for each sortable column, sets its identifier
+ for (var j = 0; j < this._headerList.length; j++) {
+ var cell = document.getElementById(this._headerList[j]._id);
+ if (cell == null) continue;
+
+ var sortable = this._headerList[j]._sortable;
+ if (sortable && sortable == defaultColumnSort)
+ cell.className = "DwtListView-Column DwtListView-ColumnActive";
+
+ var isResizeable = this._headerList[j]._resizeable;
+ if (isResizeable) {
+ // always get the sibling cell to the right
+ var sashCell = cell.firstChild.firstChild.rows[0].lastChild;
+ if (sashCell) {
+ sashCell._type = DwtListView.TYPE_HEADER_SASH;
[... 29237 lines stripped ...]