1/* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, you can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5const EXPORTED_SYMBOLS = ["AddrBookCard"]; 6 7ChromeUtils.defineModuleGetter( 8 this, 9 "newUID", 10 "resource:///modules/AddrBookUtils.jsm" 11); 12 13/** 14 * Prototype for nsIAbCard objects that are not mailing lists. 15 * 16 * @implements {nsIAbCard} 17 */ 18function AddrBookCard() { 19 this._directoryUID = ""; 20 this._properties = new Map([ 21 ["PreferMailFormat", Ci.nsIAbPreferMailFormat.unknown], 22 ["PopularityIndex", 0], 23 ["LastModifiedDate", 0], 24 ]); 25} 26 27AddrBookCard.prototype = { 28 QueryInterface: ChromeUtils.generateQI(["nsIAbCard"]), 29 classID: Components.ID("{1143991d-31cd-4ea6-9c97-c587d990d724}"), 30 31 /* nsIAbCard */ 32 33 generateName(generateFormat, bundle) { 34 let result = ""; 35 let format; 36 if (generateFormat == Ci.nsIAbCard.GENERATE_DISPLAY_NAME) { 37 result = this.displayName; 38 } else if (!this.lastName.length) { 39 result = this.firstName; 40 } else if (!this.firstName.length) { 41 result = this.lastName; 42 } else if (generateFormat == Ci.nsIAbCard.GENERATE_LAST_FIRST_ORDER) { 43 format = bundle ? bundle.GetStringFromName("lastFirstFormat") : "%S, %S"; 44 result = format 45 .replace("%S", this.lastName) 46 .replace("%S", this.firstName); 47 } else { 48 format = bundle ? bundle.GetStringFromName("firstLastFormat") : "%S %S"; 49 result = format 50 .replace("%S", this.firstName) 51 .replace("%S", this.lastName); 52 } 53 54 if (result == "") { 55 result = this.getProperty("Company", ""); 56 } 57 if (result == "") { 58 result = this.primaryEmail.split("@", 1)[0]; 59 } 60 61 return result; 62 }, 63 get directoryUID() { 64 return this._directoryUID; 65 }, 66 set directoryUID(value) { 67 this._directoryUID = value; 68 }, 69 get UID() { 70 if (!this._uid) { 71 this._uid = newUID(); 72 } 73 return this._uid; 74 }, 75 set UID(value) { 76 if (value != this._uid) { 77 throw Components.Exception("", Cr.NS_ERROR_FAILURE); 78 } 79 }, 80 get properties() { 81 let props = []; 82 for (const [name, value] of this._properties) { 83 props.push({ 84 get name() { 85 return name; 86 }, 87 get value() { 88 return value; 89 }, 90 QueryInterface: ChromeUtils.generateQI(["nsIProperty"]), 91 }); 92 } 93 return props; 94 }, 95 get firstName() { 96 return this.getProperty("FirstName", ""); 97 }, 98 set firstName(value) { 99 this.setProperty("FirstName", value); 100 }, 101 get lastName() { 102 return this.getProperty("LastName", ""); 103 }, 104 set lastName(value) { 105 this.setProperty("LastName", value); 106 }, 107 get displayName() { 108 return this.getProperty("DisplayName", ""); 109 }, 110 set displayName(value) { 111 this.setProperty("DisplayName", value); 112 }, 113 get primaryEmail() { 114 return this.getProperty("PrimaryEmail", ""); 115 }, 116 set primaryEmail(value) { 117 this.setProperty("PrimaryEmail", value); 118 }, 119 get isMailList() { 120 return false; 121 }, 122 get mailListURI() { 123 return ""; 124 }, 125 126 getProperty(name, defaultValue) { 127 if (this._properties.has(name)) { 128 return this._properties.get(name); 129 } 130 return defaultValue; 131 }, 132 getPropertyAsAString(name) { 133 if (!this._properties.has(name)) { 134 return ""; 135 } 136 return this.getProperty(name); 137 }, 138 getPropertyAsAUTF8String(name) { 139 if (!this._properties.has(name)) { 140 throw Components.Exception(`${name} N/A`, Cr.NS_ERROR_NOT_AVAILABLE); 141 } 142 return this.getProperty(name); 143 }, 144 getPropertyAsUint32(name) { 145 let value = this.getProperty(name); 146 if (isNaN(parseInt(value, 10))) { 147 throw Components.Exception( 148 `${name}: ${value} - not an int`, 149 Cr.NS_ERROR_NOT_AVAILABLE 150 ); 151 } 152 return value; 153 }, 154 getPropertyAsBool(name) { 155 let value = this.getProperty(name); 156 switch (value) { 157 case false: 158 case 0: 159 case "0": 160 return false; 161 case true: 162 case 1: 163 case "1": 164 return true; 165 } 166 throw Components.Exception( 167 `${name}: ${value} - not a boolean`, 168 Cr.NS_ERROR_NOT_AVAILABLE 169 ); 170 }, 171 setProperty(name, value) { 172 if ([null, undefined, ""].includes(value)) { 173 this._properties.delete(name); 174 return; 175 } 176 if (typeof value == "boolean") { 177 value = value ? "1" : "0"; 178 } 179 this._properties.set(name, "" + value); 180 }, 181 setPropertyAsAString(name, value) { 182 throw Components.Exception("", Cr.NS_ERROR_NOT_IMPLEMENTED); 183 }, 184 setPropertyAsAUTF8String(name, value) { 185 this.setProperty(name, value); 186 }, 187 setPropertyAsUint32(name, value) { 188 this.setProperty(name, value); 189 }, 190 setPropertyAsBool(name, value) { 191 this.setProperty(name, value ? "1" : "0"); 192 }, 193 deleteProperty(name) { 194 this._properties.delete(name); 195 }, 196 hasEmailAddress(emailAddress) { 197 emailAddress = emailAddress.toLowerCase(); 198 if (this.getProperty("PrimaryEmail", "").toLowerCase() == emailAddress) { 199 return true; 200 } 201 if (this.getProperty("SecondEmail", "").toLowerCase() == emailAddress) { 202 return true; 203 } 204 return false; 205 }, 206 translateTo(type) { 207 // Get nsAbCardProperty to do the work, the code is in C++ anyway. 208 let cardCopy = Cc["@mozilla.org/addressbook/cardproperty;1"].createInstance( 209 Ci.nsIAbCard 210 ); 211 cardCopy.UID = this.UID; 212 cardCopy.copy(this); 213 return cardCopy.translateTo(type); 214 }, 215 generatePhoneticName(lastNameFirst) { 216 if (lastNameFirst) { 217 return ( 218 this.getProperty("PhoneticLastName", "") + 219 this.getProperty("PhoneticFirstName", "") 220 ); 221 } 222 return ( 223 this.getProperty("PhoneticFirstName", "") + 224 this.getProperty("PhoneticLastName", "") 225 ); 226 }, 227 generateChatName() { 228 for (let name of [ 229 "_GoogleTalk", 230 "_AimScreenName", 231 "_Yahoo", 232 "_Skype", 233 "_QQ", 234 "_MSN", 235 "_ICQ", 236 "_JabberId", 237 "_IRC", 238 ]) { 239 if (this._properties.has(name)) { 240 return this._properties.get(name); 241 } 242 } 243 return ""; 244 }, 245 copy(srcCard) { 246 throw Components.Exception( 247 "nsIAbCard.copy() not implemented", 248 Cr.NS_ERROR_NOT_IMPLEMENTED 249 ); 250 }, 251 equals(card) { 252 return this.UID == card.UID; 253 }, 254}; 255