Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
michael@0 | 1 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
michael@0 | 3 | * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 4 | |
michael@0 | 5 | "use strict"; |
michael@0 | 6 | |
michael@0 | 7 | const DEBUG = false; |
michael@0 | 8 | function debug(s) { dump("-*- ContactManager: " + s + "\n"); } |
michael@0 | 9 | |
michael@0 | 10 | const Cc = Components.classes; |
michael@0 | 11 | const Ci = Components.interfaces; |
michael@0 | 12 | const Cu = Components.utils; |
michael@0 | 13 | |
michael@0 | 14 | Cu.import("resource://gre/modules/XPCOMUtils.jsm"); |
michael@0 | 15 | Cu.import("resource://gre/modules/Services.jsm"); |
michael@0 | 16 | Cu.import("resource://gre/modules/DOMRequestHelper.jsm"); |
michael@0 | 17 | |
michael@0 | 18 | XPCOMUtils.defineLazyServiceGetter(Services, "DOMRequest", |
michael@0 | 19 | "@mozilla.org/dom/dom-request-service;1", |
michael@0 | 20 | "nsIDOMRequestService"); |
michael@0 | 21 | |
michael@0 | 22 | XPCOMUtils.defineLazyServiceGetter(this, "cpmm", |
michael@0 | 23 | "@mozilla.org/childprocessmessagemanager;1", |
michael@0 | 24 | "nsIMessageSender"); |
michael@0 | 25 | |
michael@0 | 26 | const CONTACTS_SENDMORE_MINIMUM = 5; |
michael@0 | 27 | |
michael@0 | 28 | // We need this to create a copy of the mozContact object in ContactManager.save |
michael@0 | 29 | // Keep in sync with the interfaces. |
michael@0 | 30 | const PROPERTIES = [ |
michael@0 | 31 | "name", "honorificPrefix", "givenName", "additionalName", "familyName", |
michael@0 | 32 | "phoneticGivenName", "phoneticFamilyName", |
michael@0 | 33 | "honorificSuffix", "nickname", "photo", "category", "org", "jobTitle", |
michael@0 | 34 | "bday", "note", "anniversary", "sex", "genderIdentity", "key", "adr", "email", |
michael@0 | 35 | "url", "impp", "tel" |
michael@0 | 36 | ]; |
michael@0 | 37 | |
michael@0 | 38 | let mozContactInitWarned = false; |
michael@0 | 39 | |
michael@0 | 40 | function Contact() { } |
michael@0 | 41 | |
michael@0 | 42 | Contact.prototype = { |
michael@0 | 43 | __init: function(aProp) { |
michael@0 | 44 | for (let prop in aProp) { |
michael@0 | 45 | this[prop] = aProp[prop]; |
michael@0 | 46 | } |
michael@0 | 47 | }, |
michael@0 | 48 | |
michael@0 | 49 | init: function(aProp) { |
michael@0 | 50 | // init is deprecated, warn once in the console if it's used |
michael@0 | 51 | if (!mozContactInitWarned) { |
michael@0 | 52 | mozContactInitWarned = true; |
michael@0 | 53 | Cu.reportError("mozContact.init is DEPRECATED. Use the mozContact constructor instead. " + |
michael@0 | 54 | "See https://developer.mozilla.org/docs/WebAPI/Contacts for details."); |
michael@0 | 55 | } |
michael@0 | 56 | |
michael@0 | 57 | for (let prop of PROPERTIES) { |
michael@0 | 58 | this[prop] = aProp[prop]; |
michael@0 | 59 | } |
michael@0 | 60 | }, |
michael@0 | 61 | |
michael@0 | 62 | setMetadata: function(aId, aPublished, aUpdated) { |
michael@0 | 63 | this.id = aId; |
michael@0 | 64 | if (aPublished) { |
michael@0 | 65 | this.published = aPublished; |
michael@0 | 66 | } |
michael@0 | 67 | if (aUpdated) { |
michael@0 | 68 | this.updated = aUpdated; |
michael@0 | 69 | } |
michael@0 | 70 | }, |
michael@0 | 71 | |
michael@0 | 72 | classID: Components.ID("{72a5ee28-81d8-4af8-90b3-ae935396cc66}"), |
michael@0 | 73 | contractID: "@mozilla.org/contact;1", |
michael@0 | 74 | QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]), |
michael@0 | 75 | }; |
michael@0 | 76 | |
michael@0 | 77 | function ContactManager() { } |
michael@0 | 78 | |
michael@0 | 79 | ContactManager.prototype = { |
michael@0 | 80 | __proto__: DOMRequestIpcHelper.prototype, |
michael@0 | 81 | hasListenPermission: false, |
michael@0 | 82 | _cachedContacts: [] , |
michael@0 | 83 | |
michael@0 | 84 | set oncontactchange(aHandler) { |
michael@0 | 85 | this.__DOM_IMPL__.setEventHandler("oncontactchange", aHandler); |
michael@0 | 86 | }, |
michael@0 | 87 | |
michael@0 | 88 | get oncontactchange() { |
michael@0 | 89 | return this.__DOM_IMPL__.getEventHandler("oncontactchange"); |
michael@0 | 90 | }, |
michael@0 | 91 | |
michael@0 | 92 | _convertContact: function(aContact) { |
michael@0 | 93 | let newContact = new this._window.mozContact(aContact.properties); |
michael@0 | 94 | newContact.setMetadata(aContact.id, aContact.published, aContact.updated); |
michael@0 | 95 | return newContact; |
michael@0 | 96 | }, |
michael@0 | 97 | |
michael@0 | 98 | _convertContacts: function(aContacts) { |
michael@0 | 99 | let contacts = new this._window.Array(); |
michael@0 | 100 | for (let i in aContacts) { |
michael@0 | 101 | contacts.push(this._convertContact(aContacts[i])); |
michael@0 | 102 | } |
michael@0 | 103 | return contacts; |
michael@0 | 104 | }, |
michael@0 | 105 | |
michael@0 | 106 | _fireSuccessOrDone: function(aCursor, aResult) { |
michael@0 | 107 | if (aResult == null) { |
michael@0 | 108 | Services.DOMRequest.fireDone(aCursor); |
michael@0 | 109 | } else { |
michael@0 | 110 | Services.DOMRequest.fireSuccess(aCursor, aResult); |
michael@0 | 111 | } |
michael@0 | 112 | }, |
michael@0 | 113 | |
michael@0 | 114 | _pushArray: function(aArr1, aArr2) { |
michael@0 | 115 | aArr1.push.apply(aArr1, aArr2); |
michael@0 | 116 | }, |
michael@0 | 117 | |
michael@0 | 118 | receiveMessage: function(aMessage) { |
michael@0 | 119 | if (DEBUG) debug("receiveMessage: " + aMessage.name); |
michael@0 | 120 | let msg = aMessage.json; |
michael@0 | 121 | let contacts = msg.contacts; |
michael@0 | 122 | |
michael@0 | 123 | let req; |
michael@0 | 124 | switch (aMessage.name) { |
michael@0 | 125 | case "Contacts:Find:Return:OK": |
michael@0 | 126 | req = this.getRequest(msg.requestID); |
michael@0 | 127 | if (req) { |
michael@0 | 128 | let result = this._convertContacts(contacts); |
michael@0 | 129 | Services.DOMRequest.fireSuccess(req.request, result); |
michael@0 | 130 | } else { |
michael@0 | 131 | if (DEBUG) debug("no request stored!" + msg.requestID); |
michael@0 | 132 | } |
michael@0 | 133 | break; |
michael@0 | 134 | case "Contacts:GetAll:Next": |
michael@0 | 135 | let data = this.getRequest(msg.cursorId); |
michael@0 | 136 | if (!data) { |
michael@0 | 137 | break; |
michael@0 | 138 | } |
michael@0 | 139 | let result = contacts ? this._convertContacts(contacts) : [null]; |
michael@0 | 140 | if (data.waitingForNext) { |
michael@0 | 141 | if (DEBUG) debug("cursor waiting for contact, sending"); |
michael@0 | 142 | data.waitingForNext = false; |
michael@0 | 143 | let contact = result.shift(); |
michael@0 | 144 | this._pushArray(data.cachedContacts, result); |
michael@0 | 145 | this.nextTick(this._fireSuccessOrDone.bind(this, data.cursor, contact)); |
michael@0 | 146 | if (!contact) { |
michael@0 | 147 | this.removeRequest(msg.cursorId); |
michael@0 | 148 | } |
michael@0 | 149 | } else { |
michael@0 | 150 | if (DEBUG) debug("cursor not waiting, saving"); |
michael@0 | 151 | this._pushArray(data.cachedContacts, result); |
michael@0 | 152 | } |
michael@0 | 153 | break; |
michael@0 | 154 | case "Contact:Save:Return:OK": |
michael@0 | 155 | // If a cached contact was saved and a new contact ID was returned, update the contact's ID |
michael@0 | 156 | if (this._cachedContacts[msg.requestID]) { |
michael@0 | 157 | if (msg.contactID) { |
michael@0 | 158 | this._cachedContacts[msg.requestID].id = msg.contactID; |
michael@0 | 159 | } |
michael@0 | 160 | delete this._cachedContacts[msg.requestID]; |
michael@0 | 161 | } |
michael@0 | 162 | case "Contacts:Clear:Return:OK": |
michael@0 | 163 | case "Contact:Remove:Return:OK": |
michael@0 | 164 | req = this.getRequest(msg.requestID); |
michael@0 | 165 | if (req) |
michael@0 | 166 | Services.DOMRequest.fireSuccess(req.request, null); |
michael@0 | 167 | break; |
michael@0 | 168 | case "Contacts:Find:Return:KO": |
michael@0 | 169 | case "Contact:Save:Return:KO": |
michael@0 | 170 | case "Contact:Remove:Return:KO": |
michael@0 | 171 | case "Contacts:Clear:Return:KO": |
michael@0 | 172 | case "Contacts:GetRevision:Return:KO": |
michael@0 | 173 | case "Contacts:Count:Return:KO": |
michael@0 | 174 | req = this.getRequest(msg.requestID); |
michael@0 | 175 | if (req) { |
michael@0 | 176 | if (req.request) { |
michael@0 | 177 | req = req.request; |
michael@0 | 178 | } |
michael@0 | 179 | Services.DOMRequest.fireError(req, msg.errorMsg); |
michael@0 | 180 | } |
michael@0 | 181 | break; |
michael@0 | 182 | case "Contacts:GetAll:Return:KO": |
michael@0 | 183 | req = this.getRequest(msg.requestID); |
michael@0 | 184 | if (req) { |
michael@0 | 185 | Services.DOMRequest.fireError(req.cursor, msg.errorMsg); |
michael@0 | 186 | } |
michael@0 | 187 | break; |
michael@0 | 188 | case "PermissionPromptHelper:AskPermission:OK": |
michael@0 | 189 | if (DEBUG) debug("id: " + msg.requestID); |
michael@0 | 190 | req = this.getRequest(msg.requestID); |
michael@0 | 191 | if (!req) { |
michael@0 | 192 | break; |
michael@0 | 193 | } |
michael@0 | 194 | |
michael@0 | 195 | if (msg.result == Ci.nsIPermissionManager.ALLOW_ACTION) { |
michael@0 | 196 | req.allow(); |
michael@0 | 197 | } else { |
michael@0 | 198 | req.cancel(); |
michael@0 | 199 | } |
michael@0 | 200 | break; |
michael@0 | 201 | case "Contact:Changed": |
michael@0 | 202 | // Fire oncontactchange event |
michael@0 | 203 | if (DEBUG) debug("Contacts:ContactChanged: " + msg.contactID + ", " + msg.reason); |
michael@0 | 204 | let event = new this._window.MozContactChangeEvent("contactchange", { |
michael@0 | 205 | contactID: msg.contactID, |
michael@0 | 206 | reason: msg.reason |
michael@0 | 207 | }); |
michael@0 | 208 | this.dispatchEvent(event); |
michael@0 | 209 | break; |
michael@0 | 210 | case "Contacts:Revision": |
michael@0 | 211 | if (DEBUG) debug("new revision: " + msg.revision); |
michael@0 | 212 | req = this.getRequest(msg.requestID); |
michael@0 | 213 | if (req) { |
michael@0 | 214 | Services.DOMRequest.fireSuccess(req.request, msg.revision); |
michael@0 | 215 | } |
michael@0 | 216 | break; |
michael@0 | 217 | case "Contacts:Count": |
michael@0 | 218 | if (DEBUG) debug("count: " + msg.count); |
michael@0 | 219 | req = this.getRequest(msg.requestID); |
michael@0 | 220 | if (req) { |
michael@0 | 221 | Services.DOMRequest.fireSuccess(req.request, msg.count); |
michael@0 | 222 | } |
michael@0 | 223 | break; |
michael@0 | 224 | default: |
michael@0 | 225 | if (DEBUG) debug("Wrong message: " + aMessage.name); |
michael@0 | 226 | } |
michael@0 | 227 | this.removeRequest(msg.requestID); |
michael@0 | 228 | }, |
michael@0 | 229 | |
michael@0 | 230 | dispatchEvent: function(event) { |
michael@0 | 231 | if (this.hasListenPermission) { |
michael@0 | 232 | this.__DOM_IMPL__.dispatchEvent(event); |
michael@0 | 233 | } |
michael@0 | 234 | }, |
michael@0 | 235 | |
michael@0 | 236 | askPermission: function (aAccess, aRequest, aAllowCallback, aCancelCallback) { |
michael@0 | 237 | if (DEBUG) debug("askPermission for contacts"); |
michael@0 | 238 | let access; |
michael@0 | 239 | switch(aAccess) { |
michael@0 | 240 | case "create": |
michael@0 | 241 | access = "create"; |
michael@0 | 242 | break; |
michael@0 | 243 | case "update": |
michael@0 | 244 | case "remove": |
michael@0 | 245 | access = "write"; |
michael@0 | 246 | break; |
michael@0 | 247 | case "find": |
michael@0 | 248 | case "listen": |
michael@0 | 249 | case "revision": |
michael@0 | 250 | case "count": |
michael@0 | 251 | access = "read"; |
michael@0 | 252 | break; |
michael@0 | 253 | default: |
michael@0 | 254 | access = "unknown"; |
michael@0 | 255 | } |
michael@0 | 256 | |
michael@0 | 257 | // Shortcut for ALLOW_ACTION so we avoid a parent roundtrip |
michael@0 | 258 | let type = "contacts-" + access; |
michael@0 | 259 | let permValue = |
michael@0 | 260 | Services.perms.testExactPermissionFromPrincipal(this._window.document.nodePrincipal, type); |
michael@0 | 261 | if (permValue == Ci.nsIPermissionManager.ALLOW_ACTION) { |
michael@0 | 262 | aAllowCallback(); |
michael@0 | 263 | return; |
michael@0 | 264 | } |
michael@0 | 265 | |
michael@0 | 266 | let requestID = this.getRequestId({ |
michael@0 | 267 | request: aRequest, |
michael@0 | 268 | allow: function() { |
michael@0 | 269 | aAllowCallback(); |
michael@0 | 270 | }.bind(this), |
michael@0 | 271 | cancel : function() { |
michael@0 | 272 | if (aCancelCallback) { |
michael@0 | 273 | aCancelCallback() |
michael@0 | 274 | } else if (aRequest) { |
michael@0 | 275 | Services.DOMRequest.fireError(aRequest, "Not Allowed"); |
michael@0 | 276 | } |
michael@0 | 277 | }.bind(this) |
michael@0 | 278 | }); |
michael@0 | 279 | |
michael@0 | 280 | let principal = this._window.document.nodePrincipal; |
michael@0 | 281 | cpmm.sendAsyncMessage("PermissionPromptHelper:AskPermission", { |
michael@0 | 282 | type: "contacts", |
michael@0 | 283 | access: access, |
michael@0 | 284 | requestID: requestID, |
michael@0 | 285 | origin: principal.origin, |
michael@0 | 286 | appID: principal.appId, |
michael@0 | 287 | browserFlag: principal.isInBrowserElement, |
michael@0 | 288 | windowID: this._window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils).outerWindowID |
michael@0 | 289 | }); |
michael@0 | 290 | }, |
michael@0 | 291 | |
michael@0 | 292 | save: function save(aContact) { |
michael@0 | 293 | // We have to do a deep copy of the contact manually here because |
michael@0 | 294 | // nsFrameMessageManager doesn't know how to create a structured clone of a |
michael@0 | 295 | // mozContact object. |
michael@0 | 296 | let newContact = {properties: {}}; |
michael@0 | 297 | |
michael@0 | 298 | try { |
michael@0 | 299 | for (let field of PROPERTIES) { |
michael@0 | 300 | // This hack makes sure modifications to the sequence attributes get validated. |
michael@0 | 301 | aContact[field] = aContact[field]; |
michael@0 | 302 | newContact.properties[field] = aContact[field]; |
michael@0 | 303 | } |
michael@0 | 304 | } catch (e) { |
michael@0 | 305 | // And then make sure we throw a proper error message (no internal file and line #) |
michael@0 | 306 | throw new this._window.DOMError(e.name, e.message); |
michael@0 | 307 | } |
michael@0 | 308 | |
michael@0 | 309 | let request = this.createRequest(); |
michael@0 | 310 | let requestID = this.getRequestId({request: request}); |
michael@0 | 311 | |
michael@0 | 312 | let reason; |
michael@0 | 313 | if (aContact.id == "undefined") { |
michael@0 | 314 | // for example {25c00f01-90e5-c545-b4d4-21E2ddbab9e0} becomes |
michael@0 | 315 | // 25c00f0190e5c545b4d421E2ddbab9e0 |
michael@0 | 316 | aContact.id = this._getRandomId().replace(/[{}-]/g, ""); |
michael@0 | 317 | // Cache the contact so that its ID may be updated later if necessary |
michael@0 | 318 | this._cachedContacts[requestID] = aContact; |
michael@0 | 319 | reason = "create"; |
michael@0 | 320 | } else { |
michael@0 | 321 | reason = "update"; |
michael@0 | 322 | } |
michael@0 | 323 | |
michael@0 | 324 | newContact.id = aContact.id; |
michael@0 | 325 | newContact.published = aContact.published; |
michael@0 | 326 | newContact.updated = aContact.updated; |
michael@0 | 327 | |
michael@0 | 328 | if (DEBUG) debug("send: " + JSON.stringify(newContact)); |
michael@0 | 329 | |
michael@0 | 330 | let options = { contact: newContact, reason: reason }; |
michael@0 | 331 | let allowCallback = function() { |
michael@0 | 332 | cpmm.sendAsyncMessage("Contact:Save", {requestID: requestID, options: options}); |
michael@0 | 333 | }.bind(this) |
michael@0 | 334 | this.askPermission(reason, request, allowCallback); |
michael@0 | 335 | return request; |
michael@0 | 336 | }, |
michael@0 | 337 | |
michael@0 | 338 | find: function(aOptions) { |
michael@0 | 339 | if (DEBUG) debug("find! " + JSON.stringify(aOptions)); |
michael@0 | 340 | let request = this.createRequest(); |
michael@0 | 341 | let options = { findOptions: aOptions }; |
michael@0 | 342 | let allowCallback = function() { |
michael@0 | 343 | cpmm.sendAsyncMessage("Contacts:Find", {requestID: this.getRequestId({request: request, reason: "find"}), options: options}); |
michael@0 | 344 | }.bind(this) |
michael@0 | 345 | this.askPermission("find", request, allowCallback); |
michael@0 | 346 | return request; |
michael@0 | 347 | }, |
michael@0 | 348 | |
michael@0 | 349 | createCursor: function CM_createCursor(aRequest) { |
michael@0 | 350 | let data = { |
michael@0 | 351 | cursor: Services.DOMRequest.createCursor(this._window, function() { |
michael@0 | 352 | this.handleContinue(id); |
michael@0 | 353 | }.bind(this)), |
michael@0 | 354 | cachedContacts: [], |
michael@0 | 355 | waitingForNext: true, |
michael@0 | 356 | }; |
michael@0 | 357 | let id = this.getRequestId(data); |
michael@0 | 358 | if (DEBUG) debug("saved cursor id: " + id); |
michael@0 | 359 | return [id, data.cursor]; |
michael@0 | 360 | }, |
michael@0 | 361 | |
michael@0 | 362 | getAll: function CM_getAll(aOptions) { |
michael@0 | 363 | if (DEBUG) debug("getAll: " + JSON.stringify(aOptions)); |
michael@0 | 364 | let [cursorId, cursor] = this.createCursor(); |
michael@0 | 365 | let allowCallback = function() { |
michael@0 | 366 | cpmm.sendAsyncMessage("Contacts:GetAll", { |
michael@0 | 367 | cursorId: cursorId, findOptions: aOptions}); |
michael@0 | 368 | }.bind(this); |
michael@0 | 369 | this.askPermission("find", cursor, allowCallback); |
michael@0 | 370 | return cursor; |
michael@0 | 371 | }, |
michael@0 | 372 | |
michael@0 | 373 | nextTick: function nextTick(aCallback) { |
michael@0 | 374 | Services.tm.currentThread.dispatch(aCallback, Ci.nsIThread.DISPATCH_NORMAL); |
michael@0 | 375 | }, |
michael@0 | 376 | |
michael@0 | 377 | handleContinue: function CM_handleContinue(aCursorId) { |
michael@0 | 378 | if (DEBUG) debug("handleContinue: " + aCursorId); |
michael@0 | 379 | let data = this.getRequest(aCursorId); |
michael@0 | 380 | if (data.cachedContacts.length > 0) { |
michael@0 | 381 | if (DEBUG) debug("contact in cache"); |
michael@0 | 382 | let contact = data.cachedContacts.shift(); |
michael@0 | 383 | this.nextTick(this._fireSuccessOrDone.bind(this, data.cursor, contact)); |
michael@0 | 384 | if (!contact) { |
michael@0 | 385 | this.removeRequest(aCursorId); |
michael@0 | 386 | } else if (data.cachedContacts.length === CONTACTS_SENDMORE_MINIMUM) { |
michael@0 | 387 | cpmm.sendAsyncMessage("Contacts:GetAll:SendNow", { cursorId: aCursorId }); |
michael@0 | 388 | } |
michael@0 | 389 | } else { |
michael@0 | 390 | if (DEBUG) debug("waiting for contact"); |
michael@0 | 391 | data.waitingForNext = true; |
michael@0 | 392 | } |
michael@0 | 393 | }, |
michael@0 | 394 | |
michael@0 | 395 | remove: function removeContact(aRecordOrId) { |
michael@0 | 396 | let request = this.createRequest(); |
michael@0 | 397 | let id; |
michael@0 | 398 | if (typeof aRecordOrId === "string") { |
michael@0 | 399 | id = aRecordOrId; |
michael@0 | 400 | } else if (!aRecordOrId || !aRecordOrId.id) { |
michael@0 | 401 | Services.DOMRequest.fireErrorAsync(request, true); |
michael@0 | 402 | return request; |
michael@0 | 403 | } else { |
michael@0 | 404 | id = aRecordOrId.id; |
michael@0 | 405 | } |
michael@0 | 406 | |
michael@0 | 407 | let options = { id: id }; |
michael@0 | 408 | let allowCallback = function() { |
michael@0 | 409 | cpmm.sendAsyncMessage("Contact:Remove", {requestID: this.getRequestId({request: request, reason: "remove"}), options: options}); |
michael@0 | 410 | }.bind(this); |
michael@0 | 411 | this.askPermission("remove", request, allowCallback); |
michael@0 | 412 | return request; |
michael@0 | 413 | }, |
michael@0 | 414 | |
michael@0 | 415 | clear: function() { |
michael@0 | 416 | if (DEBUG) debug("clear"); |
michael@0 | 417 | let request = this.createRequest(); |
michael@0 | 418 | let options = {}; |
michael@0 | 419 | let allowCallback = function() { |
michael@0 | 420 | cpmm.sendAsyncMessage("Contacts:Clear", {requestID: this.getRequestId({request: request, reason: "remove"}), options: options}); |
michael@0 | 421 | }.bind(this); |
michael@0 | 422 | this.askPermission("remove", request, allowCallback); |
michael@0 | 423 | return request; |
michael@0 | 424 | }, |
michael@0 | 425 | |
michael@0 | 426 | getRevision: function() { |
michael@0 | 427 | let request = this.createRequest(); |
michael@0 | 428 | |
michael@0 | 429 | let allowCallback = function() { |
michael@0 | 430 | cpmm.sendAsyncMessage("Contacts:GetRevision", { |
michael@0 | 431 | requestID: this.getRequestId({ request: request }) |
michael@0 | 432 | }); |
michael@0 | 433 | }.bind(this); |
michael@0 | 434 | |
michael@0 | 435 | let cancelCallback = function() { |
michael@0 | 436 | Services.DOMRequest.fireError(request); |
michael@0 | 437 | }; |
michael@0 | 438 | |
michael@0 | 439 | this.askPermission("revision", request, allowCallback, cancelCallback); |
michael@0 | 440 | return request; |
michael@0 | 441 | }, |
michael@0 | 442 | |
michael@0 | 443 | getCount: function() { |
michael@0 | 444 | let request = this.createRequest(); |
michael@0 | 445 | |
michael@0 | 446 | let allowCallback = function() { |
michael@0 | 447 | cpmm.sendAsyncMessage("Contacts:GetCount", { |
michael@0 | 448 | requestID: this.getRequestId({ request: request }) |
michael@0 | 449 | }); |
michael@0 | 450 | }.bind(this); |
michael@0 | 451 | |
michael@0 | 452 | let cancelCallback = function() { |
michael@0 | 453 | Services.DOMRequest.fireError(request); |
michael@0 | 454 | }; |
michael@0 | 455 | |
michael@0 | 456 | this.askPermission("count", request, allowCallback, cancelCallback); |
michael@0 | 457 | return request; |
michael@0 | 458 | }, |
michael@0 | 459 | |
michael@0 | 460 | init: function(aWindow) { |
michael@0 | 461 | // DOMRequestIpcHelper.initHelper sets this._window |
michael@0 | 462 | this.initDOMRequestHelper(aWindow, ["Contacts:Find:Return:OK", "Contacts:Find:Return:KO", |
michael@0 | 463 | "Contacts:Clear:Return:OK", "Contacts:Clear:Return:KO", |
michael@0 | 464 | "Contact:Save:Return:OK", "Contact:Save:Return:KO", |
michael@0 | 465 | "Contact:Remove:Return:OK", "Contact:Remove:Return:KO", |
michael@0 | 466 | "Contact:Changed", |
michael@0 | 467 | "PermissionPromptHelper:AskPermission:OK", |
michael@0 | 468 | "Contacts:GetAll:Next", "Contacts:GetAll:Return:KO", |
michael@0 | 469 | "Contacts:Count", |
michael@0 | 470 | "Contacts:Revision", "Contacts:GetRevision:Return:KO",]); |
michael@0 | 471 | |
michael@0 | 472 | |
michael@0 | 473 | let allowCallback = function() { |
michael@0 | 474 | cpmm.sendAsyncMessage("Contacts:RegisterForMessages"); |
michael@0 | 475 | this.hasListenPermission = true; |
michael@0 | 476 | }.bind(this); |
michael@0 | 477 | |
michael@0 | 478 | this.askPermission("listen", null, allowCallback); |
michael@0 | 479 | }, |
michael@0 | 480 | |
michael@0 | 481 | classID: Components.ID("{8beb3a66-d70a-4111-b216-b8e995ad3aff}"), |
michael@0 | 482 | contractID: "@mozilla.org/contactManager;1", |
michael@0 | 483 | QueryInterface: XPCOMUtils.generateQI([Ci.nsISupportsWeakReference, |
michael@0 | 484 | Ci.nsIObserver, |
michael@0 | 485 | Ci.nsIDOMGlobalPropertyInitializer]), |
michael@0 | 486 | }; |
michael@0 | 487 | |
michael@0 | 488 | this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ |
michael@0 | 489 | Contact, ContactManager |
michael@0 | 490 | ]); |