Something went wrong on our end
Select Git revision
formatter.mjs
-
Volker Schukai authoredVolker Schukai authored
formatter.mjs 3.49 KiB
/**
* Copyright schukai GmbH and contributors 2023. All Rights Reserved.
* Node module: @schukai/monster
* This file is licensed under the AGPLv3 License.
* License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
*/
import { instanceSymbol, internalSymbol } from "../constants.mjs";
import { extend } from "../data/extend.mjs";
import { Formatter as TextFormatter } from "../text/formatter.mjs";
import { validateInstance, validateString } from "../types/validate.mjs";
import { Translations } from "./translations.mjs";
export { Formatter };
/**
* @private
* @type {symbol}
*/
const internalTranslationSymbol = Symbol("internalTranslation");
/**
* The Formatter extends the Text.Formatter with the possibility to replace the key by a translation.
*
* @externalExample ../../example/i18n/formatter.mjs
* @license AGPLv3
* @since 1.26.0
* @copyright schukai GmbH
* @memberOf Monster.I18n
*/
class Formatter extends TextFormatter {
/**
* Default values for the markers are `${` and `}`
*
* @param {object} object
* @throws {TypeError} value is not a object
*/
constructor(object, translation, options) {
super(object, options);
this[internalTranslationSymbol] = validateInstance(translation, Translations);
}
/**
* This method is called by the `instanceof` operator.
* @returns {symbol}
* @since 3.27.0
*/
static get [instanceSymbol]() {
return Symbol.for("@schukai/monster/i18n/formatter@@instance");
}
/**
* @property {object} marker
* @property {array} marker.open=["i18n{","${"]
* @property {array} marker.close=["${"]
* @property {object} parameter
* @property {string} parameter.delimiter="::"
* @property {string} parameter.assignment="="
* @property {object} callbacks
* @property {function} callbacks.i18n=()=>{}
*/
get defaults() {
const self = this;
return extend({}, super.defaults, {
callbacks: {
i18n: (value) => {
return self[internalTranslationSymbol].getText(validateString(value));
},
},
marker: {
open: ["i18n{", "${"],
close: ["}"],
},
});
}
/**
*
* @param {string} text
* @return {string}
* @throws {TypeError} value is not a string
* @throws {Error} too deep nesting
* @throws {Error} key not found
* @throws {Error} the closing marker is missing
*/
format(text) {
validateString(text);
const openMarker = this[internalSymbol]["marker"]["open"]?.[0];
const closeMarker = this[internalSymbol]["marker"]["close"]?.[0];
if (text.indexOf(openMarker) === 0) {
text = text.substring(openMarker.length);
if (text.indexOf(closeMarker) === text.length - closeMarker.length) {
text = text.substring(0, text.length - closeMarker.length);
} else {
throw new Error("the closing marker is missing");
}
}
const parts = validateString(text).split("::");
const translationKey = parts.shift().trim(); // key value delimiter
const parameter = parts.join("::").trim();
let assembledText = `${openMarker}static:${translationKey} | call:i18n`;
if (parameter.length > 0) {
assembledText += `::${parameter}`;
}
assembledText += closeMarker;
return super.format(assembledText);
}
}