@magic-translate/js 1.0.0 → 1.0.2
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.
- package/README.md +21 -14
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/magic-translate.min.js +1 -1
- package/dist/magic-translate.min.js.map +1 -1
- package/package.json +29 -27
package/README.md
CHANGED
|
@@ -8,6 +8,11 @@ the text on your page, and Magic Translate translates it on the fly. Works on
|
|
|
8
8
|
any website: plain HTML, server-rendered pages, WordPress, or apps built with
|
|
9
9
|
any framework.
|
|
10
10
|
|
|
11
|
+
No translation keys and no language files: the text stays in your HTML, and
|
|
12
|
+
adding a language is one line.
|
|
13
|
+
|
|
14
|
+
Full docs: [magictranslate.io/docs/javascript](https://magictranslate.io/docs/javascript)
|
|
15
|
+
|
|
11
16
|
## Setup with a script tag
|
|
12
17
|
|
|
13
18
|
Add one script tag to your page. You can get an API key for free at
|
|
@@ -26,19 +31,21 @@ Then wrap the text to translate in `<t>`:
|
|
|
26
31
|
|
|
27
32
|
```html
|
|
28
33
|
<h1><t>Welcome to our shop</t></h1>
|
|
29
|
-
<p
|
|
34
|
+
<p>
|
|
35
|
+
<t>Click <a href="/sale">here</a> to see <b>today's</b> deals.</t>
|
|
36
|
+
</p>
|
|
30
37
|
```
|
|
31
38
|
|
|
32
39
|
Leave out `data-language` to translate to the visitor's browser language. The
|
|
33
40
|
script tag accepts:
|
|
34
41
|
|
|
35
|
-
| Attribute | Description
|
|
36
|
-
| ---------------------- |
|
|
37
|
-
| `data-api-key` | Required. Your Magic Translate API key.
|
|
38
|
-
| `data-language` | The language content is translated to, e.g. `de`. Defaults to the browser's language.
|
|
42
|
+
| Attribute | Description |
|
|
43
|
+
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
|
|
44
|
+
| `data-api-key` | Required. Your Magic Translate API key. |
|
|
45
|
+
| `data-language` | The language content is translated to, e.g. `de`. Defaults to the browser's language. |
|
|
39
46
|
| `data-source-language` | The language your page is written in. Detected automatically by default; only set it if automatic detection gives wrong results. |
|
|
40
|
-
| `data-formality` | `formal` or `informal`. Not supported for all languages.
|
|
41
|
-
| `data-debug` | Logs requests to the console.
|
|
47
|
+
| `data-formality` | `formal` or `informal`. Not supported for all languages. |
|
|
48
|
+
| `data-debug` | Logs requests to the console. |
|
|
42
49
|
|
|
43
50
|
The script makes the running instance available as `window.magicTranslate`.
|
|
44
51
|
|
|
@@ -144,14 +151,14 @@ document.addEventListener('magictranslate:ready', (event) => {
|
|
|
144
151
|
|
|
145
152
|
`createMagicTranslate` accepts:
|
|
146
153
|
|
|
147
|
-
| Option | Description
|
|
148
|
-
| ---------------- |
|
|
149
|
-
| `apiKey` | Required. Your Magic Translate API key.
|
|
150
|
-
| `language` | The language content is translated to, e.g. `'de'`. Defaults to the browser's language.
|
|
154
|
+
| Option | Description |
|
|
155
|
+
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------- |
|
|
156
|
+
| `apiKey` | Required. Your Magic Translate API key. |
|
|
157
|
+
| `language` | The language content is translated to, e.g. `'de'`. Defaults to the browser's language. |
|
|
151
158
|
| `sourceLanguage` | The language your page is written in. Detected automatically by default; only set it if automatic detection gives wrong results. |
|
|
152
|
-
| `formality` | `'formal'` or `'informal'`. Not supported for all languages. Can be overridden per element.
|
|
153
|
-
| `root` | The element whose content is translated. Defaults to the whole document.
|
|
154
|
-
| `debug` | Logs requests to the console.
|
|
159
|
+
| `formality` | `'formal'` or `'informal'`. Not supported for all languages. Can be overridden per element. |
|
|
160
|
+
| `root` | The element whose content is translated. Defaults to the whole document. |
|
|
161
|
+
| `debug` | Logs requests to the console. |
|
|
155
162
|
|
|
156
163
|
Call `destroy()` to stop translating the page.
|
|
157
164
|
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@magic-translate/core");var t=`t, mt-translate, [data-t]`,n=`[data-t-attrs]`;function r(e){let n=e;for(let e=n.parentElement?.closest(t);e;e=n.parentElement?.closest(t))n=e;return n}function i(e){let t={},n=e.getAttribute(`data-lang`),r=e.getAttribute(`data-formality`);return n&&(t.lang=n),r&&(t.formality=r),t}var a=class{constructor(t){if(this.options=t,this.contents=new Map,this.attributes=new Map,this.listeners=new Set,!t.apiKey)throw Error(`Missing API key. Please get one at ${e.libraryWebsite}`);this.currentLanguage=t.language??(0,e.utsLocaleToLanguage)(typeof navigator>`u`?void 0:navigator.language),this.dataLoader=this.createDataLoader(),typeof document<`u`&&(this.root=t.root??document.documentElement,this.start(this.root))}get language(){return this.currentLanguage}setLanguage(e){e!==this.currentLanguage&&(this.currentLanguage=e,this.dataLoader=this.createDataLoader(),this.forget(e=>!e.isConnected||!this.root?.contains(e)),this.contents.forEach((e,t)=>this.translateContent(t,!0)),this.attributes.forEach((e,t)=>this.translateAttributes(t,!0)),this.listeners.forEach(t=>t(e)))}onLanguageChange(e){return this.listeners.add(e),()=>this.listeners.delete(e)}translate(e,t={}){return this.dataLoader.load({text:e,...t})}destroy(){this.observer?.disconnect(),this.contents.clear(),this.attributes.clear(),this.listeners.clear()}createDataLoader(){let{debug:t,apiKey:n,sourceLanguage:r,_apiUrl:i,formality:a}=this.options,o=this.options._loaderFactory??e.defaultLoaderFactory;return new e.DataLoader(o({debug:!!t,apiKey:n,lang:this.currentLanguage,sourceLang:r,apiUrl:i,formality:a}),{cacheKeyFn:(0,e.cacheKeyFn)(n,r,this.currentLanguage)})}start(e){let t=new Set,n=new Set;this.collect(e,t,n),t.forEach(e=>this.translateContent(e)),n.forEach(e=>this.translateAttributes(e)),this.observer=new MutationObserver(e=>this.handleMutations(e)),this.observer.observe(e,{subtree:!0,childList:!0,characterData:!0,attributes:!0})}collect(e,t,n){let i=[e,...Array.from(e.querySelectorAll(`*`))];for(let e of i)e.matches(`t, mt-translate, [data-t]`)?t.add(r(e)):e.matches(`[data-t-attrs]`)&&!e.closest(`t, mt-translate, [data-t]`)&&n.add(e)}handleMutations(e){let n=new Set,i=new Set;for(let a of e){let e=a.target.nodeType===Node.ELEMENT_NODE?a.target:a.target.parentElement;if(!e)continue;let o=e.closest(t);o?n.add(r(o)):(a.type===`attributes`&&e.matches(`[data-t-attrs]`)&&i.add(e),a.addedNodes.forEach(e=>{e.nodeType===Node.ELEMENT_NODE&&this.collect(e,n,i)}))}e.some(e=>e.removedNodes.length>0)&&this.forget(e=>!e.isConnected),n.forEach(e=>this.translateContent(e)),i.forEach(e=>this.translateAttributes(e))}forget(e){for(let t of
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@magic-translate/core");var t=`t, mt-translate, [data-t]`,n=`[data-t-attrs]`;function r(e){let n=e;for(let e=n.parentElement?.closest(t);e;e=n.parentElement?.closest(t))n=e;return n}function i(e){let t={},n=e.getAttribute(`data-lang`),r=e.getAttribute(`data-formality`);return n&&(t.lang=n),r&&(t.formality=r),t}var a=class{constructor(t){if(this.options=t,this.contents=new Map,this.attributes=new Map,this.listeners=new Set,!t.apiKey)throw Error(`Missing API key. Please get one at ${e.libraryWebsite}`);this.currentLanguage=t.language??(0,e.utsLocaleToLanguage)(typeof navigator>`u`?void 0:navigator.language),this.dataLoader=this.createDataLoader(),typeof document<`u`&&(this.root=t.root??document.documentElement,this.start(this.root))}get language(){return this.currentLanguage}setLanguage(e){e!==this.currentLanguage&&(this.currentLanguage=e,this.dataLoader=this.createDataLoader(),this.forget(e=>!e.isConnected||!this.root?.contains(e)),this.contents.forEach((e,t)=>this.translateContent(t,!0)),this.attributes.forEach((e,t)=>this.translateAttributes(t,!0)),this.listeners.forEach(t=>t(e)))}onLanguageChange(e){return this.listeners.add(e),()=>this.listeners.delete(e)}translate(e,t={}){return this.dataLoader.load({text:e,...t})}destroy(){this.observer?.disconnect(),this.contents.clear(),this.attributes.clear(),this.listeners.clear()}createDataLoader(){let{debug:t,apiKey:n,sourceLanguage:r,_apiUrl:i,formality:a}=this.options,o=this.options._loaderFactory??e.defaultLoaderFactory;return new e.DataLoader(o({debug:!!t,apiKey:n,lang:this.currentLanguage,sourceLang:r,apiUrl:i,formality:a}),{cacheKeyFn:(0,e.cacheKeyFn)(n,r,this.currentLanguage)})}start(e){let t=new Set,n=new Set;this.collect(e,t,n),t.forEach(e=>this.translateContent(e)),n.forEach(e=>this.translateAttributes(e)),this.observer=new MutationObserver(e=>this.handleMutations(e)),this.observer.observe(e,{subtree:!0,childList:!0,characterData:!0,attributes:!0})}collect(e,t,n){let i=[e,...Array.from(e.querySelectorAll(`*`))];for(let e of i)e.matches(`t, mt-translate, [data-t]`)?t.add(r(e)):e.matches(`[data-t-attrs]`)&&!e.closest(`t, mt-translate, [data-t]`)&&n.add(e)}handleMutations(e){let n=new Set,i=new Set;for(let a of e){let e=a.target.nodeType===Node.ELEMENT_NODE?a.target:a.target.parentElement;if(!e)continue;let o=e.closest(t);o?n.add(r(o)):(a.type===`attributes`&&e.matches(`[data-t-attrs]`)&&i.add(e),a.addedNodes.forEach(e=>{e.nodeType===Node.ELEMENT_NODE&&this.collect(e,n,i)}))}e.some(e=>e.removedNodes.length>0)&&this.forget(e=>!e.isConnected),n.forEach(e=>this.translateContent(e)),i.forEach(e=>this.translateAttributes(e))}forget(e){for(let t of this.contents.keys())e(t)&&this.contents.delete(t);for(let t of this.attributes.keys())e(t)&&this.attributes.delete(t)}translateContent(e,t=!1){let n=e.innerHTML,r=this.contents.get(e);if(!r)r={source:n,requestId:0},this.contents.set(e,r);else if(n!==r.rendered&&n!==r.source)r.source=n,r.rendered=void 0;else if(!t)return;let[,a,o,s]=/^(\s*)([\s\S]*?)(\s*)$/.exec(r.source.replace(/<!--[\s\S]*?-->/g,``));if(!o)return;let c=++r.requestId,l=r;this.translate(o,i(e)).then(t=>{if(c!==l.requestId||!e.isConnected)return;let n=`${a}${t}${s}`;e.innerHTML!==n&&(e.innerHTML=n),l.rendered=e.innerHTML})}translateAttributes(e,t=!1){let n=(e.getAttribute(`data-t-attrs`)??``).split(/[\s,]+/).filter(Boolean),r=this.attributes.get(e);r||(r=new Map,this.attributes.set(e,r));for(let a of n){let n=e.getAttribute(a);if(!n?.trim())continue;let o=r.get(a);if(!o)o={source:n,requestId:0},r.set(a,o);else if(n!==o.rendered&&n!==o.source)o.source=n,o.rendered=void 0;else if(!t)continue;let s=++o.requestId,c=o;this.translate(c.source,i(e)).then(t=>{s===c.requestId&&e.isConnected&&(c.rendered=t,e.getAttribute(a)!==t&&e.setAttribute(a,t))})}}};function o(e){return new a(e)}exports.ATTRIBUTES_SELECTOR=n,exports.CONTENT_SELECTOR=t,exports.MagicTranslate=a,exports.createMagicTranslate=o,Object.keys(e).forEach(function(t){t!=="default"&&!Object.prototype.hasOwnProperty.call(exports,t)&&Object.defineProperty(exports,t,{enumerable:!0,get:function(){return e[t]}})});
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["libraryWebsite","utsLocaleToLanguage","defaultLoaderFactory","DataLoader","cacheKeyFn","_magic_translate_core","CONTENT_SELECTOR","ATTRIBUTES_SELECTOR","outermost","current","element","parent","optionsOf","options","lang","formality","MagicTranslate","language","listener","params","loaderFactory","debug","sourceLanguage","_apiUrl","apiKey","contents","attributes","root","records","all","record","target","content","node","predicate","html","translation","force","leadingWhitespace","text","trailingWhitespace","requestId","rendered","translated","names","translations","name","value","createMagicTranslate","k"],"sources":["../src/magic-translate.ts"],"sourcesContent":["import {\n cacheKeyFn,\n DataLoader,\n DataLoaderLoadParams,\n defaultLoaderFactory,\n Language,\n libraryWebsite,\n MagicTranslateConfig,\n TranslateOptions,\n utsLocaleToLanguage,\n} from '@magic-translate/core';\n\n/**\n * Type alias to make the language enum more flexible to also allow passing language strings\n * instead of just the enum.\n */\nexport type Languages = `${Language}`;\n\nexport type TranslateParams = Omit<DataLoaderLoadParams, 'text'>;\n\nexport interface MagicTranslateOptions extends Omit<\n MagicTranslateConfig,\n 'language'\n> {\n /**\n * The language content is translated to. Defaults to the browser's language.\n */\n language?: Languages;\n /**\n * The element whose content is translated. Defaults to the whole document.\n */\n root?: Element;\n}\n\n/** Elements whose content is translated. */\nexport const CONTENT_SELECTOR = 't, mt-translate, [data-t]';\n/** Elements with attributes to translate, e.g. `data-t-attrs=\"placeholder title\"`. */\nexport const ATTRIBUTES_SELECTOR = '[data-t-attrs]';\n\ninterface Translation {\n source: string;\n // what was last written to the DOM, to tell our own changes from others\n rendered?: string;\n requestId: number;\n}\n\nfunction outermost(element: Element): Element {\n let current = element;\n for (\n let parent = current.parentElement?.closest(CONTENT_SELECTOR);\n parent;\n parent = current.parentElement?.closest(CONTENT_SELECTOR)\n ) {\n current = parent;\n }\n return current;\n}\n\nfunction optionsOf(element: Element): TranslateOptions {\n const options: TranslateOptions = {};\n const lang = element.getAttribute('data-lang');\n const formality = element.getAttribute('data-formality');\n if (lang) {\n options.lang = lang as Languages;\n }\n if (formality) {\n options.formality = formality as TranslateOptions['formality'];\n }\n return options;\n}\n\nexport class MagicTranslate {\n private currentLanguage: Languages;\n private dataLoader: DataLoader<DataLoaderLoadParams, string, string>;\n private readonly root?: Element;\n private readonly contents = new Map<Element, Translation>();\n private readonly attributes = new Map<Element, Map<string, Translation>>();\n private readonly listeners = new Set<(language: Languages) => void>();\n private observer?: MutationObserver;\n\n constructor(private readonly options: MagicTranslateOptions) {\n if (!options.apiKey) {\n throw new Error(`Missing API key. Please get one at ${libraryWebsite}`);\n }\n\n this.currentLanguage =\n options.language ??\n utsLocaleToLanguage(\n typeof navigator === 'undefined' ? undefined : navigator.language\n );\n this.dataLoader = this.createDataLoader();\n\n if (typeof document !== 'undefined') {\n this.root = options.root ?? document.documentElement;\n this.start(this.root);\n }\n }\n\n /**\n * The language content is currently translated to.\n */\n get language(): Languages {\n return this.currentLanguage;\n }\n\n /**\n * Translates the page to another language.\n */\n setLanguage(language: Languages): void {\n if (language === this.currentLanguage) {\n return;\n }\n\n this.currentLanguage = language;\n this.dataLoader = this.createDataLoader();\n\n this.forget(\n (element) => !element.isConnected || !this.root?.contains(element)\n );\n this.contents.forEach((_, element) => this.translateContent(element, true));\n this.attributes.forEach((_, element) =>\n this.translateAttributes(element, true)\n );\n this.listeners.forEach((listener) => listener(language));\n }\n\n /**\n * Calls `listener` whenever the language changes. Returns a function that\n * removes the listener again.\n */\n onLanguageChange(listener: (language: Languages) => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /**\n * Translates a string to the current language.\n */\n translate(text: string, params: TranslateParams = {}): Promise<string> {\n return this.dataLoader.load({ text, ...params });\n }\n\n /**\n * Stops translating the page. Content that is already translated stays\n * translated.\n */\n destroy(): void {\n this.observer?.disconnect();\n this.contents.clear();\n this.attributes.clear();\n this.listeners.clear();\n }\n\n private createDataLoader() {\n const { debug, apiKey, sourceLanguage, _apiUrl, formality } = this.options;\n const loaderFactory = this.options._loaderFactory ?? defaultLoaderFactory;\n\n return new DataLoader<DataLoaderLoadParams, string, string>(\n loaderFactory({\n debug: !!debug,\n apiKey,\n lang: this.currentLanguage,\n sourceLang: sourceLanguage,\n apiUrl: _apiUrl,\n formality,\n }),\n {\n cacheKeyFn: cacheKeyFn(apiKey, sourceLanguage, this.currentLanguage),\n }\n );\n }\n\n private start(root: Element) {\n const contents = new Set<Element>();\n const attributes = new Set<Element>();\n this.collect(root, contents, attributes);\n contents.forEach((element) => this.translateContent(element));\n attributes.forEach((element) => this.translateAttributes(element));\n\n // Picks up content that is added or changed later.\n this.observer = new MutationObserver((records) =>\n this.handleMutations(records)\n );\n this.observer.observe(root, {\n subtree: true,\n childList: true,\n characterData: true,\n attributes: true,\n });\n }\n\n private collect(\n root: Element,\n contents: Set<Element>,\n attributes: Set<Element>\n ) {\n const all = [root, ...Array.from(root.querySelectorAll('*'))];\n for (const element of all) {\n if (element.matches(CONTENT_SELECTOR)) {\n contents.add(outermost(element));\n } else if (\n element.matches(ATTRIBUTES_SELECTOR) &&\n !element.closest(CONTENT_SELECTOR)\n ) {\n attributes.add(element);\n }\n }\n }\n\n private handleMutations(records: MutationRecord[]) {\n const contents = new Set<Element>();\n const attributes = new Set<Element>();\n\n for (const record of records) {\n const target =\n record.target.nodeType === Node.ELEMENT_NODE\n ? (record.target as Element)\n : record.target.parentElement;\n if (!target) {\n continue;\n }\n\n const content = target.closest(CONTENT_SELECTOR);\n if (content) {\n contents.add(outermost(content));\n continue;\n }\n\n if (record.type === 'attributes' && target.matches(ATTRIBUTES_SELECTOR)) {\n attributes.add(target);\n }\n record.addedNodes.forEach((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n this.collect(node as Element, contents, attributes);\n }\n });\n }\n\n if (records.some((record) => record.removedNodes.length > 0)) {\n this.forget((element) => !element.isConnected);\n }\n contents.forEach((element) => this.translateContent(element));\n attributes.forEach((element) => this.translateAttributes(element));\n }\n\n private forget(predicate: (element: Element) => boolean) {\n for (const element of [...this.contents.keys()]) {\n if (predicate(element)) {\n this.contents.delete(element);\n }\n }\n for (const element of [...this.attributes.keys()]) {\n if (predicate(element)) {\n this.attributes.delete(element);\n }\n }\n }\n\n private translateContent(element: Element, force = false) {\n const html = element.innerHTML;\n let translation = this.contents.get(element);\n\n if (!translation) {\n translation = { source: html, requestId: 0 };\n this.contents.set(element, translation);\n } else if (html !== translation.rendered && html !== translation.source) {\n // changed by someone else, e.g. the page's own scripts\n translation.source = html;\n translation.rendered = undefined;\n } else if (!force) {\n return;\n }\n\n const [, leadingWhitespace, text, trailingWhitespace] =\n /^(\\s*)([\\s\\S]*?)(\\s*)$/.exec(\n translation.source.replace(/<!--[\\s\\S]*?-->/g, '')\n )!;\n if (!text) {\n return;\n }\n\n // make sure that we only ever use the response of the most recent request.\n const requestId = ++translation.requestId;\n const current = translation;\n this.translate(text, optionsOf(element)).then((translated) => {\n if (requestId !== current.requestId || !element.isConnected) {\n return;\n }\n const rendered = `${leadingWhitespace}${translated}${trailingWhitespace}`;\n if (element.innerHTML !== rendered) {\n element.innerHTML = rendered;\n }\n current.rendered = element.innerHTML;\n });\n }\n\n private translateAttributes(element: Element, force = false) {\n const names = (element.getAttribute('data-t-attrs') ?? '')\n .split(/[\\s,]+/)\n .filter(Boolean);\n let translations = this.attributes.get(element);\n if (!translations) {\n translations = new Map();\n this.attributes.set(element, translations);\n }\n\n for (const name of names) {\n const value = element.getAttribute(name);\n if (!value?.trim()) {\n continue;\n }\n\n let translation = translations.get(name);\n if (!translation) {\n translation = { source: value, requestId: 0 };\n translations.set(name, translation);\n } else if (\n value !== translation.rendered &&\n value !== translation.source\n ) {\n translation.source = value;\n translation.rendered = undefined;\n } else if (!force) {\n continue;\n }\n\n const requestId = ++translation.requestId;\n const current = translation;\n this.translate(current.source, optionsOf(element)).then((translated) => {\n if (requestId !== current.requestId || !element.isConnected) {\n return;\n }\n current.rendered = translated;\n if (element.getAttribute(name) !== translated) {\n element.setAttribute(name, translated);\n }\n });\n }\n }\n}\n\n/**\n * Starts translating the page: the content of every `<t>` element (or element\n * with a `data-t` attribute), and the attributes listed in `data-t-attrs`.\n * Content added later is translated as well.\n */\nexport function createMagicTranslate(\n options: MagicTranslateOptions\n): MagicTranslate {\n return new MagicTranslate(options);\n}\n"],"mappings":"A,0GAmCA,IAAaM,EAAmB,4BAEnBC,EAAsB,iBASnC,SAASC,EAAU,EAA2B,CAC5C,IAAIC,EAAUC,EACd,IACE,IAAIC,EAASF,EAAQ,eAAe,QAAQH,CAAgB,EAC5DK,EACA,EAASF,EAAQ,eAAe,QAAQH,CAAgB,EAExD,EAAUK,EAEZ,OAAOF,CACT,CAEA,SAASG,EAAU,EAAoC,CACrD,IAAMC,EAA4B,CAAC,EAC7BC,EAAOJ,EAAQ,aAAa,WAAW,EACvCK,EAAYL,EAAQ,aAAa,gBAAgB,EAOvD,OANII,IACF,EAAQ,KAAOA,GAEbC,IACF,EAAQ,UAAYA,GAEfF,CACT,CAEA,IAAaG,EAAb,KAA4B,CAS1B,YAAY,EAAiD,CAC3D,GAD2B,KAAA,QAAAH,EALD,KAAA,SAAA,IAAI,IACF,KAAA,WAAA,IAAI,IACL,KAAA,UAAA,IAAI,IAI3B,CAACA,EAAQ,OACX,MAAU,MAAM,sCAAsCb,EAAAA,gBAAgB,EAGxE,KAAK,gBACHa,EAAQ,WAAA,EACRZ,EAAAA,oBAAAA,CACE,OAAO,UAAc,IAAc,IAAA,GAAY,UAAU,QAC3D,EACF,KAAK,WAAa,KAAK,iBAAiB,EAEpC,OAAO,SAAa,MACtB,KAAK,KAAOY,EAAQ,MAAQ,SAAS,gBACrC,KAAK,MAAM,KAAK,IAAI,EAExB,CAKA,IAAI,UAAsB,CACxB,OAAO,KAAK,eACd,CAKA,YAAY,EAA2B,CACjCI,IAAa,KAAK,kBAItB,KAAK,gBAAkBA,EACvB,KAAK,WAAa,KAAK,iBAAiB,EAExC,KAAK,OACF,GAAY,CAACP,EAAQ,aAAe,CAAC,KAAK,MAAM,SAASA,CAAO,CACnE,EACA,KAAK,SAAS,SAAS,EAAG,IAAY,KAAK,iBAAiBA,EAAS,EAAI,CAAC,EAC1E,KAAK,WAAW,SAAS,EAAG,IAC1B,KAAK,oBAAoBA,EAAS,EAAI,CACxC,EACA,KAAK,UAAU,QAAS,GAAaQ,EAASD,CAAQ,CAAC,EACzD,CAMA,iBAAiB,EAAqD,CAEpE,OADA,KAAK,UAAU,IAAIC,CAAQ,MACd,KAAK,UAAU,OAAOA,CAAQ,CAC7C,CAKA,UAAU,EAAc,EAA0B,CAAC,EAAoB,CACrE,OAAO,KAAK,WAAW,KAAK,CAAE,OAAM,GAAGC,CAAO,CAAC,CACjD,CAMA,SAAgB,CACd,KAAK,UAAU,WAAW,EAC1B,KAAK,SAAS,MAAM,EACpB,KAAK,WAAW,MAAM,EACtB,KAAK,UAAU,MAAM,CACvB,CAEA,kBAA2B,CACzB,GAAM,CAAE,QAAO,SAAQ,iBAAgB,UAAS,aAAc,KAAK,QAC7DC,EAAgB,KAAK,QAAQ,gBAAkBlB,EAAAA,qBAErD,OAAO,IAAIC,EAAAA,WACTiB,EAAc,CACZ,MAAO,CAAC,CAACC,EACT,SACA,KAAM,KAAK,gBACX,WAAYC,EACZ,OAAQC,EACR,WACF,CAAC,EACD,CACE,YAAA,EAAYnB,EAAAA,WAAAA,CAAWoB,EAAQF,EAAgB,KAAK,eAAe,CACrE,CACF,CACF,CAEA,MAAc,EAAe,CAC3B,IAAMG,EAAW,IAAI,IACfC,EAAa,IAAI,IACvB,KAAK,QAAQC,EAAMF,EAAUC,CAAU,EACvCD,EAAS,QAAS,GAAY,KAAK,iBAAiBf,CAAO,CAAC,EAC5DgB,EAAW,QAAS,GAAY,KAAK,oBAAoBhB,CAAO,CAAC,EAGjE,KAAK,SAAW,IAAI,iBAAkB,GACpC,KAAK,gBAAgBkB,CAAO,CAC9B,EACA,KAAK,SAAS,QAAQD,EAAM,CAC1B,QAAS,GACT,UAAW,GACX,cAAe,GACf,WAAY,EACd,CAAC,CACH,CAEA,QACE,EACA,EACA,EACA,CACA,IAAME,EAAM,CAACF,EAAM,GAAG,MAAM,KAAKA,EAAK,iBAAiB,GAAG,CAAC,CAAC,EAC5D,IAAK,IAAMjB,KAAWmB,EAChBnB,EAAQ,QAAA,2BAAwB,EAClCe,EAAS,IAAIjB,EAAUE,CAAO,CAAC,EAE/BA,EAAQ,QAAA,gBAA2B,GACnC,CAACA,EAAQ,QAAA,2BAAwB,GAEjCgB,EAAW,IAAIhB,CAAO,CAG5B,CAEA,gBAAwB,EAA2B,CACjD,IAAMe,EAAW,IAAI,IACfC,EAAa,IAAI,IAEvB,IAAK,IAAMI,KAAUF,EAAS,CAC5B,IAAMG,EACJD,EAAO,OAAO,WAAa,KAAK,aAC3BA,EAAO,OACRA,EAAO,OAAO,cACpB,GAAI,CAACC,EACH,SAGF,IAAMC,EAAUD,EAAO,QAAQzB,CAAgB,EAC3C0B,EACFP,EAAS,IAAIjB,EAAUwB,CAAO,CAAC,GAI7BF,EAAO,OAAS,cAAgBC,EAAO,QAAA,gBAA2B,GACpEL,EAAW,IAAIK,CAAM,EAEvBD,EAAO,WAAW,QAAS,GAAS,CAC9BG,EAAK,WAAa,KAAK,cACzB,KAAK,QAAQA,EAAiBR,EAAUC,CAAU,CAEtD,CAAC,EACH,CAEIE,EAAQ,KAAM,GAAWE,EAAO,aAAa,OAAS,CAAC,GACzD,KAAK,OAAQ,GAAY,CAACpB,EAAQ,WAAW,EAE/Ce,EAAS,QAAS,GAAY,KAAK,iBAAiBf,CAAO,CAAC,EAC5DgB,EAAW,QAAS,GAAY,KAAK,oBAAoBhB,CAAO,CAAC,CACnE,CAEA,OAAe,EAA0C,CACvD,IAAK,IAAMA,IAAW,CAAC,GAAG,KAAK,SAAS,KAAK,CAAC,EACxCwB,EAAUxB,CAAO,GACnB,KAAK,SAAS,OAAOA,CAAO,EAGhC,IAAK,IAAMA,IAAW,CAAC,GAAG,KAAK,WAAW,KAAK,CAAC,EAC1CwB,EAAUxB,CAAO,GACnB,KAAK,WAAW,OAAOA,CAAO,CAGpC,CAEA,iBAAyB,EAAkB,EAAQ,GAAO,CACxD,IAAMyB,EAAOzB,EAAQ,UACjB0B,EAAc,KAAK,SAAS,IAAI1B,CAAO,EAE3C,GAAI,CAAC0B,EACH,EAAc,CAAE,OAAQD,EAAM,UAAW,CAAE,EAC3C,KAAK,SAAS,IAAIzB,EAAS0B,CAAW,OACjC,GAAID,IAASC,EAAY,UAAYD,IAASC,EAAY,OAE/D,EAAY,OAASD,EACrB,EAAY,SAAW,IAAA,QAClB,GAAI,CAACE,EACV,OAGF,GAAM,EAAGC,EAAmBC,EAAMC,GAChC,yBAAyB,KACvBJ,EAAY,OAAO,QAAQ,mBAAoB,EAAE,CACnD,EACF,GAAI,CAACG,EACH,OAIF,IAAME,EAAY,EAAEL,EAAY,UAC1B3B,EAAU2B,EAChB,KAAK,UAAUG,EAAM3B,EAAUF,CAAO,CAAC,CAAC,CAAC,KAAM,GAAe,CAC5D,GAAI+B,IAAchC,EAAQ,WAAa,CAACC,EAAQ,YAC9C,OAEF,IAAMgC,EAAW,GAAGJ,IAAoBK,IAAaH,IACjD9B,EAAQ,YAAcgC,IACxB,EAAQ,UAAYA,GAEtB,EAAQ,SAAWhC,EAAQ,SAC7B,CAAC,CACH,CAEA,oBAA4B,EAAkB,EAAQ,GAAO,CAC3D,IAAMkC,GAASlC,EAAQ,aAAa,cAAc,GAAK,GAAA,CACpD,MAAM,QAAQ,CAAC,CACf,OAAO,OAAO,EACbmC,EAAe,KAAK,WAAW,IAAInC,CAAO,EACzCmC,IACH,EAAe,IAAI,IACnB,KAAK,WAAW,IAAInC,EAASmC,CAAY,GAG3C,IAAK,IAAMC,KAAQF,EAAO,CACxB,IAAMG,EAAQrC,EAAQ,aAAaoC,CAAI,EACvC,GAAI,CAACC,GAAO,KAAK,EACf,SAGF,IAAIX,EAAcS,EAAa,IAAIC,CAAI,EACvC,GAAI,CAACV,EACH,EAAc,CAAE,OAAQW,EAAO,UAAW,CAAE,EAC5CF,EAAa,IAAIC,EAAMV,CAAW,OAC7B,GACLW,IAAUX,EAAY,UACtBW,IAAUX,EAAY,OAEtB,EAAY,OAASW,EACrB,EAAY,SAAW,IAAA,QAClB,GAAI,CAACV,EACV,SAGF,IAAMI,EAAY,EAAEL,EAAY,UAC1B3B,EAAU2B,EAChB,KAAK,UAAU3B,EAAQ,OAAQG,EAAUF,CAAO,CAAC,CAAC,CAAC,KAAM,GAAe,CAClE+B,IAAchC,EAAQ,WAAcC,EAAQ,cAGhD,EAAQ,SAAWiC,EACfjC,EAAQ,aAAaoC,CAAI,IAAMH,GACjCjC,EAAQ,aAAaoC,EAAMH,CAAU,EAEzC,CAAC,CACH,CACF,CACF,EAOA,SAAgBK,EACd,EACgB,CAChB,OAAO,IAAIhC,EAAeH,CAAO,CACnC,C"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["libraryWebsite","utsLocaleToLanguage","defaultLoaderFactory","DataLoader","cacheKeyFn","_magic_translate_core","CONTENT_SELECTOR","ATTRIBUTES_SELECTOR","outermost","current","element","parent","optionsOf","options","lang","formality","MagicTranslate","language","listener","params","loaderFactory","debug","sourceLanguage","_apiUrl","apiKey","contents","attributes","root","records","all","record","target","content","node","predicate","html","translation","force","leadingWhitespace","text","trailingWhitespace","requestId","rendered","translated","names","translations","name","value","createMagicTranslate","k"],"sources":["../src/magic-translate.ts"],"sourcesContent":["import {\n cacheKeyFn,\n DataLoader,\n DataLoaderLoadParams,\n defaultLoaderFactory,\n Language,\n libraryWebsite,\n MagicTranslateConfig,\n TranslateOptions,\n utsLocaleToLanguage,\n} from '@magic-translate/core';\n\n/**\n * Type alias to make the language enum more flexible to also allow passing language strings\n * instead of just the enum.\n */\nexport type Languages = `${Language}`;\n\nexport type TranslateParams = Omit<DataLoaderLoadParams, 'text'>;\n\nexport interface MagicTranslateOptions extends Omit<\n MagicTranslateConfig,\n 'language'\n> {\n /**\n * The language content is translated to. Defaults to the browser's language.\n */\n language?: Languages;\n /**\n * The element whose content is translated. Defaults to the whole document.\n */\n root?: Element;\n}\n\n/** Elements whose content is translated. */\nexport const CONTENT_SELECTOR = 't, mt-translate, [data-t]';\n/** Elements with attributes to translate, e.g. `data-t-attrs=\"placeholder title\"`. */\nexport const ATTRIBUTES_SELECTOR = '[data-t-attrs]';\n\ninterface Translation {\n source: string;\n // what was last written to the DOM, to tell our own changes from others\n rendered?: string;\n requestId: number;\n}\n\nfunction outermost(element: Element): Element {\n let current = element;\n for (\n let parent = current.parentElement?.closest(CONTENT_SELECTOR);\n parent;\n parent = current.parentElement?.closest(CONTENT_SELECTOR)\n ) {\n current = parent;\n }\n return current;\n}\n\nfunction optionsOf(element: Element): TranslateOptions {\n const options: TranslateOptions = {};\n const lang = element.getAttribute('data-lang');\n const formality = element.getAttribute('data-formality');\n if (lang) {\n options.lang = lang as Languages;\n }\n if (formality) {\n options.formality = formality as TranslateOptions['formality'];\n }\n return options;\n}\n\nexport class MagicTranslate {\n private currentLanguage: Languages;\n private dataLoader: DataLoader<DataLoaderLoadParams, string, string>;\n private readonly root?: Element;\n private readonly contents = new Map<Element, Translation>();\n private readonly attributes = new Map<Element, Map<string, Translation>>();\n private readonly listeners = new Set<(language: Languages) => void>();\n private observer?: MutationObserver;\n\n constructor(private readonly options: MagicTranslateOptions) {\n if (!options.apiKey) {\n throw new Error(`Missing API key. Please get one at ${libraryWebsite}`);\n }\n\n this.currentLanguage =\n options.language ??\n utsLocaleToLanguage(\n typeof navigator === 'undefined' ? undefined : navigator.language\n );\n this.dataLoader = this.createDataLoader();\n\n if (typeof document !== 'undefined') {\n this.root = options.root ?? document.documentElement;\n this.start(this.root);\n }\n }\n\n /**\n * The language content is currently translated to.\n */\n get language(): Languages {\n return this.currentLanguage;\n }\n\n /**\n * Translates the page to another language.\n */\n setLanguage(language: Languages): void {\n if (language === this.currentLanguage) {\n return;\n }\n\n this.currentLanguage = language;\n this.dataLoader = this.createDataLoader();\n\n this.forget(\n (element) => !element.isConnected || !this.root?.contains(element)\n );\n this.contents.forEach((_, element) => this.translateContent(element, true));\n this.attributes.forEach((_, element) =>\n this.translateAttributes(element, true)\n );\n this.listeners.forEach((listener) => listener(language));\n }\n\n /**\n * Calls `listener` whenever the language changes. Returns a function that\n * removes the listener again.\n */\n onLanguageChange(listener: (language: Languages) => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /**\n * Translates a string to the current language.\n */\n translate(text: string, params: TranslateParams = {}): Promise<string> {\n return this.dataLoader.load({ text, ...params });\n }\n\n /**\n * Stops translating the page. Content that is already translated stays\n * translated.\n */\n destroy(): void {\n this.observer?.disconnect();\n this.contents.clear();\n this.attributes.clear();\n this.listeners.clear();\n }\n\n private createDataLoader() {\n const { debug, apiKey, sourceLanguage, _apiUrl, formality } = this.options;\n const loaderFactory = this.options._loaderFactory ?? defaultLoaderFactory;\n\n return new DataLoader<DataLoaderLoadParams, string, string>(\n loaderFactory({\n debug: !!debug,\n apiKey,\n lang: this.currentLanguage,\n sourceLang: sourceLanguage,\n apiUrl: _apiUrl,\n formality,\n }),\n {\n cacheKeyFn: cacheKeyFn(apiKey, sourceLanguage, this.currentLanguage),\n }\n );\n }\n\n private start(root: Element) {\n const contents = new Set<Element>();\n const attributes = new Set<Element>();\n this.collect(root, contents, attributes);\n contents.forEach((element) => this.translateContent(element));\n attributes.forEach((element) => this.translateAttributes(element));\n\n // Picks up content that is added or changed later.\n this.observer = new MutationObserver((records) =>\n this.handleMutations(records)\n );\n this.observer.observe(root, {\n subtree: true,\n childList: true,\n characterData: true,\n attributes: true,\n });\n }\n\n private collect(\n root: Element,\n contents: Set<Element>,\n attributes: Set<Element>\n ) {\n const all = [root, ...Array.from(root.querySelectorAll('*'))];\n for (const element of all) {\n if (element.matches(CONTENT_SELECTOR)) {\n contents.add(outermost(element));\n } else if (\n element.matches(ATTRIBUTES_SELECTOR) &&\n !element.closest(CONTENT_SELECTOR)\n ) {\n attributes.add(element);\n }\n }\n }\n\n private handleMutations(records: MutationRecord[]) {\n const contents = new Set<Element>();\n const attributes = new Set<Element>();\n\n for (const record of records) {\n const target =\n record.target.nodeType === Node.ELEMENT_NODE\n ? (record.target as Element)\n : record.target.parentElement;\n if (!target) {\n continue;\n }\n\n const content = target.closest(CONTENT_SELECTOR);\n if (content) {\n contents.add(outermost(content));\n continue;\n }\n\n if (record.type === 'attributes' && target.matches(ATTRIBUTES_SELECTOR)) {\n attributes.add(target);\n }\n record.addedNodes.forEach((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n this.collect(node as Element, contents, attributes);\n }\n });\n }\n\n if (records.some((record) => record.removedNodes.length > 0)) {\n this.forget((element) => !element.isConnected);\n }\n contents.forEach((element) => this.translateContent(element));\n attributes.forEach((element) => this.translateAttributes(element));\n }\n\n private forget(predicate: (element: Element) => boolean) {\n for (const element of this.contents.keys()) {\n if (predicate(element)) {\n this.contents.delete(element);\n }\n }\n for (const element of this.attributes.keys()) {\n if (predicate(element)) {\n this.attributes.delete(element);\n }\n }\n }\n\n private translateContent(element: Element, force = false) {\n const html = element.innerHTML;\n let translation = this.contents.get(element);\n\n if (!translation) {\n translation = { source: html, requestId: 0 };\n this.contents.set(element, translation);\n } else if (html !== translation.rendered && html !== translation.source) {\n // changed by someone else, e.g. the page's own scripts\n translation.source = html;\n translation.rendered = undefined;\n } else if (!force) {\n return;\n }\n\n const [, leadingWhitespace, text, trailingWhitespace] =\n /^(\\s*)([\\s\\S]*?)(\\s*)$/.exec(\n translation.source.replace(/<!--[\\s\\S]*?-->/g, '')\n )!;\n if (!text) {\n return;\n }\n\n // make sure that we only ever use the response of the most recent request.\n const requestId = ++translation.requestId;\n const current = translation;\n this.translate(text, optionsOf(element)).then((translated) => {\n if (requestId !== current.requestId || !element.isConnected) {\n return;\n }\n const rendered = `${leadingWhitespace}${translated}${trailingWhitespace}`;\n if (element.innerHTML !== rendered) {\n element.innerHTML = rendered;\n }\n current.rendered = element.innerHTML;\n });\n }\n\n private translateAttributes(element: Element, force = false) {\n const names = (element.getAttribute('data-t-attrs') ?? '')\n .split(/[\\s,]+/)\n .filter(Boolean);\n let translations = this.attributes.get(element);\n if (!translations) {\n translations = new Map();\n this.attributes.set(element, translations);\n }\n\n for (const name of names) {\n const value = element.getAttribute(name);\n if (!value?.trim()) {\n continue;\n }\n\n let translation = translations.get(name);\n if (!translation) {\n translation = { source: value, requestId: 0 };\n translations.set(name, translation);\n } else if (\n value !== translation.rendered &&\n value !== translation.source\n ) {\n translation.source = value;\n translation.rendered = undefined;\n } else if (!force) {\n continue;\n }\n\n const requestId = ++translation.requestId;\n const current = translation;\n this.translate(current.source, optionsOf(element)).then((translated) => {\n if (requestId !== current.requestId || !element.isConnected) {\n return;\n }\n current.rendered = translated;\n if (element.getAttribute(name) !== translated) {\n element.setAttribute(name, translated);\n }\n });\n }\n }\n}\n\n/**\n * Starts translating the page: the content of every `<t>` element (or element\n * with a `data-t` attribute), and the attributes listed in `data-t-attrs`.\n * Content added later is translated as well.\n */\nexport function createMagicTranslate(\n options: MagicTranslateOptions\n): MagicTranslate {\n return new MagicTranslate(options);\n}\n"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -71,8 +71,8 @@ var l = class {
|
|
|
71
71
|
e.some((e) => e.removedNodes.length > 0) && this.forget((e) => !e.isConnected), t.forEach((e) => this.translateContent(e)), n.forEach((e) => this.translateAttributes(e));
|
|
72
72
|
}
|
|
73
73
|
forget(e) {
|
|
74
|
-
for (let t of
|
|
75
|
-
for (let t of
|
|
74
|
+
for (let t of this.contents.keys()) e(t) && this.contents.delete(t);
|
|
75
|
+
for (let t of this.attributes.keys()) e(t) && this.attributes.delete(t);
|
|
76
76
|
}
|
|
77
77
|
translateContent(e, t = !1) {
|
|
78
78
|
let n = e.innerHTML, r = this.contents.get(e);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["CONTENT_SELECTOR","ATTRIBUTES_SELECTOR","outermost","current","element","parent","optionsOf","options","lang","formality","MagicTranslate","libraryWebsite","utsLocaleToLanguage","language","listener","params","loaderFactory","defaultLoaderFactory","DataLoader","debug","sourceLanguage","_apiUrl","cacheKeyFn","apiKey","contents","attributes","root","records","all","record","target","content","node","predicate","html","translation","force","leadingWhitespace","text","trailingWhitespace","requestId","rendered","translated","names","translations","name","value","createMagicTranslate"],"sources":["../src/magic-translate.ts"],"sourcesContent":["import {\n cacheKeyFn,\n DataLoader,\n DataLoaderLoadParams,\n defaultLoaderFactory,\n Language,\n libraryWebsite,\n MagicTranslateConfig,\n TranslateOptions,\n utsLocaleToLanguage,\n} from '@magic-translate/core';\n\n/**\n * Type alias to make the language enum more flexible to also allow passing language strings\n * instead of just the enum.\n */\nexport type Languages = `${Language}`;\n\nexport type TranslateParams = Omit<DataLoaderLoadParams, 'text'>;\n\nexport interface MagicTranslateOptions extends Omit<\n MagicTranslateConfig,\n 'language'\n> {\n /**\n * The language content is translated to. Defaults to the browser's language.\n */\n language?: Languages;\n /**\n * The element whose content is translated. Defaults to the whole document.\n */\n root?: Element;\n}\n\n/** Elements whose content is translated. */\nexport const CONTENT_SELECTOR = 't, mt-translate, [data-t]';\n/** Elements with attributes to translate, e.g. `data-t-attrs=\"placeholder title\"`. */\nexport const ATTRIBUTES_SELECTOR = '[data-t-attrs]';\n\ninterface Translation {\n source: string;\n // what was last written to the DOM, to tell our own changes from others\n rendered?: string;\n requestId: number;\n}\n\nfunction outermost(element: Element): Element {\n let current = element;\n for (\n let parent = current.parentElement?.closest(CONTENT_SELECTOR);\n parent;\n parent = current.parentElement?.closest(CONTENT_SELECTOR)\n ) {\n current = parent;\n }\n return current;\n}\n\nfunction optionsOf(element: Element): TranslateOptions {\n const options: TranslateOptions = {};\n const lang = element.getAttribute('data-lang');\n const formality = element.getAttribute('data-formality');\n if (lang) {\n options.lang = lang as Languages;\n }\n if (formality) {\n options.formality = formality as TranslateOptions['formality'];\n }\n return options;\n}\n\nexport class MagicTranslate {\n private currentLanguage: Languages;\n private dataLoader: DataLoader<DataLoaderLoadParams, string, string>;\n private readonly root?: Element;\n private readonly contents = new Map<Element, Translation>();\n private readonly attributes = new Map<Element, Map<string, Translation>>();\n private readonly listeners = new Set<(language: Languages) => void>();\n private observer?: MutationObserver;\n\n constructor(private readonly options: MagicTranslateOptions) {\n if (!options.apiKey) {\n throw new Error(`Missing API key. Please get one at ${libraryWebsite}`);\n }\n\n this.currentLanguage =\n options.language ??\n utsLocaleToLanguage(\n typeof navigator === 'undefined' ? undefined : navigator.language\n );\n this.dataLoader = this.createDataLoader();\n\n if (typeof document !== 'undefined') {\n this.root = options.root ?? document.documentElement;\n this.start(this.root);\n }\n }\n\n /**\n * The language content is currently translated to.\n */\n get language(): Languages {\n return this.currentLanguage;\n }\n\n /**\n * Translates the page to another language.\n */\n setLanguage(language: Languages): void {\n if (language === this.currentLanguage) {\n return;\n }\n\n this.currentLanguage = language;\n this.dataLoader = this.createDataLoader();\n\n this.forget(\n (element) => !element.isConnected || !this.root?.contains(element)\n );\n this.contents.forEach((_, element) => this.translateContent(element, true));\n this.attributes.forEach((_, element) =>\n this.translateAttributes(element, true)\n );\n this.listeners.forEach((listener) => listener(language));\n }\n\n /**\n * Calls `listener` whenever the language changes. Returns a function that\n * removes the listener again.\n */\n onLanguageChange(listener: (language: Languages) => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /**\n * Translates a string to the current language.\n */\n translate(text: string, params: TranslateParams = {}): Promise<string> {\n return this.dataLoader.load({ text, ...params });\n }\n\n /**\n * Stops translating the page. Content that is already translated stays\n * translated.\n */\n destroy(): void {\n this.observer?.disconnect();\n this.contents.clear();\n this.attributes.clear();\n this.listeners.clear();\n }\n\n private createDataLoader() {\n const { debug, apiKey, sourceLanguage, _apiUrl, formality } = this.options;\n const loaderFactory = this.options._loaderFactory ?? defaultLoaderFactory;\n\n return new DataLoader<DataLoaderLoadParams, string, string>(\n loaderFactory({\n debug: !!debug,\n apiKey,\n lang: this.currentLanguage,\n sourceLang: sourceLanguage,\n apiUrl: _apiUrl,\n formality,\n }),\n {\n cacheKeyFn: cacheKeyFn(apiKey, sourceLanguage, this.currentLanguage),\n }\n );\n }\n\n private start(root: Element) {\n const contents = new Set<Element>();\n const attributes = new Set<Element>();\n this.collect(root, contents, attributes);\n contents.forEach((element) => this.translateContent(element));\n attributes.forEach((element) => this.translateAttributes(element));\n\n // Picks up content that is added or changed later.\n this.observer = new MutationObserver((records) =>\n this.handleMutations(records)\n );\n this.observer.observe(root, {\n subtree: true,\n childList: true,\n characterData: true,\n attributes: true,\n });\n }\n\n private collect(\n root: Element,\n contents: Set<Element>,\n attributes: Set<Element>\n ) {\n const all = [root, ...Array.from(root.querySelectorAll('*'))];\n for (const element of all) {\n if (element.matches(CONTENT_SELECTOR)) {\n contents.add(outermost(element));\n } else if (\n element.matches(ATTRIBUTES_SELECTOR) &&\n !element.closest(CONTENT_SELECTOR)\n ) {\n attributes.add(element);\n }\n }\n }\n\n private handleMutations(records: MutationRecord[]) {\n const contents = new Set<Element>();\n const attributes = new Set<Element>();\n\n for (const record of records) {\n const target =\n record.target.nodeType === Node.ELEMENT_NODE\n ? (record.target as Element)\n : record.target.parentElement;\n if (!target) {\n continue;\n }\n\n const content = target.closest(CONTENT_SELECTOR);\n if (content) {\n contents.add(outermost(content));\n continue;\n }\n\n if (record.type === 'attributes' && target.matches(ATTRIBUTES_SELECTOR)) {\n attributes.add(target);\n }\n record.addedNodes.forEach((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n this.collect(node as Element, contents, attributes);\n }\n });\n }\n\n if (records.some((record) => record.removedNodes.length > 0)) {\n this.forget((element) => !element.isConnected);\n }\n contents.forEach((element) => this.translateContent(element));\n attributes.forEach((element) => this.translateAttributes(element));\n }\n\n private forget(predicate: (element: Element) => boolean) {\n for (const element of [...this.contents.keys()]) {\n if (predicate(element)) {\n this.contents.delete(element);\n }\n }\n for (const element of [...this.attributes.keys()]) {\n if (predicate(element)) {\n this.attributes.delete(element);\n }\n }\n }\n\n private translateContent(element: Element, force = false) {\n const html = element.innerHTML;\n let translation = this.contents.get(element);\n\n if (!translation) {\n translation = { source: html, requestId: 0 };\n this.contents.set(element, translation);\n } else if (html !== translation.rendered && html !== translation.source) {\n // changed by someone else, e.g. the page's own scripts\n translation.source = html;\n translation.rendered = undefined;\n } else if (!force) {\n return;\n }\n\n const [, leadingWhitespace, text, trailingWhitespace] =\n /^(\\s*)([\\s\\S]*?)(\\s*)$/.exec(\n translation.source.replace(/<!--[\\s\\S]*?-->/g, '')\n )!;\n if (!text) {\n return;\n }\n\n // make sure that we only ever use the response of the most recent request.\n const requestId = ++translation.requestId;\n const current = translation;\n this.translate(text, optionsOf(element)).then((translated) => {\n if (requestId !== current.requestId || !element.isConnected) {\n return;\n }\n const rendered = `${leadingWhitespace}${translated}${trailingWhitespace}`;\n if (element.innerHTML !== rendered) {\n element.innerHTML = rendered;\n }\n current.rendered = element.innerHTML;\n });\n }\n\n private translateAttributes(element: Element, force = false) {\n const names = (element.getAttribute('data-t-attrs') ?? '')\n .split(/[\\s,]+/)\n .filter(Boolean);\n let translations = this.attributes.get(element);\n if (!translations) {\n translations = new Map();\n this.attributes.set(element, translations);\n }\n\n for (const name of names) {\n const value = element.getAttribute(name);\n if (!value?.trim()) {\n continue;\n }\n\n let translation = translations.get(name);\n if (!translation) {\n translation = { source: value, requestId: 0 };\n translations.set(name, translation);\n } else if (\n value !== translation.rendered &&\n value !== translation.source\n ) {\n translation.source = value;\n translation.rendered = undefined;\n } else if (!force) {\n continue;\n }\n\n const requestId = ++translation.requestId;\n const current = translation;\n this.translate(current.source, optionsOf(element)).then((translated) => {\n if (requestId !== current.requestId || !element.isConnected) {\n return;\n }\n current.rendered = translated;\n if (element.getAttribute(name) !== translated) {\n element.setAttribute(name, translated);\n }\n });\n }\n }\n}\n\n/**\n * Starts translating the page: the content of every `<t>` element (or element\n * with a `data-t` attribute), and the attributes listed in `data-t-attrs`.\n * Content added later is translated as well.\n */\nexport function createMagicTranslate(\n options: MagicTranslateOptions\n): MagicTranslate {\n return new MagicTranslate(options);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["CONTENT_SELECTOR","ATTRIBUTES_SELECTOR","outermost","current","element","parent","optionsOf","options","lang","formality","MagicTranslate","libraryWebsite","utsLocaleToLanguage","language","listener","params","loaderFactory","defaultLoaderFactory","DataLoader","debug","sourceLanguage","_apiUrl","cacheKeyFn","apiKey","contents","attributes","root","records","all","record","target","content","node","predicate","html","translation","force","leadingWhitespace","text","trailingWhitespace","requestId","rendered","translated","names","translations","name","value","createMagicTranslate"],"sources":["../src/magic-translate.ts"],"sourcesContent":["import {\n cacheKeyFn,\n DataLoader,\n DataLoaderLoadParams,\n defaultLoaderFactory,\n Language,\n libraryWebsite,\n MagicTranslateConfig,\n TranslateOptions,\n utsLocaleToLanguage,\n} from '@magic-translate/core';\n\n/**\n * Type alias to make the language enum more flexible to also allow passing language strings\n * instead of just the enum.\n */\nexport type Languages = `${Language}`;\n\nexport type TranslateParams = Omit<DataLoaderLoadParams, 'text'>;\n\nexport interface MagicTranslateOptions extends Omit<\n MagicTranslateConfig,\n 'language'\n> {\n /**\n * The language content is translated to. Defaults to the browser's language.\n */\n language?: Languages;\n /**\n * The element whose content is translated. Defaults to the whole document.\n */\n root?: Element;\n}\n\n/** Elements whose content is translated. */\nexport const CONTENT_SELECTOR = 't, mt-translate, [data-t]';\n/** Elements with attributes to translate, e.g. `data-t-attrs=\"placeholder title\"`. */\nexport const ATTRIBUTES_SELECTOR = '[data-t-attrs]';\n\ninterface Translation {\n source: string;\n // what was last written to the DOM, to tell our own changes from others\n rendered?: string;\n requestId: number;\n}\n\nfunction outermost(element: Element): Element {\n let current = element;\n for (\n let parent = current.parentElement?.closest(CONTENT_SELECTOR);\n parent;\n parent = current.parentElement?.closest(CONTENT_SELECTOR)\n ) {\n current = parent;\n }\n return current;\n}\n\nfunction optionsOf(element: Element): TranslateOptions {\n const options: TranslateOptions = {};\n const lang = element.getAttribute('data-lang');\n const formality = element.getAttribute('data-formality');\n if (lang) {\n options.lang = lang as Languages;\n }\n if (formality) {\n options.formality = formality as TranslateOptions['formality'];\n }\n return options;\n}\n\nexport class MagicTranslate {\n private currentLanguage: Languages;\n private dataLoader: DataLoader<DataLoaderLoadParams, string, string>;\n private readonly root?: Element;\n private readonly contents = new Map<Element, Translation>();\n private readonly attributes = new Map<Element, Map<string, Translation>>();\n private readonly listeners = new Set<(language: Languages) => void>();\n private observer?: MutationObserver;\n\n constructor(private readonly options: MagicTranslateOptions) {\n if (!options.apiKey) {\n throw new Error(`Missing API key. Please get one at ${libraryWebsite}`);\n }\n\n this.currentLanguage =\n options.language ??\n utsLocaleToLanguage(\n typeof navigator === 'undefined' ? undefined : navigator.language\n );\n this.dataLoader = this.createDataLoader();\n\n if (typeof document !== 'undefined') {\n this.root = options.root ?? document.documentElement;\n this.start(this.root);\n }\n }\n\n /**\n * The language content is currently translated to.\n */\n get language(): Languages {\n return this.currentLanguage;\n }\n\n /**\n * Translates the page to another language.\n */\n setLanguage(language: Languages): void {\n if (language === this.currentLanguage) {\n return;\n }\n\n this.currentLanguage = language;\n this.dataLoader = this.createDataLoader();\n\n this.forget(\n (element) => !element.isConnected || !this.root?.contains(element)\n );\n this.contents.forEach((_, element) => this.translateContent(element, true));\n this.attributes.forEach((_, element) =>\n this.translateAttributes(element, true)\n );\n this.listeners.forEach((listener) => listener(language));\n }\n\n /**\n * Calls `listener` whenever the language changes. Returns a function that\n * removes the listener again.\n */\n onLanguageChange(listener: (language: Languages) => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /**\n * Translates a string to the current language.\n */\n translate(text: string, params: TranslateParams = {}): Promise<string> {\n return this.dataLoader.load({ text, ...params });\n }\n\n /**\n * Stops translating the page. Content that is already translated stays\n * translated.\n */\n destroy(): void {\n this.observer?.disconnect();\n this.contents.clear();\n this.attributes.clear();\n this.listeners.clear();\n }\n\n private createDataLoader() {\n const { debug, apiKey, sourceLanguage, _apiUrl, formality } = this.options;\n const loaderFactory = this.options._loaderFactory ?? defaultLoaderFactory;\n\n return new DataLoader<DataLoaderLoadParams, string, string>(\n loaderFactory({\n debug: !!debug,\n apiKey,\n lang: this.currentLanguage,\n sourceLang: sourceLanguage,\n apiUrl: _apiUrl,\n formality,\n }),\n {\n cacheKeyFn: cacheKeyFn(apiKey, sourceLanguage, this.currentLanguage),\n }\n );\n }\n\n private start(root: Element) {\n const contents = new Set<Element>();\n const attributes = new Set<Element>();\n this.collect(root, contents, attributes);\n contents.forEach((element) => this.translateContent(element));\n attributes.forEach((element) => this.translateAttributes(element));\n\n // Picks up content that is added or changed later.\n this.observer = new MutationObserver((records) =>\n this.handleMutations(records)\n );\n this.observer.observe(root, {\n subtree: true,\n childList: true,\n characterData: true,\n attributes: true,\n });\n }\n\n private collect(\n root: Element,\n contents: Set<Element>,\n attributes: Set<Element>\n ) {\n const all = [root, ...Array.from(root.querySelectorAll('*'))];\n for (const element of all) {\n if (element.matches(CONTENT_SELECTOR)) {\n contents.add(outermost(element));\n } else if (\n element.matches(ATTRIBUTES_SELECTOR) &&\n !element.closest(CONTENT_SELECTOR)\n ) {\n attributes.add(element);\n }\n }\n }\n\n private handleMutations(records: MutationRecord[]) {\n const contents = new Set<Element>();\n const attributes = new Set<Element>();\n\n for (const record of records) {\n const target =\n record.target.nodeType === Node.ELEMENT_NODE\n ? (record.target as Element)\n : record.target.parentElement;\n if (!target) {\n continue;\n }\n\n const content = target.closest(CONTENT_SELECTOR);\n if (content) {\n contents.add(outermost(content));\n continue;\n }\n\n if (record.type === 'attributes' && target.matches(ATTRIBUTES_SELECTOR)) {\n attributes.add(target);\n }\n record.addedNodes.forEach((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n this.collect(node as Element, contents, attributes);\n }\n });\n }\n\n if (records.some((record) => record.removedNodes.length > 0)) {\n this.forget((element) => !element.isConnected);\n }\n contents.forEach((element) => this.translateContent(element));\n attributes.forEach((element) => this.translateAttributes(element));\n }\n\n private forget(predicate: (element: Element) => boolean) {\n for (const element of this.contents.keys()) {\n if (predicate(element)) {\n this.contents.delete(element);\n }\n }\n for (const element of this.attributes.keys()) {\n if (predicate(element)) {\n this.attributes.delete(element);\n }\n }\n }\n\n private translateContent(element: Element, force = false) {\n const html = element.innerHTML;\n let translation = this.contents.get(element);\n\n if (!translation) {\n translation = { source: html, requestId: 0 };\n this.contents.set(element, translation);\n } else if (html !== translation.rendered && html !== translation.source) {\n // changed by someone else, e.g. the page's own scripts\n translation.source = html;\n translation.rendered = undefined;\n } else if (!force) {\n return;\n }\n\n const [, leadingWhitespace, text, trailingWhitespace] =\n /^(\\s*)([\\s\\S]*?)(\\s*)$/.exec(\n translation.source.replace(/<!--[\\s\\S]*?-->/g, '')\n )!;\n if (!text) {\n return;\n }\n\n // make sure that we only ever use the response of the most recent request.\n const requestId = ++translation.requestId;\n const current = translation;\n this.translate(text, optionsOf(element)).then((translated) => {\n if (requestId !== current.requestId || !element.isConnected) {\n return;\n }\n const rendered = `${leadingWhitespace}${translated}${trailingWhitespace}`;\n if (element.innerHTML !== rendered) {\n element.innerHTML = rendered;\n }\n current.rendered = element.innerHTML;\n });\n }\n\n private translateAttributes(element: Element, force = false) {\n const names = (element.getAttribute('data-t-attrs') ?? '')\n .split(/[\\s,]+/)\n .filter(Boolean);\n let translations = this.attributes.get(element);\n if (!translations) {\n translations = new Map();\n this.attributes.set(element, translations);\n }\n\n for (const name of names) {\n const value = element.getAttribute(name);\n if (!value?.trim()) {\n continue;\n }\n\n let translation = translations.get(name);\n if (!translation) {\n translation = { source: value, requestId: 0 };\n translations.set(name, translation);\n } else if (\n value !== translation.rendered &&\n value !== translation.source\n ) {\n translation.source = value;\n translation.rendered = undefined;\n } else if (!force) {\n continue;\n }\n\n const requestId = ++translation.requestId;\n const current = translation;\n this.translate(current.source, optionsOf(element)).then((translated) => {\n if (requestId !== current.requestId || !element.isConnected) {\n return;\n }\n current.rendered = translated;\n if (element.getAttribute(name) !== translated) {\n element.setAttribute(name, translated);\n }\n });\n }\n }\n}\n\n/**\n * Starts translating the page: the content of every `<t>` element (or element\n * with a `data-t` attribute), and the attributes listed in `data-t-attrs`.\n * Content added later is translated as well.\n */\nexport function createMagicTranslate(\n options: MagicTranslateOptions\n): MagicTranslate {\n return new MagicTranslate(options);\n}\n"],"mappings":"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"}
|
|
@@ -4,5 +4,5 @@ Keys:
|
|
|
4
4
|
`+String(t.keys)+`
|
|
5
5
|
|
|
6
6
|
Values:
|
|
7
|
-
`+String(e));i(t);for(var n=0;n<t.callbacks.length;n++){var r=e[n];r instanceof Error?t.callbacks[n].reject(r):t.callbacks[n].resolve(r)}}).catch(function(n){r(e,t,n)})})(e,n)}),n}(this),o=this._cacheMap;if(o){t=this._cacheKeyFn(e);var s=o.get(t);if(s){var c=n.cacheHits||=[];return new Promise(function(e){c.push(function(){e(s)})})}}n.keys.push(e);var l=new Promise(function(e,t){n.callbacks.push({resolve:e,reject:t})});return o&&o.set(t,l),l},t.loadMany=function(e){if(!a(e))throw TypeError(`The loader.loadMany() function must be called with Array<key> but got: `+e+`.`);for(var t=[],n=0;n<e.length;n++)t.push(this.load(e[n]).catch(function(e){return e}));return Promise.all(t)},t.clear=function(e){var t=this._cacheMap;if(t){var n=this._cacheKeyFn(e);t.delete(n)}return this},t.clearAll=function(){var e=this._cacheMap;return e&&e.clear(),this},t.prime=function(e,t){var n=this._cacheMap;if(n){var r,i=this._cacheKeyFn(e);n.get(i)===void 0&&(t instanceof Error?(r=Promise.reject(t)).catch(function(){}):r=Promise.resolve(t),n.set(i,r))}return this},e}(),n=typeof process==`object`&&typeof process.nextTick==`function`?function(t){e||=Promise.resolve(),e.then(function(){process.nextTick(t)})}:typeof setImmediate==`function`?function(e){setImmediate(e)}:function(e){setTimeout(e)};function r(e,t,n){i(t);for(var r=0;r<t.keys.length;r++)e.clear(t.keys[r]),t.callbacks[r].reject(n)}function i(e){if(e.cacheHits)for(var t=0;t<e.cacheHits.length;t++)e.cacheHits[t]()}function a(e){return typeof e==`object`&&!!e&&typeof e.length==`number`&&(e.length===0||e.length>0&&Object.prototype.hasOwnProperty.call(e,e.length-1))}return d=t}());function m({debug:e,apiKey:t,sourceLanguage:n,_apiUrl:i,formality:a,_loaderFactory:o}){let s={debug:!!e,apiKey:t,lang:r.EN,sourceLang:n,apiUrl:i,formality:a},u=new p((o??l)(s),{cacheKeyFn:c(t,n)});return(e,t,n)=>u.load({text:t,...n,lang:e})}var h=m,g=r.EN;function _(e,t){if(!e)return t??g;if([r.FA_AF,r.FR_CA,r.PT_PT,r.ES_MX].includes(e))return e;let n=e.includes(`-`)?e.split(`-`)[0]:e;return Object.values(r).includes(n)?n:t||(console.warn(`Language not found for UTS locale "${e}" and no fallback provided was provided. Falling back to "${g}"`),g)}var v=`t, mt-translate, [data-t]`,y=`[data-t-attrs]`;function b(e){let t=e;for(let e=t.parentElement?.closest(v);e;e=t.parentElement?.closest(v))t=e;return t}function x(e){let t={},n=e.getAttribute(`data-lang`),r=e.getAttribute(`data-formality`);return n&&(t.lang=n),r&&(t.formality=r),t}var S=class{constructor(e){if(this.options=e,this.contents=new Map,this.attributes=new Map,this.listeners=new Set,!e.apiKey)throw Error(`Missing API key. Please get one at ${n}`);this.currentLanguage=e.language??_(typeof navigator>`u`?void 0:navigator.language),this.dataLoader=this.createDataLoader(),typeof document<`u`&&(this.root=e.root??document.documentElement,this.start(this.root))}get language(){return this.currentLanguage}setLanguage(e){e!==this.currentLanguage&&(this.currentLanguage=e,this.dataLoader=this.createDataLoader(),this.forget(e=>!e.isConnected||!this.root?.contains(e)),this.contents.forEach((e,t)=>this.translateContent(t,!0)),this.attributes.forEach((e,t)=>this.translateAttributes(t,!0)),this.listeners.forEach(t=>t(e)))}onLanguageChange(e){return this.listeners.add(e),()=>this.listeners.delete(e)}translate(e,t={}){return this.dataLoader.load({text:e,...t})}destroy(){this.observer?.disconnect(),this.contents.clear(),this.attributes.clear(),this.listeners.clear()}createDataLoader(){let{debug:e,apiKey:t,sourceLanguage:n,_apiUrl:r,formality:i}=this.options;return new p((this.options._loaderFactory??l)({debug:!!e,apiKey:t,lang:this.currentLanguage,sourceLang:n,apiUrl:r,formality:i}),{cacheKeyFn:c(t,n,this.currentLanguage)})}start(e){let t=new Set,n=new Set;this.collect(e,t,n),t.forEach(e=>this.translateContent(e)),n.forEach(e=>this.translateAttributes(e)),this.observer=new MutationObserver(e=>this.handleMutations(e)),this.observer.observe(e,{subtree:!0,childList:!0,characterData:!0,attributes:!0})}collect(e,t,n){let r=[e,...Array.from(e.querySelectorAll(`*`))];for(let e of r)e.matches(`t, mt-translate, [data-t]`)?t.add(b(e)):e.matches(`[data-t-attrs]`)&&!e.closest(`t, mt-translate, [data-t]`)&&n.add(e)}handleMutations(e){let t=new Set,n=new Set;for(let r of e){let e=r.target.nodeType===Node.ELEMENT_NODE?r.target:r.target.parentElement;if(!e)continue;let i=e.closest(v);i?t.add(b(i)):(r.type===`attributes`&&e.matches(`[data-t-attrs]`)&&n.add(e),r.addedNodes.forEach(e=>{e.nodeType===Node.ELEMENT_NODE&&this.collect(e,t,n)}))}e.some(e=>e.removedNodes.length>0)&&this.forget(e=>!e.isConnected),t.forEach(e=>this.translateContent(e)),n.forEach(e=>this.translateAttributes(e))}forget(e){for(let t of
|
|
7
|
+
`+String(e));i(t);for(var n=0;n<t.callbacks.length;n++){var r=e[n];r instanceof Error?t.callbacks[n].reject(r):t.callbacks[n].resolve(r)}}).catch(function(n){r(e,t,n)})})(e,n)}),n}(this),o=this._cacheMap;if(o){t=this._cacheKeyFn(e);var s=o.get(t);if(s){var c=n.cacheHits||=[];return new Promise(function(e){c.push(function(){e(s)})})}}n.keys.push(e);var l=new Promise(function(e,t){n.callbacks.push({resolve:e,reject:t})});return o&&o.set(t,l),l},t.loadMany=function(e){if(!a(e))throw TypeError(`The loader.loadMany() function must be called with Array<key> but got: `+e+`.`);for(var t=[],n=0;n<e.length;n++)t.push(this.load(e[n]).catch(function(e){return e}));return Promise.all(t)},t.clear=function(e){var t=this._cacheMap;if(t){var n=this._cacheKeyFn(e);t.delete(n)}return this},t.clearAll=function(){var e=this._cacheMap;return e&&e.clear(),this},t.prime=function(e,t){var n=this._cacheMap;if(n){var r,i=this._cacheKeyFn(e);n.get(i)===void 0&&(t instanceof Error?(r=Promise.reject(t)).catch(function(){}):r=Promise.resolve(t),n.set(i,r))}return this},e}(),n=typeof process==`object`&&typeof process.nextTick==`function`?function(t){e||=Promise.resolve(),e.then(function(){process.nextTick(t)})}:typeof setImmediate==`function`?function(e){setImmediate(e)}:function(e){setTimeout(e)};function r(e,t,n){i(t);for(var r=0;r<t.keys.length;r++)e.clear(t.keys[r]),t.callbacks[r].reject(n)}function i(e){if(e.cacheHits)for(var t=0;t<e.cacheHits.length;t++)e.cacheHits[t]()}function a(e){return typeof e==`object`&&!!e&&typeof e.length==`number`&&(e.length===0||e.length>0&&Object.prototype.hasOwnProperty.call(e,e.length-1))}return d=t}());function m({debug:e,apiKey:t,sourceLanguage:n,_apiUrl:i,formality:a,_loaderFactory:o}){let s={debug:!!e,apiKey:t,lang:r.EN,sourceLang:n,apiUrl:i,formality:a},u=new p((o??l)(s),{cacheKeyFn:c(t,n)});return(e,t,n)=>u.load({text:t,...n,lang:e})}var h=m,g=r.EN;function _(e,t){if(!e)return t??g;if([r.FA_AF,r.FR_CA,r.PT_PT,r.ES_MX].includes(e))return e;let n=e.includes(`-`)?e.split(`-`)[0]:e;return Object.values(r).includes(n)?n:t||(console.warn(`Language not found for UTS locale "${e}" and no fallback provided was provided. Falling back to "${g}"`),g)}var v=`t, mt-translate, [data-t]`,y=`[data-t-attrs]`;function b(e){let t=e;for(let e=t.parentElement?.closest(v);e;e=t.parentElement?.closest(v))t=e;return t}function x(e){let t={},n=e.getAttribute(`data-lang`),r=e.getAttribute(`data-formality`);return n&&(t.lang=n),r&&(t.formality=r),t}var S=class{constructor(e){if(this.options=e,this.contents=new Map,this.attributes=new Map,this.listeners=new Set,!e.apiKey)throw Error(`Missing API key. Please get one at ${n}`);this.currentLanguage=e.language??_(typeof navigator>`u`?void 0:navigator.language),this.dataLoader=this.createDataLoader(),typeof document<`u`&&(this.root=e.root??document.documentElement,this.start(this.root))}get language(){return this.currentLanguage}setLanguage(e){e!==this.currentLanguage&&(this.currentLanguage=e,this.dataLoader=this.createDataLoader(),this.forget(e=>!e.isConnected||!this.root?.contains(e)),this.contents.forEach((e,t)=>this.translateContent(t,!0)),this.attributes.forEach((e,t)=>this.translateAttributes(t,!0)),this.listeners.forEach(t=>t(e)))}onLanguageChange(e){return this.listeners.add(e),()=>this.listeners.delete(e)}translate(e,t={}){return this.dataLoader.load({text:e,...t})}destroy(){this.observer?.disconnect(),this.contents.clear(),this.attributes.clear(),this.listeners.clear()}createDataLoader(){let{debug:e,apiKey:t,sourceLanguage:n,_apiUrl:r,formality:i}=this.options;return new p((this.options._loaderFactory??l)({debug:!!e,apiKey:t,lang:this.currentLanguage,sourceLang:n,apiUrl:r,formality:i}),{cacheKeyFn:c(t,n,this.currentLanguage)})}start(e){let t=new Set,n=new Set;this.collect(e,t,n),t.forEach(e=>this.translateContent(e)),n.forEach(e=>this.translateAttributes(e)),this.observer=new MutationObserver(e=>this.handleMutations(e)),this.observer.observe(e,{subtree:!0,childList:!0,characterData:!0,attributes:!0})}collect(e,t,n){let r=[e,...Array.from(e.querySelectorAll(`*`))];for(let e of r)e.matches(`t, mt-translate, [data-t]`)?t.add(b(e)):e.matches(`[data-t-attrs]`)&&!e.closest(`t, mt-translate, [data-t]`)&&n.add(e)}handleMutations(e){let t=new Set,n=new Set;for(let r of e){let e=r.target.nodeType===Node.ELEMENT_NODE?r.target:r.target.parentElement;if(!e)continue;let i=e.closest(v);i?t.add(b(i)):(r.type===`attributes`&&e.matches(`[data-t-attrs]`)&&n.add(e),r.addedNodes.forEach(e=>{e.nodeType===Node.ELEMENT_NODE&&this.collect(e,t,n)}))}e.some(e=>e.removedNodes.length>0)&&this.forget(e=>!e.isConnected),t.forEach(e=>this.translateContent(e)),n.forEach(e=>this.translateAttributes(e))}forget(e){for(let t of this.contents.keys())e(t)&&this.contents.delete(t);for(let t of this.attributes.keys())e(t)&&this.attributes.delete(t)}translateContent(e,t=!1){let n=e.innerHTML,r=this.contents.get(e);if(!r)r={source:n,requestId:0},this.contents.set(e,r);else if(n!==r.rendered&&n!==r.source)r.source=n,r.rendered=void 0;else if(!t)return;let[,i,a,o]=/^(\s*)([\s\S]*?)(\s*)$/.exec(r.source.replace(/<!--[\s\S]*?-->/g,``));if(!a)return;let s=++r.requestId,c=r;this.translate(a,x(e)).then(t=>{if(s!==c.requestId||!e.isConnected)return;let n=`${i}${t}${o}`;e.innerHTML!==n&&(e.innerHTML=n),c.rendered=e.innerHTML})}translateAttributes(e,t=!1){let n=(e.getAttribute(`data-t-attrs`)??``).split(/[\s,]+/).filter(Boolean),r=this.attributes.get(e);r||(r=new Map,this.attributes.set(e,r));for(let i of n){let n=e.getAttribute(i);if(!n?.trim())continue;let a=r.get(i);if(!a)a={source:n,requestId:0},r.set(i,a);else if(n!==a.rendered&&n!==a.source)a.source=n,a.rendered=void 0;else if(!t)continue;let o=++a.requestId,s=a;this.translate(s.source,x(e)).then(t=>{o===s.requestId&&e.isConnected&&(s.rendered=t,e.getAttribute(i)!==t&&e.setAttribute(i,t))})}}};function C(e){return new S(e)}var w=`magic-translate-language`;function T(){try{return localStorage.getItem(w)??void 0}catch{return}}var E=document.currentScript,D=E?.dataset.apiKey;if(E&&D){let{language:e,sourceLanguage:t,formality:n}=E.dataset,r=()=>{let r=C({apiKey:D,language:T()??e,sourceLanguage:t,formality:n,debug:E.hasAttribute(`data-debug`)});r.onLanguageChange(e=>{try{localStorage.setItem(w,e)}catch{}}),window.magicTranslate=r,document.dispatchEvent(new CustomEvent(`magictranslate:ready`,{detail:r}))};document.readyState===`loading`?document.addEventListener(`DOMContentLoaded`,r):r()}return e.ATTRIBUTES_SELECTOR=y,e.CONTENT_SELECTOR=v,e.DataLoader=p,Object.defineProperty(e,"Language",{enumerable:!0,get:function(){return r}}),e.MagicTranslate=S,e.cacheKeyFn=c,e.createMagicTranslate=C,e.defaultDataLoaderOptions=o,e.defaultLoaderFactory=l,e.libraryName=t,e.libraryWebsite=n,e.setupT=h,e.setupTranslate=m,e.utsLocaleToLanguage=_,e})({});
|
|
8
8
|
//# sourceMappingURL=magic-translate.min.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"magic-translate.min.js","names":["libraryWebsite","utsLocaleToLanguage","defaultLoaderFactory","DataLoader","cacheKeyFn","exports","e","t","n","r","c","i","a","u","s","l","h","o","y","d","m","g","CONTENT_SELECTOR","ATTRIBUTES_SELECTOR","outermost","current","element","parent","optionsOf","options","lang","formality","MagicTranslate","language","listener","params","debug","sourceLanguage","_apiUrl","apiKey","contents","attributes","root","records","all","record","target","content","node","predicate","html","translation","force","leadingWhitespace","text","trailingWhitespace","requestId","rendered","translated","names","translations","name","value","createMagicTranslate","STORAGE_KEY","storedLanguage","script","start","magicTranslate"],"sources":["../node_modules/@magic-translate/core/dist/index.es.js","../src/magic-translate.ts","../src/script.ts"],"sourcesContent":["/*\n * 'Magic Translate Core'\n * {@link https://https://magictranslate.io\n * @copyright i42 GmbH\n */\nconst e=\"Magic Translate\",t=\"https://magictranslate.io\";var r;function n(e){return Object.keys(e).filter(t=>void 0!==e[t]).reduce((t,r)=>({...t,[r]:e[r]}),{})}function a(e){const t=new URLSearchParams,r=(e,n=\"\")=>{Array.isArray(e)?e.forEach((e,t)=>{r(e,n?`${n}[${t}]`:`[${t}]`)}):\"object\"==typeof e&&null!==e?Object.entries(e).forEach(([e,t])=>{r(t,n?`${n}.${e}`:e)}):t.append(n,e)};return r(e),t}!function(e){e.AF=\"af\",e.SQ=\"sq\",e.AM=\"am\",e.AR=\"ar\",e.HY=\"hy\",e.AZ=\"az\",e.BN=\"bn\",e.BS=\"bs\",e.BG=\"bg\",e.CA=\"ca\",e.ZH=\"zh\",e.ZH_TW=\"zh-TW\",e.HR=\"hr\",e.CS=\"cs\",e.DA=\"da\",e.FA_AF=\"fa-AF\",e.NL=\"nl\",e.EN=\"en\",e.ET=\"et\",e.FA=\"fa\",e.TL=\"tl\",e.FI=\"fi\",e.FR=\"fr\",e.FR_CA=\"fr-CA\",e.KA=\"ka\",e.DE=\"de\",e.EL=\"el\",e.GU=\"gu\",e.HT=\"ht\",e.HA=\"ha\",e.HE=\"he\",e.HI=\"hi\",e.HU=\"hu\",e.IS=\"is\",e.ID=\"id\",e.GA=\"ga\",e.IT=\"it\",e.JA=\"ja\",e.KN=\"kn\",e.KK=\"kk\",e.KO=\"ko\",e.LV=\"lv\",e.LT=\"lt\",e.MK=\"mk\",e.MS=\"ms\",e.ML=\"ml\",e.MT=\"mt\",e.MR=\"mr\",e.MN=\"mn\",e.NO=\"no\",e.PS=\"ps\",e.PL=\"pl\",e.PT=\"pt\",e.PT_PT=\"pt-PT\",e.PA=\"pa\",e.RO=\"ro\",e.RU=\"ru\",e.SR=\"sr\",e.SI=\"si\",e.SK=\"sk\",e.SL=\"sl\",e.SO=\"so\",e.ES=\"es\",e.ES_MX=\"es-MX\",e.SW=\"sw\",e.SV=\"sv\",e.TA=\"ta\",e.TE=\"te\",e.TH=\"th\",e.TR=\"tr\",e.UK=\"uk\",e.UR=\"ur\",e.UZ=\"uz\",e.VI=\"vi\",e.CY=\"cy\"}(r||(r={}));const o={debug:!1,apiUrl:\"https://api.magictranslate.io\",lang:r.DE};var c;!function(e){e.QUOTA_EXCEEDED_ERROR=\"QUOTA_EXCEEDED_ERROR\"}(c||(c={}));const i=(e,t,r)=>a=>Object.entries(n({apiKey:e,language:r,sourceLanguage:a.sourceLang??t??\"auto\",...a})).sort(([e])=>e.localeCompare(e)).reduce((e,t)=>`${e};${t.join(\"=\")}`,\"\"),u=t=>async r=>{if(t.debug&&console.debug(`[${e}]: batch function called with: `,r),t.lang===t.sourceLang)return r.map(e=>e.text);const{apiKey:c,lang:i,formality:u}=t,s=n({apiKey:c,lang:i,formality:u,items:r.map(({text:e,sourceLang:t,lang:r,...a})=>n({text:e,lang:r,sourceLang:t,...a}))});return fetch(`${t.apiUrl??o.apiUrl}/v1/translate`,{method:\"POST\",body:t.useJson?JSON.stringify(s):a(s),headers:{\"Content-Type\":t.useJson?\"application/json\":\"application/x-www-form-urlencoded\"}}).then(e=>e.json()).then(t=>\"results\"in t?t.results:(\"code\"in t?console.error(`[${e}]: ${t.message}`):console.error(`[${e}]: Unexpected payload from magic translate server: ${JSON.stringify(t)}`),r.map(e=>e.text))).catch(t=>(console.error(`[${e}]: Error while loading translations: `,t),r.map(e=>e.text)))};function s(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,\"default\")?e.default:e}var l,h;var f=function(){if(h)return l;h=1;var e,t=function(){function e(e,t){if(\"function\"!=typeof e)throw new TypeError(\"DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but got: \"+e+\".\");this._batchLoadFn=e,this._maxBatchSize=function(e){var t=!e||!1!==e.batch;if(!t)return 1;var r=e&&e.maxBatchSize;if(void 0===r)return 1/0;if(\"number\"!=typeof r||r<1)throw new TypeError(\"maxBatchSize must be a positive number: \"+r);return r}(t),this._batchScheduleFn=function(e){var t=e&&e.batchScheduleFn;if(void 0===t)return r;if(\"function\"!=typeof t)throw new TypeError(\"batchScheduleFn must be a function: \"+t);return t}(t),this._cacheKeyFn=function(e){var t=e&&e.cacheKeyFn;if(void 0===t)return function(e){return e};if(\"function\"!=typeof t)throw new TypeError(\"cacheKeyFn must be a function: \"+t);return t}(t),this._cacheMap=function(e){var t=!e||!1!==e.cache;if(!t)return null;var r=e&&e.cacheMap;if(void 0===r)return new Map;if(null!==r){var n=[\"get\",\"set\",\"delete\",\"clear\"].filter(function(e){return r&&\"function\"!=typeof r[e]});if(0!==n.length)throw new TypeError(\"Custom cacheMap missing methods: \"+n.join(\", \"))}return r}(t),this._batch=null,this.name=function(e){if(e&&e.name)return e.name;return null}(t)}var t=e.prototype;return t.load=function(e){if(null==e)throw new TypeError(\"The loader.load() function must be called with a value, but got: \"+String(e)+\".\");var t,r=function(e){var t=e._batch;if(null!==t&&!t.hasDispatched&&t.keys.length<e._maxBatchSize)return t;var r={hasDispatched:!1,keys:[],callbacks:[]};return e._batch=r,e._batchScheduleFn(function(){!function(e,t){if(t.hasDispatched=!0,0===t.keys.length)return void a(t);var r;try{r=e._batchLoadFn(t.keys)}catch(r){return n(e,t,new TypeError(\"DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but the function errored synchronously: \"+String(r)+\".\"))}if(!r||\"function\"!=typeof r.then)return n(e,t,new TypeError(\"DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but the function did not return a Promise: \"+String(r)+\".\"));r.then(function(e){if(!o(e))throw new TypeError(\"DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but the function did not return a Promise of an Array: \"+String(e)+\".\");if(e.length!==t.keys.length)throw new TypeError(\"DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but the function did not return a Promise of an Array of the same length as the Array of keys.\\n\\nKeys:\\n\"+String(t.keys)+\"\\n\\nValues:\\n\"+String(e));a(t);for(var r=0;r<t.callbacks.length;r++){var n=e[r];n instanceof Error?t.callbacks[r].reject(n):t.callbacks[r].resolve(n)}}).catch(function(r){n(e,t,r)})}(e,r)}),r}(this),c=this._cacheMap;if(c){t=this._cacheKeyFn(e);var i=c.get(t);if(i){var u=r.cacheHits||(r.cacheHits=[]);return new Promise(function(e){u.push(function(){e(i)})})}}r.keys.push(e);var s=new Promise(function(e,t){r.callbacks.push({resolve:e,reject:t})});return c&&c.set(t,s),s},t.loadMany=function(e){if(!o(e))throw new TypeError(\"The loader.loadMany() function must be called with Array<key> but got: \"+e+\".\");for(var t=[],r=0;r<e.length;r++)t.push(this.load(e[r]).catch(function(e){return e}));return Promise.all(t)},t.clear=function(e){var t=this._cacheMap;if(t){var r=this._cacheKeyFn(e);t.delete(r)}return this},t.clearAll=function(){var e=this._cacheMap;return e&&e.clear(),this},t.prime=function(e,t){var r=this._cacheMap;if(r){var n,a=this._cacheKeyFn(e);if(void 0===r.get(a))t instanceof Error?(n=Promise.reject(t)).catch(function(){}):n=Promise.resolve(t),r.set(a,n)}return this},e}(),r=\"object\"==typeof process&&\"function\"==typeof process.nextTick?function(t){e||(e=Promise.resolve()),e.then(function(){process.nextTick(t)})}:\"function\"==typeof setImmediate?function(e){setImmediate(e)}:function(e){setTimeout(e)};function n(e,t,r){a(t);for(var n=0;n<t.keys.length;n++)e.clear(t.keys[n]),t.callbacks[n].reject(r)}function a(e){if(e.cacheHits)for(var t=0;t<e.cacheHits.length;t++)e.cacheHits[t]()}function o(e){return\"object\"==typeof e&&null!==e&&\"number\"==typeof e.length&&(0===e.length||e.length>0&&Object.prototype.hasOwnProperty.call(e,e.length-1))}return l=t}(),p=s(f);function y({debug:e,apiKey:t,sourceLanguage:n,_apiUrl:a,formality:o,_loaderFactory:c}){const s={debug:!!e,apiKey:t,lang:r.EN,sourceLang:n,apiUrl:a,formality:o},l=new p((c??u)(s),{cacheKeyFn:i(t,n)});return(e,t,r)=>l.load({text:t,...r,lang:e})}const d=y,m=r.EN;function g(e,t){if(!e)return t??m;if([r.FA_AF,r.FR_CA,r.PT_PT,r.ES_MX].includes(e))return e;const n=e.includes(\"-\")?e.split(\"-\")[0]:e;return Object.values(r).includes(n)?n:t||(console.warn(`Language not found for UTS locale \"${e}\" and no fallback provided was provided. Falling back to \"${m}\"`),m)}export{p as DataLoader,r as Language,i as cacheKeyFn,o as defaultDataLoaderOptions,u as defaultLoaderFactory,e as libraryName,t as libraryWebsite,d as setupT,y as setupTranslate,g as utsLocaleToLanguage};\n//# sourceMappingURL=index.es.js.map\n","import {\n cacheKeyFn,\n DataLoader,\n DataLoaderLoadParams,\n defaultLoaderFactory,\n Language,\n libraryWebsite,\n MagicTranslateConfig,\n TranslateOptions,\n utsLocaleToLanguage,\n} from '@magic-translate/core';\n\n/**\n * Type alias to make the language enum more flexible to also allow passing language strings\n * instead of just the enum.\n */\nexport type Languages = `${Language}`;\n\nexport type TranslateParams = Omit<DataLoaderLoadParams, 'text'>;\n\nexport interface MagicTranslateOptions extends Omit<\n MagicTranslateConfig,\n 'language'\n> {\n /**\n * The language content is translated to. Defaults to the browser's language.\n */\n language?: Languages;\n /**\n * The element whose content is translated. Defaults to the whole document.\n */\n root?: Element;\n}\n\n/** Elements whose content is translated. */\nexport const CONTENT_SELECTOR = 't, mt-translate, [data-t]';\n/** Elements with attributes to translate, e.g. `data-t-attrs=\"placeholder title\"`. */\nexport const ATTRIBUTES_SELECTOR = '[data-t-attrs]';\n\ninterface Translation {\n source: string;\n // what was last written to the DOM, to tell our own changes from others\n rendered?: string;\n requestId: number;\n}\n\nfunction outermost(element: Element): Element {\n let current = element;\n for (\n let parent = current.parentElement?.closest(CONTENT_SELECTOR);\n parent;\n parent = current.parentElement?.closest(CONTENT_SELECTOR)\n ) {\n current = parent;\n }\n return current;\n}\n\nfunction optionsOf(element: Element): TranslateOptions {\n const options: TranslateOptions = {};\n const lang = element.getAttribute('data-lang');\n const formality = element.getAttribute('data-formality');\n if (lang) {\n options.lang = lang as Languages;\n }\n if (formality) {\n options.formality = formality as TranslateOptions['formality'];\n }\n return options;\n}\n\nexport class MagicTranslate {\n private currentLanguage: Languages;\n private dataLoader: DataLoader<DataLoaderLoadParams, string, string>;\n private readonly root?: Element;\n private readonly contents = new Map<Element, Translation>();\n private readonly attributes = new Map<Element, Map<string, Translation>>();\n private readonly listeners = new Set<(language: Languages) => void>();\n private observer?: MutationObserver;\n\n constructor(private readonly options: MagicTranslateOptions) {\n if (!options.apiKey) {\n throw new Error(`Missing API key. Please get one at ${libraryWebsite}`);\n }\n\n this.currentLanguage =\n options.language ??\n utsLocaleToLanguage(\n typeof navigator === 'undefined' ? undefined : navigator.language\n );\n this.dataLoader = this.createDataLoader();\n\n if (typeof document !== 'undefined') {\n this.root = options.root ?? document.documentElement;\n this.start(this.root);\n }\n }\n\n /**\n * The language content is currently translated to.\n */\n get language(): Languages {\n return this.currentLanguage;\n }\n\n /**\n * Translates the page to another language.\n */\n setLanguage(language: Languages): void {\n if (language === this.currentLanguage) {\n return;\n }\n\n this.currentLanguage = language;\n this.dataLoader = this.createDataLoader();\n\n this.forget(\n (element) => !element.isConnected || !this.root?.contains(element)\n );\n this.contents.forEach((_, element) => this.translateContent(element, true));\n this.attributes.forEach((_, element) =>\n this.translateAttributes(element, true)\n );\n this.listeners.forEach((listener) => listener(language));\n }\n\n /**\n * Calls `listener` whenever the language changes. Returns a function that\n * removes the listener again.\n */\n onLanguageChange(listener: (language: Languages) => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /**\n * Translates a string to the current language.\n */\n translate(text: string, params: TranslateParams = {}): Promise<string> {\n return this.dataLoader.load({ text, ...params });\n }\n\n /**\n * Stops translating the page. Content that is already translated stays\n * translated.\n */\n destroy(): void {\n this.observer?.disconnect();\n this.contents.clear();\n this.attributes.clear();\n this.listeners.clear();\n }\n\n private createDataLoader() {\n const { debug, apiKey, sourceLanguage, _apiUrl, formality } = this.options;\n const loaderFactory = this.options._loaderFactory ?? defaultLoaderFactory;\n\n return new DataLoader<DataLoaderLoadParams, string, string>(\n loaderFactory({\n debug: !!debug,\n apiKey,\n lang: this.currentLanguage,\n sourceLang: sourceLanguage,\n apiUrl: _apiUrl,\n formality,\n }),\n {\n cacheKeyFn: cacheKeyFn(apiKey, sourceLanguage, this.currentLanguage),\n }\n );\n }\n\n private start(root: Element) {\n const contents = new Set<Element>();\n const attributes = new Set<Element>();\n this.collect(root, contents, attributes);\n contents.forEach((element) => this.translateContent(element));\n attributes.forEach((element) => this.translateAttributes(element));\n\n // Picks up content that is added or changed later.\n this.observer = new MutationObserver((records) =>\n this.handleMutations(records)\n );\n this.observer.observe(root, {\n subtree: true,\n childList: true,\n characterData: true,\n attributes: true,\n });\n }\n\n private collect(\n root: Element,\n contents: Set<Element>,\n attributes: Set<Element>\n ) {\n const all = [root, ...Array.from(root.querySelectorAll('*'))];\n for (const element of all) {\n if (element.matches(CONTENT_SELECTOR)) {\n contents.add(outermost(element));\n } else if (\n element.matches(ATTRIBUTES_SELECTOR) &&\n !element.closest(CONTENT_SELECTOR)\n ) {\n attributes.add(element);\n }\n }\n }\n\n private handleMutations(records: MutationRecord[]) {\n const contents = new Set<Element>();\n const attributes = new Set<Element>();\n\n for (const record of records) {\n const target =\n record.target.nodeType === Node.ELEMENT_NODE\n ? (record.target as Element)\n : record.target.parentElement;\n if (!target) {\n continue;\n }\n\n const content = target.closest(CONTENT_SELECTOR);\n if (content) {\n contents.add(outermost(content));\n continue;\n }\n\n if (record.type === 'attributes' && target.matches(ATTRIBUTES_SELECTOR)) {\n attributes.add(target);\n }\n record.addedNodes.forEach((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n this.collect(node as Element, contents, attributes);\n }\n });\n }\n\n if (records.some((record) => record.removedNodes.length > 0)) {\n this.forget((element) => !element.isConnected);\n }\n contents.forEach((element) => this.translateContent(element));\n attributes.forEach((element) => this.translateAttributes(element));\n }\n\n private forget(predicate: (element: Element) => boolean) {\n for (const element of [...this.contents.keys()]) {\n if (predicate(element)) {\n this.contents.delete(element);\n }\n }\n for (const element of [...this.attributes.keys()]) {\n if (predicate(element)) {\n this.attributes.delete(element);\n }\n }\n }\n\n private translateContent(element: Element, force = false) {\n const html = element.innerHTML;\n let translation = this.contents.get(element);\n\n if (!translation) {\n translation = { source: html, requestId: 0 };\n this.contents.set(element, translation);\n } else if (html !== translation.rendered && html !== translation.source) {\n // changed by someone else, e.g. the page's own scripts\n translation.source = html;\n translation.rendered = undefined;\n } else if (!force) {\n return;\n }\n\n const [, leadingWhitespace, text, trailingWhitespace] =\n /^(\\s*)([\\s\\S]*?)(\\s*)$/.exec(\n translation.source.replace(/<!--[\\s\\S]*?-->/g, '')\n )!;\n if (!text) {\n return;\n }\n\n // make sure that we only ever use the response of the most recent request.\n const requestId = ++translation.requestId;\n const current = translation;\n this.translate(text, optionsOf(element)).then((translated) => {\n if (requestId !== current.requestId || !element.isConnected) {\n return;\n }\n const rendered = `${leadingWhitespace}${translated}${trailingWhitespace}`;\n if (element.innerHTML !== rendered) {\n element.innerHTML = rendered;\n }\n current.rendered = element.innerHTML;\n });\n }\n\n private translateAttributes(element: Element, force = false) {\n const names = (element.getAttribute('data-t-attrs') ?? '')\n .split(/[\\s,]+/)\n .filter(Boolean);\n let translations = this.attributes.get(element);\n if (!translations) {\n translations = new Map();\n this.attributes.set(element, translations);\n }\n\n for (const name of names) {\n const value = element.getAttribute(name);\n if (!value?.trim()) {\n continue;\n }\n\n let translation = translations.get(name);\n if (!translation) {\n translation = { source: value, requestId: 0 };\n translations.set(name, translation);\n } else if (\n value !== translation.rendered &&\n value !== translation.source\n ) {\n translation.source = value;\n translation.rendered = undefined;\n } else if (!force) {\n continue;\n }\n\n const requestId = ++translation.requestId;\n const current = translation;\n this.translate(current.source, optionsOf(element)).then((translated) => {\n if (requestId !== current.requestId || !element.isConnected) {\n return;\n }\n current.rendered = translated;\n if (element.getAttribute(name) !== translated) {\n element.setAttribute(name, translated);\n }\n });\n }\n }\n}\n\n/**\n * Starts translating the page: the content of every `<t>` element (or element\n * with a `data-t` attribute), and the attributes listed in `data-t-attrs`.\n * Content added later is translated as well.\n */\nexport function createMagicTranslate(\n options: MagicTranslateOptions\n): MagicTranslate {\n return new MagicTranslate(options);\n}\n","import {\n createMagicTranslate,\n Languages,\n MagicTranslate,\n TranslateParams,\n} from './magic-translate';\n\nexport * from './index';\n\ndeclare global {\n interface Window {\n magicTranslate?: MagicTranslate;\n }\n}\n\nconst STORAGE_KEY = 'magic-translate-language';\n\nfunction storedLanguage(): Languages | undefined {\n try {\n return (localStorage.getItem(STORAGE_KEY) as Languages | null) ?? undefined;\n } catch {\n return undefined;\n }\n}\n\n// `<script src=\".../magic-translate.min.js\" data-api-key=\"...\"></script>`\n// starts translating the page without any further code.\nconst script = document.currentScript as HTMLScriptElement | null;\nconst apiKey = script?.dataset.apiKey;\n\nif (script && apiKey) {\n const { language, sourceLanguage, formality } = script.dataset;\n\n const start = () => {\n const magicTranslate = createMagicTranslate({\n apiKey,\n // a language picked with the language switcher outlives page loads\n language: storedLanguage() ?? (language as Languages | undefined),\n sourceLanguage: sourceLanguage as Languages | undefined,\n formality: formality as TranslateParams['formality'],\n debug: script.hasAttribute('data-debug'),\n });\n magicTranslate.onLanguageChange((language) => {\n try {\n localStorage.setItem(STORAGE_KEY, language);\n } catch {\n // storage is unavailable, e.g. in some private windows\n }\n });\n window.magicTranslate = magicTranslate;\n document.dispatchEvent(\n new CustomEvent('magictranslate:ready', { detail: magicTranslate })\n );\n };\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', start);\n } else {\n start();\n }\n}\n"],"ignoreList":[0],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"magic-translate.min.js","names":["libraryWebsite","utsLocaleToLanguage","defaultLoaderFactory","DataLoader","cacheKeyFn","exports","e","t","n","r","c","i","a","u","s","l","h","o","y","d","m","g","CONTENT_SELECTOR","ATTRIBUTES_SELECTOR","outermost","current","element","parent","optionsOf","options","lang","formality","MagicTranslate","language","listener","params","debug","sourceLanguage","_apiUrl","apiKey","contents","attributes","root","records","all","record","target","content","node","predicate","html","translation","force","leadingWhitespace","text","trailingWhitespace","requestId","rendered","translated","names","translations","name","value","createMagicTranslate","STORAGE_KEY","storedLanguage","script","start","magicTranslate"],"sources":["../../core/dist/index.es.js","../src/magic-translate.ts","../src/script.ts"],"sourcesContent":["/*\n * 'Magic Translate Core'\n * {@link https://https://magictranslate.io\n * @copyright i42 GmbH\n */\nconst e=\"Magic Translate\",t=\"https://magictranslate.io\";var r;function n(e){return Object.keys(e).filter(t=>void 0!==e[t]).reduce((t,r)=>({...t,[r]:e[r]}),{})}function a(e){const t=new URLSearchParams,r=(e,n=\"\")=>{Array.isArray(e)?e.forEach((e,t)=>{r(e,n?`${n}[${t}]`:`[${t}]`)}):\"object\"==typeof e&&null!==e?Object.entries(e).forEach(([e,t])=>{r(t,n?`${n}.${e}`:e)}):t.append(n,e)};return r(e),t}!function(e){e.AF=\"af\",e.SQ=\"sq\",e.AM=\"am\",e.AR=\"ar\",e.HY=\"hy\",e.AZ=\"az\",e.BN=\"bn\",e.BS=\"bs\",e.BG=\"bg\",e.CA=\"ca\",e.ZH=\"zh\",e.ZH_TW=\"zh-TW\",e.HR=\"hr\",e.CS=\"cs\",e.DA=\"da\",e.FA_AF=\"fa-AF\",e.NL=\"nl\",e.EN=\"en\",e.ET=\"et\",e.FA=\"fa\",e.TL=\"tl\",e.FI=\"fi\",e.FR=\"fr\",e.FR_CA=\"fr-CA\",e.KA=\"ka\",e.DE=\"de\",e.EL=\"el\",e.GU=\"gu\",e.HT=\"ht\",e.HA=\"ha\",e.HE=\"he\",e.HI=\"hi\",e.HU=\"hu\",e.IS=\"is\",e.ID=\"id\",e.GA=\"ga\",e.IT=\"it\",e.JA=\"ja\",e.KN=\"kn\",e.KK=\"kk\",e.KO=\"ko\",e.LV=\"lv\",e.LT=\"lt\",e.MK=\"mk\",e.MS=\"ms\",e.ML=\"ml\",e.MT=\"mt\",e.MR=\"mr\",e.MN=\"mn\",e.NO=\"no\",e.PS=\"ps\",e.PL=\"pl\",e.PT=\"pt\",e.PT_PT=\"pt-PT\",e.PA=\"pa\",e.RO=\"ro\",e.RU=\"ru\",e.SR=\"sr\",e.SI=\"si\",e.SK=\"sk\",e.SL=\"sl\",e.SO=\"so\",e.ES=\"es\",e.ES_MX=\"es-MX\",e.SW=\"sw\",e.SV=\"sv\",e.TA=\"ta\",e.TE=\"te\",e.TH=\"th\",e.TR=\"tr\",e.UK=\"uk\",e.UR=\"ur\",e.UZ=\"uz\",e.VI=\"vi\",e.CY=\"cy\"}(r||(r={}));const o={debug:!1,apiUrl:\"https://api.magictranslate.io\",lang:r.DE};var c;!function(e){e.QUOTA_EXCEEDED_ERROR=\"QUOTA_EXCEEDED_ERROR\"}(c||(c={}));const i=(e,t,r)=>a=>Object.entries(n({apiKey:e,language:r,sourceLanguage:a.sourceLang??t??\"auto\",...a})).sort(([e])=>e.localeCompare(e)).reduce((e,t)=>`${e};${t.join(\"=\")}`,\"\"),u=t=>async r=>{if(t.debug&&console.debug(`[${e}]: batch function called with: `,r),t.lang===t.sourceLang)return r.map(e=>e.text);const{apiKey:c,lang:i,formality:u}=t,s=n({apiKey:c,lang:i,formality:u,items:r.map(({text:e,sourceLang:t,lang:r,...a})=>n({text:e,lang:r,sourceLang:t,...a}))});return fetch(`${t.apiUrl??o.apiUrl}/v1/translate`,{method:\"POST\",body:t.useJson?JSON.stringify(s):a(s),headers:{\"Content-Type\":t.useJson?\"application/json\":\"application/x-www-form-urlencoded\"}}).then(e=>e.json()).then(t=>\"results\"in t?t.results:(\"code\"in t?console.error(`[${e}]: ${t.message}`):console.error(`[${e}]: Unexpected payload from magic translate server: ${JSON.stringify(t)}`),r.map(e=>e.text))).catch(t=>(console.error(`[${e}]: Error while loading translations: `,t),r.map(e=>e.text)))};function s(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,\"default\")?e.default:e}var l,h;var f=function(){if(h)return l;h=1;var e,t=function(){function e(e,t){if(\"function\"!=typeof e)throw new TypeError(\"DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but got: \"+e+\".\");this._batchLoadFn=e,this._maxBatchSize=function(e){var t=!e||!1!==e.batch;if(!t)return 1;var r=e&&e.maxBatchSize;if(void 0===r)return 1/0;if(\"number\"!=typeof r||r<1)throw new TypeError(\"maxBatchSize must be a positive number: \"+r);return r}(t),this._batchScheduleFn=function(e){var t=e&&e.batchScheduleFn;if(void 0===t)return r;if(\"function\"!=typeof t)throw new TypeError(\"batchScheduleFn must be a function: \"+t);return t}(t),this._cacheKeyFn=function(e){var t=e&&e.cacheKeyFn;if(void 0===t)return function(e){return e};if(\"function\"!=typeof t)throw new TypeError(\"cacheKeyFn must be a function: \"+t);return t}(t),this._cacheMap=function(e){var t=!e||!1!==e.cache;if(!t)return null;var r=e&&e.cacheMap;if(void 0===r)return new Map;if(null!==r){var n=[\"get\",\"set\",\"delete\",\"clear\"].filter(function(e){return r&&\"function\"!=typeof r[e]});if(0!==n.length)throw new TypeError(\"Custom cacheMap missing methods: \"+n.join(\", \"))}return r}(t),this._batch=null,this.name=function(e){if(e&&e.name)return e.name;return null}(t)}var t=e.prototype;return t.load=function(e){if(null==e)throw new TypeError(\"The loader.load() function must be called with a value, but got: \"+String(e)+\".\");var t,r=function(e){var t=e._batch;if(null!==t&&!t.hasDispatched&&t.keys.length<e._maxBatchSize)return t;var r={hasDispatched:!1,keys:[],callbacks:[]};return e._batch=r,e._batchScheduleFn(function(){!function(e,t){if(t.hasDispatched=!0,0===t.keys.length)return void a(t);var r;try{r=e._batchLoadFn(t.keys)}catch(r){return n(e,t,new TypeError(\"DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but the function errored synchronously: \"+String(r)+\".\"))}if(!r||\"function\"!=typeof r.then)return n(e,t,new TypeError(\"DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but the function did not return a Promise: \"+String(r)+\".\"));r.then(function(e){if(!o(e))throw new TypeError(\"DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but the function did not return a Promise of an Array: \"+String(e)+\".\");if(e.length!==t.keys.length)throw new TypeError(\"DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but the function did not return a Promise of an Array of the same length as the Array of keys.\\n\\nKeys:\\n\"+String(t.keys)+\"\\n\\nValues:\\n\"+String(e));a(t);for(var r=0;r<t.callbacks.length;r++){var n=e[r];n instanceof Error?t.callbacks[r].reject(n):t.callbacks[r].resolve(n)}}).catch(function(r){n(e,t,r)})}(e,r)}),r}(this),c=this._cacheMap;if(c){t=this._cacheKeyFn(e);var i=c.get(t);if(i){var u=r.cacheHits||(r.cacheHits=[]);return new Promise(function(e){u.push(function(){e(i)})})}}r.keys.push(e);var s=new Promise(function(e,t){r.callbacks.push({resolve:e,reject:t})});return c&&c.set(t,s),s},t.loadMany=function(e){if(!o(e))throw new TypeError(\"The loader.loadMany() function must be called with Array<key> but got: \"+e+\".\");for(var t=[],r=0;r<e.length;r++)t.push(this.load(e[r]).catch(function(e){return e}));return Promise.all(t)},t.clear=function(e){var t=this._cacheMap;if(t){var r=this._cacheKeyFn(e);t.delete(r)}return this},t.clearAll=function(){var e=this._cacheMap;return e&&e.clear(),this},t.prime=function(e,t){var r=this._cacheMap;if(r){var n,a=this._cacheKeyFn(e);if(void 0===r.get(a))t instanceof Error?(n=Promise.reject(t)).catch(function(){}):n=Promise.resolve(t),r.set(a,n)}return this},e}(),r=\"object\"==typeof process&&\"function\"==typeof process.nextTick?function(t){e||(e=Promise.resolve()),e.then(function(){process.nextTick(t)})}:\"function\"==typeof setImmediate?function(e){setImmediate(e)}:function(e){setTimeout(e)};function n(e,t,r){a(t);for(var n=0;n<t.keys.length;n++)e.clear(t.keys[n]),t.callbacks[n].reject(r)}function a(e){if(e.cacheHits)for(var t=0;t<e.cacheHits.length;t++)e.cacheHits[t]()}function o(e){return\"object\"==typeof e&&null!==e&&\"number\"==typeof e.length&&(0===e.length||e.length>0&&Object.prototype.hasOwnProperty.call(e,e.length-1))}return l=t}(),p=s(f);function y({debug:e,apiKey:t,sourceLanguage:n,_apiUrl:a,formality:o,_loaderFactory:c}){const s={debug:!!e,apiKey:t,lang:r.EN,sourceLang:n,apiUrl:a,formality:o},l=new p((c??u)(s),{cacheKeyFn:i(t,n)});return(e,t,r)=>l.load({text:t,...r,lang:e})}const d=y,m=r.EN;function g(e,t){if(!e)return t??m;if([r.FA_AF,r.FR_CA,r.PT_PT,r.ES_MX].includes(e))return e;const n=e.includes(\"-\")?e.split(\"-\")[0]:e;return Object.values(r).includes(n)?n:t||(console.warn(`Language not found for UTS locale \"${e}\" and no fallback provided was provided. Falling back to \"${m}\"`),m)}export{p as DataLoader,r as Language,i as cacheKeyFn,o as defaultDataLoaderOptions,u as defaultLoaderFactory,e as libraryName,t as libraryWebsite,d as setupT,y as setupTranslate,g as utsLocaleToLanguage};\n//# sourceMappingURL=index.es.js.map\n","import {\n cacheKeyFn,\n DataLoader,\n DataLoaderLoadParams,\n defaultLoaderFactory,\n Language,\n libraryWebsite,\n MagicTranslateConfig,\n TranslateOptions,\n utsLocaleToLanguage,\n} from '@magic-translate/core';\n\n/**\n * Type alias to make the language enum more flexible to also allow passing language strings\n * instead of just the enum.\n */\nexport type Languages = `${Language}`;\n\nexport type TranslateParams = Omit<DataLoaderLoadParams, 'text'>;\n\nexport interface MagicTranslateOptions extends Omit<\n MagicTranslateConfig,\n 'language'\n> {\n /**\n * The language content is translated to. Defaults to the browser's language.\n */\n language?: Languages;\n /**\n * The element whose content is translated. Defaults to the whole document.\n */\n root?: Element;\n}\n\n/** Elements whose content is translated. */\nexport const CONTENT_SELECTOR = 't, mt-translate, [data-t]';\n/** Elements with attributes to translate, e.g. `data-t-attrs=\"placeholder title\"`. */\nexport const ATTRIBUTES_SELECTOR = '[data-t-attrs]';\n\ninterface Translation {\n source: string;\n // what was last written to the DOM, to tell our own changes from others\n rendered?: string;\n requestId: number;\n}\n\nfunction outermost(element: Element): Element {\n let current = element;\n for (\n let parent = current.parentElement?.closest(CONTENT_SELECTOR);\n parent;\n parent = current.parentElement?.closest(CONTENT_SELECTOR)\n ) {\n current = parent;\n }\n return current;\n}\n\nfunction optionsOf(element: Element): TranslateOptions {\n const options: TranslateOptions = {};\n const lang = element.getAttribute('data-lang');\n const formality = element.getAttribute('data-formality');\n if (lang) {\n options.lang = lang as Languages;\n }\n if (formality) {\n options.formality = formality as TranslateOptions['formality'];\n }\n return options;\n}\n\nexport class MagicTranslate {\n private currentLanguage: Languages;\n private dataLoader: DataLoader<DataLoaderLoadParams, string, string>;\n private readonly root?: Element;\n private readonly contents = new Map<Element, Translation>();\n private readonly attributes = new Map<Element, Map<string, Translation>>();\n private readonly listeners = new Set<(language: Languages) => void>();\n private observer?: MutationObserver;\n\n constructor(private readonly options: MagicTranslateOptions) {\n if (!options.apiKey) {\n throw new Error(`Missing API key. Please get one at ${libraryWebsite}`);\n }\n\n this.currentLanguage =\n options.language ??\n utsLocaleToLanguage(\n typeof navigator === 'undefined' ? undefined : navigator.language\n );\n this.dataLoader = this.createDataLoader();\n\n if (typeof document !== 'undefined') {\n this.root = options.root ?? document.documentElement;\n this.start(this.root);\n }\n }\n\n /**\n * The language content is currently translated to.\n */\n get language(): Languages {\n return this.currentLanguage;\n }\n\n /**\n * Translates the page to another language.\n */\n setLanguage(language: Languages): void {\n if (language === this.currentLanguage) {\n return;\n }\n\n this.currentLanguage = language;\n this.dataLoader = this.createDataLoader();\n\n this.forget(\n (element) => !element.isConnected || !this.root?.contains(element)\n );\n this.contents.forEach((_, element) => this.translateContent(element, true));\n this.attributes.forEach((_, element) =>\n this.translateAttributes(element, true)\n );\n this.listeners.forEach((listener) => listener(language));\n }\n\n /**\n * Calls `listener` whenever the language changes. Returns a function that\n * removes the listener again.\n */\n onLanguageChange(listener: (language: Languages) => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /**\n * Translates a string to the current language.\n */\n translate(text: string, params: TranslateParams = {}): Promise<string> {\n return this.dataLoader.load({ text, ...params });\n }\n\n /**\n * Stops translating the page. Content that is already translated stays\n * translated.\n */\n destroy(): void {\n this.observer?.disconnect();\n this.contents.clear();\n this.attributes.clear();\n this.listeners.clear();\n }\n\n private createDataLoader() {\n const { debug, apiKey, sourceLanguage, _apiUrl, formality } = this.options;\n const loaderFactory = this.options._loaderFactory ?? defaultLoaderFactory;\n\n return new DataLoader<DataLoaderLoadParams, string, string>(\n loaderFactory({\n debug: !!debug,\n apiKey,\n lang: this.currentLanguage,\n sourceLang: sourceLanguage,\n apiUrl: _apiUrl,\n formality,\n }),\n {\n cacheKeyFn: cacheKeyFn(apiKey, sourceLanguage, this.currentLanguage),\n }\n );\n }\n\n private start(root: Element) {\n const contents = new Set<Element>();\n const attributes = new Set<Element>();\n this.collect(root, contents, attributes);\n contents.forEach((element) => this.translateContent(element));\n attributes.forEach((element) => this.translateAttributes(element));\n\n // Picks up content that is added or changed later.\n this.observer = new MutationObserver((records) =>\n this.handleMutations(records)\n );\n this.observer.observe(root, {\n subtree: true,\n childList: true,\n characterData: true,\n attributes: true,\n });\n }\n\n private collect(\n root: Element,\n contents: Set<Element>,\n attributes: Set<Element>\n ) {\n const all = [root, ...Array.from(root.querySelectorAll('*'))];\n for (const element of all) {\n if (element.matches(CONTENT_SELECTOR)) {\n contents.add(outermost(element));\n } else if (\n element.matches(ATTRIBUTES_SELECTOR) &&\n !element.closest(CONTENT_SELECTOR)\n ) {\n attributes.add(element);\n }\n }\n }\n\n private handleMutations(records: MutationRecord[]) {\n const contents = new Set<Element>();\n const attributes = new Set<Element>();\n\n for (const record of records) {\n const target =\n record.target.nodeType === Node.ELEMENT_NODE\n ? (record.target as Element)\n : record.target.parentElement;\n if (!target) {\n continue;\n }\n\n const content = target.closest(CONTENT_SELECTOR);\n if (content) {\n contents.add(outermost(content));\n continue;\n }\n\n if (record.type === 'attributes' && target.matches(ATTRIBUTES_SELECTOR)) {\n attributes.add(target);\n }\n record.addedNodes.forEach((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n this.collect(node as Element, contents, attributes);\n }\n });\n }\n\n if (records.some((record) => record.removedNodes.length > 0)) {\n this.forget((element) => !element.isConnected);\n }\n contents.forEach((element) => this.translateContent(element));\n attributes.forEach((element) => this.translateAttributes(element));\n }\n\n private forget(predicate: (element: Element) => boolean) {\n for (const element of this.contents.keys()) {\n if (predicate(element)) {\n this.contents.delete(element);\n }\n }\n for (const element of this.attributes.keys()) {\n if (predicate(element)) {\n this.attributes.delete(element);\n }\n }\n }\n\n private translateContent(element: Element, force = false) {\n const html = element.innerHTML;\n let translation = this.contents.get(element);\n\n if (!translation) {\n translation = { source: html, requestId: 0 };\n this.contents.set(element, translation);\n } else if (html !== translation.rendered && html !== translation.source) {\n // changed by someone else, e.g. the page's own scripts\n translation.source = html;\n translation.rendered = undefined;\n } else if (!force) {\n return;\n }\n\n const [, leadingWhitespace, text, trailingWhitespace] =\n /^(\\s*)([\\s\\S]*?)(\\s*)$/.exec(\n translation.source.replace(/<!--[\\s\\S]*?-->/g, '')\n )!;\n if (!text) {\n return;\n }\n\n // make sure that we only ever use the response of the most recent request.\n const requestId = ++translation.requestId;\n const current = translation;\n this.translate(text, optionsOf(element)).then((translated) => {\n if (requestId !== current.requestId || !element.isConnected) {\n return;\n }\n const rendered = `${leadingWhitespace}${translated}${trailingWhitespace}`;\n if (element.innerHTML !== rendered) {\n element.innerHTML = rendered;\n }\n current.rendered = element.innerHTML;\n });\n }\n\n private translateAttributes(element: Element, force = false) {\n const names = (element.getAttribute('data-t-attrs') ?? '')\n .split(/[\\s,]+/)\n .filter(Boolean);\n let translations = this.attributes.get(element);\n if (!translations) {\n translations = new Map();\n this.attributes.set(element, translations);\n }\n\n for (const name of names) {\n const value = element.getAttribute(name);\n if (!value?.trim()) {\n continue;\n }\n\n let translation = translations.get(name);\n if (!translation) {\n translation = { source: value, requestId: 0 };\n translations.set(name, translation);\n } else if (\n value !== translation.rendered &&\n value !== translation.source\n ) {\n translation.source = value;\n translation.rendered = undefined;\n } else if (!force) {\n continue;\n }\n\n const requestId = ++translation.requestId;\n const current = translation;\n this.translate(current.source, optionsOf(element)).then((translated) => {\n if (requestId !== current.requestId || !element.isConnected) {\n return;\n }\n current.rendered = translated;\n if (element.getAttribute(name) !== translated) {\n element.setAttribute(name, translated);\n }\n });\n }\n }\n}\n\n/**\n * Starts translating the page: the content of every `<t>` element (or element\n * with a `data-t` attribute), and the attributes listed in `data-t-attrs`.\n * Content added later is translated as well.\n */\nexport function createMagicTranslate(\n options: MagicTranslateOptions\n): MagicTranslate {\n return new MagicTranslate(options);\n}\n","import {\n createMagicTranslate,\n Languages,\n MagicTranslate,\n TranslateParams,\n} from './magic-translate';\n\nexport * from './index';\n\ndeclare global {\n interface Window {\n magicTranslate?: MagicTranslate;\n }\n}\n\nconst STORAGE_KEY = 'magic-translate-language';\n\nfunction storedLanguage(): Languages | undefined {\n try {\n return (localStorage.getItem(STORAGE_KEY) as Languages | null) ?? undefined;\n } catch {\n return undefined;\n }\n}\n\n// `<script src=\".../magic-translate.min.js\" data-api-key=\"...\"></script>`\n// starts translating the page without any further code.\nconst script = document.currentScript as HTMLScriptElement | null;\nconst apiKey = script?.dataset.apiKey;\n\nif (script && apiKey) {\n const { language, sourceLanguage, formality } = script.dataset;\n\n const start = () => {\n const magicTranslate = createMagicTranslate({\n apiKey,\n // a language picked with the language switcher outlives page loads\n language: storedLanguage() ?? (language as Languages | undefined),\n sourceLanguage: sourceLanguage as Languages | undefined,\n formality: formality as TranslateParams['formality'],\n debug: script.hasAttribute('data-debug'),\n });\n magicTranslate.onLanguageChange((language) => {\n try {\n localStorage.setItem(STORAGE_KEY, language);\n } catch {\n // storage is unavailable, e.g. in some private windows\n }\n });\n window.magicTranslate = magicTranslate;\n document.dispatchEvent(\n new CustomEvent('magictranslate:ready', { detail: magicTranslate })\n );\n };\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', start);\n } else {\n start();\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,15 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@magic-translate/js",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"javascript",
|
|
6
|
+
"vanilla-js",
|
|
6
7
|
"html",
|
|
7
|
-
"
|
|
8
|
+
"script-tag",
|
|
9
|
+
"website-translation",
|
|
10
|
+
"wordpress",
|
|
8
11
|
"i18n",
|
|
9
|
-
"
|
|
10
|
-
"
|
|
12
|
+
"internationalization",
|
|
13
|
+
"localization",
|
|
14
|
+
"l10n",
|
|
15
|
+
"translation",
|
|
16
|
+
"translate",
|
|
17
|
+
"ai-translation",
|
|
18
|
+
"machine-translation",
|
|
19
|
+
"multilingual",
|
|
20
|
+
"magic-translate"
|
|
11
21
|
],
|
|
12
|
-
"description": "
|
|
22
|
+
"description": "Translate any website with one script tag. AI-powered i18n for plain JavaScript and HTML, with no translation keys or language files.",
|
|
13
23
|
"main": "dist/index.cjs",
|
|
14
24
|
"module": "dist/index.js",
|
|
15
25
|
"types": "dist/index.d.ts",
|
|
@@ -29,40 +39,32 @@
|
|
|
29
39
|
"author": "i42 GmbH <info@i42.ch>",
|
|
30
40
|
"repository": {
|
|
31
41
|
"type": "git",
|
|
32
|
-
"url": "git+https://github.com/magic-translate/magic-translate
|
|
42
|
+
"url": "git+https://github.com/magic-translate/magic-translate.git",
|
|
43
|
+
"directory": "packages/js"
|
|
33
44
|
},
|
|
34
|
-
"homepage": "https://magictranslate.io",
|
|
45
|
+
"homepage": "https://magictranslate.io/docs/javascript",
|
|
35
46
|
"license": "MIT",
|
|
36
|
-
"scripts": {
|
|
37
|
-
"build": "vite build && vite build --mode script && tsc -p tsconfig.build.json",
|
|
38
|
-
"start": "vite build --watch",
|
|
39
|
-
"test": "vitest run --coverage",
|
|
40
|
-
"test:watch": "vitest",
|
|
41
|
-
"prepare": "husky",
|
|
42
|
-
"lint": "eslint ."
|
|
43
|
-
},
|
|
44
47
|
"engines": {
|
|
45
48
|
"node": ">=22.22.1"
|
|
46
49
|
},
|
|
47
50
|
"dependencies": {
|
|
48
|
-
"@magic-translate/core": "^1.4.
|
|
51
|
+
"@magic-translate/core": "^1.4.2"
|
|
49
52
|
},
|
|
50
53
|
"devDependencies": {
|
|
51
|
-
"@commitlint/cli": "^21.2.4",
|
|
52
|
-
"@commitlint/config-conventional": "^21.2.4",
|
|
53
|
-
"@eslint/js": "^10.0.1",
|
|
54
54
|
"@types/node": "^26.6.5",
|
|
55
55
|
"@vitest/coverage-v8": "^5.0.5",
|
|
56
|
-
"eslint": "^10.13.0",
|
|
57
|
-
"eslint-config-prettier": "^10.1.8",
|
|
58
|
-
"globals": "^17.13.0",
|
|
59
|
-
"husky": "^9.1.7",
|
|
60
56
|
"jsdom": "^30.1.3",
|
|
61
|
-
"lint-staged": "^17.6.0",
|
|
62
|
-
"prettier": "^3.9.10",
|
|
63
57
|
"typescript": "~6.0.3",
|
|
64
|
-
"typescript-eslint": "^8.72.0",
|
|
65
58
|
"vite": "^8.3.5",
|
|
66
59
|
"vitest": "^5.0.5"
|
|
60
|
+
},
|
|
61
|
+
"bugs": {
|
|
62
|
+
"url": "https://github.com/magic-translate/magic-translate/issues"
|
|
63
|
+
},
|
|
64
|
+
"scripts": {
|
|
65
|
+
"build": "vite build && vite build --mode script && tsc -p tsconfig.build.json",
|
|
66
|
+
"start": "vite build --watch",
|
|
67
|
+
"test": "vitest run --coverage",
|
|
68
|
+
"test:watch": "vitest"
|
|
67
69
|
}
|
|
68
|
-
}
|
|
70
|
+
}
|