Socket
Socket
Sign inDemoInstall

@fluent/dom

Package Overview
Dependencies
1
Maintainers
4
Versions
6
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.5.0 to 0.6.0

4

CHANGELOG.md
# Changelog
## @fluent/dom 0.6.0 (August 21, 2019)
- Update `@fluent/dom` to work with `@fluent/bundle` 0.14
## @fluent/dom 0.5.0 (July 25, 2019)

@@ -4,0 +8,0 @@

240

compat.js

@@ -1,2 +0,2 @@

/* @fluent/dom@0.5.0 */
/* @fluent/dom@0.6.0 */
(function (global, factory) {

@@ -105,3 +105,3 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('cached-iterable')) :

// &, &, &.
const reOverlay = /<|&#?\w+;/;
var reOverlay = /<|&#?\w+;/;
/**

@@ -116,6 +116,6 @@ * Elements allowed in translations even if they are not present in the source

const TEXT_LEVEL_ELEMENTS = {
var TEXT_LEVEL_ELEMENTS = {
"http://www.w3.org/1999/xhtml": ["em", "strong", "small", "s", "cite", "q", "dfn", "abbr", "data", "time", "code", "var", "samp", "kbd", "sub", "sup", "i", "b", "u", "mark", "bdi", "bdo", "span", "br", "wbr"]
};
const LOCALIZABLE_ATTRIBUTES = {
var LOCALIZABLE_ATTRIBUTES = {
"http://www.w3.org/1999/xhtml": {

@@ -159,3 +159,3 @@ global: ["title", "aria-label", "aria-valuetext"],

function translateElement(element, translation) {
const value = translation.value;
var value = translation.value;

@@ -169,3 +169,3 @@ if (typeof value === "string") {

// sanitize it and replace the element's content.
const templateElement = element.ownerDocument.createElementNS("http://www.w3.org/1999/xhtml", "template");
var templateElement = element.ownerDocument.createElementNS("http://www.w3.org/1999/xhtml", "template");
templateElement.innerHTML = value;

@@ -199,3 +199,3 @@ overlayChildNodes(templateElement.content, element);

for (var _iterator = fromFragment.childNodes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
const childNode = _step.value;
var childNode = _step.value;

@@ -208,3 +208,3 @@ if (childNode.nodeType === childNode.TEXT_NODE) {

if (childNode.hasAttribute("data-l10n-name")) {
const sanitized = getNodeForNamedElement(toElement, childNode);
var sanitized = getNodeForNamedElement(toElement, childNode);
fromFragment.replaceChild(sanitized, childNode);

@@ -215,4 +215,5 @@ continue;

if (isElementAllowed(childNode)) {
const sanitized = createSanitizedElement(childNode);
fromFragment.replaceChild(sanitized, childNode);
var _sanitized = createSanitizedElement(childNode);
fromFragment.replaceChild(_sanitized, childNode);
continue;

@@ -255,3 +256,3 @@ }

for (var _iterator2 = attributes[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
let attr = _step2.value;
var attr = _step2.value;

@@ -292,7 +293,7 @@ if (attr.name === name) {

function overlayAttributes(fromElement, toElement) {
const explicitlyAllowed = toElement.hasAttribute("data-l10n-attrs") ? toElement.getAttribute("data-l10n-attrs").split(",").map(i => i.trim()) : null; // Remove existing localizable attributes if they
var explicitlyAllowed = toElement.hasAttribute("data-l10n-attrs") ? toElement.getAttribute("data-l10n-attrs").split(",").map(i => i.trim()) : null; // Remove existing localizable attributes if they
// will not be used in the new translation.
for (var _i = 0, _Array$from = Array.from(toElement.attributes); _i < _Array$from.length; _i++) {
const attr = _Array$from[_i];
var attr = _Array$from[_i];

@@ -313,6 +314,6 @@ if (isAttrNameLocalizable(attr.name, toElement, explicitlyAllowed) && !hasAttribute(fromElement.attributes, attr.name)) {

for (var _i2 = 0, _Array$from2 = Array.from(fromElement.attributes); _i2 < _Array$from2.length; _i2++) {
const attr = _Array$from2[_i2];
var _attr = _Array$from2[_i2];
if (isAttrNameLocalizable(attr.name, toElement, explicitlyAllowed) && toElement.getAttribute(attr.name) !== attr.value) {
toElement.setAttribute(attr.name, attr.value);
if (isAttrNameLocalizable(_attr.name, toElement, explicitlyAllowed) && toElement.getAttribute(_attr.name) !== _attr.value) {
toElement.setAttribute(_attr.name, _attr.value);
}

@@ -336,4 +337,4 @@ }

function getNodeForNamedElement(sourceElement, translatedChild) {
const childName = translatedChild.getAttribute("data-l10n-name");
const sourceChild = sourceElement.querySelector("[data-l10n-name=\"".concat(childName, "\"]"));
var childName = translatedChild.getAttribute("data-l10n-name");
var sourceChild = sourceElement.querySelector("[data-l10n-name=\"".concat(childName, "\"]"));

@@ -360,3 +361,3 @@ if (!sourceChild) {

const clone = sourceChild.cloneNode(false);
var clone = sourceChild.cloneNode(false);
return shallowPopulateUsing(translatedChild, clone);

@@ -379,3 +380,3 @@ }

// and non-localizable attributes defined by the translation.
const clone = element.ownerDocument.createElement(element.localName);
var clone = element.ownerDocument.createElement(element.localName);
return shallowPopulateUsing(element, clone);

@@ -408,3 +409,3 @@ }

function isElementAllowed(element) {
const allowed = TEXT_LEVEL_ELEMENTS[element.namespaceURI];
var allowed = TEXT_LEVEL_ELEMENTS[element.namespaceURI];
return allowed && allowed.includes(element.localName);

@@ -431,3 +432,3 @@ }

function isAttrNameLocalizable(name, element) {
let explicitlyAllowed = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
var explicitlyAllowed = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;

@@ -438,3 +439,3 @@ if (explicitlyAllowed && explicitlyAllowed.includes(name)) {

const allowed = LOCALIZABLE_ATTRIBUTES[element.namespaceURI];
var allowed = LOCALIZABLE_ATTRIBUTES[element.namespaceURI];

@@ -445,4 +446,4 @@ if (!allowed) {

const attrName = name.toLowerCase();
const elemName = element.localName; // Is it a globally safe attribute?
var attrName = name.toLowerCase();
var elemName = element.localName; // Is it a globally safe attribute?

@@ -465,3 +466,3 @@ if (allowed.global.includes(attrName)) {

if (element.namespaceURI === "http://www.w3.org/1999/xhtml" && elemName === "input" && attrName === "value") {
const type = element.type.toLowerCase();
var type = element.type.toLowerCase();

@@ -507,12 +508,13 @@ if (type === "submit" || type === "button" || type === "reset") {

constructor() {
let resourceIds = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
let generateBundles = arguments.length > 1 ? arguments[1] : undefined;
var resourceIds = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
var generateBundles = arguments.length > 1 ? arguments[1] : undefined;
this.resourceIds = resourceIds;
this.generateBundles = generateBundles;
this.bundles = cachedIterable.CachedAsyncIterable.from(this.generateBundles(this.resourceIds));
this.onChange(true);
}
addResourceIds(resourceIds) {
var eager = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
this.resourceIds.push(...resourceIds);
this.onChange();
this.onChange(eager);
return this.resourceIds.length;

@@ -544,3 +546,4 @@ }

return _asyncToGenerator(function* () {
const translations = [];
var translations = [];
var hasAtLeastOneBundle = false;
var _iteratorNormalCompletion = true;

@@ -553,4 +556,5 @@ var _didIteratorError = false;

for (var _iterator = _asyncIterator(_this.bundles), _step, _value; _step = yield _iterator.next(), _iteratorNormalCompletion = _step.done, _value = yield _step.value, !_iteratorNormalCompletion; _iteratorNormalCompletion = true) {
const bundle = _value;
const missingIds = keysFromBundle(method, bundle, keys, translations);
var bundle = _value;
hasAtLeastOneBundle = true;
var missingIds = keysFromBundle(method, bundle, keys, translations);

@@ -562,5 +566,5 @@ if (missingIds.size === 0) {

if (typeof console !== "undefined") {
const locale = bundle.locales[0];
const ids = Array.from(missingIds).join(", ");
console.warn("Missing translations in ".concat(locale, ": ").concat(ids));
var locale = bundle.locales[0];
var ids = Array.from(missingIds).join(", ");
console.warn("[fluent] Missing translations in ".concat(locale, ": ").concat(ids));
}

@@ -583,2 +587,7 @@ }

if (!hasAtLeastOneBundle && typeof console !== "undefined") {
// eslint-disable-next-line max-len
console.warn("[fluent] Request for keys failed because no resource bundles got generated.\n keys: ".concat(JSON.stringify(keys), ".\n resourceIds: ").concat(JSON.stringify(_this.resourceIds), "."));
}
return translations;

@@ -590,5 +599,5 @@ })();

*
* The fallback logic is the same as in `formatValues` but the argument type
* is stricter (an array of arrays) and it returns {value, attributes}
* objects which are suitable for the translation of DOM elements.
* The fallback logic is the same as in `formatValues` but it returns {value,
* attributes} objects which are suitable for the translation of DOM
* elements.
*

@@ -622,4 +631,4 @@ * docL10n.formatMessages([

*
* A generalized version of `DOMLocalization.formatValue`. Keys can
* either be simple string identifiers or `[id, args]` arrays.
* A generalized version of `DOMLocalization.formatValue`. Keys must
* be `{id, args}` objects.
*

@@ -672,8 +681,8 @@ * docL10n.formatValues([

return _asyncToGenerator(function* () {
const _ref = yield _this2.formatValues([{
var _ref = yield _this2.formatValues([{
id,
args
}]),
_ref2 = _slicedToArray(_ref, 1),
val = _ref2[0];
_ref2 = _slicedToArray(_ref, 1),
val = _ref2[0];

@@ -694,4 +703,8 @@ return val;

onChange() {
var eager = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
this.bundles = cachedIterable.CachedAsyncIterable.from(this.generateBundles(this.resourceIds));
this.bundles.touchNext(2);
if (eager) {
this.bundles.touchNext(2);
}
}

@@ -701,3 +714,3 @@

/**
* Format the value of a message into a string.
* Format the value of a message into a string or `null`.
*

@@ -707,18 +720,18 @@ * This function is passed as a method to `keysFromBundle` and resolve

*
* If the function fails to retrieve the entity, it will return an ID of it.
* If formatting fails, it will return a partially resolved entity.
* If the message doesn't have a value, return `null`.
*
* In both cases, an error is being added to the errors array.
*
* @param {FluentBundle} bundle
* @param {Array<Error>} errors
* @param {string} id
* @param {Object} args
* @returns {string}
* @param {Array<Error>} errors
* @param {Object} message
* @param {Object} args
* @returns {string|null}
* @private
*/
function valueFromBundle(bundle, errors, id, args) {
const msg = bundle.getMessage(id);
return bundle.format(msg, args, errors);
function valueFromBundle(bundle, errors, message, args) {
if (message.value) {
return bundle.formatPattern(message.value, args, errors);
}
return null;
}

@@ -734,12 +747,6 @@ /**

*
* If the function fails to retrieve the entity, the value is set to the ID of
* an entity, and attributes to `null`. If formatting fails, it will return
* a partially resolved value and attributes.
*
* In both cases, an error is being added to the errors array.
*
* @param {FluentBundle} bundle
* @param {Array<Error>} errors
* @param {String} id
* @param {Object} args
* @param {Array<Error>} errors
* @param {Object} message
* @param {Object} args
* @returns {Object}

@@ -750,25 +757,45 @@ * @private

function messageFromBundle(bundle, errors, id, args) {
const msg = bundle.getMessage(id);
const formatted = {
value: bundle.format(msg, args, errors),
function messageFromBundle(bundle, errors, message, args) {
var formatted = {
value: null,
attributes: null
};
if (msg.attrs) {
formatted.attributes = [];
if (message.value) {
formatted.value = bundle.formatPattern(message.value, args, errors);
}
for (var _i = 0, _Object$entries = Object.entries(msg.attrs); _i < _Object$entries.length; _i++) {
const _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
name = _Object$entries$_i[0],
attr = _Object$entries$_i[1];
var attrNames = Object.keys(message.attributes);
const value = bundle.format(attr, args, errors);
if (attrNames.length > 0) {
formatted.attributes = new Array(attrNames.length);
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
if (value !== null) {
formatted.attributes.push({
try {
for (var _iterator2 = attrNames.entries()[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var _step2$value = _slicedToArray(_step2.value, 2),
i = _step2$value[0],
name = _step2$value[1];
var value = bundle.formatPattern(message.attributes[name], args, errors);
formatted.attributes[i] = {
name,
value
});
};
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}

@@ -814,6 +841,6 @@ }

function keysFromBundle(method, bundle, keys, translations) {
const messageErrors = [];
const missingIds = new Set();
var messageErrors = [];
var missingIds = new Set();
keys.forEach((_ref3, i) => {
let id = _ref3.id,
var id = _ref3.id,
args = _ref3.args;

@@ -825,5 +852,14 @@

if (bundle.hasMessage(id)) {
var message = bundle.getMessage(id);
if (message) {
messageErrors.length = 0;
translations[i] = method(bundle, messageErrors, id, args); // XXX: Report resolver errors
translations[i] = method(bundle, messageErrors, message, args);
if (messageErrors.length > 0 && typeof console !== "undefined") {
var locale = bundle.locales[0];
var errors = messageErrors.join(", "); // eslint-disable-next-line max-len
console.warn("[fluent][resolver] errors in ".concat(locale, "/").concat(id, ": ").concat(errors, "."));
}
} else {

@@ -836,5 +872,5 @@ missingIds.add(id);

const L10NID_ATTR_NAME = "data-l10n-id";
const L10NARGS_ATTR_NAME = "data-l10n-args";
const L10N_ELEMENT_QUERY = "[".concat(L10NID_ATTR_NAME, "]");
var L10NID_ATTR_NAME = "data-l10n-id";
var L10NARGS_ATTR_NAME = "data-l10n-args";
var L10N_ELEMENT_QUERY = "[".concat(L10NID_ATTR_NAME, "]");
/**

@@ -876,4 +912,8 @@ * The `DOMLocalization` class is responsible for fetching resources and

onChange() {
super.onChange();
this.translateRoots();
var eager = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
super.onChange(eager);
if (this.roots) {
this.translateRoots();
}
}

@@ -966,3 +1006,3 @@ /**

for (var _iterator = this.roots[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
const root = _step.value;
var root = _step.value;

@@ -1039,3 +1079,3 @@ if (root === newRoot || root.contains(newRoot) || newRoot.contains(root)) {

translateRoots() {
const roots = Array.from(this.roots);
var roots = Array.from(this.roots);
return Promise.all(roots.map(root => this.translateFragment(root)));

@@ -1076,3 +1116,3 @@ }

for (var _iterator2 = this.roots[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
const root = _step2.value;
var root = _step2.value;
this.mutationObserver.observe(root, this.observerConfig);

@@ -1109,3 +1149,3 @@ }

for (var _iterator3 = mutations[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
const mutation = _step3.value;
var mutation = _step3.value;

@@ -1127,3 +1167,3 @@ switch (mutation.type) {

for (var _iterator4 = mutation.addedNodes[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
const addedNode = _step4.value;
var addedNode = _step4.value;

@@ -1138,3 +1178,3 @@ if (addedNode.nodeType === addedNode.ELEMENT_NODE) {

for (var _iterator5 = this.getTranslatables(addedNode)[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
const element = _step5.value;
var element = _step5.value;
this.pendingElements.add(element);

@@ -1247,4 +1287,4 @@ }

const keys = elements.map(_this.getKeysForElement);
const translations = yield _this.formatMessages(keys);
var keys = elements.map(_this.getKeysForElement);
var translations = yield _this.formatMessages(keys);
return _this.applyTranslations(elements, translations);

@@ -1265,3 +1305,3 @@ })();

for (let i = 0; i < elements.length; i++) {
for (var i = 0; i < elements.length; i++) {
if (translations[i] !== undefined) {

@@ -1284,3 +1324,3 @@ translateElement(elements[i], translations[i]);

getTranslatables(element) {
const nodes = Array.from(element.querySelectorAll(L10N_ELEMENT_QUERY));
var nodes = Array.from(element.querySelectorAll(L10N_ELEMENT_QUERY));

@@ -1287,0 +1327,0 @@ if (typeof element.hasAttribute === "function" && element.hasAttribute(L10NID_ATTR_NAME)) {

@@ -1,2 +0,2 @@

/* @fluent/dom@0.5.0 */
/* @fluent/dom@0.6.0 */
(function (global, factory) {

@@ -374,9 +374,8 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('cached-iterable')) :

this.generateBundles = generateBundles;
this.bundles = cachedIterable.CachedAsyncIterable.from(
this.generateBundles(this.resourceIds));
this.onChange(true);
}
addResourceIds(resourceIds) {
addResourceIds(resourceIds, eager = false) {
this.resourceIds.push(...resourceIds);
this.onChange();
this.onChange(eager);
return this.resourceIds.length;

@@ -405,4 +404,6 @@ }

const translations = [];
let hasAtLeastOneBundle = false;
for await (const bundle of this.bundles) {
hasAtLeastOneBundle = true;
const missingIds = keysFromBundle(method, bundle, keys, translations);

@@ -417,6 +418,13 @@

const ids = Array.from(missingIds).join(", ");
console.warn(`Missing translations in ${locale}: ${ids}`);
console.warn(`[fluent] Missing translations in ${locale}: ${ids}`);
}
}
if (!hasAtLeastOneBundle && typeof console !== "undefined") {
// eslint-disable-next-line max-len
console.warn(`[fluent] Request for keys failed because no resource bundles got generated.
keys: ${JSON.stringify(keys)}.
resourceIds: ${JSON.stringify(this.resourceIds)}.`);
}
return translations;

@@ -428,5 +436,5 @@ }

*
* The fallback logic is the same as in `formatValues` but the argument type
* is stricter (an array of arrays) and it returns {value, attributes}
* objects which are suitable for the translation of DOM elements.
* The fallback logic is the same as in `formatValues` but it returns {value,
* attributes} objects which are suitable for the translation of DOM
* elements.
*

@@ -459,4 +467,4 @@ * docL10n.formatMessages([

*
* A generalized version of `DOMLocalization.formatValue`. Keys can
* either be simple string identifiers or `[id, args]` arrays.
* A generalized version of `DOMLocalization.formatValue`. Keys must
* be `{id, args}` objects.
*

@@ -515,6 +523,8 @@ * docL10n.formatValues([

*/
onChange() {
onChange(eager = false) {
this.bundles = cachedIterable.CachedAsyncIterable.from(
this.generateBundles(this.resourceIds));
this.bundles.touchNext(2);
if (eager) {
this.bundles.touchNext(2);
}
}

@@ -524,3 +534,3 @@ }

/**
* Format the value of a message into a string.
* Format the value of a message into a string or `null`.
*

@@ -530,17 +540,17 @@ * This function is passed as a method to `keysFromBundle` and resolve

*
* If the function fails to retrieve the entity, it will return an ID of it.
* If formatting fails, it will return a partially resolved entity.
* If the message doesn't have a value, return `null`.
*
* In both cases, an error is being added to the errors array.
*
* @param {FluentBundle} bundle
* @param {Array<Error>} errors
* @param {string} id
* @param {Object} args
* @returns {string}
* @param {Array<Error>} errors
* @param {Object} message
* @param {Object} args
* @returns {string|null}
* @private
*/
function valueFromBundle(bundle, errors, id, args) {
const msg = bundle.getMessage(id);
return bundle.format(msg, args, errors);
function valueFromBundle(bundle, errors, message, args) {
if (message.value) {
return bundle.formatPattern(message.value, args, errors);
}
return null;
}

@@ -557,30 +567,25 @@

*
* If the function fails to retrieve the entity, the value is set to the ID of
* an entity, and attributes to `null`. If formatting fails, it will return
* a partially resolved value and attributes.
*
* In both cases, an error is being added to the errors array.
*
* @param {FluentBundle} bundle
* @param {Array<Error>} errors
* @param {String} id
* @param {Object} args
* @param {Array<Error>} errors
* @param {Object} message
* @param {Object} args
* @returns {Object}
* @private
*/
function messageFromBundle(bundle, errors, id, args) {
const msg = bundle.getMessage(id);
function messageFromBundle(bundle, errors, message, args) {
const formatted = {
value: bundle.format(msg, args, errors),
value: null,
attributes: null,
};
if (msg.attrs) {
formatted.attributes = [];
for (const [name, attr] of Object.entries(msg.attrs)) {
const value = bundle.format(attr, args, errors);
if (value !== null) {
formatted.attributes.push({name, value});
}
if (message.value) {
formatted.value = bundle.formatPattern(message.value, args, errors);
}
let attrNames = Object.keys(message.attributes);
if (attrNames.length > 0) {
formatted.attributes = new Array(attrNames.length);
for (let [i, name] of attrNames.entries()) {
let value = bundle.formatPattern(message.attributes[name], args, errors);
formatted.attributes[i] = {name, value};
}

@@ -633,6 +638,12 @@ }

if (bundle.hasMessage(id)) {
let message = bundle.getMessage(id);
if (message) {
messageErrors.length = 0;
translations[i] = method(bundle, messageErrors, id, args);
// XXX: Report resolver errors
translations[i] = method(bundle, messageErrors, message, args);
if (messageErrors.length > 0 && typeof console !== "undefined") {
const locale = bundle.locales[0];
const errors = messageErrors.join(", ");
// eslint-disable-next-line max-len
console.warn(`[fluent][resolver] errors in ${locale}/${id}: ${errors}.`);
}
} else {

@@ -687,5 +698,7 @@ missingIds.add(id);

onChange() {
super.onChange();
this.translateRoots();
onChange(eager = false) {
super.onChange(eager);
if (this.roots) {
this.translateRoots();
}
}

@@ -692,0 +705,0 @@

{
"name": "@fluent/dom",
"version": "0.5.0",
"version": "0.6.0",
"description": "Fluent bindings for DOM",

@@ -5,0 +5,0 @@ "repository": {

@@ -73,3 +73,3 @@ # @fluent/dom

[projectfluent.org]: http://projectfluent.org
[FTL]: http://projectfluent.org/fluent/guide/
[projectfluent.org]: https://projectfluent.org
[FTL]: https://projectfluent.org/fluent/guide/

@@ -45,5 +45,7 @@ import translateElement from "./overlay";

onChange() {
super.onChange();
this.translateRoots();
onChange(eager = false) {
super.onChange(eager);
if (this.roots) {
this.translateRoots();
}
}

@@ -50,0 +52,0 @@

@@ -23,9 +23,8 @@ /* eslint no-console: ["error", { allow: ["warn", "error"] }] */

this.generateBundles = generateBundles;
this.bundles = CachedAsyncIterable.from(
this.generateBundles(this.resourceIds));
this.onChange(true);
}
addResourceIds(resourceIds) {
addResourceIds(resourceIds, eager = false) {
this.resourceIds.push(...resourceIds);
this.onChange();
this.onChange(eager);
return this.resourceIds.length;

@@ -54,4 +53,6 @@ }

const translations = [];
let hasAtLeastOneBundle = false;
for await (const bundle of this.bundles) {
hasAtLeastOneBundle = true;
const missingIds = keysFromBundle(method, bundle, keys, translations);

@@ -66,6 +67,13 @@

const ids = Array.from(missingIds).join(", ");
console.warn(`Missing translations in ${locale}: ${ids}`);
console.warn(`[fluent] Missing translations in ${locale}: ${ids}`);
}
}
if (!hasAtLeastOneBundle && typeof console !== "undefined") {
// eslint-disable-next-line max-len
console.warn(`[fluent] Request for keys failed because no resource bundles got generated.
keys: ${JSON.stringify(keys)}.
resourceIds: ${JSON.stringify(this.resourceIds)}.`);
}
return translations;

@@ -77,5 +85,5 @@ }

*
* The fallback logic is the same as in `formatValues` but the argument type
* is stricter (an array of arrays) and it returns {value, attributes}
* objects which are suitable for the translation of DOM elements.
* The fallback logic is the same as in `formatValues` but it returns {value,
* attributes} objects which are suitable for the translation of DOM
* elements.
*

@@ -108,4 +116,4 @@ * docL10n.formatMessages([

*
* A generalized version of `DOMLocalization.formatValue`. Keys can
* either be simple string identifiers or `[id, args]` arrays.
* A generalized version of `DOMLocalization.formatValue`. Keys must
* be `{id, args}` objects.
*

@@ -164,6 +172,8 @@ * docL10n.formatValues([

*/
onChange() {
onChange(eager = false) {
this.bundles = CachedAsyncIterable.from(
this.generateBundles(this.resourceIds));
this.bundles.touchNext(2);
if (eager) {
this.bundles.touchNext(2);
}
}

@@ -173,3 +183,3 @@ }

/**
* Format the value of a message into a string.
* Format the value of a message into a string or `null`.
*

@@ -179,17 +189,17 @@ * This function is passed as a method to `keysFromBundle` and resolve

*
* If the function fails to retrieve the entity, it will return an ID of it.
* If formatting fails, it will return a partially resolved entity.
* If the message doesn't have a value, return `null`.
*
* In both cases, an error is being added to the errors array.
*
* @param {FluentBundle} bundle
* @param {Array<Error>} errors
* @param {string} id
* @param {Object} args
* @returns {string}
* @param {Array<Error>} errors
* @param {Object} message
* @param {Object} args
* @returns {string|null}
* @private
*/
function valueFromBundle(bundle, errors, id, args) {
const msg = bundle.getMessage(id);
return bundle.format(msg, args, errors);
function valueFromBundle(bundle, errors, message, args) {
if (message.value) {
return bundle.formatPattern(message.value, args, errors);
}
return null;
}

@@ -206,30 +216,25 @@

*
* If the function fails to retrieve the entity, the value is set to the ID of
* an entity, and attributes to `null`. If formatting fails, it will return
* a partially resolved value and attributes.
*
* In both cases, an error is being added to the errors array.
*
* @param {FluentBundle} bundle
* @param {Array<Error>} errors
* @param {String} id
* @param {Object} args
* @param {Array<Error>} errors
* @param {Object} message
* @param {Object} args
* @returns {Object}
* @private
*/
function messageFromBundle(bundle, errors, id, args) {
const msg = bundle.getMessage(id);
function messageFromBundle(bundle, errors, message, args) {
const formatted = {
value: bundle.format(msg, args, errors),
value: null,
attributes: null,
};
if (msg.attrs) {
formatted.attributes = [];
for (const [name, attr] of Object.entries(msg.attrs)) {
const value = bundle.format(attr, args, errors);
if (value !== null) {
formatted.attributes.push({name, value});
}
if (message.value) {
formatted.value = bundle.formatPattern(message.value, args, errors);
}
let attrNames = Object.keys(message.attributes);
if (attrNames.length > 0) {
formatted.attributes = new Array(attrNames.length);
for (let [i, name] of attrNames.entries()) {
let value = bundle.formatPattern(message.attributes[name], args, errors);
formatted.attributes[i] = {name, value};
}

@@ -282,6 +287,12 @@ }

if (bundle.hasMessage(id)) {
let message = bundle.getMessage(id);
if (message) {
messageErrors.length = 0;
translations[i] = method(bundle, messageErrors, id, args);
// XXX: Report resolver errors
translations[i] = method(bundle, messageErrors, message, args);
if (messageErrors.length > 0 && typeof console !== "undefined") {
const locale = bundle.locales[0];
const errors = messageErrors.join(", ");
// eslint-disable-next-line max-len
console.warn(`[fluent][resolver] errors in ${locale}/${id}: ${errors}.`);
}
} else {

@@ -288,0 +299,0 @@ missingIds.add(id);

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc