Bug 1459245 - Migrate <stringbundle> from a XBL binding to a Custom Element;r=mossop
This loads a JS file to register the Custom Element whenever XUL documents
get created. This is a pattern we plan to follow for future elements as well -
stringbundle is just an easy target to prove it out with.
MozReview-Commit-ID: 7PlisCknrKW
--- a/toolkit/components/processsingleton/MainProcessSingleton.js
+++ b/toolkit/components/processsingleton/MainProcessSingleton.js
@@ -60,26 +60,44 @@ MainProcessSingleton.prototype = {
Services.search.addEngine(engineURL.spec, null, iconURL ? iconURL.spec : null, true);
});
},
observe(subject, topic, data) {
switch (topic) {
case "app-startup": {
Services.obs.addObserver(this, "xpcom-shutdown");
+ Services.obs.addObserver(this, "document-element-inserted");
// Load this script early so that console.* is initialized
// before other frame scripts.
Services.mm.loadFrameScript("chrome://global/content/browser-content.js", true);
Services.ppmm.loadProcessScript("chrome://global/content/process-content.js", true);
Services.mm.addMessageListener("Search:AddEngine", this.addSearchEngine);
Services.ppmm.loadProcessScript("resource:///modules/ContentObservers.js", true);
break;
}
+ case "document-element-inserted":
+ // Set up Custom Elements for XUL windows before anything else happens
+ // in the document. Anything loaded here should be considered part of
+ // core XUL functionality. Any window-specific elements can be registered
+ // via <script> tags at the top of individual documents.
+ const doc = subject;
+ if (doc.nodePrincipal.isSystemPrincipal &&
+ doc.contentType == "application/vnd.mozilla.xul+xml") {
+ for (let script of [
+ "chrome://global/content/elements/stringbundle.js",
+ ]) {
+ Services.scriptloader.loadSubScript(script, doc.ownerGlobal);
+ }
+ }
+ break;
+
case "xpcom-shutdown":
Services.mm.removeMessageListener("Search:AddEngine", this.addSearchEngine);
+ Services.obs.removeObserver(this, "document-element-inserted");
break;
}
},
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([MainProcessSingleton]);
--- a/toolkit/content/jar.mn
+++ b/toolkit/content/jar.mn
@@ -85,24 +85,24 @@ toolkit.jar:
content/global/bindings/popup.xml (widgets/popup.xml)
content/global/bindings/progressmeter.xml (widgets/progressmeter.xml)
content/global/bindings/radio.xml (widgets/radio.xml)
content/global/bindings/remote-browser.xml (widgets/remote-browser.xml)
content/global/bindings/richlistbox.xml (widgets/richlistbox.xml)
content/global/bindings/scale.xml (widgets/scale.xml)
content/global/bindings/scrollbox.xml (widgets/scrollbox.xml)
content/global/bindings/spinner.js (widgets/spinner.js)
- content/global/bindings/stringbundle.xml (widgets/stringbundle.xml)
* content/global/bindings/tabbox.xml (widgets/tabbox.xml)
content/global/bindings/text.xml (widgets/text.xml)
* 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/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/stringbundle.xml
rename to toolkit/content/widgets/stringbundle.js
--- a/toolkit/content/widgets/stringbundle.xml
+++ b/toolkit/content/widgets/stringbundle.js
@@ -1,91 +1,63 @@
-<?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="stringBundleBindings"
- xmlns="http://www.mozilla.org/xbl"
- xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+// This is loaded into all XUL windows. Wrap in a block to prevent
+// leaking to window scope.
+{
- <binding id="stringbundle" extends="xul:spacer">
- <implementation name="XStringBundle">
+ChromeUtils.import("resource://gre/modules/Services.jsm");
- <method name="getString">
- <parameter name="aStringKey"/>
- <body>
- <![CDATA[
- try {
- return this.stringBundle.GetStringFromName(aStringKey);
- } catch (e) {
- dump("*** Failed to get string " + aStringKey + " in bundle: " + this.src + "\n");
- throw e;
- }
- ]]>
- </body>
- </method>
+class MozStringbundle extends XULElement {
+ get stringBundle() {
+ if (!this._bundle) {
+ try {
+ this._bundle = Services.strings.createBundle(this.src);
+ } catch (e) {
+ dump("Failed to get stringbundle:\n");
+ dump(e + "\n");
+ }
+ }
+ return this._bundle;
+ }
- <method name="getFormattedString">
- <parameter name="aStringKey"/>
- <parameter name="aStringsArray"/>
- <body>
- <![CDATA[
- try {
- return this.stringBundle.formatStringFromName(aStringKey, aStringsArray, aStringsArray.length);
- } catch (e) {
- dump("*** Failed to format string " + aStringKey + " in bundle: " + this.src + "\n");
- throw e;
- }
- ]]>
- </body>
- </method>
+ set src(val) {
+ this._bundle = null;
+ this.setAttribute("src", val);
+ return val;
+ }
- <property name="stringBundle" readonly="true">
- <getter>
- <![CDATA[
- if (!this._bundle) {
- try {
- this._bundle = Cc["@mozilla.org/intl/stringbundle;1"]
- .getService(Ci.nsIStringBundleService)
- .createBundle(this.src);
- } catch (e) {
- dump("Failed to get stringbundle:\n");
- dump(e + "\n");
- }
- }
- return this._bundle;
- ]]>
- </getter>
- </property>
+ get src() {
+ return this.getAttribute("src");
+ }
+
+ get strings() {
+ // Note: this is a sucky method name! Should be:
+ // readonly attribute nsISimpleEnumerator strings;
+ return this.stringBundle.getSimpleEnumeration();
+ }
- <property name="src">
- <getter>
- <![CDATA[
- return this.getAttribute("src");
- ]]>
- </getter>
- <setter>
- <![CDATA[
- this._bundle = null;
- this.setAttribute("src", val);
- return val;
- ]]>
- </setter>
- </property>
+ getString(aStringKey) {
+ try {
+ return this.stringBundle.GetStringFromName(aStringKey);
+ } catch (e) {
+ dump("*** Failed to get string " + aStringKey + " in bundle: " + this.src + "\n");
+ throw e;
+ }
+ }
- <property name="strings">
- <getter>
- <![CDATA[
- // Note: this is a sucky method name! Should be:
- // readonly attribute nsISimpleEnumerator strings;
- return this.stringBundle.getSimpleEnumeration();
- ]]>
- </getter>
- </property>
+ getFormattedString(aStringKey, aStringsArray) {
+ try {
+ return this.stringBundle.formatStringFromName(aStringKey, aStringsArray, aStringsArray.length);
+ } catch (e) {
+ dump("*** Failed to format string " + aStringKey + " in bundle: " + this.src + "\n");
+ throw e;
+ }
+ }
+}
- <field name="_bundle">null</field>
+customElements.define("stringbundle", MozStringbundle);
- </implementation>
- </binding>
-
-</bindings>
+}
--- a/toolkit/content/xul.css
+++ b/toolkit/content/xul.css
@@ -883,23 +883,19 @@ arrowscrollbox[clicktoscroll="true"] {
}
autorepeatbutton {
-moz-binding: url("chrome://global/content/bindings/scrollbox.xml#autorepeatbutton");
}
/********** stringbundle **********/
+stringbundle,
stringbundleset {
- visibility: collapse;
-}
-
-stringbundle {
- -moz-binding: url("chrome://global/content/bindings/stringbundle.xml#stringbundle");
- visibility: collapse;
+ display: none;
}
/********** dialog **********/
dialog,
dialog:root /* override :root from above */ {
-moz-binding: url("chrome://global/content/bindings/dialog.xml#dialog");
-moz-box-orient: vertical;