Bug 1461742, shared method to indicate that a custom element implements one or more interfaces, r=bgrins

This commit is contained in:
Neil Deakin 2018-07-19 08:38:51 -04:00
Родитель 0cc9fd046c
Коммит c68cebacd6
1 изменённых файлов: 50 добавлений и 0 удалений

Просмотреть файл

@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* globals MozQueryInterface */
"use strict";
// This is loaded into all XUL windows. Wrap in a block to prevent
@ -59,6 +61,54 @@ class MozXULElement extends XULElement {
range.selectNodeContents(doc.querySelector("box"));
return range.extractContents();
}
/**
* Indicate that a class defining an element implements one or more
* XPCOM interfaces. The custom element getCustomInterface is added
* as well as an implementation of QueryInterface.
*
* The supplied class should implement the properties and methods of
* all of the interfaces that are specified.
*
* @param cls
* The class that implements the interface.
* @param names
* Array of interface names
*/
static implementCustomInterface(cls, ifaces) {
cls.prototype.QueryInterface = ChromeUtils.generateQI(ifaces);
cls.prototype.getCustomInterfaceCallback = function getCustomInterfaceCallback(iface) {
if (ifaces.includes(Ci[Components.interfacesByID[iface.number]])) {
return getInterfaceProxy(this);
}
return null;
};
}
}
/**
* Given an object, add a proxy that reflects interface implementations
* onto the object itself.
*/
function getInterfaceProxy(obj) {
if (!obj._customInterfaceProxy) {
obj._customInterfaceProxy = new Proxy(obj, {
get(target, prop, receiver) {
let propOrMethod = target[prop];
if (typeof propOrMethod == "function") {
if (propOrMethod instanceof MozQueryInterface) {
return Reflect.get(target, prop, receiver);
}
return function(...args) {
return propOrMethod.apply(target, args);
};
}
return propOrMethod;
}
});
}
return obj._customInterfaceProxy;
}
// Attach the base class to the window so other scripts can use it: