l10n.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  3. * You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. "use strict";
  5. /**
  6. * An API which allows Marionette to handle localized content.
  7. *
  8. * The localization (https://mzl.la/2eUMjyF) of UI elements in Gecko based
  9. * applications is done via entities and properties. For static values entities
  10. * are used, which are located in .dtd files. Whereby for dynamically updated
  11. * content the values come from .property files. Both types of elements can be
  12. * identifed via a unique id, and the translated content retrieved.
  13. */
  14. const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
  15. Cu.import("resource://gre/modules/Services.jsm");
  16. Cu.import("resource://gre/modules/XPCOMUtils.jsm");
  17. XPCOMUtils.defineLazyServiceGetter(
  18. this, "domParser", "@mozilla.org/xmlextras/domparser;1", "nsIDOMParser");
  19. Cu.import("chrome://marionette/content/error.js");
  20. this.EXPORTED_SYMBOLS = ["l10n"];
  21. this.l10n = {};
  22. /**
  23. * Retrieve the localized string for the specified entity id.
  24. *
  25. * Example:
  26. * localizeEntity(["chrome://global/locale/about.dtd"], "about.version")
  27. *
  28. * @param {Array.<string>} urls
  29. * Array of .dtd URLs.
  30. * @param {string} id
  31. * The ID of the entity to retrieve the localized string for.
  32. *
  33. * @return {string}
  34. * The localized string for the requested entity.
  35. */
  36. l10n.localizeEntity = function (urls, id) {
  37. // Build a string which contains all possible entity locations
  38. let locations = [];
  39. urls.forEach((url, index) => {
  40. locations.push(`<!ENTITY % dtd_${index} SYSTEM "${url}">%dtd_${index};`);
  41. })
  42. // Use the DOM parser to resolve the entity and extract its real value
  43. let header = `<?xml version="1.0"?><!DOCTYPE elem [${locations.join("")}]>`;
  44. let elem = `<elem id="elementID">&${id};</elem>`;
  45. let doc = domParser.parseFromString(header + elem, "text/xml");
  46. let element = doc.querySelector("elem[id='elementID']");
  47. if (element === null) {
  48. throw new NoSuchElementError(`Entity with id='${id}' hasn't been found`);
  49. }
  50. return element.textContent;
  51. };
  52. /**
  53. * Retrieve the localized string for the specified property id.
  54. *
  55. * Example:
  56. * localizeProperty(["chrome://global/locale/findbar.properties"], "FastFind")
  57. *
  58. * @param {Array.<string>} urls
  59. * Array of .properties URLs.
  60. * @param {string} id
  61. * The ID of the property to retrieve the localized string for.
  62. *
  63. * @return {string}
  64. * The localized string for the requested property.
  65. */
  66. l10n.localizeProperty = function (urls, id) {
  67. let property = null;
  68. for (let url of urls) {
  69. let bundle = Services.strings.createBundle(url);
  70. try {
  71. property = bundle.GetStringFromName(id);
  72. break;
  73. } catch (e) {}
  74. };
  75. if (property === null) {
  76. throw new NoSuchElementError(`Property with id='${id}' hasn't been found`);
  77. }
  78. return property;
  79. };