Bug 1350646: Part 9 - Remove SDK l10n modules. r?Mossop draft
authorKris Maglione <maglione.k@gmail.com>
Sat, 05 Aug 2017 21:29:31 -0700
changeset 641189 94d0e896615122c79610be399c5cc05a4d47b339
parent 641188 311c10a72593c99a64dfe750bc40496a5889e0b7
child 641190 788a1233cb6df1cbfd252e203b9e844cfa018675
push id72469
push usermaglione.k@gmail.com
push dateSun, 06 Aug 2017 07:23:41 +0000
reviewersMossop
bugs1350646
milestone57.0a1
Bug 1350646: Part 9 - Remove SDK l10n modules. r?Mossop MozReview-Commit-ID: 8CZq3jjxnv0
addon-sdk/moz.build
addon-sdk/source/lib/sdk/content/l10n-html.js
addon-sdk/source/lib/sdk/l10n.js
addon-sdk/source/lib/sdk/l10n/core.js
addon-sdk/source/lib/sdk/l10n/html.js
addon-sdk/source/lib/sdk/l10n/json/core.js
addon-sdk/source/lib/sdk/l10n/loader.js
addon-sdk/source/lib/sdk/l10n/locale.js
addon-sdk/source/lib/sdk/l10n/plural-rules.js
addon-sdk/source/lib/sdk/l10n/prefs.js
addon-sdk/source/lib/sdk/l10n/properties/core.js
addon-sdk/source/lib/sdk/preferences/native-options.js
--- a/addon-sdk/moz.build
+++ b/addon-sdk/moz.build
@@ -38,17 +38,16 @@ modules = [
     'sdk/base64.js',
     'sdk/browser/events.js',
     'sdk/clipboard.js',
     'sdk/console/plain-text.js',
     'sdk/console/traceback.js',
     'sdk/content/content-worker.js',
     'sdk/content/content.js',
     'sdk/content/events.js',
-    'sdk/content/l10n-html.js',
     'sdk/content/loader.js',
     'sdk/content/mod.js',
     'sdk/content/sandbox.js',
     'sdk/content/sandbox/events.js',
     'sdk/content/tab-events.js',
     'sdk/content/thumbnail.js',
     'sdk/content/utils.js',
     'sdk/content/worker-child.js',
@@ -76,25 +75,16 @@ modules = [
     'sdk/fs/path.js',
     'sdk/indexed-db.js',
     'sdk/io/buffer.js',
     'sdk/io/byte-streams.js',
     'sdk/io/file.js',
     'sdk/io/fs.js',
     'sdk/io/stream.js',
     'sdk/io/text-streams.js',
-    'sdk/l10n.js',
-    'sdk/l10n/core.js',
-    'sdk/l10n/html.js',
-    'sdk/l10n/json/core.js',
-    'sdk/l10n/loader.js',
-    'sdk/l10n/locale.js',
-    'sdk/l10n/plural-rules.js',
-    'sdk/l10n/prefs.js',
-    'sdk/l10n/properties/core.js',
     'sdk/lang/functional.js',
     'sdk/lang/functional/concurrent.js',
     'sdk/lang/functional/core.js',
     'sdk/lang/functional/helpers.js',
     'sdk/lang/type.js',
     'sdk/lang/weak-set.js',
     'sdk/loader/sandbox.js',
     'sdk/messaging.js',
@@ -102,17 +92,16 @@ modules = [
     'sdk/net/url.js',
     'sdk/net/xhr.js',
     'sdk/notifications.js',
     'sdk/output/system.js',
     'sdk/passwords.js',
     'sdk/passwords/utils.js',
     'sdk/platform/xpcom.js',
     'sdk/preferences/event-target.js',
-    'sdk/preferences/native-options.js',
     'sdk/preferences/service.js',
     'sdk/preferences/utils.js',
     'sdk/private-browsing.js',
     'sdk/private-browsing/utils.js',
     'sdk/querystring.js',
     'sdk/remote/child.js',
     'sdk/remote/core.js',
     'sdk/remote/parent.js',
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/content/l10n-html.js
+++ /dev/null
@@ -1,132 +0,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";
-
-module.metadata = {
-  "stability": "unstable"
-};
-
-const { Ci, Cc, Cu } = require("chrome");
-lazyRequireModule(this, "../l10n/core", "core");
-lazyRequire(this, "../stylesheet/utils", "loadSheet", "removeSheet");
-const { process, frames } = require("../remote/child");
-
-var observerService = Cc["@mozilla.org/observer-service;1"]
-                      .getService(Ci.nsIObserverService);
-const { ShimWaiver } = Cu.import("resource://gre/modules/ShimWaiver.jsm");
-const addObserver = ShimWaiver.getProperty(observerService, "addObserver");
-const removeObserver = ShimWaiver.getProperty(observerService, "removeObserver");
-
-const assetsURI = require('../self').data.url();
-
-const hideSheetUri = "data:text/css,:root {visibility: hidden !important;}";
-
-function translateElementAttributes(element) {
-  // Translateable attributes
-  const attrList = ['title', 'accesskey', 'alt', 'label', 'placeholder'];
-  const ariaAttrMap = {
-          'ariaLabel': 'aria-label',
-          'ariaValueText': 'aria-valuetext',
-          'ariaMozHint': 'aria-moz-hint'
-        };
-  const attrSeparator = '.';
-  
-  // Try to translate each of the attributes
-  for (let attribute of attrList) {
-    const data = core.get(element.dataset.l10nId + attrSeparator + attribute);
-    if (data)
-      element.setAttribute(attribute, data);
-  }
-  
-  // Look for the aria attribute translations that match fxOS's aliases
-  for (let attrAlias in ariaAttrMap) {
-    const data = core.get(element.dataset.l10nId + attrSeparator + attrAlias);
-    if (data)
-      element.setAttribute(ariaAttrMap[attrAlias], data);
-  }
-}
-
-// Taken from Gaia:
-// https://github.com/andreasgal/gaia/blob/04fde2640a7f40314643016a5a6c98bf3755f5fd/webapi.js#L1470
-function translateElement(element) {
-  element = element || document;
-
-  // check all translatable children (= w/ a `data-l10n-id' attribute)
-  var children = element.querySelectorAll('*[data-l10n-id]');
-  var elementCount = children.length;
-  for (var i = 0; i < elementCount; i++) {
-    var child = children[i];
-
-    // translate the child
-    var key = child.dataset.l10nId;
-    var data = core.get(key);
-    if (data)
-      child.textContent = data;
-
-    translateElementAttributes(child);
-  }
-}
-exports.translateElement = translateElement;
-
-function onDocumentReady2Translate(event) {
-  let document = event.target;
-  document.removeEventListener("DOMContentLoaded", onDocumentReady2Translate);
-
-  translateElement(document);
-
-  try {
-    // Finally display document when we finished replacing all text content
-    if (document.defaultView)
-      removeSheet(document.defaultView, hideSheetUri, 'user');
-  }
-  catch(e) {
-    console.exception(e);
-  }
-}
-
-function onContentWindow(document) {
-  // Accept only HTML documents
-  if (!(document instanceof Ci.nsIDOMHTMLDocument))
-    return;
-
-  // Bug 769483: data:URI documents instanciated with nsIDOMParser
-  // have a null `location` attribute at this time
-  if (!document.location)
-    return;
-
-  // Accept only document from this addon
-  if (document.location.href.indexOf(assetsURI) !== 0)
-    return;
-
-  try {
-    // First hide content of the document in order to have content blinking
-    // between untranslated and translated states
-    loadSheet(document.defaultView, hideSheetUri, 'user');
-  }
-  catch(e) {
-    console.exception(e);
-  }
-  // Wait for DOM tree to be built before applying localization
-  document.addEventListener("DOMContentLoaded", onDocumentReady2Translate);
-}
-
-// Listen to creation of content documents in order to translate them as soon
-// as possible in their loading process
-const ON_CONTENT = "document-element-inserted";
-let enabled = false;
-function enable() {
-  if (enabled)
-    return;
-  addObserver(onContentWindow, ON_CONTENT, false);
-  enabled = true;
-}
-process.port.on("sdk/l10n/html/enable", enable);
-
-function disable() {
-  if (!enabled)
-    return;
-  removeObserver(onContentWindow, ON_CONTENT);
-  enabled = false;
-}
-process.port.on("sdk/l10n/html/disable", disable);
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/l10n.js
+++ /dev/null
@@ -1,94 +0,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";
-
-module.metadata = {
-  "stability": "stable"
-};
-
-lazyRequireModule(this, "./l10n/json/core", "json");
-lazyRequire(this, "./l10n/core", {"get": "getKey"});
-lazyRequireModule(this, "./l10n/properties/core", "properties");
-lazyRequire(this, "./l10n/plural-rules", "getRulesForLocale");
-
-const { XPCOMUtils } = require("resource://gre/modules/XPCOMUtils.jsm");
-
-// Retrieve the plural mapping function
-XPCOMUtils.defineLazyGetter(this, "pluralMappingFunction",
-                            () => getRulesForLocale(json.language()) ||
-                                  getRulesForLocale("en"));
-
-exports.get = function get(k) {
-  // For now, we only accept a "string" as first argument
-  // TODO: handle plural forms in gettext pattern
-  if (typeof k !== "string")
-    throw new Error("First argument of localization method should be a string");
-  let n = arguments[1];
-
-  // Get translation from big hashmap or default to hard coded string:
-  let localized = getKey(k, n) || k;
-
-  // # Simplest usecase:
-  //   // String hard coded in source code:
-  //   _("Hello world")
-  //   // Identifier of a key stored in properties file
-  //   _("helloString")
-  if (arguments.length <= 1)
-    return localized;
-
-  let args = Array.slice(arguments);
-  let placeholders = [null, ...args.slice(typeof(n) === "number" ? 2 : 1)];
-
-  if (typeof localized == "object" && "other" in localized) {
-    // # Plural form:
-    //   // Strings hard coded in source code:
-    //   _(["One download", "%d downloads"], 10);
-    //   // Identifier of a key stored in properties file
-    //   _("downloadNumber", 0);
-    let n = arguments[1];
-
-    // First handle simple universal forms that may not be mandatory
-    // for each language, (i.e. not different than 'other' form,
-    // but still usefull for better phrasing)
-    // For example 0 in english is the same form than 'other'
-    // but we accept 'zero' form if specified in localization file
-    if (n === 0 && "zero" in localized)
-      localized = localized["zero"];
-    else if (n === 1 && "one" in localized)
-      localized = localized["one"];
-    else if (n === 2 && "two" in localized)
-      localized = localized["two"];
-    else {
-      let pluralForm = pluralMappingFunction(n);
-      if (pluralForm in localized)
-        localized = localized[pluralForm];
-      else // Fallback in case of error: missing plural form
-        localized = localized["other"];
-    }
-
-    // Simulate a string with one placeholder:
-    args = [null, n];
-  }
-
-  // # String with placeholders:
-  //   // Strings hard coded in source code:
-  //   _("Hello %s", username)
-  //   // Identifier of a key stored in properties file
-  //   _("helloString", username)
-  // * We supports `%1s`, `%2s`, ... pattern in order to change arguments order
-  // in translation.
-  // * In case of plural form, we has `%d` instead of `%s`.
-  let offset = 1;
-  if (placeholders.length > 1) {
-    args = placeholders;
-  }
-
-  localized = localized.replace(/%(\d*)[sd]/g, (v, n) => {
-    let rv = args[n != "" ? n : offset];
-    offset++;
-    return rv;
-  });
-
-  return localized;
-}
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/l10n/core.js
+++ /dev/null
@@ -1,15 +0,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";
-
-lazyRequireModule(this, "./json/core", "json");
-lazyRequireModule(this, "./properties/core", "properties");
-
-const { XPCOMUtils } = require("resource://gre/modules/XPCOMUtils.jsm");
-XPCOMUtils.defineLazyGetter(this, "get",
-                            () => json.usingJSON ? json.get : properties.get);
-
-module.exports = Object.freeze({
-  get get() { return get; }, // ... yeah.
-});
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/l10n/html.js
+++ /dev/null
@@ -1,32 +0,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";
-
-module.metadata = {
-  "stability": "unstable"
-};
-
-const { processes, remoteRequire } = require("../remote/parent");
-remoteRequire("sdk/content/l10n-html");
-
-var enabled = false;
-function enable() {
-  if (!enabled) {
-    processes.port.emit("sdk/l10n/html/enable");
-    enabled = true;
-  }
-}
-exports.enable = enable;
-
-function disable() {
-  if (enabled) {
-    processes.port.emit("sdk/l10n/html/disable");
-    enabled = false;
-  }
-}
-exports.disable = disable;
-
-processes.forEvery(process => {
-  process.port.emit(enabled ? "sdk/l10n/html/enable" : "sdk/l10n/html/disable");
-});
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/l10n/json/core.js
+++ /dev/null
@@ -1,36 +0,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";
-
-module.metadata = {
-  "stability": "unstable"
-};
-
-var usingJSON = false;
-var hash = {}, bestMatchingLocale = null;
-try {
-  let data = require("@l10n/data");
-  hash = data.hash;
-  bestMatchingLocale = data.bestMatchingLocale;
-  usingJSON = true;
-}
-catch(e) {}
-
-exports.usingJSON = usingJSON;
-
-// Returns the translation for a given key, if available.
-exports.get = function get(k) {
-  return k in hash ? hash[k] : null;
-}
-
-// Returns the full length locale code: ja-JP-mac, en-US or fr
-exports.locale = function locale() {
-  return bestMatchingLocale;
-}
-
-// Returns the short locale code: ja, en, fr
-exports.language = function language() {
-  return bestMatchingLocale ? bestMatchingLocale.split("-")[0].toLowerCase()
-                            : "en";
-}
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/l10n/loader.js
+++ /dev/null
@@ -1,70 +0,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";
-
-module.metadata = {
-  "stability": "unstable"
-};
-
-const { Cc, Ci } = require("chrome");
-lazyRequire(this, "./locale", "getPreferedLocales", "findClosestLocale");
-lazyRequire(this, "../net/url", "readURI");
-lazyRequire(this, "../core/promise", "resolve");
-
-function parseJsonURI(uri) {
-  return readURI(uri).
-    then(JSON.parse).
-    catch(function (error) {
-      throw Error("Failed to parse locale file:\n" + uri + "\n" + error);
-    });
-}
-
-// Returns the array stored in `locales.json` manifest that list available
-// locales files
-function getAvailableLocales(rootURI) {
-  let uri = rootURI + "locales.json";
-  return parseJsonURI(uri).then(function (manifest) {
-    return "locales" in manifest &&
-           Array.isArray(manifest.locales) ?
-           manifest.locales : [];
-  });
-}
-
-// Returns URI of the best locales file to use from the XPI
-function getBestLocale(rootURI) {
-  // Read localization manifest file that contains list of available languages
-  return getAvailableLocales(rootURI).then(function (availableLocales) {
-    // Retrieve list of prefered locales to use
-    let preferedLocales = getPreferedLocales();
-
-    // Compute the most preferable locale to use by using these two lists
-    return findClosestLocale(availableLocales, preferedLocales);
-  });
-}
-
-/**
- * Read localization files and returns a promise of data to put in `@l10n/data`
- * pseudo module, in order to allow l10n/json/core to fetch it.
- */
-exports.load = function load(rootURI) {
-  // First, search for a locale file:
-  return getBestLocale(rootURI).then(function (bestMatchingLocale) {
-    // It may be null if the addon doesn't have any locale file
-    if (!bestMatchingLocale)
-      return resolve(null);
-
-    let localeURI = rootURI + "locale/" + bestMatchingLocale + ".json";
-
-    // Locale files only contains one big JSON object that is used as
-    // an hashtable of: "key to translate" => "translated key"
-    // TODO: We are likely to change this in order to be able to overload
-    //       a specific key translation. For a specific package, module or line?
-    return parseJsonURI(localeURI).then(function (json) {
-      return {
-        hash: json,
-        bestMatchingLocale: bestMatchingLocale
-      };
-    });
-  });
-}
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/l10n/locale.js
+++ /dev/null
@@ -1,85 +0,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";
-
-module.metadata = {
-  "stability": "unstable"
-};
-
-const prefs = require("../preferences/service");
-const { Cu, Cc, Ci } = require("chrome");
-const { Services } = Cu.import("resource://gre/modules/Services.jsm");
-
-function getPreferedLocales(caseSensitve) {
-  const locales = Services.locale.getRequestedLocales();
-
-  // This API expects to always append en-US fallback, so for compatibility
-  // reasons, we're going to inject it here.
-  // See bug 1373061 for details.
-  if (!locales.includes('en-US')) {
-    locales.push('en-US');
-  }
-  return locales;
-}
-exports.getPreferedLocales = getPreferedLocales;
-
-/**
- * Selects the closest matching locale from a list of locales.
- *
- * @param  aLocales
- *         An array of available locales
- * @param  aMatchLocales
- *         An array of prefered locales, ordered by priority. Most wanted first.
- *         Locales have to be in lowercase.
- *         If null, uses getPreferedLocales() results
- * @return the best match for the currently selected locale
- *
- * Stolen from http://dxr.mozilla.org/mozilla-central/source/toolkit/mozapps/extensions/internal/XPIProvider.jsm
- */
-exports.findClosestLocale = function findClosestLocale(aLocales, aMatchLocales) {
-  aMatchLocales = aMatchLocales || getPreferedLocales();
-
-  // Holds the best matching localized resource
-  let bestmatch = null;
-  // The number of locale parts it matched with
-  let bestmatchcount = 0;
-  // The number of locale parts in the match
-  let bestpartcount = 0;
-
-  for (let locale of aMatchLocales) {
-    let lparts = locale.split("-");
-    for (let localized of aLocales) {
-      let found = localized.toLowerCase();
-      // Exact match is returned immediately
-      if (locale == found)
-        return localized;
-
-      let fparts = found.split("-");
-      /* If we have found a possible match and this one isn't any longer
-         then we dont need to check further. */
-      if (bestmatch && fparts.length < bestmatchcount)
-        continue;
-
-      // Count the number of parts that match
-      let maxmatchcount = Math.min(fparts.length, lparts.length);
-      let matchcount = 0;
-      while (matchcount < maxmatchcount &&
-             fparts[matchcount] == lparts[matchcount])
-        matchcount++;
-
-      /* If we matched more than the last best match or matched the same and
-         this locale is less specific than the last best match. */
-      if (matchcount > bestmatchcount ||
-         (matchcount == bestmatchcount && fparts.length < bestpartcount)) {
-        bestmatch = localized;
-        bestmatchcount = matchcount;
-        bestpartcount = fparts.length;
-      }
-    }
-    // If we found a valid match for this locale return it
-    if (bestmatch)
-      return bestmatch;
-  }
-  return null;
-}
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/l10n/plural-rules.js
+++ /dev/null
@@ -1,407 +0,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 file is automatically generated with /python-lib/plural-rules-generator.py
-// Fetching data from: http://unicode.org/repos/cldr/trunk/common/supplemental/plurals.xml
-
-// Mapping of short locale name == to == > rule index in following list
-
-module.metadata = {
-  "stability": "unstable"
-};
-
-const LOCALES_TO_RULES = {
-  "af": 3, 
-  "ak": 4, 
-  "am": 4, 
-  "ar": 1, 
-  "asa": 3, 
-  "az": 0, 
-  "be": 11, 
-  "bem": 3, 
-  "bez": 3, 
-  "bg": 3, 
-  "bh": 4, 
-  "bm": 0, 
-  "bn": 3, 
-  "bo": 0, 
-  "br": 20, 
-  "brx": 3, 
-  "bs": 11, 
-  "ca": 3, 
-  "cgg": 3, 
-  "chr": 3, 
-  "cs": 12, 
-  "cy": 17, 
-  "da": 3, 
-  "de": 3, 
-  "dv": 3, 
-  "dz": 0, 
-  "ee": 3, 
-  "el": 3, 
-  "en": 3, 
-  "eo": 3, 
-  "es": 3, 
-  "et": 3, 
-  "eu": 3, 
-  "fa": 0, 
-  "ff": 5, 
-  "fi": 3, 
-  "fil": 4, 
-  "fo": 3, 
-  "fr": 5, 
-  "fur": 3, 
-  "fy": 3, 
-  "ga": 8, 
-  "gd": 24, 
-  "gl": 3, 
-  "gsw": 3, 
-  "gu": 3, 
-  "guw": 4, 
-  "gv": 23, 
-  "ha": 3, 
-  "haw": 3, 
-  "he": 2, 
-  "hi": 4, 
-  "hr": 11, 
-  "hu": 0, 
-  "id": 0, 
-  "ig": 0, 
-  "ii": 0, 
-  "is": 3, 
-  "it": 3, 
-  "iu": 7, 
-  "ja": 0, 
-  "jmc": 3, 
-  "jv": 0, 
-  "ka": 0, 
-  "kab": 5, 
-  "kaj": 3, 
-  "kcg": 3, 
-  "kde": 0, 
-  "kea": 0, 
-  "kk": 3, 
-  "kl": 3, 
-  "km": 0, 
-  "kn": 0, 
-  "ko": 0, 
-  "ksb": 3, 
-  "ksh": 21, 
-  "ku": 3, 
-  "kw": 7, 
-  "lag": 18, 
-  "lb": 3, 
-  "lg": 3, 
-  "ln": 4, 
-  "lo": 0, 
-  "lt": 10, 
-  "lv": 6, 
-  "mas": 3, 
-  "mg": 4, 
-  "mk": 16, 
-  "ml": 3, 
-  "mn": 3, 
-  "mo": 9, 
-  "mr": 3, 
-  "ms": 0, 
-  "mt": 15, 
-  "my": 0, 
-  "nah": 3, 
-  "naq": 7, 
-  "nb": 3, 
-  "nd": 3, 
-  "ne": 3, 
-  "nl": 3, 
-  "nn": 3, 
-  "no": 3, 
-  "nr": 3, 
-  "nso": 4, 
-  "ny": 3, 
-  "nyn": 3, 
-  "om": 3, 
-  "or": 3, 
-  "pa": 3, 
-  "pap": 3, 
-  "pl": 13, 
-  "ps": 3, 
-  "pt": 3, 
-  "rm": 3, 
-  "ro": 9, 
-  "rof": 3, 
-  "ru": 11, 
-  "rwk": 3, 
-  "sah": 0, 
-  "saq": 3, 
-  "se": 7, 
-  "seh": 3, 
-  "ses": 0, 
-  "sg": 0, 
-  "sh": 11, 
-  "shi": 19, 
-  "sk": 12, 
-  "sl": 14, 
-  "sma": 7, 
-  "smi": 7, 
-  "smj": 7, 
-  "smn": 7, 
-  "sms": 7, 
-  "sn": 3, 
-  "so": 3, 
-  "sq": 3, 
-  "sr": 11, 
-  "ss": 3, 
-  "ssy": 3, 
-  "st": 3, 
-  "sv": 3, 
-  "sw": 3, 
-  "syr": 3, 
-  "ta": 3, 
-  "te": 3, 
-  "teo": 3, 
-  "th": 0, 
-  "ti": 4, 
-  "tig": 3, 
-  "tk": 3, 
-  "tl": 4, 
-  "tn": 3, 
-  "to": 0, 
-  "tr": 0, 
-  "ts": 3, 
-  "tzm": 22, 
-  "uk": 11, 
-  "ur": 3, 
-  "ve": 3, 
-  "vi": 0, 
-  "vun": 3, 
-  "wa": 4, 
-  "wae": 3, 
-  "wo": 0, 
-  "xh": 3, 
-  "xog": 3, 
-  "yo": 0, 
-  "zh": 0, 
-  "zu": 3
-};
-
-// Utility functions for plural rules methods
-function isIn(n, list) {
-  return list.indexOf(n) !== -1;
-}
-function isBetween(n, start, end) {
-  return start <= n && n <= end;
-}
-
-// List of all plural rules methods, that maps an integer to the plural form name to use
-const RULES = {
-  "0": function (n) {
-    
-    return "other"
-  },
-  "1": function (n) {
-    if ((isBetween((n % 100), 3, 10)))
-      return "few";
-    if (n == 0)
-      return "zero";
-    if ((isBetween((n % 100), 11, 99)))
-      return "many";
-    if (n == 2)
-      return "two";
-    if (n == 1)
-      return "one";
-    return "other"
-  },
-  "2": function (n) {
-    if (n != 0 && (n % 10) == 0)
-      return "many";
-    if (n == 2)
-      return "two";
-    if (n == 1)
-      return "one";
-    return "other"
-  },
-  "3": function (n) {
-    if (n == 1)
-      return "one";
-    return "other"
-  },
-  "4": function (n) {
-    if ((isBetween(n, 0, 1)))
-      return "one";
-    return "other"
-  },
-  "5": function (n) {
-    if ((isBetween(n, 0, 2)) && n != 2)
-      return "one";
-    return "other"
-  },
-  "6": function (n) {
-    if (n == 0)
-      return "zero";
-    if ((n % 10) == 1 && (n % 100) != 11)
-      return "one";
-    return "other"
-  },
-  "7": function (n) {
-    if (n == 2)
-      return "two";
-    if (n == 1)
-      return "one";
-    return "other"
-  },
-  "8": function (n) {
-    if ((isBetween(n, 3, 6)))
-      return "few";
-    if ((isBetween(n, 7, 10)))
-      return "many";
-    if (n == 2)
-      return "two";
-    if (n == 1)
-      return "one";
-    return "other"
-  },
-  "9": function (n) {
-    if (n == 0 || n != 1 && (isBetween((n % 100), 1, 19)))
-      return "few";
-    if (n == 1)
-      return "one";
-    return "other"
-  },
-  "10": function (n) {
-    if ((isBetween((n % 10), 2, 9)) && !(isBetween((n % 100), 11, 19)))
-      return "few";
-    if ((n % 10) == 1 && !(isBetween((n % 100), 11, 19)))
-      return "one";
-    return "other"
-  },
-  "11": function (n) {
-    if ((isBetween((n % 10), 2, 4)) && !(isBetween((n % 100), 12, 14)))
-      return "few";
-    if ((n % 10) == 0 || (isBetween((n % 10), 5, 9)) || (isBetween((n % 100), 11, 14)))
-      return "many";
-    if ((n % 10) == 1 && (n % 100) != 11)
-      return "one";
-    return "other"
-  },
-  "12": function (n) {
-    if ((isBetween(n, 2, 4)))
-      return "few";
-    if (n == 1)
-      return "one";
-    return "other"
-  },
-  "13": function (n) {
-    if ((isBetween((n % 10), 2, 4)) && !(isBetween((n % 100), 12, 14)))
-      return "few";
-    if (n != 1 && (isBetween((n % 10), 0, 1)) || (isBetween((n % 10), 5, 9)) || (isBetween((n % 100), 12, 14)))
-      return "many";
-    if (n == 1)
-      return "one";
-    return "other"
-  },
-  "14": function (n) {
-    if ((isBetween((n % 100), 3, 4)))
-      return "few";
-    if ((n % 100) == 2)
-      return "two";
-    if ((n % 100) == 1)
-      return "one";
-    return "other"
-  },
-  "15": function (n) {
-    if (n == 0 || (isBetween((n % 100), 2, 10)))
-      return "few";
-    if ((isBetween((n % 100), 11, 19)))
-      return "many";
-    if (n == 1)
-      return "one";
-    return "other"
-  },
-  "16": function (n) {
-    if ((n % 10) == 1 && n != 11)
-      return "one";
-    return "other"
-  },
-  "17": function (n) {
-    if (n == 3)
-      return "few";
-    if (n == 0)
-      return "zero";
-    if (n == 6)
-      return "many";
-    if (n == 2)
-      return "two";
-    if (n == 1)
-      return "one";
-    return "other"
-  },
-  "18": function (n) {
-    if (n == 0)
-      return "zero";
-    if ((isBetween(n, 0, 2)) && n != 0 && n != 2)
-      return "one";
-    return "other"
-  },
-  "19": function (n) {
-    if ((isBetween(n, 2, 10)))
-      return "few";
-    if ((isBetween(n, 0, 1)))
-      return "one";
-    return "other"
-  },
-  "20": function (n) {
-    if ((isBetween((n % 10), 3, 4) || ((n % 10) == 9)) && !(isBetween((n % 100), 10, 19) || isBetween((n % 100), 70, 79) || isBetween((n % 100), 90, 99)))
-      return "few";
-    if ((n % 1000000) == 0 && n != 0)
-      return "many";
-    if ((n % 10) == 2 && !isIn((n % 100), [12, 72, 92]))
-      return "two";
-    if ((n % 10) == 1 && !isIn((n % 100), [11, 71, 91]))
-      return "one";
-    return "other"
-  },
-  "21": function (n) {
-    if (n == 0)
-      return "zero";
-    if (n == 1)
-      return "one";
-    return "other"
-  },
-  "22": function (n) {
-    if ((isBetween(n, 0, 1)) || (isBetween(n, 11, 99)))
-      return "one";
-    return "other"
-  },
-  "23": function (n) {
-    if ((isBetween((n % 10), 1, 2)) || (n % 20) == 0)
-      return "one";
-    return "other"
-  },
-  "24": function (n) {
-    if ((isBetween(n, 3, 10) || isBetween(n, 13, 19)))
-      return "few";
-    if (isIn(n, [2, 12]))
-      return "two";
-    if (isIn(n, [1, 11]))
-      return "one";
-    return "other"
-  },
-};
-
-/**
-  * Return a function that gives the plural form name for a given integer
-  * for the specified `locale`
-  *   let fun = getRulesForLocale('en');
-  *   fun(1)    -> 'one'
-  *   fun(0)    -> 'other'
-  *   fun(1000) -> 'other'
-  */
-exports.getRulesForLocale = function getRulesForLocale(locale) {
-  let index = LOCALES_TO_RULES[locale];
-  if (!(index in RULES)) {
-    console.warn('Plural form unknown for locale "' + locale + '"');
-    return function () { return "other"; };
-  }
-  return RULES[index];
-}
-
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/l10n/prefs.js
+++ /dev/null
@@ -1,51 +0,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";
-
-lazyRequire(this, "../system/events", "on");
-lazyRequireModule(this, "./core", "core");
-const { id: jetpackId } = require('../self');
-
-const OPTIONS_DISPLAYED = "addon-options-displayed";
-
-function enable() {
-  on(OPTIONS_DISPLAYED, onOptionsDisplayed);  
-}
-exports.enable = enable;
-
-function onOptionsDisplayed({ subject: document, data: addonId }) {
-  if (addonId !== jetpackId)
-    return;
-  localizeInlineOptions(document);
-}
-
-function localizeInlineOptions(document) {
-  let query = 'setting[data-jetpack-id="' + jetpackId + '"][pref-name], ' +
-              'button[data-jetpack-id="' + jetpackId + '"][pref-name]';
-  let nodes = document.querySelectorAll(query);
-  for (let node of nodes) {
-    let name = node.getAttribute("pref-name");
-    if (node.tagName == "setting") {
-      let desc = core.get(name + "_description");
-      if (desc)
-        node.setAttribute("desc", desc);
-      let title = core.get(name + "_title");
-      if (title)
-        node.setAttribute("title", title);
-
-      for (let item of node.querySelectorAll("menuitem, radio")) {
-          let key = name + "_options." + item.getAttribute("label");
-          let label = core.get(key);
-          if (label)
-            item.setAttribute("label", label);
-      }
-    }
-    else if (node.tagName == "button") {
-      let label = core.get(name + "_label");
-      if (label)
-        node.setAttribute("label", label);
-    }
-  }
-}
-exports.localizeInlineOptions = localizeInlineOptions;
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/l10n/properties/core.js
+++ /dev/null
@@ -1,89 +0,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";
-
-const { Cu } = require("chrome");
-lazyRequire(this, '../../url/utils', 'newURI');
-lazyRequire(this, "../plural-rules", 'getRulesForLocale');
-lazyRequire(this, '../locale', 'getPreferedLocales');
-const { rootURI } = require("@loader/options");
-const { Services } = require("resource://gre/modules/Services.jsm");
-const { XPCOMUtils } = require("resource://gre/modules/XPCOMUtils.jsm");
-
-const baseURI = rootURI + "locale/";
-
-XPCOMUtils.defineLazyGetter(this, "preferedLocales", () => getPreferedLocales(true));
-
-// Make sure we don't get stale data after an update
-// (See Bug 1300735 for rationale).
-Services.strings.flushBundles();
-
-function getLocaleURL(locale) {
-  // if the locale is a valid chrome URI, return it
-  try {
-    let uri = newURI(locale);
-    if (uri.scheme == 'chrome')
-      return uri.spec;
-  }
-  catch(_) {}
-  // otherwise try to construct the url
-  return baseURI + locale + ".properties";
-}
-
-function getKey(locale, key) {
-  let bundle = Services.strings.createBundle(getLocaleURL(locale));
-  try {
-    return bundle.GetStringFromName(key) + "";
-  }
-  catch (_) {}
-  return undefined;
-}
-
-function get(key, n, locales) {
-  // try this locale
-  let locale = locales.shift();
-  let localized;
-
-  if (typeof n == 'number') {
-    if (n == 0) {
-      localized = getKey(locale, key + '[zero]');
-    }
-    else if (n == 1) {
-      localized = getKey(locale, key + '[one]');
-    }
-    else if (n == 2) {
-      localized = getKey(locale, key + '[two]');
-    }
-
-    if (!localized) {
-      // Retrieve the plural mapping function
-      let pluralForm = (getRulesForLocale(locale.split("-")[0].toLowerCase()) ||
-                        getRulesForLocale("en"))(n);
-      localized = getKey(locale, key + '[' + pluralForm + ']');
-    }
-
-    if (!localized) {
-      localized = getKey(locale, key + '[other]');
-    }
-  }
-
-  if (!localized) {
-    localized = getKey(locale, key);
-  }
-
-  if (!localized) {
-    localized = getKey(locale, key + '[other]');
-  }
-
-  if (localized) {
-    return localized;
-  }
-
-  // try next locale
-  if (locales.length)
-    return get(key, n, locales);
-
-  return undefined;
-}
-exports.get = (k, n) => get(k, n, Array.slice(preferedLocales));
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/preferences/native-options.js
+++ /dev/null
@@ -1,178 +0,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';
-
-module.metadata = {
-  "stability": "unstable"
-};
-
-const { Cc, Ci, Cu } = require('chrome');
-lazyRequire(this, '../system/events', "on");
-lazyRequire(this, '../self', "preferencesBranch");
-lazyRequire(this, '../l10n/prefs', "localizeInlineOptions");
-
-lazyRequire(this, "resource://gre/modules/Services.jsm", "Services");
-lazyRequire(this, "resource://gre/modules/AddonManager.jsm", "AddonManager");
-lazyRequire(this, "resource://gre/modules/Preferences.jsm", "Preferences");
-
-const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";;
-const DEFAULT_OPTIONS_URL = 'data:text/xml,<placeholder/>';
-
-const VALID_PREF_TYPES = ['bool', 'boolint', 'integer', 'string', 'color',
-                          'file', 'directory', 'control', 'menulist', 'radio'];
-
-const isFennec = require("sdk/system/xul-app").is("Fennec");
-
-function enable({ preferences, id }) {
-  return new Promise(resolve => {
-    validate(preferences);
-
-    setDefaults(preferences, preferencesBranch);
-
-    // allow the use of custom options.xul
-    AddonManager.getAddonByID(id, (addon) => {
-      on('addon-options-displayed', onAddonOptionsDisplayed, true);
-      resolve({ id });
-    });
-
-    function onAddonOptionsDisplayed({ subject: doc, data }) {
-      if (data === id) {
-        let parent;
-
-        if (isFennec) {
-          parent = doc.querySelector('.options-box');
-
-          // NOTE: This disable the CSS rule that makes the options invisible
-          let item = doc.querySelector('#addons-details .addon-item');
-          item.removeAttribute("optionsURL");
-        } else {
-          parent = doc.getElementById('detail-downloads').parentNode;
-        }
-
-        if (parent) {
-          injectOptions({
-            preferences: preferences,
-            preferencesBranch: preferencesBranch,
-            document: doc,
-            parent: parent,
-            id: id
-          });
-          localizeInlineOptions(doc);
-        } else {
-          throw Error("Preferences parent node not found in Addon Details. The configured custom preferences will not be visible.");
-        }
-      }
-    }
-  });
-}
-exports.enable = enable;
-
-// centralized sanity checks
-function validate(preferences) {
-  for (let { name, title, type, label, options } of preferences) {
-    // make sure the title is set and non-empty
-    if (!title)
-      throw Error("The '" + name + "' pref requires a title");
-
-    // make sure that pref type is a valid inline option type
-    if (!~VALID_PREF_TYPES.indexOf(type))
-      throw Error("The '" + name + "' pref must be of valid type");
-
-    // if it's a control, make sure it has a label
-    if (type === 'control' && !label)
-      throw Error("The '" + name + "' control requires a label");
-
-    // if it's a menulist or radio, make sure it has options
-    if (type === 'menulist' || type === 'radio') {
-      if (!options)
-        throw Error("The '" + name + "' pref requires options");
-
-      // make sure each option has a value and a label
-      for (let item of options) {
-        if (!('value' in item) || !('label' in item))
-          throw Error("Each option requires both a value and a label");
-      }
-    }
-
-    // TODO: check that pref type matches default value type
-  }
-}
-exports.validate = validate;
-
-// initializes default preferences, emulates defaults/prefs.js
-function setDefaults(preferences, preferencesBranch) {
-  let prefs = new Preferences({
-    branch: `extensions.${preferencesBranch}.`,
-    defaultBranch: true,
-  });
-
-  for (let { name, value } of preferences)
-    if (value !== undefined)
-      prefs.set(name, value);
-}
-exports.setDefaults = setDefaults;
-
-// dynamically injects inline options into about:addons page at runtime
-// NOTE: on Firefox Desktop the about:addons page is a xul page document,
-// on Firefox for Android the about:addons page is an xhtml page, to support both
-// the XUL xml namespace have to be enforced.
-function injectOptions({ preferences, preferencesBranch, document, parent, id }) {
-  preferences.forEach(({name, type, hidden, title, description, label, options, on, off}) => {
-    if (hidden) {
-      return;
-    }
-
-    let setting = document.createElementNS(XUL_NS, 'setting');
-    setting.setAttribute('pref-name', name);
-    setting.setAttribute('data-jetpack-id', id);
-    setting.setAttribute('pref', 'extensions.' + preferencesBranch + '.' + name);
-    setting.setAttribute('type', type);
-    setting.setAttribute('title', title);
-    if (description)
-      setting.setAttribute('desc', description);
-
-    if (type === 'file' || type === 'directory') {
-      setting.setAttribute('fullpath', 'true');
-    }
-    else if (type === 'control') {
-      let button = document.createElementNS(XUL_NS, 'button');
-      button.setAttribute('pref-name', name);
-      button.setAttribute('data-jetpack-id', id);
-      button.setAttribute('label', label);
-      button.addEventListener('command', function() {
-        Services.obs.notifyObservers(null, `${id}-cmdPressed`, name);
-      }, true);
-      setting.appendChild(button);
-    }
-    else if (type === 'boolint') {
-      setting.setAttribute('on', on);
-      setting.setAttribute('off', off);
-    }
-    else if (type === 'menulist') {
-      let menulist = document.createElementNS(XUL_NS, 'menulist');
-      let menupopup = document.createElementNS(XUL_NS, 'menupopup');
-      for (let { value, label } of options) {
-        let menuitem = document.createElementNS(XUL_NS, 'menuitem');
-        menuitem.setAttribute('value', value);
-        menuitem.setAttribute('label', label);
-        menupopup.appendChild(menuitem);
-      }
-      menulist.appendChild(menupopup);
-      setting.appendChild(menulist);
-    }
-    else if (type === 'radio') {
-      let radiogroup = document.createElementNS(XUL_NS, 'radiogroup');
-      for (let { value, label } of options) {
-        let radio = document.createElementNS(XUL_NS, 'radio');
-        radio.setAttribute('value', value);
-        radio.setAttribute('label', label);
-        radiogroup.appendChild(radio);
-      }
-      setting.appendChild(radiogroup);
-    }
-
-    parent.appendChild(setting);
-  });
-}
-exports.injectOptions = injectOptions;