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 |
michael@0 | 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 4 | "use strict"; |
michael@0 | 5 | |
michael@0 | 6 | const { Cc, Ci, Cr, Cu } = require("chrome"); |
michael@0 | 7 | const { Input, start, stop, end, receive, outputs } = require("../event/utils"); |
michael@0 | 8 | const { once, off } = require("../event/core"); |
michael@0 | 9 | const { id: addonID } = require("../self"); |
michael@0 | 10 | |
michael@0 | 11 | const unloadMessage = require("@loader/unload"); |
michael@0 | 12 | const { addObserver, removeObserver } = Cc['@mozilla.org/observer-service;1']. |
michael@0 | 13 | getService(Ci.nsIObserverService); |
michael@0 | 14 | |
michael@0 | 15 | const addonUnloadTopic = "sdk:loader:destroy"; |
michael@0 | 16 | |
michael@0 | 17 | const isXrayWrapper = Cu.isXrayWrapper; |
michael@0 | 18 | // In the past SDK used to double-wrap notifications dispatched, which |
michael@0 | 19 | // made them awkward to use outside of SDK. At present they no longer |
michael@0 | 20 | // do that, although we still supported for legacy reasons. |
michael@0 | 21 | const isLegacyWrapper = x => |
michael@0 | 22 | x && x.wrappedJSObject && |
michael@0 | 23 | "observersModuleSubjectWrapper" in x.wrappedJSObject; |
michael@0 | 24 | |
michael@0 | 25 | const unwrapLegacy = x => x.wrappedJSObject.object; |
michael@0 | 26 | |
michael@0 | 27 | // `InputPort` provides a way to create a signal out of the observer |
michael@0 | 28 | // notification subject's for the given `topic`. If `options.initial` |
michael@0 | 29 | // is provided it is used as initial value otherwise `null` is used. |
michael@0 | 30 | // Constructor can be given `options.id` that will be used to create |
michael@0 | 31 | // a `topic` which is namespaced to an add-on (this avoids conflicts |
michael@0 | 32 | // when multiple add-on are used, although in a future host probably |
michael@0 | 33 | // should just be shared across add-ons). It is also possible to |
michael@0 | 34 | // specify a specific `topic` via `options.topic` which is used as |
michael@0 | 35 | // without namespacing. Created signal ends whenever add-on is |
michael@0 | 36 | // unloaded. |
michael@0 | 37 | const InputPort = function InputPort({id, topic, initial}) { |
michael@0 | 38 | this.id = id || topic; |
michael@0 | 39 | this.topic = topic || "sdk:" + addonID + ":" + id; |
michael@0 | 40 | this.value = initial === void(0) ? null : initial; |
michael@0 | 41 | this.observing = false; |
michael@0 | 42 | this[outputs] = []; |
michael@0 | 43 | }; |
michael@0 | 44 | |
michael@0 | 45 | // InputPort type implements `Input` signal interface. |
michael@0 | 46 | InputPort.prototype = new Input(); |
michael@0 | 47 | InputPort.prototype.constructor = InputPort; |
michael@0 | 48 | |
michael@0 | 49 | // When port is started (which is when it's subgraph get's |
michael@0 | 50 | // first subscriber) actual observer is registered. |
michael@0 | 51 | InputPort.start = input => { |
michael@0 | 52 | input.addListener(input); |
michael@0 | 53 | // Also register add-on unload observer to end this signal |
michael@0 | 54 | // when that happens. |
michael@0 | 55 | addObserver(input, addonUnloadTopic, false); |
michael@0 | 56 | }; |
michael@0 | 57 | InputPort.prototype[start] = InputPort.start; |
michael@0 | 58 | |
michael@0 | 59 | InputPort.addListener = input => addObserver(input, input.topic, false); |
michael@0 | 60 | InputPort.prototype.addListener = InputPort.addListener; |
michael@0 | 61 | |
michael@0 | 62 | // When port is stopped (which is when it's subgraph has no |
michael@0 | 63 | // no subcribers left) an actual observer unregistered. |
michael@0 | 64 | // Note that port stopped once it ends as well (which is when |
michael@0 | 65 | // add-on is unloaded). |
michael@0 | 66 | InputPort.stop = input => { |
michael@0 | 67 | input.removeListener(input); |
michael@0 | 68 | removeObserver(input, addonUnloadTopic); |
michael@0 | 69 | }; |
michael@0 | 70 | InputPort.prototype[stop] = InputPort.stop; |
michael@0 | 71 | |
michael@0 | 72 | InputPort.removeListener = input => removeObserver(input, input.topic); |
michael@0 | 73 | InputPort.prototype.removeListener = InputPort.removeListener; |
michael@0 | 74 | |
michael@0 | 75 | // `InputPort` also implements `nsIObserver` interface and |
michael@0 | 76 | // `nsISupportsWeakReference` interfaces as it's going to be used as such. |
michael@0 | 77 | InputPort.prototype.QueryInterface = function(iid) { |
michael@0 | 78 | if (!iid.equals(Ci.nsIObserver) && !iid.equals(Ci.nsISupportsWeakReference)) |
michael@0 | 79 | throw Cr.NS_ERROR_NO_INTERFACE; |
michael@0 | 80 | |
michael@0 | 81 | return this; |
michael@0 | 82 | }; |
michael@0 | 83 | |
michael@0 | 84 | // `InputPort` instances implement `observe` method, which is invoked when |
michael@0 | 85 | // observer notifications are dispatched. The `subject` of that notification |
michael@0 | 86 | // are received on this signal. |
michael@0 | 87 | InputPort.prototype.observe = function(subject, topic, data) { |
michael@0 | 88 | // Unwrap message from the subject. SDK used to have it's own version of |
michael@0 | 89 | // wrappedJSObjects which take precedence, if subject has `wrappedJSObject` |
michael@0 | 90 | // and it's not an XrayWrapper use it as message. Otherwise use subject as |
michael@0 | 91 | // is. |
michael@0 | 92 | const message = subject === null ? null : |
michael@0 | 93 | isLegacyWrapper(subject) ? unwrapLegacy(subject) : |
michael@0 | 94 | isXrayWrapper(subject) ? subject : |
michael@0 | 95 | subject.wrappedJSObject ? subject.wrappedJSObject : |
michael@0 | 96 | subject; |
michael@0 | 97 | |
michael@0 | 98 | // If observer topic matches topic of the input port receive a message. |
michael@0 | 99 | if (topic === this.topic) { |
michael@0 | 100 | receive(this, message); |
michael@0 | 101 | } |
michael@0 | 102 | |
michael@0 | 103 | // If observe topic is add-on unload topic we create an end message. |
michael@0 | 104 | if (topic === addonUnloadTopic && message === unloadMessage) { |
michael@0 | 105 | end(this); |
michael@0 | 106 | } |
michael@0 | 107 | }; |
michael@0 | 108 | |
michael@0 | 109 | exports.InputPort = InputPort; |