Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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 } = require("chrome"); |
michael@0 | 7 | const { Input, start, stop, receive, outputs } = require("../event/utils"); |
michael@0 | 8 | const { id: addonID } = require("../self"); |
michael@0 | 9 | const { setImmediate } = require("../timers"); |
michael@0 | 10 | const { notifyObservers } = Cc['@mozilla.org/observer-service;1']. |
michael@0 | 11 | getService(Ci.nsIObserverService); |
michael@0 | 12 | |
michael@0 | 13 | const NOT_AN_INPUT = "OutputPort can be used only for sending messages"; |
michael@0 | 14 | |
michael@0 | 15 | // `OutputPort` creates a port to which messages can be send. Those |
michael@0 | 16 | // messages are actually disptached as `subject`'s of the observer |
michael@0 | 17 | // notifications. This is handy for communicating between different |
michael@0 | 18 | // components of the SDK. By default messages are dispatched |
michael@0 | 19 | // asynchronously, although `options.sync` can be used to make them |
michael@0 | 20 | // synchronous. If `options.id` is given `topic` for observer |
michael@0 | 21 | // notifications is generated by namespacing it, to avoid spamming |
michael@0 | 22 | // other SDK add-ons. It's also possible to provide `options.topic` |
michael@0 | 23 | // to use excat `topic` without namespacing it. |
michael@0 | 24 | // |
michael@0 | 25 | // Note: Symmetric `new InputPort({ id: "x" })` instances can be used to |
michael@0 | 26 | // receive messages send to the instances of `new OutputPort({ id: "x" })`. |
michael@0 | 27 | const OutputPort = function({id, topic, sync}) { |
michael@0 | 28 | this.id = id || topic; |
michael@0 | 29 | this.sync = !!sync; |
michael@0 | 30 | this.topic = topic || "sdk:" + addonID + ":" + id; |
michael@0 | 31 | }; |
michael@0 | 32 | // OutputPort extends base signal type to implement same message |
michael@0 | 33 | // receiving interface. |
michael@0 | 34 | OutputPort.prototype = new Input(); |
michael@0 | 35 | OutputPort.constructor = OutputPort; |
michael@0 | 36 | |
michael@0 | 37 | // OutputPort can not be consumed there for starting or stopping it |
michael@0 | 38 | // is not supported. |
michael@0 | 39 | OutputPort.prototype[start] = _ => { throw TypeError(NOT_AN_INPUT); }; |
michael@0 | 40 | OutputPort.prototype[stop] = _ => { throw TypeError(NOT_AN_INPUT); }; |
michael@0 | 41 | |
michael@0 | 42 | // Port reecives message send to it, which will be dispatched via |
michael@0 | 43 | // observer notification service. |
michael@0 | 44 | OutputPort.receive = ({topic, sync}, message) => { |
michael@0 | 45 | const type = typeof(message); |
michael@0 | 46 | const supported = message === null || |
michael@0 | 47 | type === "object" || |
michael@0 | 48 | type === "function"; |
michael@0 | 49 | |
michael@0 | 50 | // There is no sensible way to wrap JS primitives that would make sense |
michael@0 | 51 | // for general observer notification users. It's also probably not very |
michael@0 | 52 | // useful to dispatch JS primitives as subject of observer service, there |
michael@0 | 53 | // for we do not support those use cases. |
michael@0 | 54 | if (!supported) |
michael@0 | 55 | throw new TypeError("Unsupproted message type: `" + type + "`"); |
michael@0 | 56 | |
michael@0 | 57 | // Normalize `message` to create a valid observer notification `subject`. |
michael@0 | 58 | // If `message` is `null`, implements `nsISupports` interface or already |
michael@0 | 59 | // represents wrapped JS object use it as is. Otherwise create a wrapped |
michael@0 | 60 | // object so that observers could receive it. |
michael@0 | 61 | const subject = message === null ? null : |
michael@0 | 62 | message instanceof Ci.nsISupports ? message : |
michael@0 | 63 | message.wrappedJSObject ? message : |
michael@0 | 64 | {wrappedJSObject: message}; |
michael@0 | 65 | if (sync) |
michael@0 | 66 | notifyObservers(subject, topic, null); |
michael@0 | 67 | else |
michael@0 | 68 | setImmediate(notifyObservers, subject, topic, null); |
michael@0 | 69 | }; |
michael@0 | 70 | OutputPort.prototype[receive] = OutputPort.receive; |
michael@0 | 71 | exports.OutputPort = OutputPort; |