Bug 1478139 - Migrate <editor> to a Custom Element;r=paolo draft
authorBrian Grinstead <bgrinstead@mozilla.com>
Thu, 02 Aug 2018 13:22:45 -0700
changeset 826006 8fdae00d624bb81a54fce5018d85f7503c22fd70
parent 825858 a2d65d03e46a9a42b5bee5c2a7864d3f987a8ca7
push id118229
push userbgrinstead@mozilla.com
push dateThu, 02 Aug 2018 20:23:04 +0000
reviewerspaolo
bugs1478139
milestone63.0a1
Bug 1478139 - Migrate <editor> to a Custom Element;r=paolo MozReview-Commit-ID: IiTzndil1MV
toolkit/content/customElements.js
toolkit/content/jar.mn
toolkit/content/widgets/editor.js
toolkit/content/widgets/editor.xml
toolkit/content/xul.css
--- a/toolkit/content/customElements.js
+++ b/toolkit/content/customElements.js
@@ -121,9 +121,14 @@ for (let script of [
   Services.scriptloader.loadSubScript(script, window);
 }
 
 customElements.setElementCreationCallback("printpreview-toolbar", type => {
   Services.scriptloader.loadSubScript(
     "chrome://global/content/printPreviewToolbar.js", window);
 });
 
+customElements.setElementCreationCallback("editor", type => {
+  Services.scriptloader.loadSubScript(
+    "chrome://global/content/elements/editor.js", window);
+});
+
 }
--- a/toolkit/content/jar.mn
+++ b/toolkit/content/jar.mn
@@ -70,17 +70,16 @@ toolkit.jar:
    content/global/bindings/checkbox.xml        (widgets/checkbox.xml)
    content/global/bindings/colorpicker.xml     (widgets/colorpicker.xml)
    content/global/bindings/datekeeper.js       (widgets/datekeeper.js)
    content/global/bindings/datepicker.js       (widgets/datepicker.js)
    content/global/bindings/datetimepopup.xml   (widgets/datetimepopup.xml)
    content/global/bindings/datetimebox.xml     (widgets/datetimebox.xml)
    content/global/bindings/datetimebox.css     (widgets/datetimebox.css)
 *  content/global/bindings/dialog.xml          (widgets/dialog.xml)
-   content/global/bindings/editor.xml          (widgets/editor.xml)
 *  content/global/bindings/findbar.xml         (widgets/findbar.xml)
    content/global/bindings/general.xml         (widgets/general.xml)
    content/global/bindings/groupbox.xml        (widgets/groupbox.xml)
    content/global/bindings/menu.xml            (widgets/menu.xml)
    content/global/bindings/menulist.xml        (widgets/menulist.xml)
    content/global/bindings/notification.xml    (widgets/notification.xml)
    content/global/bindings/numberbox.xml       (widgets/numberbox.xml)
    content/global/bindings/popup.xml           (widgets/popup.xml)
@@ -95,15 +94,16 @@ toolkit.jar:
 *  content/global/bindings/textbox.xml         (widgets/textbox.xml)
    content/global/bindings/timekeeper.js       (widgets/timekeeper.js)
    content/global/bindings/timepicker.js       (widgets/timepicker.js)
    content/global/bindings/toolbar.xml         (widgets/toolbar.xml)
    content/global/bindings/toolbarbutton.xml   (widgets/toolbarbutton.xml)
    content/global/bindings/tree.xml            (widgets/tree.xml)
    content/global/bindings/videocontrols.xml   (widgets/videocontrols.xml)
 *  content/global/bindings/wizard.xml          (widgets/wizard.xml)
-   content/global/elements/general.js           (widgets/general.js)
+   content/global/elements/editor.js           (widgets/editor.js)
+   content/global/elements/general.js          (widgets/general.js)
    content/global/elements/stringbundle.js     (widgets/stringbundle.js)
 #ifdef XP_MACOSX
    content/global/macWindowMenu.js
 #endif
    content/global/gmp-sources/openh264.json    (gmp-sources/openh264.json)
    content/global/gmp-sources/widevinecdm.json (gmp-sources/widevinecdm.json)
rename from toolkit/content/widgets/editor.xml
rename to toolkit/content/widgets/editor.js
--- a/toolkit/content/widgets/editor.xml
+++ b/toolkit/content/widgets/editor.js
@@ -1,166 +1,161 @@
-<?xml version="1.0"?>
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
-   - 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/. -->
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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/. */
 
+"use strict";
 
-<bindings id="editorBindings"
-   xmlns="http://www.mozilla.org/xbl"
-   xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-   xmlns:xbl="http://www.mozilla.org/xbl">
+{
+
+/* globals XULFrameElement */
 
-  <binding id="editor">
-    <implementation type="application/javascript">
-      <constructor>
-        <![CDATA[
-          // Make window editable immediately only
-          //   if the "editortype" attribute is supplied
-          // This allows using same contentWindow for different editortypes,
-          //   where the type is determined during the apps's window.onload handler.
-          if (this.editortype)
-            this.makeEditable(this.editortype, true);
-        ]]>
-      </constructor>
-      <destructor/>
+class MozEditor extends XULFrameElement {
+  connectedCallback() {
+    this._editorContentListener = {
+      QueryInterface: ChromeUtils.generateQI(["nsIURIContentListener",
+        "nsISupportsWeakReference"
+      ]),
+      onStartURIOpen(uri) {
+        return false;
+      },
+      doContent(contentType, isContentPreferred, request, contentHandler) {
+        return false;
+      },
+      isPreferred(contentType, desiredContentType) {
+        return false;
+      },
+      canHandleContent(contentType, isContentPreferred, desiredContentType) {
+        return false;
+      },
+      loadCookie: null,
+      parentContentListener: null
+    };
+
+    this._finder = null;
+
+    this._fastFind = null;
+
+    this._lastSearchString = null;
 
-      <field name="_editorContentListener">
-        <![CDATA[
-          ({
-            QueryInterface: ChromeUtils.generateQI(["nsIURIContentListener",
-                                                    "nsISupportsWeakReference"]),
-            onStartURIOpen(uri) {
-              return false;
-            },
-            doContent(contentType, isContentPreferred, request, contentHandler) {
-              return false;
-            },
-            isPreferred(contentType, desiredContentType) {
-              return false;
-            },
-            canHandleContent(contentType, isContentPreferred, desiredContentType) {
-              return false;
-            },
-            loadCookie: null,
-            parentContentListener: null
-          })
-        ]]>
-      </field>
-      <method name="makeEditable">
-        <parameter name="editortype"/>
-        <parameter name="waitForUrlLoad"/>
-        <body>
-        <![CDATA[
-          this.editingSession.makeWindowEditable(this.contentWindow, editortype, waitForUrlLoad, true, false);
-          this.setAttribute("editortype", editortype);
+    // Make window editable immediately only
+    //   if the "editortype" attribute is supplied
+    // This allows using same contentWindow for different editortypes,
+    //   where the type is determined during the apps's window.onload handler.
+    if (this.editortype)
+      this.makeEditable(this.editortype, true);
+  }
+
+  get finder() {
+    if (!this._finder) {
+      if (!this.docShell)
+        return null;
+
+      let Finder = ChromeUtils.import("resource://gre/modules/Finder.jsm", {}).Finder;
+      this._finder = new Finder(this.docShell);
+    }
+    return this._finder;
+  }
 
-          this.docShell.QueryInterface(Ci.nsIInterfaceRequestor)
-              .getInterface(Ci.nsIURIContentListener)
-              .parentContentListener = this._editorContentListener;
-        ]]>
-        </body>
-      </method>
-      <method name="getEditor">
-        <parameter name="containingWindow"/>
-        <body>
-        <![CDATA[
-          return this.editingSession.getEditorForWindow(containingWindow);
-        ]]>
-        </body>
-      </method>
-      <method name="getHTMLEditor">
-        <parameter name="containingWindow"/>
-        <body>
-        <![CDATA[
-          var editor = this.editingSession.getEditorForWindow(containingWindow);
-          return editor.QueryInterface(Ci.nsIHTMLEditor);
-        ]]>
-        </body>
-      </method>
+  get fastFind() {
+    if (!this._fastFind) {
+      if (!("@mozilla.org/typeaheadfind;1" in Cc))
+        return null;
+
+      if (!this.docShell)
+        return null;
+
+      this._fastFind = Cc["@mozilla.org/typeaheadfind;1"]
+        .createInstance(Ci.nsITypeAheadFind);
+      this._fastFind.init(this.docShell);
+    }
+    return this._fastFind;
+  }
+
+  set editortype(val) {
+    this.setAttribute("editortype", val);
+    return val;
+  }
+
+  get editortype() {
+    return this.getAttribute("editortype");
+  }
 
-      <field name="_finder">null</field>
-      <property name="finder" readonly="true">
-        <getter><![CDATA[
-          if (!this._finder) {
-            if (!this.docShell)
-              return null;
+  get currentURI() {
+    return this.webNavigation.currentURI;
+  }
+
+  get contentWindowAsCPOW() {
+    return this.contentWindow;
+  }
 
-            let Finder = ChromeUtils.import("resource://gre/modules/Finder.jsm", {}).Finder;
-            this._finder = new Finder(this.docShell);
-          }
-          return this._finder;
-        ]]></getter>
-      </property>
+  get webBrowserFind() {
+    return this.docShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebBrowserFind);
+  }
+
+  get markupDocumentViewer() {
+    return this.docShell.contentViewer;
+  }
+
+  get editingSession() {
+    return this.webNavigation.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIEditingSession);
+  }
 
-      <field name="_fastFind">null</field>
-      <property name="fastFind"
-                readonly="true">
-        <getter>
-        <![CDATA[
-          if (!this._fastFind) {
-            if (!("@mozilla.org/typeaheadfind;1" in Cc))
-              return null;
+  get commandManager() {
+    return this.webNavigation.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsICommandManager);
+  }
+
+  set fullZoom(val) {
+    this.markupDocumentViewer.fullZoom = val;
+  }
 
-            if (!this.docShell)
-              return null;
+  get fullZoom() {
+    return this.markupDocumentViewer.fullZoom;
+  }
 
-            this._fastFind = Cc["@mozilla.org/typeaheadfind;1"]
-                               .createInstance(Ci.nsITypeAheadFind);
-            this._fastFind.init(this.docShell);
-          }
-          return this._fastFind;
-        ]]>
-        </getter>
-      </property>
+  set textZoom(val) {
+    this.markupDocumentViewer.textZoom = val;
+  }
 
-      <field name="_lastSearchString">null</field>
+  get textZoom() {
+    return this.markupDocumentViewer.textZoom;
+  }
 
-      <property name="editortype"
-                onget="return this.getAttribute('editortype');"
-                onset="this.setAttribute('editortype', val); return val;"/>
-      <property name="currentURI"
-                readonly="true"
-                onget="return this.webNavigation.currentURI;"/>
-      <property name="contentWindowAsCPOW"
-                readonly="true"
-                onget="return this.contentWindow;"/>
-      <property name="webBrowserFind"
-                readonly="true"
-                onget="return this.docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIWebBrowserFind);"/>
-      <property name="markupDocumentViewer"
-                readonly="true"
-                onget="return this.docShell.contentViewer;"/>
-      <property name="editingSession"
-                readonly="true"
-                onget="return this.webNavigation.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIEditingSession);"/>
-      <property name="commandManager"
-                readonly="true"
-                onget="return this.webNavigation.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsICommandManager);"/>
-      <property name="fullZoom"
-                onget="return this.markupDocumentViewer.fullZoom;"
-                onset="this.markupDocumentViewer.fullZoom = val;"/>
-      <property name="textZoom"
-                onget="return this.markupDocumentViewer.textZoom;"
-                onset="this.markupDocumentViewer.textZoom = val;"/>
-      <property name="isSyntheticDocument"
-                onget="return this.contentDocument.isSyntheticDocument;"
-                readonly="true"/>
-      <property name="messageManager"
-                readonly="true">
-        <getter>
-          <![CDATA[
-            if (this.frameLoader) {
-              return this.frameLoader.messageManager;
-            }
-            return null;
-          ]]>
-        </getter>
-      </property>
-      <property name="outerWindowID" readonly="true">
-        <getter><![CDATA[
-          return this.contentWindow.windowUtils.outerWindowID;
-        ]]></getter>
-      </property>
-    </implementation>
-  </binding>
+  get isSyntheticDocument() {
+    return this.contentDocument.isSyntheticDocument;
+  }
+
+  get messageManager() {
+    if (this.frameLoader) {
+      return this.frameLoader.messageManager;
+    }
+    return null;
+  }
+
+  get outerWindowID() {
+    return this.contentWindow
+      .QueryInterface(Ci.nsIInterfaceRequestor)
+      .getInterface(Ci.nsIDOMWindowUtils)
+      .outerWindowID;
+  }
 
-</bindings>
+  makeEditable(editortype, waitForUrlLoad) {
+    this.editingSession.makeWindowEditable(this.contentWindow, editortype, waitForUrlLoad, true, false);
+    this.setAttribute("editortype", editortype);
+
+    this.docShell.QueryInterface(Ci.nsIInterfaceRequestor)
+      .getInterface(Ci.nsIURIContentListener)
+      .parentContentListener = this._editorContentListener;
+  }
+
+  getEditor(containingWindow) {
+    return this.editingSession.getEditorForWindow(containingWindow);
+  }
+
+  getHTMLEditor(containingWindow) {
+    var editor = this.editingSession.getEditorForWindow(containingWindow);
+    return editor.QueryInterface(Ci.nsIHTMLEditor);
+  }
+}
+
+customElements.define("editor", MozEditor);
+
+}
--- a/toolkit/content/xul.css
+++ b/toolkit/content/xul.css
@@ -169,20 +169,16 @@ iframe {
 browser {
   -moz-binding: url("chrome://global/content/bindings/browser.xml#browser");
 }
 
 browser[remote=true]:not(.lightweight) {
   -moz-binding: url("chrome://global/content/bindings/remote-browser.xml#remote-browser");
 }
 
-editor {
-  -moz-binding: url("chrome://global/content/bindings/editor.xml#editor");
-}
-
 /********** notifications **********/
 
 notificationbox {
   -moz-binding: url("chrome://global/content/bindings/notification.xml#notificationbox");
   -moz-box-orient: vertical;
 }
 
 .notificationbox-stack {