web-internationalization 2.0.42 → 2.0.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/index.d.ts +4 -3
  2. package/index.js +267 -1
  3. package/package.json +16 -19
  4. package/type.d.ts +1 -1
package/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
- import { HTMLItem, Lock, Logger, Mapping } from 'clientnode';
2
- import { WebComponentAPI } from 'web-component-wrapper/type';
1
+ import type { HTMLItem, Mapping } from 'clientnode';
2
+ import type { WebComponentAPI } from 'web-component-wrapper/type';
3
+ import type { DefaultOptions, Options, Replacement } from './type';
4
+ import { Lock, Logger } from 'clientnode';
3
5
  import { Web } from 'web-component-wrapper/Web';
4
- import { DefaultOptions, Options, Replacement } from './type';
5
6
  export declare const log: Logger;
6
7
  /**
7
8
  * This plugin holds all necessary methods to extend a website for
package/index.js CHANGED
@@ -1 +1,267 @@
1
- "use strict";if("undefined"!=typeof module&&null!==module&&"undefined"!==eval("typeof require")&&null!==eval("require")&&"main"in eval("require")&&"undefined"!==eval("typeof require.main")&&null!==eval("require.main")){var ORIGINAL_MAIN_MODULE=module;module!==eval("require.main")&&"paths"in module&&"paths"in eval("require.main")&&"undefined"!=typeof __dirname&&null!==__dirname&&(module.paths=eval("require.main.paths").concat(module.paths.filter((function(path){return eval("require.main.paths").includes(path)}))))}if(null==window)var window="undefined"==typeof global||null===global?{}:global;!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t(require("@babel/runtime/helpers/initializerDefineProperty"),require("@babel/runtime/helpers/applyDecoratedDescriptor"),require("@babel/runtime/helpers/initializerWarningHelper"),require("clientnode"),require("clientnode/property-types"),require("web-component-wrapper/decorator"),require("web-component-wrapper/Web"));else if("function"==typeof define&&define.amd)define(["@babel/runtime/helpers/initializerDefineProperty","@babel/runtime/helpers/applyDecoratedDescriptor","@babel/runtime/helpers/initializerWarningHelper","clientnode","clientnode/property-types","web-component-wrapper/decorator","web-component-wrapper/Web"],t);else{var o="object"==typeof exports?t(require("@babel/runtime/helpers/initializerDefineProperty"),require("@babel/runtime/helpers/applyDecoratedDescriptor"),require("@babel/runtime/helpers/initializerWarningHelper"),require("clientnode"),require("clientnode/property-types"),require("web-component-wrapper/decorator"),require("web-component-wrapper/Web")):t(e["@babel/runtime/helpers/initializerDefineProperty"],e["@babel/runtime/helpers/applyDecoratedDescriptor"],e["@babel/runtime/helpers/initializerWarningHelper"],e.clientnode,e["clientnode/property-types"],e["web-component-wrapper/decorator"],e["web-component-wrapper/Web"]);for(var n in o)("object"==typeof exports?exports:e)[n]=o[n]}}(this,((e,t,o,n,i,a,r)=>(()=>{var s=[,t=>{t.exports=e},e=>{e.exports=t},e=>{e.exports=o},e=>{e.exports=n},e=>{e.exports=i},e=>{e.exports=a},e=>{e.exports=r}],l={};function c(e){var t=l[e];if(void 0!==t)return t.exports;var o=l[e]={exports:{}};return s[e](o,o.exports,c),o.exports}c.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return c.d(t,{a:t}),t},c.d=(e,t)=>{for(var o in t)c.o(t,o)&&!c.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:t[o]})},c.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),c.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var p={};c.r(p),c.d(p,{WebInternationalization:()=>k,api:()=>E,default:()=>R,log:()=>O});var u,d,h,m,g,f,N,b,w,T,_,x,D=c(1),y=c.n(D),L=c(2),C=c.n(L),v=(c(3),c(4)),A=c(5),P=c(6),S=c(7);const O=new v.Logger({name:"web-internationalization"});let k=(u=(0,P.property)({type:A.object}),d=(0,P.property)({type:A.func}),h=(0,P.property)({type:A.func}),m=(0,P.property)({type:A.func}),g=(0,P.property)({type:A.func}),x=class e extends S.Web{constructor(){super(),this.self=e,y()(this,"options",N,this),y()(this,"onEnsure",b,this),y()(this,"onSwitch",w,this),y()(this,"onEnsured",T,this),y()(this,"onSwitched",_,this),this.switchLanguageButtonDomNodes=null,this.currentLanguage="enUS",this.knownTranslations={},this.lock=new v.Lock,this._domNodesToFade=[],this._replacements=[],this._domNodesWithKnownTranslation={},this.defineGetterAndSetterInterface()}async onUpdateAttribute(e,t){await super.onUpdateAttribute(e,t),"options"===e&&this._extendOptions()}async render(e="unknown",t=!0){await super.render(e,!1),0===Object.keys(this.options).length&&this._extendOptions(),this.options.preReplacementLanguagePattern=(0,v.format)(this.options.preReplacementLanguagePattern,this.options.replacementLanguagePattern.substring(1,this.options.replacementLanguagePattern.length-1)),this.options.lockDescription=(0,v.format)(this.options.lockDescription,this.self._name),this.options.sessionDescription=(0,v.format)(this.options.sessionDescription,this.self._name),await this.waitForNestedComponentRendering(),this.switchLanguageButtonDomNodes=this.hostDomNode.querySelectorAll(`a[href^="#${this.options.languageHashPrefix}"]`),this._movePreReplacementNodes(),this.currentLanguage=this._normalizeLanguage(this.options.default);const o=this._determineUsefulLanguage(),n=0===this.options.selection.length;for(const e of this.switchLanguageButtonDomNodes){n&&this.options.selection.push(e.getAttribute("href").substring(`#${this.options.languageHashPrefix}`.length));const t=e=>{e.preventDefault();const t=e.target?.getAttribute("href");t&&this.switch(t.substring(this.options.languageHashPrefix.length+1))};this.addSecureEventListener(e,"click",t)}this.currentLanguage===o?await this.refresh():await this.switch(o,!0),await this.resolveRenderingPromiseIfSet(e,t)}async switch(e,t=!1){if(!0===e||!this.options.selection.length||this.options.selection.includes(e)){if(await this.lock.acquire(this.options.lockDescription),!0===e?(t=!0,e=this.currentLanguage):e=this._normalizeLanguage(e),t||this.currentLanguage!==e){let o="Switch to";return t&&(o="Ensure"),O.debug(`${o} "${e}".`),this._switchCurrentLanguageIndicator(e),t?await this.onEnsure(e):await this.onSwitch(this.currentLanguage,e),this._domNodesToFade=[],this._replacements=[],this._collectDomNodesToReplace(e,t),void await this._handleSwitchEffect(e,t)}O.debug(`"${e}" is already current selected language.`),this.lock.release(this.options.lockDescription)}else O.debug(`"${e}" isn't one of the allowed languages.`)}refresh(){return this._movePreReplacementNodes(),this.switch(!0)}_extendOptions(){this.setPropertyValue("options",(0,v.extend)(!0,{},this.self._defaultOptions,this.options))}async _handleSwitchEffect(e,t){const o=this.currentLanguage;if(!t&&this.options.useEffect&&this._domNodesToFade.length>0)return await Promise.all(this._domNodesToFade.map((e=>{const t=(0,v.fadeOut)(e);return t.then((()=>{t.resetStyles()}))}))),this._switchLanguage(e),await Promise.all(this._domNodesToFade.map((e=>{const t=(0,v.fadeIn)(e);return t.then((()=>{t.resetStyles()}))}))),this.onSwitched(o,e),void this.lock.release(this.options.lockDescription);this._switchLanguage(e),t?this.onEnsured(e):this.onSwitched(o,e),this.lock.release(this.options.lockDescription)}_movePreReplacementNodes(){for(const e of(0,v.getAll)(this.hostDomNode)){const t=e.nodeName.toLowerCase();if(this.options.replacementDomNodeNames.includes(t)){["#comment","#text"].includes(t)||e.classList.add(this.options.selectors.hideClassName);const o=new RegExp(this.options.preReplacementLanguagePattern),n=e.textContent?.match(o);if(e.textContent&&n&&n[0]&&(e.textContent=e.textContent.replace(o,n[1]),e.parentElement)){let t=!1;for(const o of(0,v.getAll)(e.parentElement)){if(t&&(0,v.getText)(o,!0).length>0){o.appendChild(e);break}e===o&&(t=!0)}}}}}_collectDomNodesToReplace(e,t){let o=null,n=null;this.knownTranslations={};for(const i of(0,v.getAll)(this.hostDomNode)){const a=i.nodeName.toLowerCase(),r=(0,v.getText)(i,!0);if(!this._shouldSkipDomNode(i,r,o))if(this.options.replaceDomNodeNames.includes(a))o=i;else if(this.options.alternativeDomNodeNames.includes(a))i.hasAttribute("lang")?i.getAttribute("lang")===e&&this._processAlternativeDomNode(i,e,t,n):this._initializeCurrentLanguageDomNode(i,t);else if(o){if(this.options.replacementDomNodeNames.includes(a)){({domNodeToTranslate:o,languageDomNode:n}=this._processReplacementDomNode(i,a,e,t,o,n));continue}o=null,n=null}}this._registerKnownTextNodes()}_shouldSkipDomNode(e,t,o){return 0===t.length&&(e.nodeType!==Node.COMMENT_NODE||""===(e.nodeValue||"").trim())||Boolean(o?.contains(e))||Boolean((0,v.closest)(e,this.options.replaceDomNodeNames.concat(this.options.replacementDomNodeNames).join(","),!0))}_processAlternativeDomNode(e,t,o,n){let i=null;for(const t of e.parentElement.querySelectorAll(this.options.alternativeDomNodeNames.join(",")))if(t.hasAttribute("active")||!t.hasAttribute("lang")){i=t;break}i&&(this._initializeCurrentLanguageDomNode(i,o),this._registerTextNodeToChange(i,e,e.innerHTML,n))}_initializeCurrentLanguageDomNode(e,t){e.hasAttribute("active")||e.setAttribute("active",""),e.hasAttribute("lang")||e.setAttribute("lang",t&&this.options.default||this.currentLanguage)}_processReplacementDomNode(e,t,o,n,i,a){const r=("#comment"===t?e.textContent:e.innerHTML).match(new RegExp(this.options.replacementLanguagePattern));return Array.isArray(r)&&r[1]===o?(this.knownTranslations[(0,v.getText)(i,!0).join(" ")]=r[2].trim(),a=this._ensureLastTextNodeHavingLanguageIndicator(i,a,n),this._registerTextNodeToChange(i,e,r[2],a),{domNodeToTranslate:null,languageDomNode:null}):(e.textContent.match(new RegExp(this.options.currentLanguagePattern))&&(a=e),{domNodeToTranslate:i,languageDomNode:a})}_registerKnownTextNodes(){this._domNodesWithKnownTranslation={};for(const e of this.hostDomNode.querySelectorAll(this.options.selectors.knownTranslation))for(const t of(0,v.getAll)(e)){const e=(0,v.getText)(t).join(" ");e&&!this.options.replaceDomNodeNames.includes(t.nodeName.toLowerCase())&&!(0,v.closest)(t,this.options.replaceDomNodeNames.join(","),!0)&&Object.prototype.hasOwnProperty.call(this.knownTranslations,e)&&(this._domNodesToFade.push(t.parentElement),Object.prototype.hasOwnProperty.call(this._domNodesWithKnownTranslation,this.knownTranslations[e])?this._domNodesWithKnownTranslation[this.knownTranslations[e]].push(t):this._domNodesWithKnownTranslation[this.knownTranslations[e]]=[t])}}_normalizeLanguage(e){for(const[t,o]of Object.entries(this.options.languageMapping))if(o.includes(t.toLowerCase())||o.push(t.toLowerCase()),o.includes(e.toLowerCase()))return t;return this.options.default}_determineUsefulLanguage(){let e;return this.options.initial?e=this.options.initial:Object.prototype.hasOwnProperty.call(v.globalContext,"window")&&(v.globalContext.window?.localStorage.getItem(this.options.sessionDescription)?(e=v.globalContext.window.localStorage.getItem(this.options.sessionDescription),O.debug(`Determine "${e}", because of local storage`,"information.")):v.globalContext.window?.navigator.language&&(e=v.globalContext.window.navigator.language,O.debug(`Determine "${e}", because of browser settings.`))),e||(e=this.options.default,O.debug(`Determine "${e}", because of default option.`)),e=this._normalizeLanguage(e),this.options.selection.length&&!this.options.selection.includes(e)&&(O.debug(`"${e}" isn't one of the allowed languages. Set`,`language to "${this.options.selection[0]}".`),e=this.options.selection[0]),v.globalContext.window?.localStorage&&v.globalContext.window.localStorage.setItem(this.options.sessionDescription,e),e}_registerTextNodeToChange(e,t,o,n){this._domNodesToFade.push(e.parentElement),t&&this._replacements.push({domNodeToTranslate:e,domNodeToReplaceWith:t,textToReplaceWith:o,currentLanguageDomNode:n})}_ensureLastTextNodeHavingLanguageIndicator(e,t,o){if(e&&!t){let n=this.currentLanguage;o&&(n=this.options.default||this.currentLanguage),(t=v.globalContext.document?.createComment(n)||null)&&e.after(t)}return t}_switchLanguage(e){for(const t of this._replacements){const o=this._getCurrentNodeText(t.domNodeToTranslate),n=o.trim();if(!this.options.templateDelimiter||!n.endsWith(this.options.templateDelimiter.post)&&this.options.templateDelimiter.post){const n=this._resolveCurrentLanguageDomNode(t),i=n.textContent;i&&e===i&&O.warn(`Text node "${t.textToReplaceWith}" is`,`marked as "${i}" and has same`,"translation language as it already is.");const a=t.domNodeToReplaceWith.nodeName.toLowerCase();if(this.options.alternativeDomNodeNames.includes(a)){t.domNodeToReplaceWith.setAttribute("active",""),t.domNodeToTranslate.removeAttribute("active");continue}const r=this._createBackupNode(a,i,o,t.domNodeToTranslate);t.domNodeToTranslate.after(r),t.domNodeToTranslate.after(v.globalContext.document.createComment(e)),this._applyTextReplacement(t),n.remove(),t.domNodeToReplaceWith.remove()}}this._updateKnownTextNodes(),v.globalContext.localStorage&&v.globalContext.localStorage.setItem(this.options.sessionDescription,e),this.currentLanguage=e}_getCurrentNodeText(e){return"innerHTML"in e?e.innerHTML:e.textContent}_resolveCurrentLanguageDomNode(e){if(e.currentLanguageDomNode)return e.currentLanguageDomNode;let t=document.body,o=!1;for(const n of(0,v.getAll)(e.domNodeToTranslate.parentElement)){if(o){e.currentLanguageDomNode=t=n;break}n===e.domNodeToTranslate&&(o=!0)}return t}_createBackupNode(e,t,o,n){if("#comment"===e)return v.globalContext.document.createComment(`${t}:${o}`);const i=v.globalContext.document.createElement(e);i.appendChild(v.globalContext.document.createTextNode(`${t}:`)),i.classList.add(this.options.selectors.hideClassName);for(const e of Array.from(n.childNodes))i.appendChild(e);return i}_applyTextReplacement(e){if("innerHTML"in e.domNodeToTranslate)if("#comment"===e.domNodeToReplaceWith.nodeName.toLowerCase())e.domNodeToTranslate.innerHTML=e.textToReplaceWith;else{let t=!1;for(const o of Array.from(e.domNodeToReplaceWith.childNodes))t||(o.textContent=o.textContent.replace(/^[a-z]{2}[A-Z]{2}:/,""),t=!0),e.domNodeToTranslate.appendChild(o)}else e.domNodeToTranslate.textContent=e.textToReplaceWith}_updateKnownTextNodes(){for(const[e,t]of Object.entries(this._domNodesWithKnownTranslation))for(const o of t)o.textContent=e}_switchCurrentLanguageIndicator(e){for(const e of this.hostDomNode.querySelectorAll(`a[href="#${this.options.languageHashPrefix}${this.currentLanguage}"].`+this.options.currentLanguageIndicatorClassName))e.classList.remove(this.options.currentLanguageIndicatorClassName);for(const t of this.hostDomNode.querySelectorAll(`a[href="#${this.options.languageHashPrefix}${e}"]`))t.classList.add(this.options.currentLanguageIndicatorClassName)}},x._name="WebInternationalization",x._defaultOptions={currentLanguageIndicatorClassName:"current",currentLanguagePattern:"^[a-z]{2}[A-Z]{2}$",default:"enUS",useEffect:!0,initial:null,languageHashPrefix:"lang-",languageMapping:{deDE:["de","de_de","de-de","german","deutsch"],enUS:["en","en_us","en-us"],enEN:["en_en","en-en","english"],frFR:["fr","fr_fr","fr-fr","french"]},lockDescription:"{1}Switch",preReplacementLanguagePattern:"^\\|({1})$",alternativeDomNodeNames:["lang-alternative"],replaceDomNodeNames:["#text","lang-replace"],replacementDomNodeNames:["#comment","lang-replacement"],replacementLanguagePattern:"^([a-z]{2}[A-Z]{2}):((.|\\s)*)$",selection:[],selectors:{knownTranslation:".web-internationalization-generated-content",hideClassName:"wi-hide"},sessionDescription:"{1}",templateDelimiter:{pre:"{{",post:"}}"}},f=x,N=C()(f.prototype,"options",[u],{configurable:!0,enumerable:!0,writable:!0,initializer:function(){return{}}}),b=C()(f.prototype,"onEnsure",[d],{configurable:!0,enumerable:!0,writable:!0,initializer:function(){return v.NOOP}}),w=C()(f.prototype,"onSwitch",[h],{configurable:!0,enumerable:!0,writable:!0,initializer:function(){return v.NOOP}}),T=C()(f.prototype,"onEnsured",[m],{configurable:!0,enumerable:!0,writable:!0,initializer:function(){return v.NOOP}}),_=C()(f.prototype,"onSwitched",[g],{configurable:!0,enumerable:!0,writable:!0,initializer:function(){return v.NOOP}}),f);const E={component:k,register:(e=(0,v.camelCaseToDelimited)(k._name))=>{customElements.define(e,k)}},R=k;return v.globalContext.AUTO_DEFINE_WEB_INTERNATIONALIZATION&&E.register(),p})()));
1
+ if(typeof window==='undefined'||window===null)var window=(typeof global==='undefined'||global===null)?{}:global;import { Lock as __WEBPACK_EXTERNAL_MODULE_clientnode_Lock__, Logger as __WEBPACK_EXTERNAL_MODULE_clientnode_Logger__, NOOP as __WEBPACK_EXTERNAL_MODULE_clientnode_NOOP__, camelCaseToDelimited as __WEBPACK_EXTERNAL_MODULE_clientnode_camelCaseToDelimited__, closest as __WEBPACK_EXTERNAL_MODULE_clientnode_closest__, extend as __WEBPACK_EXTERNAL_MODULE_clientnode_extend__, fadeIn as __WEBPACK_EXTERNAL_MODULE_clientnode_fadeIn__, fadeOut as __WEBPACK_EXTERNAL_MODULE_clientnode_fadeOut__, format as __WEBPACK_EXTERNAL_MODULE_clientnode_format__, getAll as __WEBPACK_EXTERNAL_MODULE_clientnode_getAll__, getText as __WEBPACK_EXTERNAL_MODULE_clientnode_getText__, globalContext as __WEBPACK_EXTERNAL_MODULE_clientnode_globalContext__ } from "clientnode";
2
+ import { func as __WEBPACK_EXTERNAL_MODULE_clientnode_property_types_4789ebe2_func__, object as __WEBPACK_EXTERNAL_MODULE_clientnode_property_types_4789ebe2_object__ } from "clientnode/property-types";
3
+ import { property as __WEBPACK_EXTERNAL_MODULE_web_component_wrapper_decorator_a680de5c_property__ } from "web-component-wrapper/decorator";
4
+ import { Web as __WEBPACK_EXTERNAL_MODULE_web_component_wrapper_Web_aacc6608_Web__ } from "web-component-wrapper/Web";
5
+
6
+ ;// external "clientnode"
7
+
8
+ ;// external "clientnode/property-types"
9
+
10
+ ;// external "web-component-wrapper/decorator"
11
+
12
+ ;// external "web-component-wrapper/Web"
13
+
14
+ ;// ./index.ts
15
+ // #!/usr/bin/env babel-node
16
+ // -*- coding: utf-8 -*-
17
+ /** @module web-internationalization *//* !
18
+ region header
19
+ [Project page](https://torben.website/web-internationalization)
20
+
21
+ Copyright Torben Sickert (info["~at~"]torben.website) 16.12.2012
22
+
23
+ License
24
+ -------
25
+
26
+ This library written by Torben Sickert stands under a creative commons
27
+ naming 3.0 unported license.
28
+ See https://creativecommons.org/licenses/by/3.0/deed.de
29
+ endregion
30
+ */// region imports
31
+ var _dec,_dec2,_dec3,_dec4,_dec5,_class,_descriptor,_descriptor2,_descriptor3,_descriptor4,_descriptor5,_WebInternationalization;function _initializerDefineProperty(e,i,r,l){r&&Object.defineProperty(e,i,{enumerable:r.enumerable,configurable:r.configurable,writable:r.writable,value:r.initializer?r.initializer.call(l):void 0})}function _defineProperty(e,r,t){return(r=_toPropertyKey(r))in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function _toPropertyKey(t){var i=_toPrimitive(t,"string");return"symbol"==typeof i?i:i+""}function _toPrimitive(t,r){if("object"!=typeof t||!t)return t;var e=t[Symbol.toPrimitive];if(void 0!==e){var i=e.call(t,r||"default");if("object"!=typeof i)return i;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===r?String:Number)(t)}function _applyDecoratedDescriptor(i,e,r,n,l){var a={};return Object.keys(n).forEach(function(i){a[i]=n[i]}),a.enumerable=!!a.enumerable,a.configurable=!!a.configurable,("value"in a||a.initializer)&&(a.writable=!0),a=r.slice().reverse().reduce(function(r,n){return n(i,e,r)||r},a),l&&void 0!==a.initializer&&(a.value=a.initializer?a.initializer.call(l):void 0,a.initializer=void 0),void 0===a.initializer?(Object.defineProperty(i,e,a),null):a}function _initializerWarningHelper(r,e){throw Error("Decorating class property failed. Please ensure that transform-class-properties is enabled and runs after the decorators transform.")};// endregion
32
+ const log=new __WEBPACK_EXTERNAL_MODULE_clientnode_Logger__({name:"web-internationalization"});// region plugins/classes
33
+ /**
34
+ * This plugin holds all necessary methods to extend a website for
35
+ * internationalization.
36
+ * @property _defaultOptions - Options extended by the options given to the
37
+ * initializer method.
38
+ * @property _defaultOptions.currentLanguageIndicatorClassName - Class name
39
+ * which marks current language switcher button or link.
40
+ * @property _defaultOptions.currentLanguagePattern - Saves a pattern to
41
+ * recognize current language marker.
42
+ * @property _defaultOptions.default - Initial language to use.
43
+ * @property _defaultOptions.useEffect - Indicates whether a fade effect
44
+ * should be performed.
45
+ * @property _defaultOptions.initial - Initial set language (if omitted it will
46
+ * be determined based on environment information).
47
+ * @property _defaultOptions.languageHashPrefix - Hash prefix to determine
48
+ * current active language by url.
49
+ * @property _defaultOptions.languageMapping - A mapping of alternate language
50
+ * descriptions.
51
+ * @property _defaultOptions.lockDescription - Lock description.
52
+ * @property _defaultOptions.preReplacementLanguagePattern - Pattern to
53
+ * introduce a pre-replacement language node.
54
+ * @property _defaultOptions.replaceDomNodeNames - Tag names which indicates
55
+ * dom nodes which should be replaced.
56
+ * @property _defaultOptions.replacementDomNodeNames - Dom node tag name which
57
+ * should be interpreted as a hidden alternate language node (contains text in
58
+ * another language).
59
+ * @property _defaultOptions.replacementLanguagePattern - Text pattern to
60
+ * introduce a post-replacement node.
61
+ * @property _defaultOptions.selection - List of all supported languages.
62
+ * @property _defaultOptions.selectors - Mapping of necessary dom node
63
+ * selectors.
64
+ * @property _defaultOptions.selectors.knownTranslation - Selector to find
65
+ * known translation sections.
66
+ * @property _defaultOptions.sessionDescription - Description to save current
67
+ * language in session storage.
68
+ * @property _defaultOptions.templateDelimiter - Template delimiter to
69
+ * recognize dynamic content.
70
+ * @property _defaultOptions.templateDelimiter.pre - Delimiter that introduces
71
+ * a dynamic expression.
72
+ * @property _defaultOptions.templateDelimiter.post - Delimiter which finishes
73
+ * a dynamic expression.
74
+ * @property options - Finally configured given options.
75
+ * @property currentLanguage - Saves the current language.
76
+ * @property knownTranslations - Saves a mapping of known language strings and
77
+ * their corresponding translations, to boost language replacements or saves
78
+ * redundant replacements in a dom tree.
79
+ * @property lock - Lock instance when updating dom noes.
80
+ * @property _domNodesToFade - Saves all dom nodes that should be animated.
81
+ * @property _replacements - Saves all text nodes that should be replaced.
82
+ * @property _domNodesWithKnownTranslation - Saves a mapping of known text
83
+ * snippets to their corresponding $-extended dom nodes.
84
+ */let WebInternationalization=(_dec=__WEBPACK_EXTERNAL_MODULE_web_component_wrapper_decorator_a680de5c_property__({type:__WEBPACK_EXTERNAL_MODULE_clientnode_property_types_4789ebe2_object__}),_dec2=__WEBPACK_EXTERNAL_MODULE_web_component_wrapper_decorator_a680de5c_property__({type:__WEBPACK_EXTERNAL_MODULE_clientnode_property_types_4789ebe2_func__}),_dec3=__WEBPACK_EXTERNAL_MODULE_web_component_wrapper_decorator_a680de5c_property__({type:__WEBPACK_EXTERNAL_MODULE_clientnode_property_types_4789ebe2_func__}),_dec4=__WEBPACK_EXTERNAL_MODULE_web_component_wrapper_decorator_a680de5c_property__({type:__WEBPACK_EXTERNAL_MODULE_clientnode_property_types_4789ebe2_func__}),_dec5=__WEBPACK_EXTERNAL_MODULE_web_component_wrapper_decorator_a680de5c_property__({type:__WEBPACK_EXTERNAL_MODULE_clientnode_property_types_4789ebe2_func__}),_class=(_WebInternationalization=class WebInternationalization extends __WEBPACK_EXTERNAL_MODULE_web_component_wrapper_Web_aacc6608_Web__{// region public methods
85
+ /// region live-cycle
86
+ /**
87
+ * Defines dynamic getter and setter interface and resolves a configuration
88
+ * object. Initializes the map implementation.
89
+ */constructor(){super();/*
90
+ Babel property declaration transformation overwrites defined
91
+ properties at the end of an implicit constructor. So we have to
92
+ redefine them as long as we want to declare expected component
93
+ interface properties to enable static type checks.
94
+ */_defineProperty(this,"self",WebInternationalization);// region api properties
95
+ _initializerDefineProperty(this,"options",_descriptor,this);_initializerDefineProperty(this,"onEnsure",_descriptor2,this);_initializerDefineProperty(this,"onSwitch",_descriptor3,this);_initializerDefineProperty(this,"onEnsured",_descriptor4,this);_initializerDefineProperty(this,"onSwitched",_descriptor5,this);// endregion
96
+ _defineProperty(this,"switchLanguageButtonDomNodes",null);_defineProperty(this,"currentLanguage","enUS");_defineProperty(this,"knownTranslations",{});_defineProperty(this,"lock",new __WEBPACK_EXTERNAL_MODULE_clientnode_Lock__);_defineProperty(this,"_domNodesToFade",[]);_defineProperty(this,"_replacements",[]);_defineProperty(this,"_domNodesWithKnownTranslation",{});this.defineGetterAndSetterInterface()}/**
97
+ * Triggered when ever a given attribute has changed and triggers to update
98
+ * configured dom content.
99
+ * @param name - Attribute name which was updates.
100
+ * @param newValue - New updated value.
101
+ * @returns Returns when attribute has been updated.
102
+ */async onUpdateAttribute(name,newValue){await super.onUpdateAttribute(name,newValue);if(name==="options")this._extendOptions()}/**
103
+ * Updates controlled dom elements.
104
+ * @param reason - Why an update has been triggered.
105
+ * @param resolveRendering - Indicates whether rendering should be resolved
106
+ * finally. Should be set to "false" via super calls in inherited render
107
+ * methods which do further dom manipulations afterward and resolve the
108
+ * rendering process by their own.
109
+ * @returns A promise resolving when rendering has finished. A promise may
110
+ * be needed for classes inheriting from this class.
111
+ */async render(reason="unknown",resolveRendering=true){await super.render(reason,false);if(Object.keys(this.options).length===0)this._extendOptions();this.options.preReplacementLanguagePattern=__WEBPACK_EXTERNAL_MODULE_clientnode_format__(this.options.preReplacementLanguagePattern,this.options.replacementLanguagePattern.substring(1,this.options.replacementLanguagePattern.length-1));this.options.lockDescription=__WEBPACK_EXTERNAL_MODULE_clientnode_format__(this.options.lockDescription,this.self._name);this.options.sessionDescription=__WEBPACK_EXTERNAL_MODULE_clientnode_format__(this.options.sessionDescription,this.self._name);await this.waitForNestedComponentRendering();this.switchLanguageButtonDomNodes=this.hostDomNode.querySelectorAll(`a[href^="#${this.options.languageHashPrefix}"]`);this._movePreReplacementNodes();this.currentLanguage=this._normalizeLanguage(this.options.default);/*
112
+ NOTE: Only switch current language indicator if we haven't an
113
+ initial language switch which will perform the indicator switch.
114
+ */const newLanguage=this._determineUsefulLanguage();const determineSelection=this.options.selection.length===0;for(const domNode of this.switchLanguageButtonDomNodes){if(determineSelection)this.options.selection.push(domNode.getAttribute("href").substring(`#${this.options.languageHashPrefix}`.length));const handler=event=>{event.preventDefault();const url=event.target?.getAttribute("href");if(url)void this.switch(url.substring(this.options.languageHashPrefix.length+1))};this.addSecureEventListener(domNode,"click",handler)}if(this.currentLanguage===newLanguage)await this.refresh();else await this.switch(newLanguage,true);await this.resolveRenderingPromiseIfSet(reason,resolveRendering)}/// endregion
115
+ /**
116
+ * Switches the current language to a given language. This method is
117
+ * mutually synchronized.
118
+ * @param language - New language as string or "true". If set to "true" it
119
+ * indicates that the dom tree should be checked again current language to
120
+ * ensure every text node has the right content.
121
+ * @param ensure - Indicates if a switch effect should be avoided.
122
+ * @returns Returns the current instance wrapped in a promise.
123
+ */async switch(language,ensure=false){if(language!==true&&this.options.selection.length&&!this.options.selection.includes(language)){log.debug(`"${language}" isn't one of the allowed languages.`);return}await this.lock.acquire(this.options.lockDescription);if(language===true){ensure=true;language=this.currentLanguage}else language=this._normalizeLanguage(language);if(ensure||this.currentLanguage!==language){let actionDescription="Switch to";if(ensure)actionDescription="Ensure";log.debug(`${actionDescription} "${language}".`);this._switchCurrentLanguageIndicator(language);if(ensure)await this.onEnsure(language);else await this.onSwitch(this.currentLanguage,language);this._domNodesToFade=[];this._replacements=[];this._collectDomNodesToReplace(language,ensure);await this._handleSwitchEffect(language,ensure);return}log.debug(`"${language}" is already current selected language.`);void this.lock.release(this.options.lockDescription)}/**
124
+ * Ensures current selected language.
125
+ * @returns Promise resolving to nothing when switching as finished.
126
+ */refresh(){this._movePreReplacementNodes();return this.switch(true)}/// endregion
127
+ // region protected methods
128
+ /**
129
+ * Extends given options by default options.
130
+ */_extendOptions(){/*
131
+ NOTE: Using the internal setter avoids triggering an additional
132
+ rendering.
133
+ */this.setPropertyValue("options",__WEBPACK_EXTERNAL_MODULE_clientnode_extend__(true,{},this.self._defaultOptions,this.options))}/**
134
+ * Depending on activated switching effect this method initialized the
135
+ * effect of replace all text string directly.
136
+ * @param language - New language to use.
137
+ * @param ensure - Indicates if current language should be ensured again
138
+ * every text node content.
139
+ * @returns Returns the current instance wrapped in a promise.
140
+ */async _handleSwitchEffect(language,ensure){const oldLanguage=this.currentLanguage;if(!ensure&&this.options.useEffect&&this._domNodesToFade.length>0){await Promise.all(this._domNodesToFade.map(domNode=>{const handler=__WEBPACK_EXTERNAL_MODULE_clientnode_fadeOut__(domNode);return handler.then(()=>{handler.resetStyles()})}));this._switchLanguage(language);await Promise.all(this._domNodesToFade.map(domNode=>{const handler=__WEBPACK_EXTERNAL_MODULE_clientnode_fadeIn__(domNode);return handler.then(()=>{handler.resetStyles()})}));this.onSwitched(oldLanguage,language);void this.lock.release(this.options.lockDescription);return}this._switchLanguage(language);if(ensure)this.onEnsured(language);else this.onSwitched(oldLanguage,language);void this.lock.release(this.options.lockDescription)}/**
141
+ * Moves pre-replacement dom nodes into the next dom node behind the
142
+ * translation text to use the same translation algorithm for both.
143
+ */_movePreReplacementNodes(){for(const domNode of __WEBPACK_EXTERNAL_MODULE_clientnode_getAll__(this.hostDomNode)){const nodeName=domNode.nodeName.toLowerCase();if(this.options.replacementDomNodeNames.includes(nodeName)){if(!["#comment","#text"].includes(nodeName))// NOTE: Hide replacement dom nodes.
144
+ domNode.classList.add(this.options.selectors.hideClassName);const regularExpression=new RegExp(this.options.preReplacementLanguagePattern);const match=domNode.textContent?.match(regularExpression);if(domNode.textContent&&match&&match[0]){domNode.textContent=domNode.textContent.replace(regularExpression,match[1]);if(domNode.parentElement){let selfFound=false;for(const subDomNode of __WEBPACK_EXTERNAL_MODULE_clientnode_getAll__(domNode.parentElement)){if(selfFound&&__WEBPACK_EXTERNAL_MODULE_clientnode_getText__(subDomNode,true).length>0){subDomNode.appendChild(domNode);break}if(domNode===subDomNode)selfFound=true}}}}}}/**
145
+ * Collects all text nodes that should be replaced later.
146
+ * @param language - New language to use.
147
+ * @param ensure - Indicates if the whole dom should be checked again
148
+ * current language to ensure every text node has right content.
149
+ */_collectDomNodesToReplace(language,ensure){let currentDomNodeToTranslate=null;let currentLanguageDomNode=null;this.knownTranslations={};for(const domNode of __WEBPACK_EXTERNAL_MODULE_clientnode_getAll__(this.hostDomNode)){const nodeName=domNode.nodeName.toLowerCase();const nodeTextContent=__WEBPACK_EXTERNAL_MODULE_clientnode_getText__(domNode,true);// NOTE: We skip empty and nested nodes.
150
+ if(this._shouldSkipDomNode(domNode,nodeTextContent,currentDomNodeToTranslate))continue;if(this.options.replaceDomNodeNames.includes(nodeName))currentDomNodeToTranslate=domNode;else if(this.options.alternativeDomNodeNames.includes(nodeName)){if(!domNode.hasAttribute("lang"))this._initializeCurrentLanguageDomNode(domNode,ensure);else if(domNode.getAttribute("lang")===language)this._processAlternativeDomNode(domNode,language,ensure,currentLanguageDomNode)}else if(currentDomNodeToTranslate){if(this.options.replacementDomNodeNames.includes(nodeName)){;({domNodeToTranslate:currentDomNodeToTranslate,languageDomNode:currentLanguageDomNode}=this._processReplacementDomNode(domNode,nodeName,language,ensure,currentDomNodeToTranslate,currentLanguageDomNode));continue}currentDomNodeToTranslate=null;currentLanguageDomNode=null}}this._registerKnownTextNodes()}/**
151
+ * Determines whether a given dom node should be skipped during
152
+ * translation collection.
153
+ * @param domNode - The dom node to evaluate.
154
+ * @param nodeTextContent - Pre-computed text content of the node.
155
+ * @param currentDomNodeToTranslate - The currently tracked translation
156
+ * ancestor node.
157
+ * @returns Returns true if the node should be skipped.
158
+ */_shouldSkipDomNode(domNode,nodeTextContent,currentDomNodeToTranslate){return nodeTextContent.length===0&&(domNode.nodeType!==Node.COMMENT_NODE||(domNode.nodeValue||"").trim()==="")||Boolean(currentDomNodeToTranslate?.contains(domNode))||Boolean(__WEBPACK_EXTERNAL_MODULE_clientnode_closest__(domNode,this.options.replaceDomNodeNames.concat(this.options.replacementDomNodeNames).join(","),true))}/**
159
+ * Processes an alternative dom node by finding its active sibling,
160
+ * ensuring it has the necessary attributes and registering it for
161
+ * replacement.
162
+ * @param domNode - The alternative language dom node.
163
+ * @param language - New language to use.
164
+ * @param ensure - Indicates if current language should be ensured again
165
+ * every text node content.
166
+ * @param currentLanguageDomNode - The currently tracked language indicator
167
+ * node.
168
+ */_processAlternativeDomNode(domNode,language,ensure,currentLanguageDomNode){/*
169
+ When dealing with alternative dom nodes we do not rely on dom node
170
+ positions to keep them stable. Therefore, we identify the current
171
+ dom node to translate by going through all siblings.
172
+ */let activeSibling=null;for(const candidate of domNode.parentElement.querySelectorAll(this.options.alternativeDomNodeNames.join(",")))if(candidate.hasAttribute("active")||!candidate.hasAttribute("lang")){activeSibling=candidate;break}if(!activeSibling)return;this._initializeCurrentLanguageDomNode(activeSibling,ensure);this._registerTextNodeToChange(activeSibling,domNode,domNode.innerHTML,currentLanguageDomNode)}_initializeCurrentLanguageDomNode(domNode,ensure){if(!domNode.hasAttribute("active"))domNode.setAttribute("active","");if(!domNode.hasAttribute("lang"))domNode.setAttribute("lang",ensure?this.options.default||this.currentLanguage:this.currentLanguage)}/**
173
+ * Processes a replacement dom node like comment or lang-replacement
174
+ * element and updates translation state accordingly.
175
+ * @param domNode - The replacement dom node.
176
+ * @param nodeName - Lowercase node name of the replacement node.
177
+ * @param language - New language to use.
178
+ * @param ensure - Indicates if current language should be ensured again
179
+ * every text node content.
180
+ * @param currentDomNodeToTranslate - The currently tracked node whose
181
+ * content is to be replaced.
182
+ * @param currentLanguageDomNode - The currently tracked language indicator
183
+ * node.
184
+ * @returns Updated references for the tracked translation and language
185
+ * indicator nodes.
186
+ */_processReplacementDomNode(domNode,nodeName,language,ensure,currentDomNodeToTranslate,currentLanguageDomNode){const content=nodeName==="#comment"?domNode.textContent:domNode.innerHTML;const match=content.match(new RegExp(this.options.replacementLanguagePattern));if(Array.isArray(match)&&match[1]===language){// Save known text translations.
187
+ this.knownTranslations[__WEBPACK_EXTERNAL_MODULE_clientnode_getText__(currentDomNodeToTranslate,true).join(" ")]=match[2].trim();currentLanguageDomNode=this._ensureLastTextNodeHavingLanguageIndicator(currentDomNodeToTranslate,currentLanguageDomNode,ensure);this._registerTextNodeToChange(currentDomNodeToTranslate,domNode,match[2],currentLanguageDomNode);return{domNodeToTranslate:null,languageDomNode:null}}if(domNode.textContent.match(new RegExp(this.options.currentLanguagePattern)))currentLanguageDomNode=domNode;return{domNodeToTranslate:currentDomNodeToTranslate,languageDomNode:currentLanguageDomNode}}/**
188
+ * Iterates all text nodes in language known area with known translations.
189
+ */_registerKnownTextNodes(){this._domNodesWithKnownTranslation={};for(const domNode of this.hostDomNode.querySelectorAll(this.options.selectors.knownTranslation))for(const node of __WEBPACK_EXTERNAL_MODULE_clientnode_getAll__(domNode)){const content=__WEBPACK_EXTERNAL_MODULE_clientnode_getText__(node).join(" ");// NOTE: We skip empty and nested text nodes.
190
+ if(content&&!this.options.replaceDomNodeNames.includes(node.nodeName.toLowerCase())&&!__WEBPACK_EXTERNAL_MODULE_clientnode_closest__(node,this.options.replaceDomNodeNames.join(","),true)&&Object.prototype.hasOwnProperty.call(this.knownTranslations,content)){this._domNodesToFade.push(node.parentElement);if(Object.prototype.hasOwnProperty.call(this._domNodesWithKnownTranslation,this.knownTranslations[content]))this._domNodesWithKnownTranslation[this.knownTranslations[content]].push(node);else this._domNodesWithKnownTranslation[this.knownTranslations[content]]=[node]}}}/**
191
+ * Normalizes a given language string.
192
+ * @param language - New language to use.
193
+ * @returns Returns the normalized version of given language.
194
+ */_normalizeLanguage(language){for(const[otherLanguage,aliases]of Object.entries(this.options.languageMapping)){if(!aliases.includes(otherLanguage.toLowerCase()))aliases.push(otherLanguage.toLowerCase());if(aliases.includes(language.toLowerCase()))return otherLanguage}return this.options.default}/**
195
+ * Determines a useful initial language depending on session and browser
196
+ * settings.
197
+ * @returns Returns the determined language.
198
+ */_determineUsefulLanguage(){let result;if(this.options.initial)result=this.options.initial;else if(Object.prototype.hasOwnProperty.call(__WEBPACK_EXTERNAL_MODULE_clientnode_globalContext__,"window"))if(__WEBPACK_EXTERNAL_MODULE_clientnode_globalContext__.window?.localStorage.getItem(this.options.sessionDescription)){result=__WEBPACK_EXTERNAL_MODULE_clientnode_globalContext__.window.localStorage.getItem(this.options.sessionDescription);log.debug(`Determine "${result}", because of local storage`,"information.")}else if(__WEBPACK_EXTERNAL_MODULE_clientnode_globalContext__.window?.navigator.language){result=__WEBPACK_EXTERNAL_MODULE_clientnode_globalContext__.window.navigator.language;log.debug(`Determine "${result}", because of browser settings.`)}if(!result){result=this.options.default;log.debug(`Determine "${result}", because of default option.`)}result=this._normalizeLanguage(result);if(this.options.selection.length&&!this.options.selection.includes(result)){log.debug(`"${result}" isn't one of the allowed languages. Set`,`language to "${this.options.selection[0]}".`);result=this.options.selection[0]}if(__WEBPACK_EXTERNAL_MODULE_clientnode_globalContext__.window?.localStorage)__WEBPACK_EXTERNAL_MODULE_clientnode_globalContext__.window.localStorage.setItem(this.options.sessionDescription,result);return result}/**
199
+ * Registers a text node to change its content with a given replacement.
200
+ * @param domNodeToTranslate - Text node with content to
201
+ * translate.
202
+ * @param domNodeToReplaceWith - A node with replacement content.
203
+ * @param textToReplaceWith - Text content to use as replacement.
204
+ * @param currentLanguageDomNode - A potential given text node indicating
205
+ * the language of given text node.
206
+ */_registerTextNodeToChange(domNodeToTranslate,domNodeToReplaceWith,textToReplaceWith,currentLanguageDomNode){this._domNodesToFade.push(domNodeToTranslate.parentElement);if(domNodeToReplaceWith)this._replacements.push({domNodeToTranslate,domNodeToReplaceWith,textToReplaceWith,currentLanguageDomNode})}/**
207
+ * Checks if the last text node has a language indication comment node.
208
+ * This function is called after each parsed dom text node.
209
+ * @param lastTextNodeToTranslate - Last text node to check.
210
+ * @param lastLanguageDomNode - A potential given language indication
211
+ * commend node.
212
+ * @param ensure - Indicates if current language should be ensured again
213
+ * every text node content.
214
+ * @returns Returns the retrieved or newly created language indicating
215
+ * comment node.
216
+ */_ensureLastTextNodeHavingLanguageIndicator(lastTextNodeToTranslate,lastLanguageDomNode,ensure){if(lastTextNodeToTranslate&&!lastLanguageDomNode){/*
217
+ Last text node doesn't have a current language indicating dom
218
+ node.
219
+ */let currentLocalLanguage=this.currentLanguage;if(ensure)currentLocalLanguage=this.options.default||this.currentLanguage;lastLanguageDomNode=__WEBPACK_EXTERNAL_MODULE_clientnode_globalContext__.document?.createComment(currentLocalLanguage)||null;if(lastLanguageDomNode)lastTextNodeToTranslate.after(lastLanguageDomNode)}return lastLanguageDomNode}/**
220
+ * Performs the low-level text replacements for switching to a given
221
+ * language.
222
+ * @param language - The new language to switch to.
223
+ */_switchLanguage(language){for(const replacement of this._replacements){const currentText=this._getCurrentNodeText(replacement.domNodeToTranslate);const trimmedText=currentText.trim();if(!this.options.templateDelimiter||!trimmedText.endsWith(this.options.templateDelimiter.post)&&this.options.templateDelimiter.post){const currentLanguageDomNode=this._resolveCurrentLanguageDomNode(replacement);const currentLanguage=currentLanguageDomNode.textContent;if(currentLanguage&&language===currentLanguage)log.warn(`Text node "${replacement.textToReplaceWith}" is`,`marked as "${currentLanguage}" and has same`,"translation language as it already is.");// Move markup to be replaced next its parent node.
224
+ const nodeName=replacement.domNodeToReplaceWith.nodeName.toLowerCase();if(this.options.alternativeDomNodeNames.includes(nodeName)){;replacement.domNodeToReplaceWith.setAttribute("active","");replacement.domNodeToTranslate.removeAttribute("active");continue}const newNode=this._createBackupNode(nodeName,currentLanguage,currentText,replacement.domNodeToTranslate);replacement.domNodeToTranslate.after(newNode);replacement.domNodeToTranslate.after(__WEBPACK_EXTERNAL_MODULE_clientnode_globalContext__.document.createComment(language));this._applyTextReplacement(replacement);currentLanguageDomNode.remove();replacement.domNodeToReplaceWith.remove()}}this._updateKnownTextNodes();if(__WEBPACK_EXTERNAL_MODULE_clientnode_globalContext__.localStorage)__WEBPACK_EXTERNAL_MODULE_clientnode_globalContext__.localStorage.setItem(this.options.sessionDescription,language);this.currentLanguage=language}/**
225
+ * Returns the current text content of a dom node, preferring innerHTML
226
+ * over textContent when available.
227
+ * @param domNode - The dom node to read the text content from.
228
+ * @returns The current text content of the dom node.
229
+ */_getCurrentNodeText(domNode){return"innerHTML"in domNode?domNode.innerHTML:domNode.textContent}/**
230
+ * Resolves the current language dom node for a given replacement. If the
231
+ * node was not set initially it is determined by iterating through the
232
+ * siblings and cached on the replacement object.
233
+ * @param replacement - The replacement whose language dom node should be
234
+ * resolved.
235
+ * @returns The resolved language indicator dom node or null.
236
+ */_resolveCurrentLanguageDomNode(replacement){if(replacement.currentLanguageDomNode)return replacement.currentLanguageDomNode;/*
237
+ Language dom node wasn't present initially. So we have to
238
+ determine it now.
239
+ */let currentLanguageDomNode=document.body;let currentDomNodeFound=false;for(const domNode of __WEBPACK_EXTERNAL_MODULE_clientnode_getAll__(replacement.domNodeToTranslate.parentElement)){if(currentDomNodeFound){replacement.currentLanguageDomNode=currentLanguageDomNode=domNode;break}if(domNode===replacement.domNodeToTranslate)currentDomNodeFound=true}return currentLanguageDomNode}/**
240
+ * Creates a backup node for the current dom node content before the
241
+ * replacement is applied. Returns either a comment node or an element
242
+ * node depending on `nodeName`.
243
+ * @param nodeName - Lowercase node name of the replacement node.
244
+ * @param currentLanguage - Current language string used as prefix.
245
+ * @param currentText - Text content of the node to back up.
246
+ * @param domNodeToTranslate - The dom node whose children are moved into
247
+ * the backup element (for non-comment nodes).
248
+ * @returns The created backup node.
249
+ */_createBackupNode(nodeName,currentLanguage,currentText,domNodeToTranslate){if(nodeName==="#comment")return __WEBPACK_EXTERNAL_MODULE_clientnode_globalContext__.document.createComment(`${currentLanguage}:${currentText}`);const newNode=__WEBPACK_EXTERNAL_MODULE_clientnode_globalContext__.document.createElement(nodeName);newNode.appendChild(__WEBPACK_EXTERNAL_MODULE_clientnode_globalContext__.document.createTextNode(`${currentLanguage}:`));newNode.classList.add(this.options.selectors.hideClassName);// NOTE: We need to use "Array.from" to copy the list.
250
+ for(const childNode of Array.from(domNodeToTranslate.childNodes))newNode.appendChild(childNode);return newNode}/**
251
+ * Applies the actual text replacement to the target dom node. Moves
252
+ * child nodes from the replacement node or sets innerHTML/textContent
253
+ * directly depending on the node type.
254
+ * @param replacement - Replacement object containing source, target and
255
+ * replacement text information.
256
+ */_applyTextReplacement(replacement){if("innerHTML"in replacement.domNodeToTranslate){if(replacement.domNodeToReplaceWith.nodeName.toLowerCase()==="#comment")replacement.domNodeToTranslate.innerHTML=replacement.textToReplaceWith;else{let languageRemoved=false;// NOTE: We need to use "Array.from" to copy the list.
257
+ for(const childNode of Array.from(replacement.domNodeToReplaceWith.childNodes)){if(!languageRemoved){childNode.textContent=childNode.textContent.replace(/^[a-z]{2}[A-Z]{2}:/,"");languageRemoved=true}replacement.domNodeToTranslate.appendChild(childNode)}}}else replacement.domNodeToTranslate.textContent=replacement.textToReplaceWith}/**
258
+ * Updates all dom nodes that have a known translation to their translated
259
+ * text content.
260
+ */_updateKnownTextNodes(){for(const[content,domNodes]of Object.entries(this._domNodesWithKnownTranslation))for(const domNode of domNodes)domNode.textContent=content}/**
261
+ * Switches the current language indicator in language switch triggered dom
262
+ * nodes.
263
+ * @param language - The new language to switch to.
264
+ */_switchCurrentLanguageIndicator(language){for(const domNode of this.hostDomNode.querySelectorAll(`a[href="#${this.options.languageHashPrefix}`+`${this.currentLanguage}"].`+this.options.currentLanguageIndicatorClassName))domNode.classList.remove(this.options.currentLanguageIndicatorClassName);for(const domNode of this.hostDomNode.querySelectorAll(`a[href="#${this.options.languageHashPrefix}${language}"]`))domNode.classList.add(this.options.currentLanguageIndicatorClassName)}// endregion
265
+ },_defineProperty(_WebInternationalization,"_name","WebInternationalization"),_defineProperty(_WebInternationalization,"_defaultOptions",{currentLanguageIndicatorClassName:"current",currentLanguagePattern:"^[a-z]{2}[A-Z]{2}$",default:"enUS",useEffect:true,initial:null,languageHashPrefix:"lang-",languageMapping:{deDE:["de","de_de","de-de","german","deutsch"],enUS:["en","en_us","en-us"],enEN:["en_en","en-en","english"],frFR:["fr","fr_fr","fr-fr","french"]},lockDescription:"{1}Switch",preReplacementLanguagePattern:"^\\|({1})$",alternativeDomNodeNames:["lang-alternative"],replaceDomNodeNames:["#text","lang-replace"],replacementDomNodeNames:["#comment","lang-replacement"],replacementLanguagePattern:"^([a-z]{2}[A-Z]{2}):((.|\\s)*)$",selection:[],selectors:{knownTranslation:".web-internationalization-generated-content",hideClassName:"wi-hide"},sessionDescription:"{1}",templateDelimiter:{pre:"{{",post:"}}"}}),_WebInternationalization),_descriptor=_applyDecoratedDescriptor(_class.prototype,"options",[_dec],{configurable:true,enumerable:true,writable:true,initializer:function(){return{}}}),_descriptor2=_applyDecoratedDescriptor(_class.prototype,"onEnsure",[_dec2],{configurable:true,enumerable:true,writable:true,initializer:function(){return __WEBPACK_EXTERNAL_MODULE_clientnode_NOOP__}}),_descriptor3=_applyDecoratedDescriptor(_class.prototype,"onSwitch",[_dec3],{configurable:true,enumerable:true,writable:true,initializer:function(){return __WEBPACK_EXTERNAL_MODULE_clientnode_NOOP__}}),_descriptor4=_applyDecoratedDescriptor(_class.prototype,"onEnsured",[_dec4],{configurable:true,enumerable:true,writable:true,initializer:function(){return __WEBPACK_EXTERNAL_MODULE_clientnode_NOOP__}}),_descriptor5=_applyDecoratedDescriptor(_class.prototype,"onSwitched",[_dec5],{configurable:true,enumerable:true,writable:true,initializer:function(){return __WEBPACK_EXTERNAL_MODULE_clientnode_NOOP__}}),_class);// endregion
266
+ const api={component:WebInternationalization,register:(tagName=__WEBPACK_EXTERNAL_MODULE_clientnode_camelCaseToDelimited__(WebInternationalization._name))=>{customElements.define(tagName,WebInternationalization)}};/* harmony default export */ const index = (WebInternationalization);if(__WEBPACK_EXTERNAL_MODULE_clientnode_globalContext__.AUTO_DEFINE_WEB_INTERNATIONALIZATION)api.register();
267
+ export { WebInternationalization, api, index as default, log };
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.0.42",
2
+ "version": "2.0.44",
3
3
  "name": "web-internationalization",
4
4
  "description": "Expand your audience",
5
5
  "keywords": [
@@ -49,34 +49,34 @@
49
49
  "watch": "weboptimizer build --watch"
50
50
  },
51
51
  "devDependencies": {
52
- "@babel/eslint-parser": "^7.29.7",
53
- "@babel/plugin-transform-proto-to-assign": "^7.29.7",
54
- "@babel/runtime": "^7.29.7",
52
+ "@babel/eslint-parser": "^8.0.1",
53
+ "@babel/plugin-transform-proto-to-assign": "^8.0.1",
54
+ "@babel/runtime": "^8.0.0",
55
55
  "@eslint/js": "^10.0.1",
56
56
  "@stylistic/eslint-plugin": "^5.10.0",
57
57
  "@types/ejs": "^3.1.5",
58
58
  "@types/html-minifier": "^4.0.6",
59
59
  "@types/imagemin": "^9.0.1",
60
60
  "@types/jsdom": "^28.0.3",
61
- "@types/node": "^25.9.3",
61
+ "@types/node": "^26.1.1",
62
62
  "@types/webpack-env": "^1.18.8",
63
- "@typescript-eslint/eslint-plugin": "^8.61.0",
64
- "@typescript-eslint/parser": "^8.61.0",
63
+ "@typescript-eslint/eslint-plugin": "^8.65.0",
64
+ "@typescript-eslint/parser": "^8.65.0",
65
65
  "@webcomponents/webcomponentsjs": "^2.8.0",
66
- "clientnode": "^4.0.1423",
67
- "eslint": "^10.5.0",
66
+ "clientnode": "^4.0.1472",
67
+ "eslint": "^10.8.0",
68
68
  "eslint-config-google": "^0.14.0",
69
- "eslint-plugin-jsdoc": "^63.0.2",
69
+ "eslint-plugin-jsdoc": "^63.2.2",
70
70
  "favicons-webpack-plugin": "^6.0.1",
71
71
  "image-minimizer-webpack-plugin": "^5.0.0",
72
72
  "jest": "^30.4.2",
73
73
  "jsdoc": "^4.0.5",
74
74
  "prop-types": "^15.8.1",
75
- "typescript-eslint": "^8.61.0",
76
- "web-component-wrapper": "^0.0.602",
77
- "web-documentation": "^1.0.39",
78
- "weboptimizer": "^3.0.24",
79
- "webpack-dev-server": "^5.2.5"
75
+ "typescript-eslint": "^8.65.0",
76
+ "web-component-wrapper": "^0.0.606",
77
+ "web-documentation": "^1.0.42",
78
+ "weboptimizer": "^4.0.37",
79
+ "webpack-dev-server": "^6.0.0"
80
80
  },
81
81
  "peerDependencies": {
82
82
  "@babel/runtime": "*",
@@ -101,6 +101,7 @@
101
101
  "globals@npm:^9.18.0": "patch:globals@npm%3A11.12.0#~/.yarn/patches/globals-npm-11.12.0-1fa7f41a6c.patch"
102
102
  },
103
103
  "sideEffects": false,
104
+ "type": "module",
104
105
  "webDocumentation": {
105
106
  "languages": [
106
107
  "deDE",
@@ -134,10 +135,6 @@
134
135
  }
135
136
  },
136
137
  "optimizer": {
137
- "babelMinify": {
138
- "#": "Avoids TypeError: Cannot read properties of undefined (reading 'add')",
139
- "module": null
140
- },
141
138
  "htmlMinifier": {
142
139
  "ignoreCustomComments": [
143
140
  {
package/type.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { HTMLItem, Mapping } from 'clientnode';
1
+ import type { HTMLItem, Mapping } from 'clientnode';
2
2
  export interface Replacement {
3
3
  domNodeToTranslate: HTMLItem;
4
4
  domNodeToReplaceWith: HTMLItem;