New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@dbp-toolkit/language-select

Package Overview
Dependencies
Maintainers
3
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@dbp-toolkit/language-select - npm Package Compare versions

Comparing version

to
0.2.3

dist/shared/language-select.3e05fcd8.es.js

1

.eslintrc.json
{
"root": true,
"extends": "./../../eslint.common.json"
}

741

dist/dbp-language-select-demo.js

@@ -1,623 +0,153 @@

import { t as templateCaches$1, m as marker, T as Template, a as TemplateResult, A as AdapterLitElement, L as LanguageSelect, h as html, d as defineCustomElement } from './shared/language-select.baef0a1f.es.js';
import { a as Logger, S as ScopedElementsMixin, A as AdapterLitElement, L as LanguageSelect, h as html, d as defineCustomElement, c as createInstance, s as setOverrides } from './shared/language-select.3e05fcd8.es.js';
const appliedClassMixins = new WeakMap();
class Provider extends HTMLElement {
constructor() {
super();
this.callbackStore = [];
this.root = false;
/** Vefify if the Mixin was previously applyed
* @private
* @param {function} mixin Mixin being applyed
* @param {object} superClass Class receiving the new mixin
* @returns {boolean}
*/
function wasMixinPreviouslyApplied(mixin, superClass) {
let klass = superClass;
while (klass) {
if (appliedClassMixins.get(klass) === mixin) {
return true;
// Previously we used direct properties like this["lang"] (instead of this.properties["lang"]) for storing the
// properties, but the "lang" property seems to be updated before the event from the MutationObserver, so we
// cannot observe a value change directly (as workaround we use another property (e.g. "langValue") instead of "lang")
this.properties = {};
// We need to store our own "last values" because we cannot be sure what the MutationObserver detects
this.lastProperties = {};
Logger.debug('Provider constructor()');
}
klass = Object.getPrototypeOf(klass);
}
return false;
}
/** Apply each mixin in the chain to make sure they are not applied more than once to the final class.
* @export
* @param {function} mixin Mixin to be applyed
* @returns {object} Mixed class with mixin applied
*/
function dedupeMixin(mixin) {
return superClass => {
if (wasMixinPreviouslyApplied(mixin, superClass)) {
return superClass;
getProperty(name) {
return this.properties[name];
}
const mixedClass = mixin(superClass);
appliedClassMixins.set(mixedClass, mixin);
return mixedClass;
};
}
/**
* Cache class that allows to search in a cache hierarchy.
* @template T, Q
*/
class Cache {
/**
* Creates a Cache instance
* @param {Cache} [parent]
*/
constructor(parent) {
this._parent = parent;
this._cache = new Map();
}
/**
* Returns a boolean indicating whether an element with the specified key exists or not.
*
* @param {T} key - The key of the element to test for presence in the Cache object.
* @return {boolean}
*/
has(key) {
return !!(this._cache.has(key) || (this._parent && this._parent._cache.has(key)));
}
/**
* Adds or updates an element with a specified key and a value to a Cache object.
*
* @param {T} key - The key of the element to add to the Cache object.
* @param {Q} value - The value of the element to add to the Cache object.
* @return {Cache<T, Q>} the cache object
*/
set(key, value) {
this._cache.set(key, value);
return this;
}
/**
* Returns a specified element from a Map object. If the value that is associated to the provided key is an
* object, then you will get a reference to that object and any change made to that object will effectively modify
* it inside the Map object.
*
* @param {T} key - The key of the element to return from the Cache object.
* @return {Q}
*/
get(key) {
return this._cache.get(key) || (this._parent && this._parent._cache.get(key));
}
}
/**
* Global counter to scope the custom elements
*
* @type {number}
*/
let counter = Math.round(Math.random() * 100000);
/**
* Allowed tag name chars
*
* @type {string}
*/
const chars = `-|\\.|[0-9]|[a-z]`;
/**
* Regular expression to check if a value is a valid tag name
*
* @type {RegExp}
*/
const tagRegExp = new RegExp(`[a-z](${chars})*-(${chars})*`);
/**
* Checks if the tag name is valid
*
* @param {string} tag
* @returns {boolean}
*/
const isValid = tag => tagRegExp.exec(tag) !== null;
/**
* Checks if the tag is already registered
*
* @param {string} name
* @param {CustomElementRegistry} registry
* @returns {boolean}
*/
const isTagRegistered = (name, registry) => !!registry.get(name);
/**
* Given a tag name scopes it with a number suffix
*
* @param {string} tagName
* @param {CustomElementRegistry} registry
* @returns {string} scoped tag name
*/
const incrementTagName = (tagName, registry) => {
const newTagName = `${tagName}-${(counter += 1)}`;
if (isTagRegistered(newTagName, registry)) {
return incrementTagName(tagName, registry);
}
return newTagName;
};
/**
* Creates a unique scoped tag name
*
* @exports
* @param {string} tagName - tag name to scope
* @param {CustomElementRegistry} registry
* @returns {string} scoped tag name
*/
function createUniqueTag(tagName, registry = customElements) {
if (!isValid(tagName)) {
throw new Error('tagName is invalid');
}
return incrementTagName(tagName, registry);
}
/**
* The global cache for tag names
*
* @type {WeakMap<typeof HTMLElement, string>}
*/
const globalTagsCache = new WeakMap();
/**
* Adds a tag to the global tags cache
*
* @param {string} tag
* @param {typeof HTMLElement} klass
*/
const addToGlobalTagsCache = (tag, klass) => globalTagsCache.set(klass, tag);
/**
* Gets a tag from the global tags cache
*
* @exports
* @param {typeof HTMLElement} klass
* @returns {undefined|string}
*/
const getFromGlobalTagsCache = klass => globalTagsCache.get(klass);
/**
* Checks if klass is a subclass of HTMLElement
*
* @param {typeof HTMLElement} klass
* @returns {boolean}
*/
const extendsHTMLElement = klass => Object.prototype.isPrototypeOf.call(HTMLElement, klass);
/**
* Defines a custom element
*
* @param {string} tagName
* @param {typeof HTMLElement} klass
* @param {CustomElementRegistry} registry
*/
const defineElement = (tagName, klass, registry = customElements) => {
addToGlobalTagsCache(tagName, klass);
registry.define(tagName, class extends klass {});
};
/**
* Stores a lazy element in the cache to be used in future
*
* @param {string} tagName
* @param {CustomElementRegistry} registry
* @param {import('./Cache.js').Cache<string, string>} tagsCache
* @returns {string}
*/
const storeLazyElementInCache = (tagName, registry, tagsCache) => {
const tag = createUniqueTag(tagName, registry);
if (!tagsCache) {
throw new Error('Lazy scoped elements requires the use of tags cache');
}
tagsCache.set(tagName, tag);
return tag;
};
/**
* Define a scoped custom element storing the scoped tag name in the cache
*
* @param {string} tagName
* @param {typeof HTMLElement} klass
* @param {import('./Cache.js').Cache<string, string>} tagsCache
* @returns {string}
*/
const defineElementAndStoreInCache = (tagName, klass, tagsCache) => {
const registry = customElements;
if (!extendsHTMLElement(klass)) {
return storeLazyElementInCache(tagName, registry, tagsCache);
}
if (klass === customElements.get(tagName)) {
addToGlobalTagsCache(tagName, klass);
return tagName;
}
const tag = createUniqueTag(tagName, registry);
// @ts-ignore
// we extend it just in case the class has been defined manually
defineElement(tag, klass, registry);
return tag;
};
/**
* Gets a scoped tag name from the cache or generates a new one and defines the element if needed
*
* @exports
* @param {string} tagName
* @param {typeof HTMLElement} klass
* @param {import('./Cache.js').Cache<string, string>} tagsCache
* @returns {string}
*/
function registerElement(tagName, klass, tagsCache = undefined) {
const tag =
getFromGlobalTagsCache(klass) ||
(tagsCache && tagsCache.get(tagName)) ||
defineElementAndStoreInCache(tagName, klass, tagsCache);
return tag;
}
/**
* Defines a lazy element
*
* @param {string} tagName
* @param {typeof HTMLElement} klass
* @param {import('./Cache.js').Cache<string, string>} tagsCache
*/
function defineScopedElement(tagName, klass, tagsCache) {
const tag = tagsCache.get(tagName);
if (tag) {
if (customElements.get(tag) === undefined) {
defineElement(tag, klass, customElements);
setProperty(name, value) {
this.lastProperties[name] = value;
this.properties[name] = value;
}
} else {
tagsCache.set(tagName, registerElement(tagName, klass, tagsCache));
}
}
/**
* @typedef {import('./types').ScopedElementsMap} ScopedElementsMap
*/
/**
* Allowed tag name chars
*
* @type {string}
*/
const chars$1 = `-|\\.|[0-9]|[a-z]`;
/**
* Regular Expression to find a custom element tag
*
* @type {RegExp}
*/
const re = new RegExp(`<\\/?([a-z](${chars$1})*-(${chars$1})*)`, 'g');
/**
* The global cache of processed string arrays
*
* @type {Cache<TemplateStringsArray, TemplateStringsArray>}
*/
const globalCache = new Cache();
/**
* Find custom element tags in the string
*
* @param {string} str
* @returns {RegExpExecArray[]}
*/
const matchAll = str => {
const matches = [];
let result;
// eslint-disable-next-line no-cond-assign
while ((result = re.exec(str)) !== null) {
matches.push(result);
}
return matches;
};
/**
* Transforms a string array into another one with resolved scoped elements and caches it for future references
*
* @param {TemplateStringsArray} strings
* @param {ScopedElementsMap} scopedElements
* @param {Cache<TemplateStringsArray, TemplateStringsArray>} templateCache
* @param {Cache<string, string>} tagsCache
* @returns {TemplateStringsArray}
*/
const transformTemplate = (strings, scopedElements, templateCache, tagsCache) => {
const transformedStrings = strings.map(str => {
let acc = str;
const matches = matchAll(str);
for (let i = matches.length - 1; i >= 0; i -= 1) {
const item = matches[i];
const [block, tagName] = item;
const tag = registerElement(tagName, scopedElements[tagName], tagsCache);
const start = item.index + block.length - tagName.length;
const end = start + tagName.length;
const isClosingTag = block.indexOf('</') === 0;
acc =
acc.slice(0, start) +
(isClosingTag ? tag : `${tag} data-tag-name="${tagName}"`) +
acc.slice(end);
hasPropertyChanged(name, value) {
return this.lastProperties[name] !== value;
}
return acc;
});
// @ts-ignore
// noinspection JSCheckFunctionSignatures
templateCache.set(strings, transformedStrings);
// @ts-ignore
// noinspection JSValidateTypes
return transformedStrings;
};
/**
* Obtains the cached strings array with resolved scoped elements or creates it
*
* @exports
* @param {TemplateStringsArray} strings
* @param {ScopedElementsMap} scopedElements
* @param {import('./Cache.js').Cache<TemplateStringsArray, TemplateStringsArray>} templateCache
* @param {import('./Cache.js').Cache<string, string>} tagsCache
* @returns {TemplateStringsArray}
*/
function transform(strings, scopedElements, templateCache = globalCache, tagsCache) {
return (
templateCache.get(strings) ||
transformTemplate(strings, scopedElements, templateCache, tagsCache)
);
}
const getTemplateCacheKey = (type, scopeName) => `${type}--${scopeName}`;
let compatibleShadyCSSVersion = true;
// @ts-ignore
const { ShadyCSS } = window;
if (typeof ShadyCSS === 'undefined') {
compatibleShadyCSSVersion = false;
} else if (typeof ShadyCSS.prepareTemplateDom === 'undefined') {
compatibleShadyCSSVersion = false;
}
/**
* Template factory which scopes template DOM using ShadyCSS.
* @param scopeName {string}
*/
const shadyTemplateFactory = scopeName => result => {
const cacheKey = getTemplateCacheKey(result.type, scopeName);
let templateCache = templateCaches$1.get(cacheKey);
if (templateCache === undefined) {
templateCache = {
stringsArray: new WeakMap(),
keyString: new Map(),
};
templateCaches$1.set(cacheKey, templateCache);
}
let template = templateCache.stringsArray.get(result.strings);
if (template !== undefined) {
return template;
}
const key = result.strings.join(marker);
template = templateCache.keyString.get(key);
if (template === undefined) {
const element = result.getTemplateElement();
if (compatibleShadyCSSVersion) {
ShadyCSS.prepareTemplateDom(element, scopeName);
hasProperty(name) {
return Object.hasOwnProperty.call(this.properties, name);
}
template = new Template(result, element);
templateCache.keyString.set(key, template);
}
templateCache.stringsArray.set(result.strings, template);
return template;
};
/* eslint-disable no-use-before-define */
connectedCallback() {
Logger.debug('Provider(' + this.id + ') connectedCallback()');
/**
* @typedef {import('./types').ScopedElementsMixin} ScopedElementsMixin
* @typedef {import('./types').ScopedElementsMap} ScopedElementsMap
* @typedef {import("lit-element").LitElement} LitElement
* @typedef {import('lit-html/lib/shady-render').ShadyRenderOptions} ShadyRenderOptions
* @typedef {function(TemplateResult, Element|DocumentFragment|ShadowRoot, ShadyRenderOptions): void} RenderFunction
*/
const that = this;
/**
* Template caches
*
* @type {WeakMap<Function, Cache<TemplateStringsArray, TemplateStringsArray>>}
*/
const templateCaches = new WeakMap();
this.addEventListener('dbp-subscribe', function (e) {
const name = e.detail.name;
if (that.hasProperty(name) || that.root) {
Logger.debug('Provider(' + that.id + ') eventListener("dbp-subscribe",..) name "' + name + '" found.');
that.callbackStore.push({name: name, callback: e.detail.callback, sender: e.detail.sender});
/**
* Retrieves or creates a templateCache for a specific key
*
* @param {Function} key
* @returns {Cache<TemplateStringsArray, TemplateStringsArray>}
*/
const getTemplateCache = key => {
if (!templateCaches.has(key)) {
// @ts-ignore
templateCaches.set(key, new Cache(templateCaches.get(key.constructor)));
}
e.detail.callback(that.getProperty(name));
e.stopPropagation();
}
}, false);
return templateCaches.get(key);
};
this.addEventListener('dbp-unsubscribe', function (e) {
const name = e.detail.name;
const sender = e.detail.sender;
if (that.hasProperty(name) || that.root) {
Logger.debug('Provider(' + that.id + ') eventListener("dbp-unsubscribe",..) name "' + name + '" found.');
that.callbackStore.forEach(item => {
if (item.sender === sender && item.name === name) {
const index = that.callbackStore.indexOf(item);
that.callbackStore.splice(index, 1);
Logger.debug('Provider(' + that.id + ') eventListener for name "' + name + '" removed.');
}
});
/**
* Tags caches
*
* @type {WeakMap<object, Cache<string, string>>}
*/
const tagsCaches = new WeakMap();
e.stopPropagation();
}
}, false);
/**
* Retrieves or creates a tagsCache for a specific key
* @param {object} key
* @returns {Cache<string, string>}
*/
const getTagsCache = key => {
if (!tagsCaches.has(key)) {
tagsCaches.set(key, new Cache(tagsCaches.get(key.constructor)));
}
// listen to property changes
this.addEventListener('dbp-set-property', function (e) {
const name = e.detail.name;
const value = e.detail.value;
return tagsCaches.get(key);
};
if (that.hasProperty(name) || that.root) {
Logger.debug('Provider(' + that.id + ') eventListener("dbp-set-property",..) name "' + name + '" found.');
that.setProperty(name, value);
/**
* Transforms an array of TemplateResults or arrays into another one with resolved scoped elements
*
* @param {ReadonlyArray} items
* @param {ScopedElementsMap} scopedElements
* @param {Cache<TemplateStringsArray, TemplateStringsArray>} templateCache
* @param {Cache<string, string>} tagsCache
* @returns {ReadonlyArray}
*/
const transformArray = (items, scopedElements, templateCache, tagsCache) =>
items.map(value => {
if (value instanceof TemplateResult) {
return transformTemplate$1(value, scopedElements, templateCache, tagsCache);
}
that.callbackStore.forEach(item => {
if (item.name === name) {
item.callback(value);
}
});
if (Array.isArray(value)) {
return transformArray(value, scopedElements, templateCache, tagsCache);
}
e.stopPropagation();
}
}, false);
return value;
});
// Options for the observer (which mutations to observe)
const config = { attributes: true, childList: false, subtree: false };
/**
* Transforms a TemplateResult into another one with resolved scoped elements
*
* @param {TemplateResult} template
* @param {ScopedElementsMap} scopedElements
* @param {Cache<TemplateStringsArray, TemplateStringsArray>} templateCache
* @param {Cache<string, string>} tagsCache
* @returns {TemplateResult}
*/
const transformTemplate$1 = (template, scopedElements, templateCache, tagsCache) =>
new TemplateResult(
transform(template.strings, scopedElements, templateCache, tagsCache),
transformArray(template.values, scopedElements, templateCache, tagsCache),
template.type,
template.processor,
);
// Callback function to execute when mutations are observed
const callback = function(mutationsList, observer) {
// Use traditional 'for loops' for IE 11
for(const mutation of mutationsList) {
if (mutation.type === 'attributes') {
const name = mutation.attributeName;
const value = that.getAttribute(name);
/**
* Gets an instance of the ScopedElementsTemplateFactory
*
* @param {string} scopeName
* @param {ScopedElementsMap} scopedElements
* @param {Cache<TemplateStringsArray, TemplateStringsArray>} templateCache
* @param {Cache<string, string>} tagsCache
* @returns {function(any): any}
*/
const scopedElementsTemplateFactory = (
scopeName,
scopedElements,
templateCache,
tagsCache,
) => template => {
const newTemplate = transformTemplate$1(template, scopedElements, templateCache, tagsCache);
if (that.hasPropertyChanged(name, value)) {
Logger.debug('Provider (' + that.id + ') observed attribute "' + name + '" changed');
that.setProperty(name, value);
return shadyTemplateFactory(scopeName)(newTemplate);
};
that.callbackStore.forEach(item => {
if (item.name === name) {
item.callback(value);
}
});
}
}
}
};
/** @type {ScopedElementsMixin} */
const ScopedElementsMixinImplementation = superclass =>
class ScopedElementsHost extends superclass {
/**
* Obtains the scoped elements definitions map
*
* @returns {ScopedElementsMap}
*/
static get scopedElements() {
return {};
}
// Create an observer instance linked to the callback function
const observer = new MutationObserver(callback);
/** @override */
static render(template, container, options) {
if (!options || typeof options !== 'object' || !options.scopeName) {
throw new Error('The `scopeName` option is required.');
}
const { scopeName, eventContext } = options;
// Start observing the target node for configured mutations
observer.observe(this, config);
const templateCache = getTemplateCache(eventContext);
const tagsCache = getTagsCache(eventContext);
const { scopedElements } = this;
// get all *not observed* attributes
if (this.hasAttributes()) {
const attrs = this.attributes;
for(let i = attrs.length - 1; i >= 0; i--) {
if (['id', 'class', 'style', 'data-tag-name'].includes(attrs[i].name)) {
continue;
}
return super.render(template, container, {
...options,
templateFactory: scopedElementsTemplateFactory(
scopeName,
scopedElements,
templateCache,
tagsCache,
),
});
this.setProperty(attrs[i].name, attrs[i].value);
Logger.debug('Provider (' + that.id + ') found attribute "' + attrs[i].name + '" = "' + attrs[i].value + '"');
}
}
}
/**
* Defines a scoped element
*
* @param {string} tagName
* @param {typeof HTMLElement} klass
*/
defineScopedElement(tagName, klass) {
return defineScopedElement(tagName, klass, getTagsCache(this));
get id() {
return this.getAttribute('id');
}
}
/**
* Returns a scoped tag name
*
* @deprecated Please, use the instance method instead of the static one. This static method is not able to
* obtain the tagName of lazy defined elements, while the instance one is.
* @param {string} tagName
* @returns {string|undefined}
*/
static getScopedTagName(tagName) {
// @ts-ignore
const klass = this.scopedElements[tagName];
return klass
? registerElement(tagName, klass, getTagsCache(this))
: getTagsCache(this).get(tagName);
// This is an example on how to override translations at runtime
let OVERRIDES = {
'de': {
'translation': {
'demo': 'Überschrieben'
}
},
'en': {
'translation': {
'demo': 'Overridden'
}
}
};
/**
* Returns a scoped tag name
*
* @param {string} tagName
* @returns {string|undefined}
*/
getScopedTagName(tagName) {
// @ts-ignore
const klass = this.constructor.scopedElements[tagName];
return klass
? registerElement(tagName, klass, getTagsCache(this))
: getTagsCache(this).get(tagName);
}
};
const ScopedElementsMixin = dedupeMixin(ScopedElementsMixinImplementation);
class LanguageSelectDisplay extends AdapterLitElement {

@@ -628,2 +158,4 @@

this.lang = 'de';
this._i18n = createInstance();
setOverrides(this._i18n, OVERRIDES);
}

@@ -637,4 +169,14 @@

update(changedProperties) {
changedProperties.forEach((oldValue, propName) => {
switch (propName) {
case 'lang':
this._i18n.changeLanguage(this.lang);
}
});
super.update(changedProperties);
}
render() {
return html`${this.lang}`;
return html`<b>${this.lang}: ${this._i18n.t('demo')}</b>`;
}

@@ -653,2 +195,3 @@ }

'dbp-language-select-display': LanguageSelectDisplay,
'dbp-provider': Provider,
};

@@ -659,12 +202,14 @@ }

return html`
Select 1: <dbp-language-select subscribe="lang"></dbp-language-select>
<br>
<br>
Select 2: <dbp-language-select subscribe="lang"></dbp-language-select>
<br>
<br>
Current language 1: <dbp-language-select-display subscribe="lang"></dbp-language-select-display>
<br>
<br>
Current language 2: <dbp-language-select-display subscribe="lang"></dbp-language-select-display>
<dbp-provider lang="">
Select 1: <dbp-language-select subscribe="lang"></dbp-language-select>
<br>
<br>
Select 2: <dbp-language-select subscribe="lang"></dbp-language-select>
<br>
<br>
Current language 1: <dbp-language-select-display subscribe="lang"></dbp-language-select-display>
<br>
<br>
Current language 2: <dbp-language-select-display subscribe="lang"></dbp-language-select-display>
</dbp-provider>
`;

@@ -671,0 +216,0 @@ }

@@ -1,4 +0,4 @@

import { d as defineCustomElement, L as LanguageSelect } from './shared/language-select.baef0a1f.es.js';
import { d as defineCustomElement, L as LanguageSelect } from './shared/language-select.3e05fcd8.es.js';
defineCustomElement('dbp-language-select', LanguageSelect);
//# sourceMappingURL=dbp-language-select.js.map

@@ -9,2 +9,3 @@ module.exports = {

removeUnusedKeys: true,
func: {list: ['i18n.t', '_i18n.t']},
lngs: ['en','de'],

@@ -11,0 +12,0 @@ resource: {

{
"name": "@dbp-toolkit/language-select",
"homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/language-select",
"version": "0.2.2",
"version": "0.2.3",
"main": "src/index.js",

@@ -17,8 +17,8 @@ "license": "LGPL-2.1-or-later",

"devDependencies": {
"@rollup/plugin-commonjs": "^17.0.0",
"@esm-bundle/chai": "^4.2.0",
"@rollup/plugin-commonjs": "^19.0.0",
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-node-resolve": "^11.0.0",
"chai": "^4.2.0",
"@rollup/plugin-node-resolve": "^13.0.0",
"eslint": "^7.3.1",
"eslint-plugin-jsdoc": "^31.0.0",
"eslint-plugin-jsdoc": "^35.0.0",
"i18next-scanner": "^3.0.0",

@@ -29,3 +29,3 @@ "karma": "^6.0.0",

"karma-mocha": "^2.0.1",
"mocha": "^8.0.1",
"mocha": "^9.0.0",
"rollup": "^2.33.3",

@@ -39,3 +39,3 @@ "rollup-plugin-copy": "^3.1.0",

"@dbp-toolkit/common": "^0.2.2",
"@open-wc/scoped-elements": "^1.3.2",
"@open-wc/scoped-elements": "^1.3.3",
"lit-element": "^2.4.0"

@@ -58,3 +58,3 @@ },

},
"gitHead": "b599340edfeb6cf3ea26ef418a4e281146abe884"
"gitHead": "cfe0f21eb1ffb5a4ad95a096bd6995fdffc86bfe"
}

@@ -16,2 +16,9 @@ # Language Select Web Component

Or directly via CDN:
```html
<dbp-language-select></dbp-language-select>
<script type="module" src="https://unpkg.com/@dbp-toolkit/language-select@0.2.2/dist/dbp-language-select.js"></script>
```
## Attributes

@@ -18,0 +25,0 @@

@@ -22,9 +22,2 @@ import glob from 'glob';

},
onwarn: function (warning, warn) {
// ignore chai warnings
if (warning.code === 'CIRCULAR_DEPENDENCY') {
return;
}
warn(warning);
},
plugins: [

@@ -31,0 +24,0 @@ del({

@@ -6,3 +6,18 @@ import {html} from 'lit-element';

import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element";
import {Provider} from "@dbp-toolkit/provider";
import {createInstance, setOverrides} from './i18n.js';
// This is an example on how to override translations at runtime
let OVERRIDES = {
'de': {
'translation': {
'demo': 'Überschrieben'
}
},
'en': {
'translation': {
'demo': 'Overridden'
}
}
};

@@ -14,2 +29,4 @@ class LanguageSelectDisplay extends AdapterLitElement {

this.lang = 'de';
this._i18n = createInstance();
setOverrides(this._i18n, OVERRIDES);
}

@@ -23,4 +40,14 @@

update(changedProperties) {
changedProperties.forEach((oldValue, propName) => {
switch (propName) {
case 'lang':
this._i18n.changeLanguage(this.lang);
}
});
super.update(changedProperties);
}
render() {
return html`${this.lang}`;
return html`<b>${this.lang}: ${this._i18n.t('demo')}</b>`;
}

@@ -39,2 +66,3 @@ }

'dbp-language-select-display': LanguageSelectDisplay,
'dbp-provider': Provider,
};

@@ -45,12 +73,14 @@ }

return html`
Select 1: <dbp-language-select subscribe="lang"></dbp-language-select>
<br>
<br>
Select 2: <dbp-language-select subscribe="lang"></dbp-language-select>
<br>
<br>
Current language 1: <dbp-language-select-display subscribe="lang"></dbp-language-select-display>
<br>
<br>
Current language 2: <dbp-language-select-display subscribe="lang"></dbp-language-select-display>
<dbp-provider lang="">
Select 1: <dbp-language-select subscribe="lang"></dbp-language-select>
<br>
<br>
Select 2: <dbp-language-select subscribe="lang"></dbp-language-select>
<br>
<br>
Current language 1: <dbp-language-select-display subscribe="lang"></dbp-language-select-display>
<br>
<br>
Current language 2: <dbp-language-select-display subscribe="lang"></dbp-language-select-display>
</dbp-provider>
`;

@@ -57,0 +87,0 @@ }

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

import {createInstance} from '@dbp-toolkit/common/i18next.js';
import {createInstance as _createInstance, setOverrides} from '@dbp-toolkit/common/i18next.js';

@@ -6,2 +6,6 @@ import de from './i18n/de/translation.json';

export const i18n = createInstance({en: en, de: de}, 'de', 'en');
export function createInstance() {
return _createInstance({en: en, de: de}, 'de', 'en');
}
export {setOverrides};

@@ -5,3 +5,4 @@ {

"de-action": "Auf Deutsch anzeigen",
"en-action": "Auf Englisch anzeigen"
"en-action": "Auf Englisch anzeigen",
"demo": "Hallo Welt"
}

@@ -5,3 +5,4 @@ {

"de-action": "Switch to German",
"en-action": "Switch to English"
"en-action": "Switch to English",
"demo": "Hello World"
}
import {html, css} from 'lit-element';
import {i18n} from './i18n.js';
import {createInstance} from './i18n.js';
import * as commonStyles from '@dbp-toolkit/common/styles';
import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element";
/**

@@ -16,7 +17,8 @@ * Emits a dbp-language-changed event where event.detail.lang is the new selected language

this._i18n = createInstance();
// for the i18next scanner
i18n.t('de');
i18n.t('de-action');
i18n.t('en');
i18n.t('en-action');
this._i18n.t('de');
this._i18n.t('de-action');
this._i18n.t('en');
this._i18n.t('en-action');
}

@@ -62,3 +64,3 @@

// In case of more than two this doesn't make that much sense, but for now..
i18n.changeLanguage(this.next);
this._i18n.changeLanguage(this.next);
}

@@ -111,3 +113,3 @@ }

render() {
var linkTitle = i18n.t(this.next + '-action');
var linkTitle = this._i18n.t(this.next + '-action');
return html`

@@ -114,0 +116,0 @@ <a href="#" title="${linkTitle}" @click=${this.onClick}>${this.next.toUpperCase()}</a>

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

import {assert, expect} from 'chai';
import {assert, expect} from '@esm-bundle/chai';

@@ -3,0 +3,0 @@ import '../src/dbp-language-select.js';

Sorry, the diff of this file is not supported yet