Bug 1440490 - Move l10n related functions into calL10NUtils.jsm - part 1 - initial manual changes. r=MakeMyDay
authorPhilipp Kewisch <mozilla@kewis.ch>
Thu, 22 Feb 2018 07:35:59 +0100
changeset 30543 10085a3cc8a189498141c21b58018f277e0055fc
parent 30542 c75db1860608b515e8e0f6a2a5df4ec165f53525
child 30544 6e8d7aef9631f3d31a92c1262c74fe5595e415af
push id2172
push usermozilla@kewis.ch
push dateSun, 15 Apr 2018 05:33:14 +0000
treeherdercomm-beta@33a67b0129b3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMakeMyDay
bugs1440490
Bug 1440490 - Move l10n related functions into calL10NUtils.jsm - part 1 - initial manual changes. r=MakeMyDay MozReview-Commit-ID: 9OhRVmaDaZj
calendar/.eslintrc.js
calendar/base/content/widgets/calendar-widgets.xml
calendar/base/modules/calL10NUtils.jsm
calendar/base/modules/calPrintUtils.jsm
calendar/base/modules/calUnifinderUtils.jsm
calendar/base/modules/calUtils.jsm
calendar/base/modules/calUtilsCompat.jsm
calendar/base/modules/moz.build
calendar/base/src/calUtils.js
--- a/calendar/.eslintrc.js
+++ b/calendar/.eslintrc.js
@@ -481,16 +481,17 @@ module.exports = {
         // easier updates in the future.
         "no-else-return": 0,
     },
     "overrides": [{
         files: [
             "base/modules/calEmailUtils.jsm",
             "base/modules/calItipUtils.jsm",
             "base/modules/calUnifinderUtils.jsm",
+            "base/modules/calL10NUtils.jsm",
         ],
         rules: {
             "require-jsdoc": [2, { require: { ClassDeclaration: true } }],
 
             "valid-jsdoc": [2, {
                 prefer: { returns: "return" },
                 preferType: {
                     "boolean": "Boolean",
--- a/calendar/base/content/widgets/calendar-widgets.xml
+++ b/calendar/base/content/widgets/calendar-widgets.xml
@@ -153,17 +153,17 @@
             let categoryListbox = document.getAnonymousElementByAttribute(this, "anonid", "categories-listbox");
             let categoryTextbox = document.getAnonymousElementByAttribute(this, "anonid", "category-textbox");
             let category = categoryTextbox.value;
 
             if (!category) {
                 return;
             }
 
-            let localeCollator = cal.createLocaleCollator();
+            let localeCollator = cal.l10n.createLocaleCollator();
             let compare = localeCollator.compareString.bind(localeCollator, 0);
 
             let children = categoryListbox.childNodes;
             let categories = [];
             for (let i = 0; i < children.length; i++) {
                 categories.push(children[i].label);
             }
 
@@ -192,17 +192,17 @@
 
             for (let cat of categoryList) {
                 // First insert all categories from the prefs
                 let item = categoryListbox.appendItem(cat, cat);
                 item.setAttribute("type", "checkbox");
             }
 
             if (aItem) {
-                let localeCollator = cal.createLocaleCollator();
+                let localeCollator = cal.l10n.createLocaleCollator();
                 let compare = localeCollator.compareString.bind(localeCollator, 0);
 
                 // Ensure the item's categories are in the list and they are checked.
                 for (let cat of aItem.getCategories({})) {
                     this.insertCategory(cat, categoryList, categoryListbox, compare);
                 }
             }
         ]]></body>
new file mode 100644
--- /dev/null
+++ b/calendar/base/modules/calL10NUtils.jsm
@@ -0,0 +1,131 @@
+/* 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/. */
+
+ChromeUtils.import("resource://gre/modules/Services.jsm");
+
+this.EXPORTED_SYMBOLS = ["call10n"]; /* exported call10n */
+
+/**
+ * Gets the value of a string in a .properties file.
+ *
+ * @param {String} aComponent       Stringbundle component name
+ * @param {String} aBundleName      The name of the properties file
+ * @param {String} aStringName      The name of the string within the properties file
+ * @param {String[]} aParams        (optional) Parameters to format the string
+ * @return {String}                 The formatted string
+ */
+function _getString(aComponent, aBundleName, aStringName, aParams=[]) {
+    let propName = `chrome://${aComponent}/locale/${aBundleName}.properties`;
+
+    try {
+        if (!(propName in _getString._bundleCache)) {
+            _getString._bundleCache[propName] = Services.strings.createBundle(propName);
+        }
+        let props = _getString._bundleCache[propName];
+
+        if (aParams.length) {
+            return props.formatStringFromName(aStringName, aParams, aParams.length);
+        } else {
+            return props.GetStringFromName(aStringName);
+        }
+    } catch (ex) {
+        let msg = `Failed to read '${aStringName}' from ${propName}.`;
+        Components.utils.reportError(`${msg} Error: ${ex}`);
+        return aStringName;
+    }
+}
+_getString._bundleCache = {};
+
+
+var call10n = {
+    /**
+     * Gets the value of a string in a .properties file.
+     *
+     * @param {String} aComponent       Stringbundle component name
+     * @param {String} aBundleName      The name of the properties file
+     * @param {String} aStringName      The name of the string within the properties file
+     * @param {String[]} aParams        (optional) Parameters to format the string
+     * @return {String}                 The formatted string
+     */
+    getAnyString: _getString,
+
+    /**
+     * Gets a string from a bundle from chrome://calendar/
+     *
+     * @param {String} aBundleName      The name of the properties file
+     * @param {String} aStringName      The name of the string within the properties file
+     * @param {String[]} aParams        (optional) Parameters to format the string
+     * @return {String}                 The formatted string
+     */
+    getString: _getString.bind(undefined, "calendar"),
+
+    /**
+     * Gets a string from chrome://calendar/locale/calendar.properties bundle
+     *
+     * @param {String} aStringName      The name of the string within the properties file
+     * @param {String[]} aParams        (optional) Parameters to format the string
+     * @return {String}                 The formatted string
+     */
+    getCalString: _getString.bind(undefined, "calendar", "calendar"),
+
+    /**
+     * Gets a string from chrome://lightning/locale/lightning.properties
+     *
+     * @param {String} aStringName      The name of the string within the properties file
+     * @param {String[]} aParams        (optional) Parameters to format the string
+     * @return {String}                 The formatted string
+     */
+    getLtnString: _getString.bind(undefined, "lightning", "lightning"),
+
+    /**
+     * Gets a date format string from chrome://calendar/locale/dateFormat.properties bundle
+     *
+     * @param {String} aStringName      The name of the string within the properties file
+     * @param {String[]} aParams        (optional) Parameters to format the string
+     * @return {String}                 The formatted string
+     */
+    getDateFmtString: _getString.bind(undefined, "calendar", "dateFormat"),
+
+    /**
+     * Gets the month name string in the right form depending on a base string.
+     *
+     * @param {Number} aMonthNum     The month numer to get, 1-based.
+     * @param {String} aBundleName   The Bundle to get the string from
+     * @param {String} aStringBase   The base string name, .monthFormat will be appended
+     * @return {String}              The formatted month name
+     */
+    formatMonth: function(aMonthNum, aBundleName, aStringBase) {
+        let monthForm = call10n.getString(aBundleName, aStringBase + ".monthFormat") || "nominative";
+
+        if (monthForm == "nominative") {
+            // Fall back to the default name format
+            monthForm = "name";
+        }
+
+        return call10n.getDateFmtString(`month.${aMonthNum}.${monthForm}`);
+    },
+
+    /**
+     * Create a new locale collator
+     *
+     * @return {nsICollation}       A new locale collator
+     */
+    createLocaleCollator: function() {
+        return Components.classes["@mozilla.org/intl/collation-factory;1"]
+                         .getService(Components.interfaces.nsICollationFactory)
+                         .CreateCollation();
+    },
+
+    /**
+     * Sort an array of strings in place, according to the current locale.
+     *
+     * @param {String[]} aStringArray   The strings to sort
+     * @return {String[]}               The sorted strings, more specifically aStringArray
+     */
+    sortArrayByLocaleCollator: function(aStringArray) {
+        let collator = call10n.createLocaleCollator();
+        aStringArray.sort((a, b) => collator.compareString(0, a, b));
+        return aStringArray;
+    }
+};
--- a/calendar/base/modules/calPrintUtils.jsm
+++ b/calendar/base/modules/calPrintUtils.jsm
@@ -142,17 +142,17 @@ cal.print = {
 
         // Fill in details of the task
         if (item.isCompleted) {
             taskNode.querySelector(".task-checkbox").setAttribute("checked", "checked");
         }
 
         taskNode.querySelector(".task-title").textContent = item.title;
 
-        let collator = cal.createLocaleCollator();
+        let collator = cal.l10n.createLocaleCollator();
         cal.data.binaryInsertNode(taskContainer, taskNode, item, (a, b) => collator.compareString(0, a, b), node => node.item.title);
     },
 
     /**
      * Get time interval string for the given item. Returns an empty string for all-day items.
      *
      * @param aItem     The item providing the interval
      * @return          The string describing the interval
--- a/calendar/base/modules/calUnifinderUtils.jsm
+++ b/calendar/base/modules/calUnifinderUtils.jsm
@@ -183,17 +183,17 @@ const sortCompare = calunifinder.sortEnt
     string: function(a, b, modifier=1) {
         if (a.length == 0 || b.length == 0) {
             // sort empty values to end (so when users first sort by a
             // column, they can see and find the desired values in that
             // column without scrolling past all the empty values).
             return -(a.length - b.length) * modifier;
         }
 
-        let collator = cal.createLocaleCollator();
+        let collator = cal.l10n.createLocaleCollator();
         return collator.compareString(0, a, b) * modifier;
     },
 
     /**
      * Catch-all function to compare two unknown values. Will return 0.
      *
      * @param {*} a                 The first thing to compare
      * @param {*} b                 The second thing to compare
--- a/calendar/base/modules/calUtils.jsm
+++ b/calendar/base/modules/calUtils.jsm
@@ -52,22 +52,16 @@ var cal = {
                                     "icalString"),
     createRecurrenceRule: _instance("@mozilla.org/calendar/recurrence-rule;1",
                                     Components.interfaces.calIRecurrenceRule,
                                     "icalString"),
     createRecurrenceInfo: _instance("@mozilla.org/calendar/recurrence-info;1",
                                     Components.interfaces.calIRecurrenceInfo,
                                     "item"),
 
-    createLocaleCollator: function() {
-        return Components.classes["@mozilla.org/intl/collation-factory;1"]
-                         .getService(Components.interfaces.nsICollationFactory)
-                         .CreateCollation();
-    },
-
     getCalendarManager: _service("@mozilla.org/calendar/manager;1",
                                  Components.interfaces.calICalendarManager),
     getIcsService: _service("@mozilla.org/calendar/ics-service;1",
                             Components.interfaces.calIICSService),
     getTimezoneService: _service("@mozilla.org/calendar/timezone-service;1",
                                  Components.interfaces.calITimezoneService),
     getCalendarSearchService: _service("@mozilla.org/calendar/calendarsearch-service;1",
                                        Components.interfaces.calICalendarSearchProvider),
@@ -275,45 +269,16 @@ var cal = {
         let uuidGen = Components.classes["@mozilla.org/uuid-generator;1"]
                                 .getService(Components.interfaces.nsIUUIDGenerator);
         // generate uuids without braces to avoid problems with
         // CalDAV servers that don't support filenames with {}
         return uuidGen.generateUUID().toString().replace(/[{}]/g, "");
     },
 
     /**
-     * Sort an array of strings according to the current locale.
-     * Modifies aStringArray, returning it sorted.
-     */
-    sortArrayByLocaleCollator: function(aStringArray) {
-        let localeCollator = cal.createLocaleCollator();
-        function compare(a, b) { return localeCollator.compareString(0, a, b); }
-        aStringArray.sort(compare);
-        return aStringArray;
-    },
-
-    /**
-     * Gets the month name string in the right form depending on a base string.
-     *
-     * @param aMonthNum     The month numer to get, 1-based.
-     * @param aBundleName   The Bundle to get the string from
-     * @param aStringBase   The base string name, .monthFormat will be appended
-     */
-    formatMonth: function(aMonthNum, aBundleName, aStringBase) {
-        let monthForm = cal.calGetString(aBundleName, aStringBase + ".monthFormat") || "nominative";
-
-        if (monthForm == "nominative") {
-            // Fall back to the default name format
-            monthForm = "name";
-        }
-
-        return cal.calGetString("dateFormat", "month." + aMonthNum + "." + monthForm);
-    },
-
-    /**
      * Adds an observer listening for the topic.
      *
      * @param func function to execute on topic
      * @param topic topic to listen for
      * @param oneTime whether to listen only once
      */
     addObserver: function(func, topic, oneTime) {
         let observer = { // nsIObserver:
@@ -401,16 +366,17 @@ XPCOMUtils.defineLazyPreferenceGetter(ca
 // Sub-modules for calUtils
 XPCOMUtils.defineLazyModuleGetter(cal, "acl", "resource://calendar/modules/calACLUtils.jsm", "calacl");
 XPCOMUtils.defineLazyModuleGetter(cal, "category", "resource://calendar/modules/calCategoryUtils.jsm", "calcategory");
 XPCOMUtils.defineLazyModuleGetter(cal, "data", "resource://calendar/modules/calDataUtils.jsm", "caldata");
 XPCOMUtils.defineLazyModuleGetter(cal, "dtz", "resource://calendar/modules/calDateTimeUtils.jsm", "caldtz");
 XPCOMUtils.defineLazyModuleGetter(cal, "email", "resource://calendar/modules/calEmailUtils.jsm", "calemail");
 XPCOMUtils.defineLazyModuleGetter(cal, "item", "resource://calendar/modules/calItemUtils.jsm", "calitem");
 XPCOMUtils.defineLazyModuleGetter(cal, "itip", "resource://calendar/modules/calItipUtils.jsm", "calitip");
+XPCOMUtils.defineLazyModuleGetter(cal, "l10n", "resource://calendar/modules/calL10NUtils.jsm", "call10n");
 XPCOMUtils.defineLazyModuleGetter(cal, "unifinder", "resource://calendar/modules/calUnifinderUtils.jsm", "calunifinder");
 XPCOMUtils.defineLazyModuleGetter(cal, "view", "resource://calendar/modules/calViewUtils.jsm", "calview");
 XPCOMUtils.defineLazyModuleGetter(cal, "window", "resource://calendar/modules/calWindowUtils.jsm", "calwindow");
 
 /**
  * Returns a function that provides access to the given service.
  *
  * @param cid           The contract id to create
--- a/calendar/base/modules/calUtilsCompat.jsm
+++ b/calendar/base/modules/calUtilsCompat.jsm
@@ -148,9 +148,18 @@ function generateForward(global, namespa
  * @param global        The global object to inject on.
  */
 function injectCalUtilsCompat(global) {
     for (let [namespace, nsdata] of Object.entries(migrations)) {
         for (let [from, to] of Object.entries(nsdata)) {
             generateForward(global, namespace, from, to);
         }
     }
+
+    // calGetString is special, as the argument order and kind has changed as well
+    global.calGetString = function(aBundleName, aStringName, aParams, aComponent="calendar") {
+        Deprecated.warning("calUtils' cal.calGetString() has changed to cal.l10n.get*String()" +
+                           " and the parameter order has changed",
+                           "https://bugzilla.mozilla.org/show_bug.cgi?id=905097",
+                           Components.stack.caller);
+        return cal.l10n.getAnyString(aComponent, aBundleName, aStringName, aParams);
+    };
 }
--- a/calendar/base/modules/moz.build
+++ b/calendar/base/modules/moz.build
@@ -12,16 +12,17 @@ EXTRA_JS_MODULES += [
     'calDataUtils.jsm',
     'calDateTimeUtils.jsm',
     'calEmailUtils.jsm',
     'calExtract.jsm',
     'calHashedArray.jsm',
     'calItemUtils.jsm',
     'calIteratorUtils.jsm',
     'calItipUtils.jsm',
+    'calL10NUtils.jsm',
     'calPrintUtils.jsm',
     'calProviderUtils.jsm',
     'calRecurrenceUtils.jsm',
     'calUnifinderUtils.jsm',
     'calUtils.jsm',
     'calUtilsCompat.jsm',
     'calViewUtils.jsm',
     'calWindowUtils.jsm',
--- a/calendar/base/src/calUtils.js
+++ b/calendar/base/src/calUtils.js
@@ -1,39 +1,7 @@
 /* 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 file contains commonly used functions in a centralized place so that
- * various components (and other js scopes) don't need to replicate them. Note
- * that loading this file twice in the same scope will throw errors.
- */
-
-/* exported calGetString */
-
-ChromeUtils.import("resource://gre/modules/Services.jsm");
-
-/**
- * Gets the value of a string in a .properties file from the calendar bundle
- *
- * @param aBundleName  the name of the properties file.  It is assumed that the
- *                     file lives in chrome://calendar/locale/
- * @param aStringName  the name of the string within the properties file
- * @param aParams      optional array of parameters to format the string
- * @param aComponent   optional stringbundle component name
- */
-function calGetString(aBundleName, aStringName, aParams, aComponent="calendar") {
-    let propName = "chrome://" + aComponent + "/locale/" + aBundleName + ".properties";
-
-    try {
-        let props = Services.strings.createBundle(propName);
-
-        if (aParams && aParams.length) {
-            return props.formatStringFromName(aStringName, aParams, aParams.length);
-        } else {
-            return props.GetStringFromName(aStringName);
-        }
-    } catch (ex) {
-        let msg = "Failed to read '" + aStringName + "' from " + propName + ".";
-        Components.utils.reportError(msg + " Error: " + ex);
-        return msg;
-    }
-}
+/* Goodbye, calUtils.js. You've been a great friend over the years. We'll miss
+ * you and wish you all the best for your departure in one of the next
+ * changesets. */