No bug - fix merge conflict mistake r=Aryx on a CLOSED TREE

--HG--
extra : amend_source : 78dc5d2a30fb4208ca64ed8bde4db3fda63cb86b
This commit is contained in:
Andreea Pavel 2018-06-30 13:57:50 +03:00
parent 1bf7ac45bb
commit c5bb0d1b10

View File

@ -260,280 +260,6 @@ function flushJarCache(jarPath) {
Services.obs.notifyObservers(null, "flush-cache-entry", jarPath);
}
<<<<<<< working copy
=======
/**
* Convert any of several different representations of a date/time to a Date object.
* Accepts several formats:
* a Date object, an ISO8601 string, or a number of milliseconds since the epoch as
* either a number or a string.
*
* @param {Date|string|number} date
* The date to convert.
* @returns {Date}
* A Date object
*/
function normalizeTime(date) {
// Of all the formats we accept the "number of milliseconds since the epoch as a string"
// is an outlier, everything else can just be passed directly to the Date constructor.
return new Date((typeof date == "string" && /^\d+$/.test(date))
? parseInt(date, 10) : date);
}
/**
* Defines a lazy getter for the given property on the given object. The
* first time the property is accessed, the return value of the getter
* is defined on the current `this` object with the given property name.
* Importantly, this means that a lazy getter defined on an object
* prototype will be invoked separately for each object instance that
* it's accessed on.
*
* @param {object} object
* The prototype object on which to define the getter.
* @param {string|Symbol} prop
* The property name for which to define the getter.
* @param {function} getter
* The function to call in order to generate the final property
* value.
*/
function defineLazyGetter(object, prop, getter) {
let redefine = (obj, value) => {
Object.defineProperty(obj, prop, {
enumerable: true,
configurable: true,
writable: true,
value,
});
return value;
};
Object.defineProperty(object, prop, {
enumerable: true,
configurable: true,
get() {
return redefine(this, getter.call(this));
},
set(value) {
redefine(this, value);
},
});
}
/**
* Acts as a proxy for a message manager or message manager owner, and
* tracks docShell swaps so that messages are always sent to the same
* receiver, even if it is moved to a different <browser>.
*
* @param {nsIMessageSender|Element} target
* The target message manager on which to send messages, or the
* <browser> element which owns it.
*/
class MessageManagerProxy {
constructor(target) {
this.listeners = new DefaultMap(() => new Map());
this.closed = false;
if (target instanceof Ci.nsIMessageSender) {
this.messageManager = target;
} else {
this.addListeners(target);
}
Services.obs.addObserver(this, "message-manager-close");
}
/**
* Disposes of the proxy object, removes event listeners, and drops
* all references to the underlying message manager.
*
* Must be called before the last reference to the proxy is dropped,
* unless the underlying message manager or <browser> is also being
* destroyed.
*/
dispose() {
if (this.eventTarget) {
this.removeListeners(this.eventTarget);
this.eventTarget = null;
}
this.messageManager = null;
Services.obs.removeObserver(this, "message-manager-close");
}
observe(subject, topic, data) {
if (topic === "message-manager-close") {
if (subject === this.messageManager) {
this.closed = true;
}
}
}
/**
* Returns true if the given target is the same as, or owns, the given
* message manager.
*
* @param {nsIMessageSender|MessageManagerProxy|Element} target
* The message manager, MessageManagerProxy, or <browser>
* element against which to match.
* @param {nsIMessageSender} messageManager
* The message manager against which to match `target`.
*
* @returns {boolean}
* True if `messageManager` is the same object as `target`, or
* `target` is a MessageManagerProxy or <browser> element that
* is tied to it.
*/
static matches(target, messageManager) {
return target === messageManager || target.messageManager === messageManager;
}
/**
* @property {nsIMessageSender|null} messageManager
* The message manager that is currently being proxied. This
* may change during the life of the proxy object, so should
* not be stored elsewhere.
*/
/**
* Sends a message on the proxied message manager.
*
* @param {array} args
* Arguments to be passed verbatim to the underlying
* sendAsyncMessage method.
* @returns {undefined}
*/
sendAsyncMessage(...args) {
if (this.messageManager) {
return this.messageManager.sendAsyncMessage(...args);
}
Cu.reportError(`Cannot send message: Other side disconnected: ${uneval(args)}`);
}
get isDisconnected() {
return this.closed || !this.messageManager;
}
/**
* Adds a message listener to the current message manager, and
* transfers it to the new message manager after a docShell swap.
*
* @param {string} message
* The name of the message to listen for.
* @param {nsIMessageListener} listener
* The listener to add.
* @param {boolean} [listenWhenClosed = false]
* If true, the listener will receive messages which were sent
* after the remote side of the listener began closing.
*/
addMessageListener(message, listener, listenWhenClosed = false) {
this.messageManager.addMessageListener(message, listener, listenWhenClosed);
this.listeners.get(message).set(listener, listenWhenClosed);
}
/**
* Adds a message listener from the current message manager.
*
* @param {string} message
* The name of the message to stop listening for.
* @param {nsIMessageListener} listener
* The listener to remove.
*/
removeMessageListener(message, listener) {
this.messageManager.removeMessageListener(message, listener);
let listeners = this.listeners.get(message);
listeners.delete(listener);
if (!listeners.size) {
this.listeners.delete(message);
}
}
/**
* @private
* Iterates over all of the currently registered message listeners.
*/
* iterListeners() {
for (let [message, listeners] of this.listeners) {
for (let [listener, listenWhenClosed] of listeners) {
yield {message, listener, listenWhenClosed};
}
}
}
/**
* @private
* Adds docShell swap listeners to the message manager owner.
*
* @param {Element} target
* The target element.
*/
addListeners(target) {
target.addEventListener("SwapDocShells", this);
this.eventTarget = target;
this.messageManager = target.messageManager;
for (let {message, listener, listenWhenClosed} of this.iterListeners()) {
this.messageManager.addMessageListener(message, listener, listenWhenClosed);
}
}
/**
* @private
* Removes docShell swap listeners to the message manager owner.
*
* @param {Element} target
* The target element.
*/
removeListeners(target) {
target.removeEventListener("SwapDocShells", this);
for (let {message, listener} of this.iterListeners()) {
this.messageManager.removeMessageListener(message, listener);
}
}
handleEvent(event) {
if (event.type == "SwapDocShells") {
this.removeListeners(this.eventTarget);
this.addListeners(event.detail);
}
}
}
function checkLoadURL(url, principal, options) {
let ssm = Services.scriptSecurityManager;
let flags = ssm.STANDARD;
if (!options.allowScript) {
flags |= ssm.DISALLOW_SCRIPT;
}
if (!options.allowInheritsPrincipal) {
flags |= ssm.DISALLOW_INHERIT_PRINCIPAL;
}
if (options.dontReportErrors) {
flags |= ssm.DONT_REPORT_ERRORS;
}
try {
ssm.checkLoadURIWithPrincipal(principal,
Services.io.newURI(url),
flags);
} catch (e) {
return false;
}
return true;
}
function makeWidgetId(id) {
id = id.toLowerCase();
// FIXME: This allows for collisions.
return id.replace(/[^a-z0-9_-]/g, "_");
}
const chromeModifierKeyMap = {
"Alt": "alt",
"Command": "accel",
@ -543,9 +269,7 @@ const chromeModifierKeyMap = {
};
var ExtensionUtils = {
checkLoadURL,
chromeModifierKeyMap,
defineLazyGetter,
flushJarCache,
getInnerWindowID,
getMessageManager,