diff --git a/.eslintignore b/.eslintignore index 5eb425666e5f..3a9b45d9e601 100644 --- a/.eslintignore +++ b/.eslintignore @@ -24,7 +24,6 @@ gfx/tests/chrome/** gfx/tests/mochitest/** gfx/tests/unit/** image/** -intl/** layout/** memory/replace/dmd/test/** modules/** @@ -303,6 +302,12 @@ dom/media/webvtt/** gfx/ots/** gfx/skia/** +# intl/ exclusions +intl/icu/** +intl/locale/** +intl/strres/** +intl/uconv/** + # Exclude everything but self-hosted JS js/ductwork/** js/examples/** diff --git a/intl/l10n/DOMLocalization.jsm b/intl/l10n/DOMLocalization.jsm index b0dc30b9b5fa..7f046228c137 100644 --- a/intl/l10n/DOMLocalization.jsm +++ b/intl/l10n/DOMLocalization.jsm @@ -16,7 +16,7 @@ */ -/* fluent@0.6.0 */ +/* fluent@0.6.3 */ const { Localization } = ChromeUtils.import("resource://gre/modules/Localization.jsm", {}); @@ -31,36 +31,36 @@ const reOverlay = /<|&#?\w+;/; * Source: https://www.w3.org/TR/html5/text-level-semantics.html */ const LOCALIZABLE_ELEMENTS = { - 'http://www.w3.org/1999/xhtml': [ - 'a', 'em', 'strong', 'small', 's', 'cite', 'q', 'dfn', 'abbr', 'data', - 'time', 'code', 'var', 'samp', 'kbd', 'sub', 'sup', 'i', 'b', 'u', - 'mark', 'ruby', 'rt', 'rp', 'bdi', 'bdo', 'span', 'br', 'wbr' + "http://www.w3.org/1999/xhtml": [ + "a", "em", "strong", "small", "s", "cite", "q", "dfn", "abbr", "data", + "time", "code", "var", "samp", "kbd", "sub", "sup", "i", "b", "u", + "mark", "ruby", "rt", "rp", "bdi", "bdo", "span", "br", "wbr" ], }; const LOCALIZABLE_ATTRIBUTES = { - 'http://www.w3.org/1999/xhtml': { - global: ['title', 'aria-label', 'aria-valuetext', 'aria-moz-hint'], - a: ['download'], - area: ['download', 'alt'], + "http://www.w3.org/1999/xhtml": { + global: ["title", "aria-label", "aria-valuetext", "aria-moz-hint"], + a: ["download"], + area: ["download", "alt"], // value is special-cased in isAttrNameLocalizable - input: ['alt', 'placeholder'], - menuitem: ['label'], - menu: ['label'], - optgroup: ['label'], - option: ['label'], - track: ['label'], - img: ['alt'], - textarea: ['placeholder'], - th: ['abbr'] + input: ["alt", "placeholder"], + menuitem: ["label"], + menu: ["label"], + optgroup: ["label"], + option: ["label"], + track: ["label"], + img: ["alt"], + textarea: ["placeholder"], + th: ["abbr"] }, - 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul': { + "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul": { global: [ - 'accesskey', 'aria-label', 'aria-valuetext', 'aria-moz-hint', 'label' + "accesskey", "aria-label", "aria-valuetext", "aria-moz-hint", "label" ], - key: ['key', 'keycode'], - textbox: ['placeholder'], - toolbarbutton: ['tooltiptext'], + key: ["key", "keycode"], + textbox: ["placeholder"], + toolbarbutton: ["tooltiptext"], } }; @@ -75,7 +75,7 @@ const LOCALIZABLE_ATTRIBUTES = { function overlayElement(targetElement, translation) { const value = translation.value; - if (typeof value === 'string') { + if (typeof value === "string") { if (!reOverlay.test(value)) { // If the translation doesn't contain any markup skip the overlay logic. targetElement.textContent = value; @@ -83,7 +83,8 @@ function overlayElement(targetElement, translation) { // Else parse the translation's HTML using an inert template element, // sanitize it and replace the targetElement's content. const templateElement = targetElement.ownerDocument.createElementNS( - 'http://www.w3.org/1999/xhtml', 'template'); + "http://www.w3.org/1999/xhtml", "template"); + // eslint-disable-next-line no-unsanitized/property templateElement.innerHTML = value; targetElement.appendChild( // The targetElement will be cleared at the end of sanitization. @@ -92,9 +93,9 @@ function overlayElement(targetElement, translation) { } } - const explicitlyAllowed = targetElement.hasAttribute('data-l10n-attrs') - ? targetElement.getAttribute('data-l10n-attrs') - .split(',').map(i => i.trim()) + const explicitlyAllowed = targetElement.hasAttribute("data-l10n-attrs") + ? targetElement.getAttribute("data-l10n-attrs") + .split(",").map(i => i.trim()) : null; // Remove localizable attributes which may have been set by a previous @@ -182,7 +183,7 @@ function sanitizeUsing(translationFragment, sourceElement) { // SourceElement might have been already modified by shiftNamedElement. // Let's clear it to make sure other code doesn't rely on random leftovers. - sourceElement.textContent = ''; + sourceElement.textContent = ""; return translationFragment; } @@ -274,10 +275,10 @@ function isAttrNameLocalizable(name, element, explicitlyAllowed = null) { } // Special case for value on HTML inputs with type button, reset, submit - if (element.namespaceURI === 'http://www.w3.org/1999/xhtml' && - elemName === 'input' && attrName === 'value') { + if (element.namespaceURI === "http://www.w3.org/1999/xhtml" && + elemName === "input" && attrName === "value") { const type = element.type.toLowerCase(); - if (type === 'submit' || type === 'button' || type === 'reset') { + if (type === "submit" || type === "button" || type === "reset") { return true; } } @@ -303,8 +304,8 @@ function shiftNamedElement(element, localName) { return null; } -const L10NID_ATTR_NAME = 'data-l10n-id'; -const L10NARGS_ATTR_NAME = 'data-l10n-args'; +const L10NID_ATTR_NAME = "data-l10n-id"; +const L10NARGS_ATTR_NAME = "data-l10n-args"; const L10N_ELEMENT_QUERY = `[${L10NID_ATTR_NAME}]`; @@ -430,7 +431,7 @@ class DOMLocalization extends Localization { if (root === newRoot || root.contains(newRoot) || newRoot.contains(root)) { - throw new Error('Cannot add a root that overlaps with existing root.'); + throw new Error("Cannot add a root that overlaps with existing root."); } } @@ -500,10 +501,10 @@ class DOMLocalization extends Localization { translateMutations(mutations) { for (const mutation of mutations) { switch (mutation.type) { - case 'attributes': + case "attributes": this.pendingElements.add(mutation.target); break; - case 'childList': + case "childList": for (const addedNode of mutation.addedNodes) { if (addedNode.nodeType === addedNode.ELEMENT_NODE) { if (addedNode.childElementCount) { @@ -600,7 +601,7 @@ class DOMLocalization extends Localization { getTranslatables(element) { const nodes = Array.from(element.querySelectorAll(L10N_ELEMENT_QUERY)); - if (typeof element.hasAttribute === 'function' && + if (typeof element.hasAttribute === "function" && element.hasAttribute(L10NID_ATTR_NAME)) { nodes.push(element); } @@ -625,4 +626,4 @@ class DOMLocalization extends Localization { } this.DOMLocalization = DOMLocalization; -this.EXPORTED_SYMBOLS = ['DOMLocalization']; +this.EXPORTED_SYMBOLS = ["DOMLocalization"]; diff --git a/intl/l10n/L10nRegistry.jsm b/intl/l10n/L10nRegistry.jsm index b26965b46d77..d55891c05b4d 100644 --- a/intl/l10n/L10nRegistry.jsm +++ b/intl/l10n/L10nRegistry.jsm @@ -1,7 +1,7 @@ const { AppConstants } = ChromeUtils.import("resource://gre/modules/AppConstants.jsm", {}); -const { Services } = ChromeUtils.import('resource://gre/modules/Services.jsm', {}); +const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm", {}); const { MessageContext } = ChromeUtils.import("resource://gre/modules/MessageContext.jsm", {}); -Components.utils.importGlobalProperties(["fetch"]); /* globals fetch */ +Cu.importGlobalProperties(["fetch"]); /** * L10nRegistry is a localization resource management system for Gecko. @@ -89,7 +89,7 @@ const L10nRegistry = { * @param {Array} resourceIds * @returns {AsyncIterator} */ - async * generateContexts(requestedLangs, resourceIds) { + async* generateContexts(requestedLangs, resourceIds) { if (this.bootstrap !== null) { await this.bootstrap; } @@ -167,8 +167,8 @@ const L10nRegistry = { * @returns {String} */ function generateContextID(locale, sourcesOrder, resourceIds) { - const sources = sourcesOrder.join(','); - const ids = resourceIds.join(','); + const sources = sourcesOrder.join(","); + const ids = resourceIds.join(","); return `${locale}|${sources}|${ids}`; } @@ -219,7 +219,7 @@ async function* generateContextsForLocale(locale, sourcesOrder, resourceIds, res } } -const MSG_CONTEXT_OPTIONS = { +const MSG_CONTEXT_OPTIONS = { // Temporarily disable bidi isolation due to Microsoft not supporting FSI/PDI. // See bug 1439018 for details. useIsolating: Services.prefs.getBoolPref("intl.l10n.enable-bidi-marks", false), @@ -242,7 +242,7 @@ const MSG_CONTEXT_OPTIONS = { } } } -} +}; /** * Generates a single MessageContext by loading all resources @@ -360,11 +360,9 @@ class FileSource { if (this.cache[fullPath].then) { return this.cache[fullPath]; } - } else { - if (this.indexed) { + } else if (this.indexed) { return Promise.reject(`The source has no resources for path "${fullPath}"`); } - } return this.cache[fullPath] = L10nRegistry.load(fullPath).then( data => { return this.cache[fullPath] = data; @@ -417,7 +415,7 @@ L10nRegistry.load = function(url) { if (!response.ok) { return Promise.reject(response.statusText); } - return response.text() + return response.text(); }); }; @@ -425,4 +423,4 @@ this.L10nRegistry = L10nRegistry; this.FileSource = FileSource; this.IndexedFileSource = IndexedFileSource; -this.EXPORTED_SYMBOLS = ['L10nRegistry', 'FileSource', 'IndexedFileSource']; +this.EXPORTED_SYMBOLS = ["L10nRegistry", "FileSource", "IndexedFileSource"]; diff --git a/intl/l10n/Localization.jsm b/intl/l10n/Localization.jsm index 56a363151d17..cc30b5a256e3 100644 --- a/intl/l10n/Localization.jsm +++ b/intl/l10n/Localization.jsm @@ -16,15 +16,14 @@ */ -/* fluent@0.6.0 */ +/* fluent@0.6.3 */ /* eslint no-console: ["error", { allow: ["warn", "error"] }] */ /* global console */ const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm", {}); const { L10nRegistry } = ChromeUtils.import("resource://gre/modules/L10nRegistry.jsm", {}); -const LocaleService = Cc["@mozilla.org/intl/localeservice;1"].getService(Ci.mozILocaleService); -const ObserverService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService); +const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm", {}); /* * CachedIterable caches the elements yielded by an iterable. @@ -45,7 +44,7 @@ class CachedIterable { } else if (Symbol.iterator in Object(iterable)) { this.iterator = iterable[Symbol.iterator](); } else { - throw new TypeError('Argument must implement the iteration protocol.'); + throw new TypeError("Argument must implement the iteration protocol."); } this.seen = []; @@ -104,7 +103,7 @@ class CachedIterable { class L10nError extends Error { constructor(message) { super(); - this.name = 'L10nError'; + this.name = "L10nError"; this.message = message; } } @@ -121,7 +120,7 @@ class L10nError extends Error { function defaultGenerateMessages(resourceIds) { const availableLocales = L10nRegistry.getAvailableLocales(); - const appLocales = LocaleService.getAppLocalesAsLangTags(); + const appLocales = Services.locale.getAppLocalesAsLangTags(); return L10nRegistry.generateContexts(appLocales, resourceIds); } @@ -162,7 +161,7 @@ class Localization { for await (let ctx of this.ctxs) { // This can operate on synchronous and asynchronous // contexts coming from the iterator. - if (typeof ctx.then === 'function') { + if (typeof ctx.then === "function") { ctx = await ctx; } const errors = keysFromContext(method, ctx, keys, translations); @@ -254,14 +253,14 @@ class Localization { * Register weak observers on events that will trigger cache invalidation */ registerObservers() { - ObserverService.addObserver(this, 'intl:app-locales-changed', true); + Services.obs.addObserver(this, 'intl:app-locales-changed', true); } /** * Unregister observers on events that will trigger cache invalidation */ unregisterObservers() { - ObserverService.removeObserver(this, 'intl:app-locales-changed'); + Services.obs.removeObserver(this, 'intl:app-locales-changed'); } /** @@ -273,7 +272,7 @@ class Localization { */ observe(subject, topic, data) { switch (topic) { - case 'intl:app-locales-changed': + case "intl:app-locales-changed": this.onLanguageChange(); break; default: @@ -435,4 +434,4 @@ function keysFromContext(method, ctx, keys, translations) { } this.Localization = Localization; -this.EXPORTED_SYMBOLS = ['Localization']; +this.EXPORTED_SYMBOLS = ["Localization"]; diff --git a/intl/l10n/MessageContext.jsm b/intl/l10n/MessageContext.jsm index 02b381bc8ebc..d7196922aadb 100644 --- a/intl/l10n/MessageContext.jsm +++ b/intl/l10n/MessageContext.jsm @@ -16,7 +16,7 @@ */ -/* fluent@0.6.0 */ +/* fluent@0.6.3 */ /* eslint no-magic-numbers: [0] */ @@ -86,7 +86,7 @@ class RuntimeParser { // The index here should either be at the beginning of the file // or right after new line. if (this._index !== 0 && - this._source[this._index - 1] !== '\n') { + this._source[this._index - 1] !== "\n") { throw this.error(`Expected an entry to start at the beginning of the file or on a new line.`); } @@ -94,14 +94,14 @@ class RuntimeParser { const ch = this._source[this._index]; // We don't care about comments or sections at runtime - if (ch === '/' || - (ch === '#' && - [' ', '#', '\n'].includes(this._source[this._index + 1]))) { + if (ch === "/" || + (ch === "#" && + [" ", "#", "\n"].includes(this._source[this._index + 1]))) { this.skipComment(); return; } - if (ch === '[') { + if (ch === "[") { this.skipSection(); return; } @@ -116,7 +116,7 @@ class RuntimeParser { */ skipSection() { this._index += 1; - if (this._source[this._index] !== '[') { + if (this._source[this._index] !== "[") { throw this.error('Expected "[[" to open a section'); } @@ -126,8 +126,8 @@ class RuntimeParser { this.getVariantName(); this.skipInlineWS(); - if (this._source[this._index] !== ']' || - this._source[this._index + 1] !== ']') { + if (this._source[this._index] !== "]" || + this._source[this._index + 1] !== "]") { throw this.error('Expected "]]" to close a section'); } @@ -145,7 +145,7 @@ class RuntimeParser { this.skipInlineWS(); - if (this._source[this._index] === '=') { + if (this._source[this._index] === "=") { this._index++; } @@ -153,27 +153,27 @@ class RuntimeParser { const val = this.getPattern(); - if (id.startsWith('-') && val === null) { - throw this.error('Expected term to have a value'); + if (id.startsWith("-") && val === null) { + throw this.error("Expected term to have a value"); } let attrs = null; - if (this._source[this._index] === ' ') { + if (this._source[this._index] === " ") { const lineStart = this._index; this.skipInlineWS(); - if (this._source[this._index] === '.') { + if (this._source[this._index] === ".") { this._index = lineStart; attrs = this.getAttributes(); } } - if (attrs === null && typeof val === 'string') { + if (attrs === null && typeof val === "string") { this.entries[id] = val; } else { if (val === null && attrs === null) { - throw this.error('Expected message to have a value or attributes'); + throw this.error("Expected message to have a value or attributes"); } this.entries[id] = {}; @@ -195,7 +195,7 @@ class RuntimeParser { */ skipWS() { let ch = this._source[this._index]; - while (ch === ' ' || ch === '\n' || ch === '\t' || ch === '\r') { + while (ch === " " || ch === "\n" || ch === "\t" || ch === "\r") { ch = this._source[++this._index]; } } @@ -207,7 +207,7 @@ class RuntimeParser { */ skipInlineWS() { let ch = this._source[this._index]; - while (ch === ' ' || ch === '\t') { + while (ch === " " || ch === "\t") { ch = this._source[++this._index]; } } @@ -223,7 +223,7 @@ class RuntimeParser { this.skipInlineWS(); - if (this._source[this._index] === '\n') { + if (this._source[this._index] === "\n") { this._index += 1; } else { this._index = ptr; @@ -271,7 +271,7 @@ class RuntimeParser { * @private */ getVariantName() { - let name = ''; + let name = ""; const start = this._index; let cc = this._source.charCodeAt(this._index); @@ -281,7 +281,7 @@ class RuntimeParser { cc === 95 || cc === 32) { // _ cc = this._source.charCodeAt(++this._index); } else { - throw this.error('Expected a keyword (starting with [a-zA-Z_])'); + throw this.error("Expected a keyword (starting with [a-zA-Z_])"); } while ((cc >= 97 && cc <= 122) || // a-z @@ -301,7 +301,7 @@ class RuntimeParser { name += this._source.slice(start, this._index); - return { type: 'varname', name }; + return { type: "varname", name }; } /** @@ -320,8 +320,8 @@ class RuntimeParser { break; } - if (ch === '\n') { - throw this.error('Unterminated string expression'); + if (ch === "\n") { + throw this.error("Unterminated string expression"); } } @@ -343,7 +343,7 @@ class RuntimeParser { // Then, if either the line contains a placeable opening `{` or the // next line starts an indentation, we switch to complex pattern. const start = this._index; - let eol = this._source.indexOf('\n', this._index); + let eol = this._source.indexOf("\n", this._index); if (eol === -1) { eol = this._length; @@ -352,7 +352,7 @@ class RuntimeParser { const firstLineContent = start !== eol ? this._source.slice(start, eol) : null; - if (firstLineContent && firstLineContent.includes('{')) { + if (firstLineContent && firstLineContent.includes("{")) { return this.getComplexPattern(); } @@ -360,7 +360,7 @@ class RuntimeParser { this.skipBlankLines(); - if (this._source[this._index] !== ' ') { + if (this._source[this._index] !== " ") { // No indentation means we're done with this message. Callers should check // if the return value here is null. It may be OK for messages, but not OK // for terms, attributes and variants. @@ -371,7 +371,7 @@ class RuntimeParser { this.skipInlineWS(); - if (this._source[this._index] === '.') { + if (this._source[this._index] === ".") { // The pattern is followed by an attribute. Rewind _index to the first // column of the current line as expected by getAttributes. this._index = lineStart; @@ -398,7 +398,7 @@ class RuntimeParser { */ /* eslint-disable complexity */ getComplexPattern() { - let buffer = ''; + let buffer = ""; const content = []; let placeables = 0; @@ -407,7 +407,7 @@ class RuntimeParser { while (this._index < this._length) { // This block handles multi-line strings combining strings separated // by new line. - if (ch === '\n') { + if (ch === "\n") { this._index++; // We want to capture the start and end pointers @@ -419,15 +419,15 @@ class RuntimeParser { const blankLinesEnd = this._index; - if (this._source[this._index] !== ' ') { + if (this._source[this._index] !== " ") { break; } this.skipInlineWS(); - if (this._source[this._index] === '}' || - this._source[this._index] === '[' || - this._source[this._index] === '*' || - this._source[this._index] === '.') { + if (this._source[this._index] === "}" || + this._source[this._index] === "[" || + this._source[this._index] === "*" || + this._source[this._index] === ".") { this._index = blankLinesEnd; break; } @@ -435,17 +435,17 @@ class RuntimeParser { buffer += this._source.substring(blankLinesStart, blankLinesEnd); if (buffer.length || content.length) { - buffer += '\n'; + buffer += "\n"; } ch = this._source[this._index]; continue; - } else if (ch === '\\') { + } else if (ch === "\\") { const ch2 = this._source[this._index + 1]; - if (ch2 === '"' || ch2 === '{' || ch2 === '\\') { + if (ch2 === '"' || ch2 === "{" || ch2 === "\\") { ch = ch2; this._index++; } - } else if (ch === '{') { + } else if (ch === "{") { // Push the buffer to content array right before placeable if (buffer.length) { content.push(buffer); @@ -454,7 +454,7 @@ class RuntimeParser { throw this.error( `Too many placeables, maximum allowed is ${MAX_PLACEABLES}`); } - buffer = ''; + buffer = ""; content.push(this.getPlaceable()); this._index++; @@ -495,13 +495,13 @@ class RuntimeParser { this.skipWS(); - if (this._source[this._index] === '*' || - (this._source[this._index] === '[' && - this._source[this._index + 1] !== ']')) { + if (this._source[this._index] === "*" || + (this._source[this._index] === "[" && + this._source[this._index + 1] !== "]")) { const variants = this.getVariants(); return { - type: 'sel', + type: "sel", exp: null, vars: variants[0], def: variants[1] @@ -518,31 +518,31 @@ class RuntimeParser { const ch = this._source[this._index]; - if (ch === '}') { - if (selector.type === 'attr' && selector.id.name.startsWith('-')) { + if (ch === "}") { + if (selector.type === "attr" && selector.id.name.startsWith("-")) { throw this.error( - 'Attributes of private messages cannot be interpolated.' + "Attributes of private messages cannot be interpolated." ); } return selector; } - if (ch !== '-' || this._source[this._index + 1] !== '>') { + if (ch !== "-" || this._source[this._index + 1] !== ">") { throw this.error('Expected "}" or "->"'); } - if (selector.type === 'ref') { - throw this.error('Message references cannot be used as selectors.'); + if (selector.type === "ref") { + throw this.error("Message references cannot be used as selectors."); } - if (selector.type === 'var') { - throw this.error('Variants cannot be used as selectors.'); + if (selector.type === "var") { + throw this.error("Variants cannot be used as selectors."); } - if (selector.type === 'attr' && !selector.id.name.startsWith('-')) { + if (selector.type === "attr" && !selector.id.name.startsWith("-")) { throw this.error( - 'Attributes of public messages cannot be used as selectors.' + "Attributes of public messages cannot be used as selectors." ); } @@ -551,8 +551,8 @@ class RuntimeParser { this.skipInlineWS(); - if (this._source[this._index] !== '\n') { - throw this.error('Variants should be listed in a new line'); + if (this._source[this._index] !== "\n") { + throw this.error("Variants should be listed in a new line"); } this.skipWS(); @@ -560,11 +560,11 @@ class RuntimeParser { const variants = this.getVariants(); if (variants[0].length === 0) { - throw this.error('Expected members for the select expression'); + throw this.error("Expected members for the select expression"); } return { - type: 'sel', + type: "sel", exp: selector, vars: variants[0], def: variants[1] @@ -580,48 +580,48 @@ class RuntimeParser { getSelectorExpression() { const literal = this.getLiteral(); - if (literal.type !== 'ref') { + if (literal.type !== "ref") { return literal; } - if (this._source[this._index] === '.') { + if (this._source[this._index] === ".") { this._index++; const name = this.getIdentifier(); this._index++; return { - type: 'attr', + type: "attr", id: literal, name }; } - if (this._source[this._index] === '[') { + if (this._source[this._index] === "[") { this._index++; const key = this.getVariantKey(); this._index++; return { - type: 'var', + type: "var", id: literal, key }; } - if (this._source[this._index] === '(') { + if (this._source[this._index] === "(") { this._index++; const args = this.getCallArgs(); if (!functionIdentifierRe.test(literal.name)) { - throw this.error('Function names must be all upper-case'); + throw this.error("Function names must be all upper-case"); } this._index++; - literal.type = 'fun'; + literal.type = "fun"; return { - type: 'call', + type: "call", fun: literal, args }; @@ -642,7 +642,7 @@ class RuntimeParser { while (this._index < this._length) { this.skipInlineWS(); - if (this._source[this._index] === ')') { + if (this._source[this._index] === ")") { return args; } @@ -650,12 +650,12 @@ class RuntimeParser { // MessageReference in this place may be an entity reference, like: // `call(foo)`, or, if it's followed by `:` it will be a key-value pair. - if (exp.type !== 'ref') { + if (exp.type !== "ref") { args.push(exp); } else { this.skipInlineWS(); - if (this._source[this._index] === ':') { + if (this._source[this._index] === ":") { this._index++; this.skipInlineWS(); @@ -666,18 +666,18 @@ class RuntimeParser { // // We don't have to check here if the pattern is quote delimited // because that's the only type of string allowed in expressions. - if (typeof val === 'string' || + if (typeof val === "string" || Array.isArray(val) || - val.type === 'num') { + val.type === "num") { args.push({ - type: 'narg', + type: "narg", name: exp.name, val }); } else { - this._index = this._source.lastIndexOf(':', this._index) + 1; + this._index = this._source.lastIndexOf(":", this._index) + 1; throw this.error( - 'Expected string in quotes, number.'); + "Expected string in quotes, number."); } } else { @@ -687,9 +687,9 @@ class RuntimeParser { this.skipInlineWS(); - if (this._source[this._index] === ')') { + if (this._source[this._index] === ")") { break; - } else if (this._source[this._index] === ',') { + } else if (this._source[this._index] === ",") { this._index++; } else { throw this.error('Expected "," or ")"'); @@ -706,12 +706,12 @@ class RuntimeParser { * @private */ getNumber() { - let num = ''; + let num = ""; let cc = this._source.charCodeAt(this._index); // The number literal may start with negative sign `-`. if (cc === 45) { - num += '-'; + num += "-"; cc = this._source.charCodeAt(++this._index); } @@ -744,7 +744,7 @@ class RuntimeParser { } return { - type: 'num', + type: "num", val: num }; } @@ -759,12 +759,12 @@ class RuntimeParser { const attrs = {}; while (this._index < this._length) { - if (this._source[this._index] !== ' ') { + if (this._source[this._index] !== " ") { break; } this.skipInlineWS(); - if (this._source[this._index] !== '.') { + if (this._source[this._index] !== ".") { break; } this._index++; @@ -773,7 +773,7 @@ class RuntimeParser { this.skipInlineWS(); - if (this._source[this._index] !== '=') { + if (this._source[this._index] !== "=") { throw this.error('Expected "="'); } this._index++; @@ -783,10 +783,10 @@ class RuntimeParser { const val = this.getPattern(); if (val === null) { - throw this.error('Expected attribute to have a value'); + throw this.error("Expected attribute to have a value"); } - if (typeof val === 'string') { + if (typeof val === "string") { attrs[key] = val; } else { attrs[key] = { @@ -814,16 +814,16 @@ class RuntimeParser { while (this._index < this._length) { const ch = this._source[this._index]; - if ((ch !== '[' || this._source[this._index + 1] === '[') && - ch !== '*') { + if ((ch !== "[" || this._source[this._index + 1] === "[") && + ch !== "*") { break; } - if (ch === '*') { + if (ch === "*") { this._index++; defaultIndex = index; } - if (this._source[this._index] !== '[') { + if (this._source[this._index] !== "[") { throw this.error('Expected "["'); } @@ -836,7 +836,7 @@ class RuntimeParser { const val = this.getPattern(); if (val === null) { - throw this.error('Expected variant to have a value'); + throw this.error("Expected variant to have a value"); } variants[index++] = {key, val}; @@ -865,7 +865,7 @@ class RuntimeParser { literal = this.getVariantName(); } - if (this._source[this._index] !== ']') { + if (this._source[this._index] !== "]") { throw this.error('Expected "]"'); } @@ -885,7 +885,7 @@ class RuntimeParser { if (cc0 === 36) { // $ this._index++; return { - type: 'ext', + type: "ext", name: this.getIdentifier() }; } @@ -899,7 +899,7 @@ class RuntimeParser { if ((cc1 >= 97 && cc1 <= 122) || // a-z (cc1 >= 65 && cc1 <= 90)) { // A-Z return { - type: 'ref', + type: "ref", name: this.getEntryIdentifier() }; } @@ -912,7 +912,7 @@ class RuntimeParser { return this.getString(); } - throw this.error('Expected literal'); + throw this.error("Expected literal"); } /** @@ -923,15 +923,15 @@ class RuntimeParser { skipComment() { // At runtime, we don't care about comments so we just have // to parse them properly and skip their content. - let eol = this._source.indexOf('\n', this._index); + let eol = this._source.indexOf("\n", this._index); while (eol !== -1 && - ((this._source[eol + 1] === '/' && this._source[eol + 2] === '/') || - (this._source[eol + 1] === '#' && - [' ', '#'].includes(this._source[eol + 2])))) { + ((this._source[eol + 1] === "/" && this._source[eol + 2] === "/") || + (this._source[eol + 1] === "#" && + [" ", "#"].includes(this._source[eol + 2])))) { this._index = eol + 3; - eol = this._source.indexOf('\n', this._index); + eol = this._source.indexOf("\n", this._index); if (eol === -1) { break; @@ -967,7 +967,7 @@ class RuntimeParser { let start = this._index; while (true) { - if (start === 0 || this._source[start - 1] === '\n') { + if (start === 0 || this._source[start - 1] === "\n") { const cc = this._source.charCodeAt(start); if ((cc >= 97 && cc <= 122) || // a-z @@ -978,7 +978,7 @@ class RuntimeParser { } } - start = this._source.indexOf('\n', start); + start = this._source.indexOf("\n", start); if (start === -1) { this._index = this._length; @@ -1044,13 +1044,13 @@ class FluentType { * @returns {string} */ toString() { - throw new Error('Subclasses of FluentType must implement toString.'); + throw new Error("Subclasses of FluentType must implement toString."); } } class FluentNone extends FluentType { toString() { - return this.value || '???'; + return this.value || "???"; } } @@ -1119,7 +1119,7 @@ class FluentSymbol extends FluentType { match(ctx, other) { if (other instanceof FluentSymbol) { return this.value === other.value; - } else if (typeof other === 'string') { + } else if (typeof other === "string") { return this.value === other; } else if (other instanceof FluentNumber) { const pr = ctx._memoizeIntlObject( @@ -1145,9 +1145,9 @@ class FluentSymbol extends FluentType { */ const builtins = { - 'NUMBER': ([arg], opts) => + "NUMBER": ([arg], opts) => new FluentNumber(arg.valueOf(), merge(arg.opts, opts)), - 'DATETIME': ([arg], opts) => + "DATETIME": ([arg], opts) => new FluentDateTime(arg.valueOf(), merge(arg.opts, opts)), }; @@ -1211,13 +1211,12 @@ function values(opts) { * This is used to prevent cyclic resolutions. */ - // Prevent expansion of too long placeables. const MAX_PLACEABLE_LENGTH = 2500; // Unicode bidi isolation characters. -const FSI = '\u2068'; -const PDI = '\u2069'; +const FSI = "\u2068"; +const PDI = "\u2069"; /** @@ -1240,7 +1239,7 @@ function DefaultMember(env, members, def) { } const { errors } = env; - errors.push(new RangeError('No default')); + errors.push(new RangeError("No default")); return new FluentNone(); } @@ -1259,12 +1258,12 @@ function DefaultMember(env, members, def) { */ function MessageReference(env, {name}) { const { ctx, errors } = env; - const message = name.startsWith('-') + const message = name.startsWith("-") ? ctx._terms.get(name) : ctx._messages.get(name); if (!message) { - const err = name.startsWith('-') + const err = name.startsWith("-") ? new ReferenceError(`Unknown term: ${name}`) : new ReferenceError(`Unknown message: ${name}`); errors.push(err); @@ -1301,7 +1300,7 @@ function VariantExpression(env, {id, key}) { function isVariantList(node) { return Array.isArray(node) && - node[0].type === 'sel' && + node[0].type === "sel" && node[0].exp === null; } @@ -1418,7 +1417,7 @@ function SelectExpression(env, {exp, vars, def}) { function Type(env, expr) { // A fast-path for strings which are the most common case, and for // `FluentNone` which doesn't require any additional logic. - if (typeof expr === 'string' || expr instanceof FluentNone) { + if (typeof expr === "string" || expr instanceof FluentNone) { return expr; } @@ -1430,29 +1429,29 @@ function Type(env, expr) { switch (expr.type) { - case 'varname': + case "varname": return new FluentSymbol(expr.name); - case 'num': + case "num": return new FluentNumber(expr.val); - case 'ext': + case "ext": return ExternalArgument(env, expr); - case 'fun': + case "fun": return FunctionReference(env, expr); - case 'call': + case "call": return CallExpression(env, expr); - case 'ref': { + case "ref": { const message = MessageReference(env, expr); return Type(env, message); } - case 'attr': { + case "attr": { const attr = AttributeExpression(env, expr); return Type(env, attr); } - case 'var': { + case "var": { const variant = VariantExpression(env, expr); return Type(env, variant); } - case 'sel': { + case "sel": { const member = SelectExpression(env, expr); return Type(env, member); } @@ -1463,7 +1462,7 @@ function Type(env, expr) { } const { errors } = env; - errors.push(new RangeError('No value')); + errors.push(new RangeError("No value")); return new FluentNone(); } default: @@ -1500,11 +1499,11 @@ function ExternalArgument(env, {name}) { // Convert the argument to a Fluent type. switch (typeof arg) { - case 'string': + case "string": return arg; - case 'number': + case "number": return new FluentNumber(arg); - case 'object': + case "object": if (arg instanceof Date) { return new FluentDateTime(arg); } @@ -1539,7 +1538,7 @@ function FunctionReference(env, {name}) { return new FluentNone(`${name}()`); } - if (typeof func !== 'function') { + if (typeof func !== "function") { errors.push(new TypeError(`Function ${name}() is not callable`)); return new FluentNone(`${name}()`); } @@ -1572,7 +1571,7 @@ function CallExpression(env, {fun, args}) { const keyargs = {}; for (const arg of args) { - if (arg.type === 'narg') { + if (arg.type === "narg") { keyargs[arg.name] = Type(env, arg.val); } else { posargs.push(Type(env, arg)); @@ -1601,7 +1600,7 @@ function Pattern(env, ptn) { const { ctx, dirty, errors } = env; if (dirty.has(ptn)) { - errors.push(new RangeError('Cyclic reference')); + errors.push(new RangeError("Cyclic reference")); return new FluentNone(); } @@ -1610,7 +1609,7 @@ function Pattern(env, ptn) { const result = []; for (const elem of ptn) { - if (typeof elem === 'string') { + if (typeof elem === "string") { result.push(elem); continue; } @@ -1624,7 +1623,7 @@ function Pattern(env, ptn) { if (part.length > MAX_PLACEABLE_LENGTH) { errors.push( new RangeError( - 'Too many characters in placeable ' + + "Too many characters in placeable " + `(${part.length}, max allowed is ${MAX_PLACEABLE_LENGTH})` ) ); @@ -1639,7 +1638,7 @@ function Pattern(env, ptn) { } dirty.delete(ptn); - return result.join(''); + return result.join(""); } /** @@ -1773,7 +1772,7 @@ class MessageContext { addMessages(source) { const [entries, errors] = parse(source); for (const id in entries) { - if (id.startsWith('-')) { + if (id.startsWith("-")) { // Identifiers starting with a dash (-) define terms. Terms are private // and cannot be retrieved from MessageContext. this._terms.set(id, entries[id]); @@ -1817,12 +1816,12 @@ class MessageContext { */ format(message, args, errors) { // optimize entities which are simple strings with no attributes - if (typeof message === 'string') { + if (typeof message === "string") { return message; } // optimize simple-string entities with attributes - if (typeof message.val === 'string') { + if (typeof message.val === "string") { return message.val; } @@ -1848,4 +1847,4 @@ class MessageContext { } this.MessageContext = MessageContext; -this.EXPORTED_SYMBOLS = ['MessageContext']; +this.EXPORTED_SYMBOLS = ["MessageContext"]; diff --git a/intl/l10n/l10n.js b/intl/l10n/l10n.js index 29e103d62643..3b8dcac8c206 100644 --- a/intl/l10n/l10n.js +++ b/intl/l10n/l10n.js @@ -1,6 +1,6 @@ { const { DOMLocalization } = - ChromeUtils.import("resource://gre/modules/DOMLocalization.jsm"); + ChromeUtils.import("resource://gre/modules/DOMLocalization.jsm", {}); /** * Polyfill for document.ready polyfill. @@ -14,11 +14,11 @@ * @returns {Promise} */ function documentReady(callback) { - if (document.contentType === 'application/vnd.mozilla.xul+xml') { + if (document.contentType === "application/vnd.mozilla.xul+xml") { // XUL return new Promise( resolve => document.addEventListener( - 'MozBeforeInitialXULLayout', () => { + "MozBeforeInitialXULLayout", () => { resolve(callback()); }, { once: true } ) @@ -27,12 +27,12 @@ // HTML const rs = document.readyState; - if (rs === 'interactive' || rs === 'completed') { - return Promise.resolve(callback()); + if (rs === "interactive" || rs === "completed") { + return Promise.resolve(callback); } return new Promise( resolve => document.addEventListener( - 'readystatechange', () => { + "readystatechange", () => { resolve(callback()); }, { once: true } ) @@ -47,7 +47,7 @@ */ function getResourceLinks(elem) { return Array.from(elem.querySelectorAll('link[rel="localization"]')).map( - el => el.getAttribute('href') + el => el.getAttribute("href") ); } @@ -60,7 +60,7 @@ document.l10n.ready = documentReady(() => { document.l10n.registerObservers(); - window.addEventListener('unload', () => { + window.addEventListener("unload", () => { document.l10n.unregisterObservers(); }); document.l10n.connectRoot(document.documentElement); diff --git a/intl/l10n/test/.eslintrc.js b/intl/l10n/test/.eslintrc.js new file mode 100644 index 000000000000..95936bd6a1a4 --- /dev/null +++ b/intl/l10n/test/.eslintrc.js @@ -0,0 +1,8 @@ +"use strict"; + +module.exports = { + "extends": [ + "plugin:mozilla/xpcshell-test", + "plugin:mozilla/browser-test" + ] +}; diff --git a/intl/l10n/test/dom/test_domloc_connectRoot.html b/intl/l10n/test/dom/test_domloc_connectRoot.html index 3f9ef5d687e4..811972c136c7 100644 --- a/intl/l10n/test/dom/test_domloc_connectRoot.html +++ b/intl/l10n/test/dom/test_domloc_connectRoot.html @@ -10,10 +10,10 @@ const { DOMLocalization } = ChromeUtils.import("resource://gre/modules/DOMLocalization.jsm", {}); - async function * mockGenerateMessages(locales, resourceIds) { + async function* mockGenerateMessages(locales, resourceIds) { } - window.onload = async function () { + window.onload = async function() { SimpleTest.waitForExplicitFinish(); const domLoc = new DOMLocalization( @@ -23,7 +23,7 @@ ); - const frag = document.querySelectorAll('div')[0]; + const frag = document.querySelectorAll("div")[0]; domLoc.connectRoot(frag); is(domLoc.roots.has(frag), true); diff --git a/intl/l10n/test/dom/test_domloc_disconnectRoot.html b/intl/l10n/test/dom/test_domloc_disconnectRoot.html index f853f1fd0f59..70653b2d531e 100644 --- a/intl/l10n/test/dom/test_domloc_disconnectRoot.html +++ b/intl/l10n/test/dom/test_domloc_disconnectRoot.html @@ -10,10 +10,10 @@ const { DOMLocalization } = ChromeUtils.import("resource://gre/modules/DOMLocalization.jsm", {}); - async function * mockGenerateMessages(locales, resourceIds) { + async function* mockGenerateMessages(locales, resourceIds) { } - window.onload = async function () { + window.onload = async function() { SimpleTest.waitForExplicitFinish(); const domLoc = new DOMLocalization( @@ -22,7 +22,7 @@ mockGenerateMessages ); - const frag = document.querySelectorAll('div')[0]; + const frag = document.querySelectorAll("div")[0]; domLoc.connectRoot(frag); is(domLoc.roots.has(frag), true); diff --git a/intl/l10n/test/dom/test_domloc_getAttributes.html b/intl/l10n/test/dom/test_domloc_getAttributes.html index f7c7e007a3ff..7dc424fab0d5 100644 --- a/intl/l10n/test/dom/test_domloc_getAttributes.html +++ b/intl/l10n/test/dom/test_domloc_getAttributes.html @@ -10,9 +10,9 @@ const { DOMLocalization } = ChromeUtils.import("resource://gre/modules/DOMLocalization.jsm", {}); - async function * mockGenerateMessages(locales, resourceIds) {} + async function* mockGenerateMessages(locales, resourceIds) {} - window.onload = function () { + window.onload = function() { SimpleTest.waitForExplicitFinish(); const domLoc = new DOMLocalization( @@ -21,9 +21,9 @@ mockGenerateMessages ); - const p1 = document.querySelectorAll('p')[0]; - const p2 = document.querySelectorAll('p')[1]; - const p3 = document.querySelectorAll('p')[2]; + const p1 = document.querySelectorAll("p")[0]; + const p2 = document.querySelectorAll("p")[1]; + const p3 = document.querySelectorAll("p")[2]; const attrs1 = domLoc.getAttributes(p1); const attrs2 = domLoc.getAttributes(p2); const attrs3 = domLoc.getAttributes(p3); diff --git a/intl/l10n/test/dom/test_domloc_mutations.html b/intl/l10n/test/dom/test_domloc_mutations.html index 543ba026c081..8c5d5d7b9dc0 100644 --- a/intl/l10n/test/dom/test_domloc_mutations.html +++ b/intl/l10n/test/dom/test_domloc_mutations.html @@ -12,14 +12,14 @@ const { MessageContext } = ChromeUtils.import("resource://gre/modules/MessageContext.jsm", {}); - async function * mockGenerateMessages(locales, resourceIds) { + async function* mockGenerateMessages(locales, resourceIds) { const mc = new MessageContext(locales); - mc.addMessages('title = Hello World'); - mc.addMessages('title2 = Hello Another World'); + mc.addMessages("title = Hello World"); + mc.addMessages("title2 = Hello Another World"); yield mc; } - window.onload = async function () { + window.onload = async function() { SimpleTest.waitForExplicitFinish(); const domLoc = new DOMLocalization( @@ -28,7 +28,7 @@ mockGenerateMessages ); - const h1 = document.querySelectorAll('h1')[0]; + const h1 = document.querySelectorAll("h1")[0]; domLoc.connectRoot(document.body); @@ -45,7 +45,7 @@ mo.observe(h1, { childList: true, characterData: true }); - domLoc.setAttributes(h1, 'title2'); + domLoc.setAttributes(h1, "title2"); }; diff --git a/intl/l10n/test/dom/test_domloc_overlay.html b/intl/l10n/test/dom/test_domloc_overlay.html index 6a2c7d2004c0..78e1b1d02e22 100644 --- a/intl/l10n/test/dom/test_domloc_overlay.html +++ b/intl/l10n/test/dom/test_domloc_overlay.html @@ -12,14 +12,14 @@ const { MessageContext } = ChromeUtils.import("resource://gre/modules/MessageContext.jsm", {}); - async function * mockGenerateMessages(locales, resourceIds) { + async function* mockGenerateMessages(locales, resourceIds) { const mc = new MessageContext(locales); - mc.addMessages('title = Hello World'); - mc.addMessages('title2 = This is a link!'); + mc.addMessages("title = Hello World"); + mc.addMessages("title2 = This is a link!"); yield mc; } - window.onload = async function () { + window.onload = async function() { SimpleTest.waitForExplicitFinish(); const domLoc = new DOMLocalization( @@ -28,20 +28,20 @@ mockGenerateMessages ); - const p1 = document.querySelectorAll('p')[0]; - const p2 = document.querySelectorAll('p')[1]; - const a = p2.querySelector('a'); - a.addEventListener('click', function() { + const p1 = document.querySelectorAll("p")[0]; + const p2 = document.querySelectorAll("p")[1]; + const a = p2.querySelector("a"); + a.addEventListener("click", function() { SimpleTest.finish(); }); await domLoc.translateFragment(document.body); - is(p1.querySelector('strong').textContent, "Hello"); + is(p1.querySelector("strong").textContent, "Hello"); - is(p2.querySelector('a').getAttribute('href'), "http://www.mozilla.org"); - is(p2.querySelector('a').textContent, "a link"); + is(p2.querySelector("a").getAttribute("href"), "http://www.mozilla.org"); + is(p2.querySelector("a").textContent, "a link"); a.click(); }; diff --git a/intl/l10n/test/dom/test_domloc_overlay_missing_children.html b/intl/l10n/test/dom/test_domloc_overlay_missing_children.html index a19e2e01f23a..327160c4eeea 100644 --- a/intl/l10n/test/dom/test_domloc_overlay_missing_children.html +++ b/intl/l10n/test/dom/test_domloc_overlay_missing_children.html @@ -12,13 +12,13 @@ const { MessageContext } = ChromeUtils.import("resource://gre/modules/MessageContext.jsm", {}); - async function * mockGenerateMessages(locales, resourceIds) { + async function* mockGenerateMessages(locales, resourceIds) { const mc = new MessageContext(locales); - mc.addMessages('title = Visit Mozilla or Firefox website!'); + mc.addMessages("title = Visit Mozilla or Firefox website!"); yield mc; } - window.onload = async function () { + window.onload = async function() { SimpleTest.waitForExplicitFinish(); const domLoc = new DOMLocalization( @@ -29,14 +29,14 @@ await domLoc.translateFragment(document.body); - const p1 = document.querySelectorAll('p')[0]; - const linkList = p1.querySelectorAll('a'); + const p1 = document.querySelectorAll("p")[0]; + const linkList = p1.querySelectorAll("a"); - is(linkList[0].getAttribute('href'), 'http://www.mozilla.org'); - is(linkList[0].textContent, 'Mozilla'); - is(linkList[1].getAttribute('href'), 'http://www.firefox.com'); - is(linkList[1].textContent, 'Firefox'); + is(linkList[0].getAttribute("href"), "http://www.mozilla.org"); + is(linkList[0].textContent, "Mozilla"); + is(linkList[1].getAttribute("href"), "http://www.firefox.com"); + is(linkList[1].textContent, "Firefox"); is(linkList.length, 2, "There should be exactly two links in the result."); diff --git a/intl/l10n/test/dom/test_domloc_overlay_repeated.html b/intl/l10n/test/dom/test_domloc_overlay_repeated.html index bdcaf3ad3873..4c9e25985e1f 100644 --- a/intl/l10n/test/dom/test_domloc_overlay_repeated.html +++ b/intl/l10n/test/dom/test_domloc_overlay_repeated.html @@ -12,13 +12,13 @@ const { MessageContext } = ChromeUtils.import("resource://gre/modules/MessageContext.jsm", {}); - async function * mockGenerateMessages(locales, resourceIds) { + async function* mockGenerateMessages(locales, resourceIds) { const mc = new MessageContext(locales); - mc.addMessages('title = Visit Mozilla or Firefox website!'); + mc.addMessages("title = Visit Mozilla or Firefox website!"); yield mc; } - window.onload = async function () { + window.onload = async function() { SimpleTest.waitForExplicitFinish(); const domLoc = new DOMLocalization( @@ -29,14 +29,14 @@ await domLoc.translateFragment(document.body); - const p1 = document.querySelectorAll('p')[0]; - const linkList = p1.querySelectorAll('a'); + const p1 = document.querySelectorAll("p")[0]; + const linkList = p1.querySelectorAll("a"); - is(linkList[0].getAttribute('href'), 'http://www.mozilla.org'); - is(linkList[0].textContent, 'Mozilla'); - is(linkList[1].getAttribute('href'), 'http://www.firefox.com'); - is(linkList[1].textContent, 'Firefox'); + is(linkList[0].getAttribute("href"), "http://www.mozilla.org"); + is(linkList[0].textContent, "Mozilla"); + is(linkList[1].getAttribute("href"), "http://www.firefox.com"); + is(linkList[1].textContent, "Firefox"); SimpleTest.finish(); }; diff --git a/intl/l10n/test/dom/test_domloc_setAttributes.html b/intl/l10n/test/dom/test_domloc_setAttributes.html index e73419561379..e571d4ff312e 100644 --- a/intl/l10n/test/dom/test_domloc_setAttributes.html +++ b/intl/l10n/test/dom/test_domloc_setAttributes.html @@ -10,9 +10,9 @@ const { DOMLocalization } = ChromeUtils.import("resource://gre/modules/DOMLocalization.jsm", {}); - async function * mockGenerateMessages(locales, resourceIds) {} + async function* mockGenerateMessages(locales, resourceIds) {} - window.onload = function () { + window.onload = function() { SimpleTest.waitForExplicitFinish(); const domLoc = new DOMLocalization( @@ -21,14 +21,14 @@ mockGenerateMessages ); - const p1 = document.querySelectorAll('p')[0]; + const p1 = document.querySelectorAll("p")[0]; - domLoc.setAttributes(p1, 'title'); - is(p1.getAttribute('data-l10n-id'), 'title'); + domLoc.setAttributes(p1, "title"); + is(p1.getAttribute("data-l10n-id"), "title"); - domLoc.setAttributes(p1, 'title2', {userName: "John"}); - is(p1.getAttribute('data-l10n-id'), 'title2'); - is(p1.getAttribute('data-l10n-args'), JSON.stringify({userName: "John"})); + domLoc.setAttributes(p1, "title2", {userName: "John"}); + is(p1.getAttribute("data-l10n-id"), "title2"); + is(p1.getAttribute("data-l10n-args"), JSON.stringify({userName: "John"})); SimpleTest.finish(); }; diff --git a/intl/l10n/test/dom/test_domloc_translateElements.html b/intl/l10n/test/dom/test_domloc_translateElements.html index ac15221e763b..1d0f05471cba 100644 --- a/intl/l10n/test/dom/test_domloc_translateElements.html +++ b/intl/l10n/test/dom/test_domloc_translateElements.html @@ -12,14 +12,14 @@ const { MessageContext } = ChromeUtils.import("resource://gre/modules/MessageContext.jsm", {}); - async function * mockGenerateMessages(locales, resourceIds) { + async function* mockGenerateMessages(locales, resourceIds) { const mc = new MessageContext(locales); - mc.addMessages('title = Hello World'); - mc.addMessages('link\n .title = Click me'); + mc.addMessages("title = Hello World"); + mc.addMessages("link\n .title = Click me"); yield mc; } - window.onload = async function () { + window.onload = async function() { SimpleTest.waitForExplicitFinish(); const domLoc = new DOMLocalization( @@ -28,13 +28,13 @@ mockGenerateMessages ); - const p1 = document.querySelectorAll('p')[0]; - const link1 = document.querySelectorAll('a')[0]; + const p1 = document.querySelectorAll("p")[0]; + const link1 = document.querySelectorAll("a")[0]; await domLoc.translateElements([p1, link1]); is(p1.textContent, "Hello World"); - is(link1.getAttribute('title'), "Click me"); + is(link1.getAttribute("title"), "Click me"); SimpleTest.finish(); }; diff --git a/intl/l10n/test/dom/test_domloc_translateFragment.html b/intl/l10n/test/dom/test_domloc_translateFragment.html index 4c71af2a91e3..244fa5036897 100644 --- a/intl/l10n/test/dom/test_domloc_translateFragment.html +++ b/intl/l10n/test/dom/test_domloc_translateFragment.html @@ -12,14 +12,14 @@ const { MessageContext } = ChromeUtils.import("resource://gre/modules/MessageContext.jsm", {}); - async function * mockGenerateMessages(locales, resourceIds) { + async function* mockGenerateMessages(locales, resourceIds) { const mc = new MessageContext(locales); - mc.addMessages('title = Hello World'); - mc.addMessages('subtitle = Welcome to Fluent'); + mc.addMessages("title = Hello World"); + mc.addMessages("subtitle = Welcome to Fluent"); yield mc; } - window.onload = async function () { + window.onload = async function() { SimpleTest.waitForExplicitFinish(); const domLoc = new DOMLocalization( @@ -28,9 +28,9 @@ mockGenerateMessages ); - const frag = document.querySelectorAll('div')[0]; - const h1 = document.querySelectorAll('h1')[0]; - const p1 = document.querySelectorAll('p')[0]; + const frag = document.querySelectorAll("div")[0]; + const h1 = document.querySelectorAll("h1")[0]; + const p1 = document.querySelectorAll("p")[0]; await domLoc.translateFragment(frag); is(h1.textContent, "Hello World"); diff --git a/intl/l10n/test/dom/test_domloc_translateRoots.html b/intl/l10n/test/dom/test_domloc_translateRoots.html index 50108fa523be..58a191541e12 100644 --- a/intl/l10n/test/dom/test_domloc_translateRoots.html +++ b/intl/l10n/test/dom/test_domloc_translateRoots.html @@ -12,14 +12,14 @@ const { MessageContext } = ChromeUtils.import("resource://gre/modules/MessageContext.jsm", {}); - async function * mockGenerateMessages(locales, resourceIds) { + async function* mockGenerateMessages(locales, resourceIds) { const mc = new MessageContext(locales); - mc.addMessages('title = Hello World'); - mc.addMessages('title2 = Hello Another World'); + mc.addMessages("title = Hello World"); + mc.addMessages("title2 = Hello Another World"); yield mc; } - window.onload = async function () { + window.onload = async function() { SimpleTest.waitForExplicitFinish(); const domLoc = new DOMLocalization( @@ -28,10 +28,10 @@ mockGenerateMessages ); - const frag1 = document.querySelectorAll('div')[0]; - const frag2 = document.querySelectorAll('div')[1]; - const h1 = document.querySelectorAll('h1')[0]; - const h2 = document.querySelectorAll('h2')[0]; + const frag1 = document.querySelectorAll("div")[0]; + const frag2 = document.querySelectorAll("div")[1]; + const h1 = document.querySelectorAll("h1")[0]; + const h2 = document.querySelectorAll("h2")[0]; domLoc.connectRoot(frag1); domLoc.connectRoot(frag2); diff --git a/intl/l10n/test/test_l10nregistry.js b/intl/l10n/test/test_l10nregistry.js index af3b288d481d..ebe3f2f87f69 100644 --- a/intl/l10n/test/test_l10nregistry.js +++ b/intl/l10n/test/test_l10nregistry.js @@ -11,10 +11,10 @@ ChromeUtils.import("resource://gre/modules/Timer.jsm"); let fs; L10nRegistry.load = async function(url) { if (!fs.hasOwnProperty(url)) { - return Promise.reject('Resource unavailable'); + return Promise.reject("Resource unavailable"); } return fs[url]; -} +}; add_task(function test_methods_presence() { equal(typeof L10nRegistry.generateContexts, "function"); @@ -29,17 +29,17 @@ add_task(function test_methods_presence() { */ add_task(async function test_methods_calling() { fs = { - '/localization/en-US/browser/menu.ftl': 'key = Value', + "/localization/en-US/browser/menu.ftl": "key = Value", }; - const source = new FileSource('test', ['en-US'], '/localization/{locale}'); + const source = new FileSource("test", ["en-US"], "/localization/{locale}"); L10nRegistry.registerSource(source); - const ctxs = L10nRegistry.generateContexts(['en-US'], ['/browser/menu.ftl']); + const ctxs = L10nRegistry.generateContexts(["en-US"], ["/browser/menu.ftl"]); const ctx = (await ctxs.next()).value; - equal(ctx.hasMessage('key'), true); + equal(ctx.hasMessage("key"), true); // cleanup L10nRegistry.sources.clear(); @@ -51,9 +51,9 @@ add_task(async function test_methods_calling() { * for the single source scenario */ add_task(async function test_has_one_source() { - let oneSource = new FileSource('app', ['en-US'], './app/data/locales/{locale}/'); + let oneSource = new FileSource("app", ["en-US"], "./app/data/locales/{locale}/"); fs = { - './app/data/locales/en-US/test.ftl': 'key = value en-US' + "./app/data/locales/en-US/test.ftl": "key = value en-US" }; L10nRegistry.registerSource(oneSource); @@ -61,21 +61,21 @@ add_task(async function test_has_one_source() { // has one source equal(L10nRegistry.sources.size, 1); - equal(L10nRegistry.sources.has('app'), true); + equal(L10nRegistry.sources.has("app"), true); // returns a single context - let ctxs = L10nRegistry.generateContexts(['en-US'], ['test.ftl']); + let ctxs = L10nRegistry.generateContexts(["en-US"], ["test.ftl"]); let ctx0 = (await ctxs.next()).value; - equal(ctx0.hasMessage('key'), true); + equal(ctx0.hasMessage("key"), true); equal((await ctxs.next()).done, true); // returns no contexts for missing locale - ctxs = L10nRegistry.generateContexts(['pl'], ['test.ftl']); + ctxs = L10nRegistry.generateContexts(["pl"], ["test.ftl"]); equal((await ctxs.next()).done, true); @@ -89,50 +89,50 @@ add_task(async function test_has_one_source() { * for the dual source scenario. */ add_task(async function test_has_two_sources() { - let oneSource = new FileSource('platform', ['en-US'], './platform/data/locales/{locale}/'); + let oneSource = new FileSource("platform", ["en-US"], "./platform/data/locales/{locale}/"); L10nRegistry.registerSource(oneSource); - let secondSource = new FileSource('app', ['pl'], './app/data/locales/{locale}/'); + let secondSource = new FileSource("app", ["pl"], "./app/data/locales/{locale}/"); L10nRegistry.registerSource(secondSource); fs = { - './platform/data/locales/en-US/test.ftl': 'key = platform value', - './app/data/locales/pl/test.ftl': 'key = app value' + "./platform/data/locales/en-US/test.ftl": "key = platform value", + "./app/data/locales/pl/test.ftl": "key = app value" }; // has two sources equal(L10nRegistry.sources.size, 2); - equal(L10nRegistry.sources.has('app'), true); - equal(L10nRegistry.sources.has('platform'), true); + equal(L10nRegistry.sources.has("app"), true); + equal(L10nRegistry.sources.has("platform"), true); // returns correct contexts for en-US - let ctxs = L10nRegistry.generateContexts(['en-US'], ['test.ftl']); + let ctxs = L10nRegistry.generateContexts(["en-US"], ["test.ftl"]); let ctx0 = (await ctxs.next()).value; - equal(ctx0.hasMessage('key'), true); - let msg = ctx0.getMessage('key'); - equal(ctx0.format(msg), 'platform value'); + equal(ctx0.hasMessage("key"), true); + let msg = ctx0.getMessage("key"); + equal(ctx0.format(msg), "platform value"); equal((await ctxs.next()).done, true); // returns correct contexts for [pl, en-US] - ctxs = L10nRegistry.generateContexts(['pl', 'en-US'], ['test.ftl']); + ctxs = L10nRegistry.generateContexts(["pl", "en-US"], ["test.ftl"]); ctx0 = (await ctxs.next()).value; - equal(ctx0.locales[0], 'pl'); - equal(ctx0.hasMessage('key'), true); - let msg0 = ctx0.getMessage('key'); - equal(ctx0.format(msg0), 'app value'); + equal(ctx0.locales[0], "pl"); + equal(ctx0.hasMessage("key"), true); + let msg0 = ctx0.getMessage("key"); + equal(ctx0.format(msg0), "app value"); let ctx1 = (await ctxs.next()).value; - equal(ctx1.locales[0], 'en-US'); - equal(ctx1.hasMessage('key'), true); - let msg1 = ctx1.getMessage('key'); - equal(ctx1.format(msg1), 'platform value'); + equal(ctx1.locales[0], "en-US"); + equal(ctx1.hasMessage("key"), true); + let msg1 = ctx1.getMessage("key"); + equal(ctx1.format(msg1), "platform value"); equal((await ctxs.next()).done, true); @@ -149,20 +149,20 @@ add_task(async function test_has_two_sources() { * missing files as `false` instead of `undefined`. */ add_task(async function test_indexed() { - let oneSource = new IndexedFileSource('langpack-pl', ['pl'], '/data/locales/{locale}/', [ - '/data/locales/pl/test.ftl', + let oneSource = new IndexedFileSource("langpack-pl", ["pl"], "/data/locales/{locale}/", [ + "/data/locales/pl/test.ftl", ]); L10nRegistry.registerSource(oneSource); fs = { - '/data/locales/pl/test.ftl': 'key = value' + "/data/locales/pl/test.ftl": "key = value" }; equal(L10nRegistry.sources.size, 1); - equal(L10nRegistry.sources.has('langpack-pl'), true); + equal(L10nRegistry.sources.has("langpack-pl"), true); - equal(oneSource.getPath('pl', 'test.ftl'), '/data/locales/pl/test.ftl'); - equal(oneSource.hasFile('pl', 'test.ftl'), true); - equal(oneSource.hasFile('pl', 'missing.ftl'), false); + equal(oneSource.getPath("pl", "test.ftl"), "/data/locales/pl/test.ftl"); + equal(oneSource.hasFile("pl", "test.ftl"), true); + equal(oneSource.hasFile("pl", "missing.ftl"), false); // cleanup L10nRegistry.sources.clear(); @@ -174,34 +174,34 @@ add_task(async function test_indexed() { * scenarios where a new file source is added on top of the default one. */ add_task(async function test_override() { - let fileSource = new FileSource('app', ['pl'], '/app/data/locales/{locale}/'); + let fileSource = new FileSource("app", ["pl"], "/app/data/locales/{locale}/"); L10nRegistry.registerSource(fileSource); - let oneSource = new IndexedFileSource('langpack-pl', ['pl'], '/data/locales/{locale}/', [ - '/data/locales/pl/test.ftl' + let oneSource = new IndexedFileSource("langpack-pl", ["pl"], "/data/locales/{locale}/", [ + "/data/locales/pl/test.ftl" ]); L10nRegistry.registerSource(oneSource); fs = { - '/app/data/locales/pl/test.ftl': 'key = value', - '/data/locales/pl/test.ftl': 'key = addon value' + "/app/data/locales/pl/test.ftl": "key = value", + "/data/locales/pl/test.ftl": "key = addon value" }; equal(L10nRegistry.sources.size, 2); - equal(L10nRegistry.sources.has('langpack-pl'), true); + equal(L10nRegistry.sources.has("langpack-pl"), true); - let ctxs = L10nRegistry.generateContexts(['pl'], ['test.ftl']); + let ctxs = L10nRegistry.generateContexts(["pl"], ["test.ftl"]); let ctx0 = (await ctxs.next()).value; - equal(ctx0.locales[0], 'pl'); - equal(ctx0.hasMessage('key'), true); - let msg0 = ctx0.getMessage('key'); - equal(ctx0.format(msg0), 'addon value'); + equal(ctx0.locales[0], "pl"); + equal(ctx0.hasMessage("key"), true); + let msg0 = ctx0.getMessage("key"); + equal(ctx0.format(msg0), "addon value"); let ctx1 = (await ctxs.next()).value; - equal(ctx1.locales[0], 'pl'); - equal(ctx1.hasMessage('key'), true); - let msg1 = ctx1.getMessage('key'); - equal(ctx1.format(msg1), 'value'); + equal(ctx1.locales[0], "pl"); + equal(ctx1.hasMessage("key"), true); + let msg1 = ctx1.getMessage("key"); + equal(ctx1.format(msg1), "value"); equal((await ctxs.next()).done, true); @@ -215,33 +215,33 @@ add_task(async function test_override() { * after source update. */ add_task(async function test_updating() { - let oneSource = new IndexedFileSource('langpack-pl', ['pl'], '/data/locales/{locale}/', [ - '/data/locales/pl/test.ftl', + let oneSource = new IndexedFileSource("langpack-pl", ["pl"], "/data/locales/{locale}/", [ + "/data/locales/pl/test.ftl", ]); L10nRegistry.registerSource(oneSource); fs = { - '/data/locales/pl/test.ftl': 'key = value' + "/data/locales/pl/test.ftl": "key = value" }; - let ctxs = L10nRegistry.generateContexts(['pl'], ['test.ftl']); + let ctxs = L10nRegistry.generateContexts(["pl"], ["test.ftl"]); let ctx0 = (await ctxs.next()).value; - equal(ctx0.locales[0], 'pl'); - equal(ctx0.hasMessage('key'), true); - let msg0 = ctx0.getMessage('key'); - equal(ctx0.format(msg0), 'value'); + equal(ctx0.locales[0], "pl"); + equal(ctx0.hasMessage("key"), true); + let msg0 = ctx0.getMessage("key"); + equal(ctx0.format(msg0), "value"); - const newSource = new IndexedFileSource('langpack-pl', ['pl'], '/data/locales/{locale}/', [ - '/data/locales/pl/test.ftl' + const newSource = new IndexedFileSource("langpack-pl", ["pl"], "/data/locales/{locale}/", [ + "/data/locales/pl/test.ftl" ]); - fs['/data/locales/pl/test.ftl'] = 'key = new value'; + fs["/data/locales/pl/test.ftl"] = "key = new value"; L10nRegistry.updateSource(newSource); equal(L10nRegistry.sources.size, 1); - ctxs = L10nRegistry.generateContexts(['pl'], ['test.ftl']); + ctxs = L10nRegistry.generateContexts(["pl"], ["test.ftl"]); ctx0 = (await ctxs.next()).value; - msg0 = ctx0.getMessage('key'); - equal(ctx0.format(msg0), 'new value'); + msg0 = ctx0.getMessage("key"); + equal(ctx0.format(msg0), "new value"); // cleanup L10nRegistry.sources.clear(); @@ -253,60 +253,60 @@ add_task(async function test_updating() { * after sources are being removed. */ add_task(async function test_removing() { - let fileSource = new FileSource('app', ['pl'], '/app/data/locales/{locale}/'); + let fileSource = new FileSource("app", ["pl"], "/app/data/locales/{locale}/"); L10nRegistry.registerSource(fileSource); - let oneSource = new IndexedFileSource('langpack-pl', ['pl'], '/data/locales/{locale}/', [ - '/data/locales/pl/test.ftl' + let oneSource = new IndexedFileSource("langpack-pl", ["pl"], "/data/locales/{locale}/", [ + "/data/locales/pl/test.ftl" ]); L10nRegistry.registerSource(oneSource); fs = { - '/app/data/locales/pl/test.ftl': 'key = value', - '/data/locales/pl/test.ftl': 'key = addon value' + "/app/data/locales/pl/test.ftl": "key = value", + "/data/locales/pl/test.ftl": "key = addon value" }; equal(L10nRegistry.sources.size, 2); - equal(L10nRegistry.sources.has('langpack-pl'), true); + equal(L10nRegistry.sources.has("langpack-pl"), true); - let ctxs = L10nRegistry.generateContexts(['pl'], ['test.ftl']); + let ctxs = L10nRegistry.generateContexts(["pl"], ["test.ftl"]); let ctx0 = (await ctxs.next()).value; - equal(ctx0.locales[0], 'pl'); - equal(ctx0.hasMessage('key'), true); - let msg0 = ctx0.getMessage('key'); - equal(ctx0.format(msg0), 'addon value'); + equal(ctx0.locales[0], "pl"); + equal(ctx0.hasMessage("key"), true); + let msg0 = ctx0.getMessage("key"); + equal(ctx0.format(msg0), "addon value"); let ctx1 = (await ctxs.next()).value; - equal(ctx1.locales[0], 'pl'); - equal(ctx1.hasMessage('key'), true); - let msg1 = ctx1.getMessage('key'); - equal(ctx1.format(msg1), 'value'); + equal(ctx1.locales[0], "pl"); + equal(ctx1.hasMessage("key"), true); + let msg1 = ctx1.getMessage("key"); + equal(ctx1.format(msg1), "value"); equal((await ctxs.next()).done, true); // Remove langpack - L10nRegistry.removeSource('langpack-pl'); + L10nRegistry.removeSource("langpack-pl"); equal(L10nRegistry.sources.size, 1); - equal(L10nRegistry.sources.has('langpack-pl'), false); + equal(L10nRegistry.sources.has("langpack-pl"), false); - ctxs = L10nRegistry.generateContexts(['pl'], ['test.ftl']); + ctxs = L10nRegistry.generateContexts(["pl"], ["test.ftl"]); ctx0 = (await ctxs.next()).value; - equal(ctx0.locales[0], 'pl'); - equal(ctx0.hasMessage('key'), true); - msg0 = ctx0.getMessage('key'); - equal(ctx0.format(msg0), 'value'); + equal(ctx0.locales[0], "pl"); + equal(ctx0.hasMessage("key"), true); + msg0 = ctx0.getMessage("key"); + equal(ctx0.format(msg0), "value"); equal((await ctxs.next()).done, true); // Remove app source - L10nRegistry.removeSource('app'); + L10nRegistry.removeSource("app"); equal(L10nRegistry.sources.size, 0); - ctxs = L10nRegistry.generateContexts(['pl'], ['test.ftl']); + ctxs = L10nRegistry.generateContexts(["pl"], ["test.ftl"]); equal((await ctxs.next()).done, true); // cleanup @@ -319,30 +319,30 @@ add_task(async function test_removing() { * file in the FileSource scenario. */ add_task(async function test_missing_file() { - let oneSource = new FileSource('app', ['en-US'], './app/data/locales/{locale}/'); + let oneSource = new FileSource("app", ["en-US"], "./app/data/locales/{locale}/"); L10nRegistry.registerSource(oneSource); - let twoSource = new FileSource('platform', ['en-US'], './platform/data/locales/{locale}/'); + let twoSource = new FileSource("platform", ["en-US"], "./platform/data/locales/{locale}/"); L10nRegistry.registerSource(twoSource); fs = { - './app/data/locales/en-US/test.ftl': 'key = value en-US', - './platform/data/locales/en-US/test.ftl': 'key = value en-US', - './platform/data/locales/en-US/test2.ftl': 'key2 = value2 en-US' + "./app/data/locales/en-US/test.ftl": "key = value en-US", + "./platform/data/locales/en-US/test.ftl": "key = value en-US", + "./platform/data/locales/en-US/test2.ftl": "key2 = value2 en-US" }; // has two sources equal(L10nRegistry.sources.size, 2); - equal(L10nRegistry.sources.has('app'), true); - equal(L10nRegistry.sources.has('platform'), true); + equal(L10nRegistry.sources.has("app"), true); + equal(L10nRegistry.sources.has("platform"), true); // returns a single context - let ctxs = L10nRegistry.generateContexts(['en-US'], ['test.ftl', 'test2.ftl']); - let ctx0 = (await ctxs.next()).value; - let ctx1 = (await ctxs.next()).value; + let ctxs = L10nRegistry.generateContexts(["en-US"], ["test.ftl", "test2.ftl"]); + (await ctxs.next()); + (await ctxs.next()); equal((await ctxs.next()).done, true); @@ -368,33 +368,33 @@ add_task(async function test_parallel_io() { } fetchIndex.set(url, fetchIndex.get(url) + 1); - if (url === '/en-US/slow-file.ftl') { + if (url === "/en-US/slow-file.ftl") { return new Promise((resolve, reject) => { setTimeout(() => { // Despite slow-file being the first on the list, // by the time the it finishes loading, the other // two files are already fetched. - equal(fetchIndex.get('/en-US/test.ftl'), 1); - equal(fetchIndex.get('/en-US/test2.ftl'), 1); + equal(fetchIndex.get("/en-US/test.ftl"), 1); + equal(fetchIndex.get("/en-US/test2.ftl"), 1); - resolve(''); + resolve(""); }, 10); }); - }; - return Promise.resolve(''); - } - let oneSource = new FileSource('app', ['en-US'], '/{locale}/'); + } + return Promise.resolve(""); + }; + let oneSource = new FileSource("app", ["en-US"], "/{locale}/"); L10nRegistry.registerSource(oneSource); fs = { - '/en-US/test.ftl': 'key = value en-US', - '/en-US/test2.ftl': 'key2 = value2 en-US', - '/en-US/slow-file.ftl': 'key-slow = value slow en-US', + "/en-US/test.ftl": "key = value en-US", + "/en-US/test2.ftl": "key2 = value2 en-US", + "/en-US/slow-file.ftl": "key-slow = value slow en-US", }; // returns a single context - let ctxs = L10nRegistry.generateContexts(['en-US'], ['slow-file.ftl', 'test.ftl', 'test2.ftl']); + let ctxs = L10nRegistry.generateContexts(["en-US"], ["slow-file.ftl", "test.ftl", "test2.ftl"]); equal(fetchIndex.size, 0); @@ -406,7 +406,7 @@ add_task(async function test_parallel_io() { // When requested again, the cache should make the load operation not // increase the fetchedIndex count - let ctxs2= L10nRegistry.generateContexts(['en-US'], ['test.ftl', 'test2.ftl', 'slow-file.ftl']); + L10nRegistry.generateContexts(["en-US"], ["test.ftl", "test2.ftl", "slow-file.ftl"]); // cleanup L10nRegistry.sources.clear(); diff --git a/intl/l10n/test/test_localization.js b/intl/l10n/test/test_localization.js index f741f0fd769f..cadce6be30ad 100644 --- a/intl/l10n/test/test_localization.js +++ b/intl/l10n/test/test_localization.js @@ -3,6 +3,7 @@ const { AppConstants } = ChromeUtils.import("resource://gre/modules/AppConstants.jsm", {}); const { Localization } = ChromeUtils.import("resource://gre/modules/Localization.jsm", {}); +const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm", {}); add_task(function test_methods_presence() { equal(typeof Localization.prototype.formatValues, "function"); @@ -13,58 +14,55 @@ add_task(function test_methods_presence() { add_task(async function test_methods_calling() { const { L10nRegistry, FileSource } = ChromeUtils.import("resource://gre/modules/L10nRegistry.jsm", {}); - const LocaleService = - Components.classes["@mozilla.org/intl/localeservice;1"].getService( - Components.interfaces.mozILocaleService); const fs = { - '/localization/de/browser/menu.ftl': 'key = [de] Value2', - '/localization/en-US/browser/menu.ftl': 'key = [en] Value2\nkey2 = [en] Value3', + "/localization/de/browser/menu.ftl": "key = [de] Value2", + "/localization/en-US/browser/menu.ftl": "key = [en] Value2\nkey2 = [en] Value3", }; const originalLoad = L10nRegistry.load; - const originalRequested = LocaleService.getRequestedLocales(); + const originalRequested = Services.locale.getRequestedLocales(); L10nRegistry.load = async function(url) { return fs[url]; - } + }; - const source = new FileSource('test', ['de', 'en-US'], '/localization/{locale}'); + const source = new FileSource("test", ["de", "en-US"], "/localization/{locale}"); L10nRegistry.registerSource(source); async function* generateMessages(resIds) { - yield * await L10nRegistry.generateContexts(['de', 'en-US'], resIds); + yield * await L10nRegistry.generateContexts(["de", "en-US"], resIds); } const l10n = new Localization([ - '/browser/menu.ftl' + "/browser/menu.ftl" ], generateMessages); - let values = await l10n.formatValues([['key'], ['key2']]); + let values = await l10n.formatValues([["key"], ["key2"]]); - equal(values[0], '[de] Value2'); - equal(values[1], '[en] Value3'); + equal(values[0], "[de] Value2"); + equal(values[1], "[en] Value3"); L10nRegistry.sources.clear(); L10nRegistry.load = originalLoad; - LocaleService.setRequestedLocales(originalRequested); + Services.locale.setRequestedLocales(originalRequested); }); add_task(async function test_builtins() { const { L10nRegistry, FileSource } = - Components.utils.import("resource://gre/modules/L10nRegistry.jsm", {}); + ChromeUtils.import("resource://gre/modules/L10nRegistry.jsm", {}); const known_platforms = { - 'linux': 'linux', - 'win': 'windows', - 'macosx': 'macos', - 'android': 'android', + "linux": "linux", + "win": "windows", + "macosx": "macos", + "android": "android", }; const fs = { - '/localization/en-US/test.ftl': ` + "/localization/en-US/test.ftl": ` key = { PLATFORM() -> ${ Object.values(known_platforms).map( - name => ` [${ name }] ${ name.toUpperCase() } Value\n`).join('') } + name => ` [${ name }] ${ name.toUpperCase() } Value\n`).join("") } *[other] OTHER Value }`, }; @@ -72,20 +70,20 @@ key = { PLATFORM() -> L10nRegistry.load = async function(url) { return fs[url]; - } + }; - const source = new FileSource('test', ['en-US'], '/localization/{locale}'); + const source = new FileSource("test", ["en-US"], "/localization/{locale}"); L10nRegistry.registerSource(source); async function* generateMessages(resIds) { - yield * await L10nRegistry.generateContexts(['en-US'], resIds); + yield * await L10nRegistry.generateContexts(["en-US"], resIds); } const l10n = new Localization([ - '/test.ftl' + "/test.ftl" ], generateMessages); - let values = await l10n.formatValues([['key']]); + let values = await l10n.formatValues([["key"]]); ok(values[0].includes( `${ known_platforms[AppConstants.platform].toUpperCase() } Value`));