Bug 1499476 - Add the ability to mixin the base MozXULElement;r=paolo
authorBrian Grinstead <bgrinstead@mozilla.com>
Tue, 16 Oct 2018 19:59:16 +0000
changeset 489887 425bec190a04d3de38be9ded779d25b57c35849e
parent 489886 943c165146e677a243702a51d5d9f3a5cfe163ba
child 489888 d4fe026dee75521ac39478591cb84d782eb0b189
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewerspaolo
bugs1499476
milestone64.0a1
Bug 1499476 - Add the ability to mixin the base MozXULElement;r=paolo Differential Revision: https://phabricator.services.mozilla.com/D8898
toolkit/content/customElements.js
toolkit/content/tests/chrome/test_custom_element_base.xul
--- a/toolkit/content/customElements.js
+++ b/toolkit/content/customElements.js
@@ -29,17 +29,17 @@ window.addEventListener("DOMContentLoade
     } catch (ex) { console.error(ex); }
   }
   gElementsPendingConnection.clear();
 }, { once: true, capture: true });
 
 const gXULDOMParser = new DOMParser();
 gXULDOMParser.forceEnableXULXBL();
 
-class MozXULElement extends XULElement {
+const MozElementMixin = Base => class MozElement extends Base {
   /**
    * Sometimes an element may not want to run connectedCallback logic during
    * parse. This could be because we don't want to initialize the element before
    * the element's contents have been fully parsed, or for performance reasons.
    * If you'd like to opt-in to this, then add this to the beginning of your
    * `connectedCallback` and `disconnectedCallback`:
    *
    *    if (this.delayConnectedCallback()) { return }
@@ -174,17 +174,19 @@ class MozXULElement extends XULElement {
     cls.prototype.customInterfaceNumbers = numbers;
     cls.prototype.getCustomInterfaceCallback = function getCustomInterfaceCallback(iface) {
       if (numbers.has(iface.number)) {
         return getInterfaceProxy(this);
       }
       return null;
     };
   }
-}
+};
+
+const MozXULElement = MozElementMixin(XULElement);
 
 /**
  * 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, {
@@ -230,16 +232,17 @@ class MozBaseControl extends MozXULEleme
       this.removeAttribute("tabindex");
     }
   }
 }
 
 MozXULElement.implementCustomInterface(MozBaseControl, [Ci.nsIDOMXULControlElement]);
 
 // Attach the base class to the window so other scripts can use it:
+window.MozElementMixin = MozElementMixin;
 window.MozXULElement = MozXULElement;
 window.MozBaseControl = MozBaseControl;
 
 // For now, don't load any elements in the extension dummy document.
 // We will want to load <browser> when that's migrated (bug 1441935).
 const isDummyDocument = document.documentURI == "chrome://extensions/content/dummy.xul";
 if (!isDummyDocument) {
   for (let script of [
--- a/toolkit/content/tests/chrome/test_custom_element_base.xul
+++ b/toolkit/content/tests/chrome/test_custom_element_base.xul
@@ -20,30 +20,37 @@
 
   <!-- test code goes here -->
   <script type="application/javascript"><![CDATA[
 
   SimpleTest.waitForExplicitFinish();
 
   async function runTests() {
     ok(MozXULElement, "MozXULElement defined on the window");
+    testMixin();
     testParseXULToFragment();
     await testCustomInterface();
 
     let htmlWin = await new Promise(resolve => {
       let htmlIframe = document.createElement("iframe");
       htmlIframe.src = "file_empty.xhtml";
       htmlIframe.onload = () => resolve(htmlIframe.contentWindow);
       document.documentElement.appendChild(htmlIframe);
     });
 
     ok(htmlWin.MozXULElement, "MozXULElement defined on a chrome HTML window");
     SimpleTest.finish();
   }
 
+  function testMixin() {
+    ok(MozElementMixin, "Mixin exists");
+    let MixedHTMLElement = MozElementMixin(HTMLElement);
+    ok(MixedHTMLElement.insertFTLIfNeeded, "Mixed in class contains helper functions");
+  }
+
   function testParseXULToFragment() {
     ok(MozXULElement.parseXULToFragment, "parseXULToFragment helper exists");
 
     let frag = MozXULElement.parseXULToFragment(`<deck id='foo' />`);
     ok(frag instanceof DocumentFragment);
 
     document.documentElement.appendChild(frag);