@seanox/aspect-js
Version:
full stack JavaScript framework for SPAs incl. reactivity rendering, mvc / mvvm, models, expression language, datasource, virtual paths, unit test and some more
136 lines (128 loc) • 5.29 kB
JavaScript
/**
* LIZENZBEDINGUNGEN - Seanox Software Solutions ist ein Open-Source-Projekt,
* im Folgenden Seanox Software Solutions oder kurz Seanox genannt.
* Diese Software unterliegt der Version 2 der Apache License.
*
* Seanox aspect-js, fullstack for single page applications
* Copyright (C) 2023 Seanox Software Solutions
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*
*
* DESCRIPTION
* ----
* (Resource)Messages is a static DataSource extension for internationalization
* and localization. The implementation is based on a set of key-value or
* label-value data which is stored in the locales.xml of the DataSource.
*
* + data
* + de
* + en
* - locales.xml
* + modules
* + resources
* - index.html
*
* The elements for the supported languages are organized in locales in this
* file. Locales is a set of supported country codes. In each country code, the
* key values are recorded as label entries.
*
* <?xml version="1.0"?>
* <locales>
* <de>
* <label key="contact.title" value="Kontakt"/>
* <label key="contact.development.title">Entwicklung</label>
* ...
* </de>
* <en default="true">
* <label key="contact.title" value="Contact"/>
* <label key="contact.development.title">Development</label>
* ...
* </en>
* </locales>
*
* The language is selected automatically on the basis of the language setting
* of the browser. If the language set there is not supported, the language
* declared as 'default' is used.
*
* After loading the application, Messages are available as an associative
* array and can be used directly in JavaScript and Markup via Expression
* Language.
*
* Messages["contact.title"];
*
* <h1 output="{{Messages['contact.title']}}"/>
*
* In addition, the object message is also provided. Unlike Messages, message is
* an object tree analogous to the keys from Messages. The dot in the keys is
* the indicator of the levels in the tree.
*
* messages.contact.title;
*
* <h1 output="{{messages.contact.title}}"/>
*
* Both objects are only available if there are also labels.
*
* @author Seanox Software Solutions
* @version 1.6.0 20230304
*/
(() => {
compliant("messages");
compliant(null, window.messages = {});
compliant("Messages");
compliant(null, window.Messages = {});
const _localize = DataSource.localize;
DataSource.localize = (locale) => {
_localize(locale);
delete window.messages;
delete window.Messages;
window.Messages = {
customize(label, ...values) {
let text = Messages[label] || "";
for (let index = 0; index < values.length; index++)
text = text.replace(new RegExp("\\{" + index + "\\}", "g"), values[index]);
return text.replace(/\{\d+\}/g, "");
}
}
const map = new Map();
const xpath = "/locales/" + DataSource.locale + "/label";
const result = DataSource.data.evaluate(xpath, DataSource.data, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
for (let node = result.iterateNext(); node; node = result.iterateNext())
map.set((node.getAttribute("key") || "").trim(),
((node.getAttribute("value") || "").trim()
|| (node.textContent || "").trim()).unescape());
new Map([...map.entries()].sort()).forEach((value, key) => {
const match = key.match(/^(?:((?:\w+\.)*\w+)\.)*(\w+)$/);
if (match) {
// In order for the object tree to branch from each level, each
// level must be an object. Therefore, an anonymous object is
// used for the level, which returns the actual text via
// Object.prototype.toString().
const namespace = "messages" + (match[1] ? "." + match[1] : "");
Object.defineProperty(Namespace.use(namespace), match[2], {
value: {toString() {return value;}}
});
Object.defineProperty(Namespace.use("Messages"), key, {
value
});
}
});
};
// Messages are based on DataSources. To initialize, DataSource.localize()
// must be overwritten and loading of the key-value pairs is embedded.
if (DataSource.data
&& DataSource.locale
&& DataSource.locales
&& DataSource.locales.includes(DataSource.locale))
DataSource.localize(DataSource.locale);
})();