1 /* ***** BEGIN LICENSE BLOCK ***** 2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 3 * 4 * The contents of this file are subject to the Mozilla Public License Version 5 * 1.1 (the "License"); you may not use this file except in compliance with 6 * the License. You may obtain a copy of the License at 7 * http://www.mozilla.org/MPL/ 8 * 9 * Software distributed under the License is distributed on an "AS IS" basis, 10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 11 * for the specific language governing rights and limitations under the 12 * License. 13 * 14 * The Original Code is gContactSync. 15 * 16 * The Initial Developer of the Original Code is 17 * Josh Geenen <gcontactsync@pirules.org>. 18 * Portions created by the Initial Developer are Copyright (C) 2008-2009 19 * the Initial Developer. All Rights Reserved. 20 * 21 * Contributor(s): 22 * 23 * Alternatively, the contents of this file may be used under the terms of 24 * either the GNU General Public License Version 2 or later (the "GPL"), or 25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 26 * in which case the provisions of the GPL or the LGPL are applicable instead 27 * of those above. If you wish to allow use of your version of this file only 28 * under the terms of either the GPL or the LGPL, and not to allow others to 29 * use your version of this file under the terms of the MPL, indicate your 30 * decision by deleting the provisions above and replace them with the notice 31 * and other provisions required by the GPL or the LGPL. If you do not delete 32 * the provisions above, a recipient may use your version of this file under 33 * the terms of any one of the MPL, the GPL or the LGPL. 34 * 35 * ***** END LICENSE BLOCK ***** */ 36 37 if (!com) var com = {}; // A generic wrapper variable 38 // A wrapper for all GCS functions and variables 39 if (!com.gContactSync) com.gContactSync = {}; 40 41 window.addEventListener("load", 42 /** Initializes the CardDialogOverlay when the window has finished loading. */ 43 function gCS_CardDialogOverlayLoadListener(e) { 44 com.gContactSync.CardDialogOverlay.init(); 45 }, 46 false); 47 /** 48 * Attributes added to TB by gContactSync AND present in the card dialog overlay 49 */ 50 com.gContactSync.gAttributes = { 51 "ThirdEmail": {}, 52 "FourthEmail": {}, 53 "TalkScreenName": {}, 54 "JabberScreenName": {}, 55 "YahooScreenName": {}, 56 "MSNScreenName": {}, 57 "ICQScreenName": {}, 58 "HomeFaxNumber": {}, 59 "OtherNumber": {}, 60 "PrimaryEmailType": {}, 61 "SecondEmailType": {}, 62 "ThirdEmailType": {}, 63 "FourthEmailType": {}, 64 "_AimScreenNameType": {}, 65 "TalkScreenNameType": {}, 66 "JabberScreenNameType": {}, 67 "YahooScreenNameType": {}, 68 "MSNScreenNameType": {}, 69 "ICQScreenNameType": {}, 70 "WorkPhoneType": {}, 71 "HomePhoneType": {}, 72 "FaxNumberType": {}, 73 "CellularNumberType": {}, 74 "PagerNumberType": {}, 75 "HomeFaxNumberType": {}, 76 "OtherNumberType": {}, 77 "Relation0": {}, 78 "Relation0Type": {}, 79 "Relation1": {}, 80 "Relation1Type": {}, 81 "Relation2": {}, 82 "Relation2Type": {}, 83 "Relation3": {}, 84 "Relation3Type": {}, 85 "WebPage1Type": {}, 86 "WebPage2Type": {}, 87 "FullHomeAddress": {}, 88 "FullWorkAddress": {}, 89 "OtherAddress": {} 90 }; 91 /** 92 * Adds a tab to the tab box in the New and Edit Card Dialogs. Using JavaScript 93 * is necessary because the tab box doesn't have an ID. 94 * @class 95 */ 96 com.gContactSync.CardDialogOverlay = { 97 /** The XUL namespace */ 98 mNamespace: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", 99 /** The number of times an attempt was made to initialize the dialog */ 100 mLoadNumber: 0, 101 /** This stores whether the contact is read-only (ie from LDAP or the Mac AB) */ 102 mDisabled: false, 103 /** 104 * Adds a tab to the tab box, if possible. Waits until the abCardOverlay is 105 * loaded. 106 */ 107 init: function CardDialogOverlay_init() { 108 // if it isn't finished loading yet wait another 200 ms and try again 109 if (!document.getElementById("abTabs")) { 110 // if it has tried to load more than 50 times something is wrong, so quit 111 if (com.gContactSync.CardDialogOverlay.mLoadNumber < 50) 112 setTimeout(com.gContactSync.CardDialogOverlay.init, 200); 113 com.gContactSync.CardDialogOverlay.mLoadNumber++; 114 return; 115 } 116 117 try { 118 // QI the card if it doesn't have the getProperty method 119 // if the card cannot accept custom attributes, quit and do not add the 120 // extra tabs 121 if (!gEditCard.card.getProperty) 122 gEditCard.card.QueryInterface(Components.interfaces.nsIAbMDBCard); 123 } 124 catch (e) { 125 document.getElementById("gContactSyncTab").collapsed = true; 126 return; 127 } 128 // some contacts are read-only so extra attributes should be disabled for 129 // those cards (see Mozdev Bug 20169) 130 try { 131 com.gContactSync.CardDialogOverlay.mDisabled = document.getElementById("PreferMailFormatPopup").disabled; 132 } 133 catch (ex) { 134 com.gContactSync.alertError("Error while determining if contact is read-only: " + ex); 135 com.gContactSync.CardDialogOverlay.mDisabled = true; 136 } 137 // add the email type drop down menus 138 try { 139 // add the type for Postbox (this does nothing for TB or Seamonkey) 140 if (!this.addPostboxEmailType(document.getElementById("PrimaryEmail"))) { 141 var emailTypes = com.gContactSync.gdata.contacts.EMAIL_TYPES, 142 primaryEmailBox = this.getBox("PrimaryEmail"), 143 secondEmailBox = this.getBox("SecondEmail"), 144 thirdEmailBox = this.getBox("ThirdEmail"), 145 fourthEmailBox = this.getBox("FourthEmail"); 146 // add the type menulist to e-mail elements if this isn't Postbox 147 this.addMenuItems(primaryEmailBox, emailTypes, "PrimaryEmailType", "other"); 148 this.addMenuItems(secondEmailBox, emailTypes, "SecondEmailType", "other"); 149 this.addMenuItems(thirdEmailBox, emailTypes, "ThirdEmailType", "other"); 150 this.addMenuItems(fourthEmailBox, emailTypes, "FourthEmailType", "other"); 151 } 152 else { 153 document.getElementById("additionalEmailBox").collapsed = true; 154 } 155 } 156 catch (ex0) { 157 com.gContactSync.alertError("Unable to setup email types: " + ex0); 158 } 159 try { 160 // add drop down menus for screen name protocols 161 var imTypes = com.gContactSync.gdata.contacts.IM_TYPES, 162 aimBox = this.getBox("ScreenName"), 163 talkBox = this.getBox("TalkScreenName"), 164 yahooBox = this.getBox("YahooScreenName"), 165 icqBox = this.getBox("ICQScreenName"), 166 msnBox = this.getBox("MSNScreenName"), 167 jabberBox = this.getBox("JabberScreenName"); 168 this.addMenuItems(aimBox, imTypes, "_AimScreenNameType", "AIM"); 169 this.addMenuItems(talkBox, imTypes, "TalkScreenNameType", "GOOGLE_TALK"); 170 this.addMenuItems(icqBox, imTypes, "ICQScreenNameType", "ICQ"); 171 this.addMenuItems(yahooBox, imTypes, "YahooScreenNameType", "YAHOO"); 172 this.addMenuItems(msnBox, imTypes, "MSNScreenNameType", "MSN"); 173 this.addMenuItems(jabberBox, imTypes, "JabberScreenNameType", "JABBER"); 174 } 175 catch (ex1) { 176 com.gContactSync.alertError("Unable to setup screen name protocol menus\n" + ex1); 177 } 178 var pager; 179 try { 180 // swap pager and mobile phone textboxes and values 181 pager = document.getElementById("PagerNumber"); 182 pager.setAttribute("id", "tmp"); 183 var pagerValue = pager.value, 184 mobile = document.getElementById("CellularNumber"); 185 mobile.setAttribute("id", "PagerNumber"); 186 pager.setAttribute("id", "CellularNumber"); 187 pager.value = mobile.value; 188 mobile.value = pagerValue; 189 } 190 catch (e1) { 191 com.gContactSync.alertError("Unable to swap pager and mobile number values\n" + e1); 192 } 193 var newDialog = false, // post-Mailnews Core Bug 63941 194 showPhoneTypes = com.gContactSync.Preferences.mSyncPrefs.phoneTypes.value, 195 work = document.getElementById("WorkPhone"), 196 home = document.getElementById("HomePhone"), 197 fax = document.getElementById("FaxNumber"); 198 mobile = document.getElementById("CellularNumber"); 199 pager = document.getElementById("PagerNumber"); 200 // then replace all phone labels and remove the access keys 201 var workLabel = work.parentNode.previousSibling; 202 if (!workLabel) { 203 newDialog = true; 204 workLabel = work.previousSibling; 205 } 206 if (showPhoneTypes) { 207 try { 208 workLabel.value = com.gContactSync.StringBundle.getStr("first"); 209 workLabel.setAttribute("accesskey", ""); 210 var homeLabel = newDialog ? home.previousSibling 211 : home.parentNode.previousSibling; 212 homeLabel.value = com.gContactSync.StringBundle.getStr("second"); 213 homeLabel.setAttribute("accesskey", ""); 214 var faxLabel = newDialog ? fax.previousSibling 215 : fax.parentNode.previousSibling; 216 faxLabel.value = com.gContactSync.StringBundle.getStr("third"); 217 faxLabel.setAttribute("accesskey", ""); 218 var mobileLabel = newDialog ? mobile.previousSibling 219 : mobile.parentNode.previousSibling; 220 mobileLabel.value = com.gContactSync.StringBundle.getStr("fourth"); 221 mobileLabel.setAttribute("accesskey", ""); 222 var pagerLabel = newDialog ? pager.previousSibling 223 : pager.parentNode.previousSibling; 224 pagerLabel.value = com.gContactSync.StringBundle.getStr("fifth"); 225 pagerLabel.setAttribute("accesskey", ""); 226 } 227 catch (ex2) { 228 com.gContactSync.alertError("Unable to replace phone labels and remove access keys\n" + ex2); 229 } 230 } 231 else { 232 // TODO - replace the Sixth and Seventh labels 233 } 234 var phoneTypes = com.gContactSync.gdata.contacts.PHONE_TYPES; 235 try { 236 // setup the types for the phone numbers 237 var workBox = work.parentNode; 238 this.addMenuItems(workBox, phoneTypes, "WorkPhoneType", "work") 239 .collapsed = !showPhoneTypes; 240 var homeBox = home.parentNode; 241 this.addMenuItems(homeBox, phoneTypes, "HomePhoneType", "home") 242 .collapsed = !showPhoneTypes; 243 var faxBox = fax.parentNode; 244 this.addMenuItems(faxBox, phoneTypes, "FaxNumberType", "work_fax") 245 .collapsed = !showPhoneTypes; 246 var mobileBox = mobile.parentNode; 247 this.addMenuItems(mobileBox, phoneTypes, "CellularNumberType", "mobile") 248 .collapsed = !showPhoneTypes; 249 var pagerBox = pager.parentNode; 250 this.addMenuItems(pagerBox, phoneTypes, "PagerNumberType", "pager") 251 .collapsed = !showPhoneTypes; 252 var homeFaxBox = document.getElementById("HomeFaxNumber").parentNode; 253 this.addMenuItems(homeFaxBox, phoneTypes, "HomeFaxNumberType", "home_fax") 254 .collapsed = !showPhoneTypes; 255 var otherNumberBox = document.getElementById("OtherNumber").parentNode; 256 this.addMenuItems(otherNumberBox, phoneTypes, "OtherNumberType", "other") 257 .collapsed = !showPhoneTypes; 258 } 259 catch (ex3) { 260 com.gContactSync.alertError("Unable to setup phone number types\n" + ex3); 261 } 262 263 // Add the website types 264 var websiteTypes = com.gContactSync.gdata.contacts.WEBSITE_TYPES; 265 var site1Box = document.getElementById("WebPage1").parentNode; 266 this.addMenuItems(site1Box, websiteTypes, "WebPage1Type", "work"); 267 var site2Box = document.getElementById("WebPage2").parentNode; 268 this.addMenuItems(site2Box, websiteTypes, "WebPage2Type", "home"); 269 if (newDialog) { 270 // rename the hidden phone number field IDs 271 try { 272 document.getElementById("HomeFaxNumber").id = "OldHomeFaxNumber"; 273 document.getElementById("HomeFaxNumberType").id = "OldHomeFaxNumberType"; 274 document.getElementById("OtherNumber").id = "OldOtherNumber"; 275 document.getElementById("OtherNumberType").id = "OldOtherNumberType"; 276 } 277 catch (e) {} 278 try { 279 // change the width of the phone numbers 280 var phoneIDs = ["HomePhone", "WorkPhone", "CellularNumber", "FaxNumber", 281 "PagerNumber"]; 282 for (var i = 0; i < phoneIDs.length; i++) { 283 var elem = document.getElementById(phoneIDs[i]); 284 if (!elem) continue; 285 elem.setAttribute("width", "150px"); 286 } 287 // add the sixth and seventh numbers below 1 - 5 288 var sixthNum = this.setupNumBox("HomeFaxNumber", 289 com.gContactSync.StringBundle.getStr("sixth")), 290 seventhNum = this.setupNumBox("OtherNumber", 291 com.gContactSync.StringBundle.getStr("seventh")); 292 pager.parentNode.parentNode.appendChild(sixthNum); 293 this.addMenuItems(sixthNum, phoneTypes, "HomeFaxNumberType", "home_fax") 294 .collapsed = !showPhoneTypes; 295 pager.parentNode.parentNode.appendChild(seventhNum); 296 this.addMenuItems(seventhNum, phoneTypes, "OtherNumberType", "other") 297 .collapsed = !showPhoneTypes; 298 299 // Add the relation fields 300 try { 301 document.getElementById("relationFields").removeAttribute("hidden"); 302 var relationTypes = [""]; 303 // copy the relation types over 304 for (i in com.gContactSync.gdata.contacts.RELATION_TYPES) { 305 relationTypes.push(i); 306 } 307 for (i = 0; i < 4; i++) { 308 var relationBox = document.getElementById("Relation" + i + "Box"); 309 this.addMenuItems(relationBox, relationTypes, "Relation" + i + "Type", "", com.gContactSync.StringBundle.getStr("relationWidth")); 310 } 311 } 312 catch (ex5) { 313 com.gContactSync.LOGGER.LOG_WARNING("Could not add the relation fields.", ex5); 314 } 315 /* 316 var nameWidth = "width: 30ch;"; 317 document.getElementById("FirstName").setAttribute("style", nameWidth); 318 document.getElementById("LastName").setAttribute("style", nameWidth); 319 document.getElementById("DisplayName").setAttribute("style", nameWidth); 320 document.getElementById("NickName").setAttribute("style", nameWidth); 321 document.getElementById("FirstName").removeAttribute("flex"); 322 document.getElementById("LastName").removeAttribute("flex"); 323 document.getElementById("DisplayName").removeAttribute("flex"); 324 document.getElementById("NickName").removeAttribute("flex"); 325 var emailWidth = "width: 20ch;"; 326 document.getElementById("PrimaryEmail").setAttribute("style", emailWidth); 327 document.getElementById("SecondEmail").setAttribute("style", emailWidth); 328 document.getElementById("ScreenName").setAttribute("width", "150px"); 329 document.getElementById("PrimaryEmail").removeAttribute("flex"); 330 document.getElementById("SecondEmail").removeAttribute("flex"); 331 document.getElementById("ScreenName").removeAttribute("flex"); 332 document.getElementById("abNameTab").firstChild.firstChild.style.minWidth = "50ch"; 333 document.getElementById("abNameTab").firstChild.firstChild.style.maxWidth = "50ch"; 334 var elem = document.getElementById("abTabPanels"); 335 elem.style.width = "850px"; 336 elem.style.maxWidth = "850px"; 337 elem.style.minWidth = "850px"; 338 */ 339 } 340 catch (ex6) { 341 com.gContactSync.alertError("Unable to setup the extra tabs\n" + ex6); 342 } 343 } 344 // if this is the old dialog, show the extra phone numbers 345 else { 346 try { 347 // move the address descriptions below the addresses (rather than beside) 348 var gbox = document.getElementById("addressDescGroupBox"); 349 if (gbox) { 350 var parent = gbox.parentNode; 351 parent.removeChild(gbox); 352 parent.parentNode.firstChild.appendChild(gbox); 353 } 354 document.getElementById("numbersGroupBox").removeAttribute("hidden"); 355 } 356 catch (e) { 357 com.gContactSync.LOGGER.LOG_WARNING("Unable to move addressDescGroupBox" + 358 " or remove hidden from numbersGB", e); 359 } 360 } 361 362 // if this is a read-only card, make added elements disabled 363 // the menulists are already taken care of 364 // TODO update CardDialogOverlay... 365 if (com.gContactSync.CardDialogOverlay.mDisabled) { 366 document.getElementById("ThirdEmail").readOnly = true; 367 document.getElementById("FourthEmail").readOnly = true; 368 document.getElementById("TalkScreenName").readOnly = true; 369 document.getElementById("ICQScreenName").readOnly = true; 370 document.getElementById("YahooScreenName").readOnly = true; 371 document.getElementById("MSNScreenName").readOnly = true; 372 document.getElementById("JabberScreenName").readOnly = true; 373 document.getElementById("HomeFaxNumber").readOnly = true; 374 document.getElementById("OtherNumber").readOnly = true; 375 document.getElementById("Relation").readOnly = true; 376 } 377 // fix the width of the dialog 378 window.sizeToContent(); 379 380 // override the check and set card values function 381 com.gContactSync.originalCheckAndSetCardValues = CheckAndSetCardValues; 382 CheckAndSetCardValues = com.gContactSync.CardDialogOverlay.CheckAndSetCardValues; 383 // get the extra card values 384 this.GetCardValues(gEditCard.card, document); 385 }, 386 /** 387 * Gets the parent node of an element with the given ID. 388 * If there is no element with the given ID then this function will return 389 * null. 390 * @param aID The ID of the element whose parent node is returned. 391 * @returns {XULElement} The parentNode of the element with the given ID. 392 */ 393 getBox: function CardDialogOverlay_getBox(aID) { 394 var elem = document.getElementById(aID); 395 if (elem && elem.tagName === "emailaddress-input") { // Postbox 396 return elem; 397 } 398 return elem ? elem.parentNode : null; 399 }, 400 /** 401 * Adds the e-mail type menulist to Postbox's emailaddress-input element. 402 * This also overrides the addRow method to add the type menulist to 403 * future emailaddress-input elements (and calls the original addRow) 404 * @param aElem The emailaddress-input element. 405 * @returns {boolean} True if the application is Postbox and the menulist was 406 * added. 407 */ 408 addPostboxEmailType: function CardDialogOverlay_addPBEmailType(aElem) { 409 if (!aElem || aElem.tagName !== "emailaddress-input") { 410 return false; 411 } 412 /* 413 var emailTypes = com.gContactSync.gdata.contacts.EMAIL_TYPES; 414 this.addMenuItems(aElem, emailTypes, "", "other"); 415 // save the original addRow method 416 aElem.origAddRow = aElem.addRow; 417 // override addRow to call the original then add the e-mail types 418 aElem.addRow = function gContactSync_addRow() { 419 // call the original 420 this.origAddRow.apply(this, arguments); 421 // add the e-mail type menulist 422 com.gContactSync.CardDialogOverlay.addPostboxEmailType(this.nextSibling); 423 // resize the window 424 window.sizeToContent(); 425 } 426 */ 427 return true; 428 }, 429 /** 430 * Sets the attributes added by this extension as the value in the textbox or 431 * drop down menu in aDoc whose ID is identical to the attribute's name. 432 * Calls the original CheckAndSetCardValues function when finished. 433 * @param aCard {nsIAbCard} The card to set the values for. 434 * @param aDoc {Document Object} The document. 435 * @param aCheck Unused, but passed to the original method. 436 */ 437 CheckAndSetCardValues: function CardDialogOverlay_CheckAndSetCardValues(aCard, aDoc, aCheck) { 438 // make sure the required data is present (abCardOverlay.js) 439 if (!CheckCardRequiredDataPresence(aDoc)) { 440 return false; 441 } 442 var contact = new com.gContactSync.TBContact(aCard); 443 var existingTypes = { 444 "WorkPhoneType": {}, 445 "HomePhoneType": {}, 446 "FaxNumberType": {}, 447 "CellularNumberType": {}, 448 "PagerNumberType": {} 449 }; 450 // iterate through all the added attributes and types and set the card's value 451 // for each one of them 452 for (var attr in com.gContactSync.gAttributes) { 453 try { 454 // if the element exists, set the card's value as its value 455 var elem = aDoc.getElementById(attr); 456 if (elem) { 457 // I do not know why this is necessary, but it seems to be the only 458 // way to get the value correct in TB 2... 459 if (attr === "HomeFaxNumberType" || attr === "OtherNumberType") { 460 elem.value = elem.getAttribute("value"); 461 } 462 com.gContactSync.LOGGER.VERBOSE_LOG("Attribute: '" + attr + "' - Value: '" + elem.value + "'"); 463 contact.setValue(attr, elem.value); 464 } 465 } 466 catch (e) { 467 com.gContactSync.alertError("Error in com.gContactSync.CheckAndSetCardValues: " + attr + "\n" + e); 468 } 469 } 470 if (!contact.mContact.getProperty && gEditCard.abURI) { 471 if (contact.mContact.editCardToDatabase) { // Thunderbird 2 472 contact.mContact.editCardToDatabase(gEditCard.abURI); 473 } 474 else if (GetDirectoryFromURI) { // Postbox doesn't have editCardToDatabase 475 var dir = GetDirectoryFromURI(gEditCard.abURI); 476 if (dir) { 477 dir.modifyCard(contact.mContact); 478 } 479 } 480 } 481 // ensure that every contact edited through this dialog has at least a dummy 482 // e-mail address if necessary 483 var primEmailElem = aDoc.getElementById("PrimaryEmail"); 484 if (!primEmailElem.value) { 485 // if it is a new contact it isn't already in any lists 486 if (gEditCard.abURI) { 487 // Check if it is in any mailing lists. If so, force a dummy address 488 // When fetching lists, do not get the contacts (if it is found there is 489 // no need to get the contacts in every list) 490 var ab = com.gContactSync.GAbManager.getAbByURI(gEditCard.abURI), 491 ab = (ab ? new com.gContactSync.GAddressBook(ab) : null), 492 lists = ab.getAllLists(true); 493 for (var i in lists) { 494 // if the list does have the contact then make sure it gets a dummy 495 // e-mail address regardless of the preference 496 // do not check the PrimaryEmail address in hasContact since it is now 497 // empty 498 if (lists[i].hasContact(contact)) { 499 primEmailElem.value = com.gContactSync.makeDummyEmail(contact.mContact, true); 500 com.gContactSync.alertError(com.gContactSync.StringBundle.getStr("dummyEmailAdded") + "\n" + primEmailElem.value); 501 break; 502 } 503 } 504 } 505 } 506 // call the original and return its return value 507 return com.gContactSync.originalCheckAndSetCardValues.apply(this, arguments); 508 }, 509 /** 510 * A method that gets all of the attributes added by this extension and sets 511 * the value of the textbox or drop down menu in aDoc whose ID is identical to 512 * the attribute's name. 513 * @param aCard {nsIAbCard} The card to get the values from. 514 * @param aDoc {Document Object} The document. 515 */ 516 GetCardValues: function CardDialogOverlay_GetCardValues(aCard, aDoc) { 517 // iterate through all the added type elements and get the card's value for 518 // each one of them to set as the value for the element 519 for (var attr in com.gContactSync.gAttributes) { 520 try { 521 var elem = aDoc.getElementById(attr); 522 // if the element exists, set its value as the card's value 523 if (elem) { 524 var value; 525 if (aCard.getProperty) // post Bug 413260 526 value = aCard.getProperty(attr, null); 527 else // pre Bug 413260 528 value = aCard.getStringAttribute(attr); 529 // set the element's value if attr isn't a type OR it is a type and 530 // the card's value for the attribute isn't null or blank 531 if (attr.indexOf("Type") == -1 || (value && value != "")) { 532 elem.value = value; 533 } 534 } 535 } catch (e) { com.gContactSync.alertError("Error in com.gContactSync.GetCardValues: " + attr + "\n" + e); } 536 } 537 538 if (com.gContactSync.isDummyEmail(aDoc.getElementById("PrimaryEmail").value)) 539 aDoc.getElementById("PrimaryEmail").value = null; 540 }, 541 /** 542 * Sets up a type menu list element with a menuitem for each string in the 543 * array. 544 * @param aBox {XUL Box} The box element to which this menu list is added. 545 * @param aArray {array} The array of values to set for the menuitems. There 546 * must be a string in the string bundle with the same 547 * name as the value. 548 * @param aID {string} The ID for this menu list, which should be the name 549 * of the attribute with Type added to the end, such as 550 * WorkNumberType 551 * @param aValue {string} The default value to set for this list. 552 * @param aWidth {int} The maximum width, if any. 553 * 554 * @returns {XULElement} The menulist element. 555 */ 556 addMenuItems: function CardDialogOverlay_addMenuItems(aBox, aArray, aID, aValue, aWidth) { 557 if (!aBox) { 558 return false; 559 } 560 var menuList = document.createElement("menulist"); 561 menuList.setAttribute("id", aID); 562 var menuPopup = document.createElement("menupopup"); 563 // put the default value first in the menupopup, if possible 564 var index = aArray.indexOf(aValue); 565 var elem; 566 if (index != -1) { 567 elem = document.createElement("menuitem"); 568 elem.setAttribute("value", aValue); 569 elem.setAttribute("label", com.gContactSync.StringBundle.getStr(aValue ? aValue : "blank")); 570 aArray[index] = null; 571 menuPopup.appendChild(elem); 572 } 573 // then add the other values 574 for (var i = 0; i < aArray.length; i++) { 575 if (!aArray[i]) { // if this element is null it was the default value 576 aArray[i] = aValue; // so restore its value and skip adding it again 577 continue; 578 } 579 elem = document.createElement("menuitem"); 580 elem.setAttribute("value", aArray[i]); 581 elem.setAttribute("label", com.gContactSync.StringBundle.getStr(aArray[i])); 582 menuPopup.appendChild(elem); 583 } 584 menuList.setAttribute("sizetopopup", "always"); 585 if (aWidth) { 586 menuList.setAttribute("width", aWidth); 587 menuList.style.width = aWidth; 588 menuList.style.maxWidth = aWidth; 589 } 590 // add the popup to the menu list 591 menuList.appendChild(menuPopup); 592 // disable the menu list if this card is read-only 593 menuList.setAttribute("disabled", com.gContactSync.CardDialogOverlay.mDisabled); 594 // add the menu list to the box 595 aBox.appendChild(menuList); 596 return menuList; 597 }, 598 /** 599 * Adds an hbox containing a label and textbox for a phone number. 600 * @param aID {string} The ID for the textbox. 601 * @param aLabel {string} The text for the textbox's label. 602 */ 603 setupNumBox: function CardDialogOverlay_setupNumBox(aID, aLabel) { 604 var box = document.createElement("hbox"); 605 box.setAttribute("align", "center"); 606 var spacer = document.createElement("spacer"); 607 spacer.setAttribute("flex", 1); 608 box.appendChild(spacer); 609 var label = document.createElement("label"); 610 label.setAttribute("control", aID); 611 label.setAttribute("value", aLabel); 612 box.appendChild(label); 613 var textbox = document.createElement("textbox"); 614 textbox.setAttribute("id", aID); 615 textbox.setAttribute("class", "PhoneEditWidth"); 616 if (com.gContactSync.CardDialogOverlay.mDisabled) 617 textbox.setAttribute("readonly", true); 618 else if (textbox.hasAttribute("readonly")) 619 textbox.removeAttribute("readonly"); 620 textbox.setAttribute("width", "150px"); 621 box.appendChild(textbox); 622 return box; 623 } 624 }; 625