locize 3.0.5 → 3.1.0
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/CHANGELOG.md +4 -0
- package/README.md +67 -31
- package/dist/cjs/api/handleConfirmInitialized.js +1 -0
- package/dist/cjs/index.d.ts +30 -0
- package/dist/cjs/index.js +2 -0
- package/dist/cjs/locizePlugin.js +103 -77
- package/dist/cjs/observer.js +28 -1
- package/dist/cjs/utils.js +11 -0
- package/dist/esm/api/handleConfirmInitialized.js +1 -0
- package/dist/esm/index.d.ts +30 -0
- package/dist/esm/index.js +3 -2
- package/dist/esm/locizePlugin.js +103 -78
- package/dist/esm/observer.js +28 -1
- package/dist/esm/utils.js +11 -1
- package/dist/umd/locize.js +142 -78
- package/dist/umd/locize.min.js +1 -1
- package/index.d.ts +30 -0
- package/locize.js +142 -78
- package/locize.min.js +1 -1
- package/package.json +1 -1
- package/src/api/handleConfirmInitialized.js +1 -0
- package/src/index.js +3 -1
- package/src/locizePlugin.js +123 -85
- package/src/observer.js +48 -1
- package/src/ui/utils.js +5 -5
- package/src/utils.js +12 -0
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -16,67 +16,92 @@ npm i locize
|
|
|
16
16
|
|
|
17
17
|
**Hint:** This module runs only in browser.
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
### InContext variants
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
For i18next based solutions (i18next, react-i18next, locizify, ...) there are two options to work with locize incontext:
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
#### a) Iframe on your page
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
import 'locize';
|
|
27
|
-
```
|
|
25
|
+
The solution is best in class and uses [i18next-subliminal](https://github.com/i18next/i18next-subliminal) to add information about key and namespace as hidden text to the output of the `i18next.t` calls. Beside that it scans your website based on mutation observer to look out for those texts.
|
|
28
26
|
|
|
29
|
-
|
|
27
|
+
You can both click text elements on your website or keys in the locize iframe to edit content. Results will always be exact matches based on the namespace and key.
|
|
30
28
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
**Hint:** You can bind the ifame to a specific project by setting `ì18next.options.editor = { projectId, version }` or `ì18next.options.backend = { projectId, verstion }` (backend info might already exist when using i18next-locize-backend)
|
|
30
|
+
|
|
31
|
+
**Caveats:** You might have elements that rerender too often in short time. This might will give you a warning output in console that that element change was ignored for passing to the iframe. Consider adding the `data-locize-editor-ignore: true` attribute to the element to ignore it completely.
|
|
32
|
+
|
|
33
|
+
#### b) Opening it on https://locize.app
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
Details for setting this up can be found [here](https://docs.locize.com/different-views/incontext)
|
|
36
36
|
|
|
37
|
+
The solution extracts the text on the clicked element and passes it for a fuzzy search to the parent frame. As the search is fuzzy there is no guarantee for exact results.
|
|
38
|
+
|
|
39
|
+
**hint** To get exact matches you can add following attributes to the element or it's parent:
|
|
40
|
+
|
|
41
|
+
`data-i18n` -> will pass exact key
|
|
42
|
+
`data-i18n-ns` -> will pass namespace name
|
|
43
|
+
|
|
44
|
+
# Using
|
|
45
|
+
|
|
46
|
+
## with locizify
|
|
47
|
+
|
|
48
|
+
This plugin is already included in [locizify](https://github.com/locize/locizify) >= v4.1.0
|
|
49
|
+
|
|
50
|
+
## with i18next
|
|
51
|
+
|
|
52
|
+
### this will show the locize incontext editor as a popup in your website
|
|
37
53
|
```js
|
|
38
54
|
import { locizePlugin } from 'locize';
|
|
39
55
|
|
|
40
56
|
i18next.use(locizePlugin);
|
|
41
57
|
```
|
|
42
58
|
|
|
59
|
+
### this will show the locize incontext editor as a popup in your website only if the url contains the incontext=true query paramenter, i.e. http://localhost:8080?incontext=true
|
|
60
|
+
```js
|
|
61
|
+
import { locizeEditorPlugin } from 'locize';
|
|
62
|
+
|
|
63
|
+
i18next.use(locizeEditorPlugin());
|
|
64
|
+
```
|
|
65
|
+
|
|
43
66
|
Using react-i18next you might want to bind the editorSaved event to trigger a rerender:
|
|
44
67
|
|
|
45
68
|
```js
|
|
46
69
|
i18next.init({
|
|
47
70
|
// ...
|
|
48
71
|
react: {
|
|
49
|
-
bindI18n: 'languageChanged editorSaved'
|
|
50
|
-
}
|
|
51
|
-
})
|
|
72
|
+
bindI18n: 'languageChanged editorSaved'
|
|
73
|
+
}
|
|
74
|
+
})
|
|
52
75
|
```
|
|
53
76
|
|
|
54
|
-
|
|
77
|
+
## without i18next
|
|
55
78
|
|
|
56
|
-
|
|
79
|
+
Not using i18next currently only the option to show your website inside the locize incontext solution (https://locize.app) is available.
|
|
57
80
|
|
|
58
81
|
### with other as module
|
|
59
82
|
|
|
60
83
|
```js
|
|
61
|
-
import { addLocizeSavedHandler, startStandalone, setEditorLng } from 'locize'
|
|
84
|
+
import { addLocizeSavedHandler, startStandalone, setEditorLng } from 'locize'
|
|
62
85
|
|
|
63
86
|
addLocizeSavedHandler(res => {
|
|
64
87
|
res.updated.forEach(item => {
|
|
65
|
-
const { lng, ns, key, data } = item
|
|
88
|
+
const { lng, ns, key, data } = item
|
|
66
89
|
// load the translations somewhere...
|
|
67
90
|
// and maybe rerender your UI
|
|
68
|
-
})
|
|
69
|
-
})
|
|
91
|
+
})
|
|
92
|
+
})
|
|
70
93
|
|
|
71
94
|
// start
|
|
72
|
-
startStandalone()
|
|
95
|
+
startStandalone()
|
|
73
96
|
|
|
74
97
|
// switch lng in locize editor
|
|
75
|
-
setEditorLng(lng)
|
|
98
|
+
setEditorLng(lng)
|
|
76
99
|
```
|
|
77
100
|
|
|
78
101
|
### with other in vanilla javascript
|
|
79
102
|
|
|
103
|
+
Only relevant when your website is shown inside the locize incontext solution on https://locize.app.
|
|
104
|
+
|
|
80
105
|
```html
|
|
81
106
|
<script src="https://unpkg.com/locize/locize.min.js" />
|
|
82
107
|
```
|
|
@@ -84,23 +109,34 @@ setEditorLng(lng);
|
|
|
84
109
|
```js
|
|
85
110
|
window.locizeSavedHandler = res => {
|
|
86
111
|
res.updated.forEach(item => {
|
|
87
|
-
const { lng, ns, key, data } = item
|
|
112
|
+
const { lng, ns, key, data } = item
|
|
88
113
|
// load the translations somewhere...
|
|
89
114
|
// and maybe rerender your UI
|
|
90
|
-
})
|
|
91
|
-
}
|
|
115
|
+
})
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
window.locizeStartStandalone()
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
**Hint** you can fix the integration to a locize project by adding:
|
|
92
122
|
|
|
93
|
-
|
|
123
|
+
```js
|
|
124
|
+
<script
|
|
125
|
+
id="locize"
|
|
126
|
+
projectid="5e9ed7da-51ab-4b15-888b-27903f06be09"
|
|
127
|
+
version="latest"
|
|
128
|
+
src="https://unpkg.com/locize/locize.min.js"
|
|
129
|
+
>
|
|
94
130
|
```
|
|
95
131
|
|
|
96
|
-
|
|
132
|
+
### turn on/off click interception programmatically
|
|
97
133
|
|
|
98
134
|
```js
|
|
99
|
-
import { turnOn, turnOff } from 'locize'
|
|
135
|
+
import { turnOn, turnOff } from 'locize'
|
|
100
136
|
|
|
101
|
-
let isOff
|
|
137
|
+
let isOff
|
|
102
138
|
|
|
103
139
|
// or use window.locize.turnOn
|
|
104
|
-
isOff = turnOff()
|
|
105
|
-
isOff = turnOn()
|
|
140
|
+
isOff = turnOff() // -> true
|
|
141
|
+
isOff = turnOn() // -> false
|
|
106
142
|
```
|
|
@@ -5,6 +5,7 @@ var postMessage = require('./postMessage.js');
|
|
|
5
5
|
function handler(payload) {
|
|
6
6
|
postMessage.api.initialized = true;
|
|
7
7
|
clearInterval(postMessage.api.initInterval);
|
|
8
|
+
delete postMessage.api.initInterval;
|
|
8
9
|
postMessage.api.sendCurrentParsedContent();
|
|
9
10
|
postMessage.api.sendCurrentTargetLanguage();
|
|
10
11
|
}
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -1,15 +1,45 @@
|
|
|
1
1
|
export * from 'i18next-subliminal'
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* The i18next plugin for the locize incontext editor.
|
|
5
|
+
*/
|
|
3
6
|
export interface LocizePlugin {
|
|
4
7
|
type: '3rdParty';
|
|
5
8
|
init(i18next: any): () => void;
|
|
6
9
|
}
|
|
7
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Returns an i18next plugin that will show the incontext editor.
|
|
13
|
+
*/
|
|
8
14
|
export const locizePlugin: LocizePlugin
|
|
9
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Returns an i18next plugin that will only show the incontext editor if the qsProp in your url is set to true.
|
|
18
|
+
* @param opt defaults to: { qsProp: 'incontext' }
|
|
19
|
+
*/
|
|
20
|
+
export function locizeEditorPlugin(opt?: { qsProp?: string }): LocizePlugin
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Turn on programmatically.
|
|
24
|
+
*/
|
|
10
25
|
export function turnOn(): void;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Turn off programmatically.
|
|
29
|
+
*/
|
|
11
30
|
export function turnOff(): void;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Set the language for the editor.
|
|
34
|
+
*/
|
|
12
35
|
export function setEditorLng(lng: string): void;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* To load the translations somewhere.
|
|
39
|
+
*/
|
|
13
40
|
export function addLocizeSavedHandler(fn: (data: any) => void): void;
|
|
14
41
|
|
|
42
|
+
/**
|
|
43
|
+
* If used without i18next.
|
|
44
|
+
*/
|
|
15
45
|
export function startStandalone(): void;
|
package/dist/cjs/index.js
CHANGED
|
@@ -24,12 +24,14 @@ var index = {
|
|
|
24
24
|
PostProcessor: i18nextSubliminal.PostProcessor,
|
|
25
25
|
addLocizeSavedHandler: postMessage.addLocizeSavedHandler,
|
|
26
26
|
locizePlugin: locizePlugin.locizePlugin,
|
|
27
|
+
locizeEditorPlugin: locizePlugin.locizeEditorPlugin,
|
|
27
28
|
turnOn: postMessage.turnOn,
|
|
28
29
|
turnOff: postMessage.turnOff,
|
|
29
30
|
setEditorLng: postMessage.setEditorLng,
|
|
30
31
|
startStandalone: startStandalone.startStandalone
|
|
31
32
|
};
|
|
32
33
|
|
|
34
|
+
exports.locizeEditorPlugin = locizePlugin.locizeEditorPlugin;
|
|
33
35
|
exports.locizePlugin = locizePlugin.locizePlugin;
|
|
34
36
|
exports.startStandalone = startStandalone.startStandalone;
|
|
35
37
|
exports.addLocizeSavedHandler = postMessage.addLocizeSavedHandler;
|
package/dist/cjs/locizePlugin.js
CHANGED
|
@@ -6,6 +6,7 @@ var _defineProperty = require('@babel/runtime/helpers/defineProperty');
|
|
|
6
6
|
var i18nextSubliminal = require('i18next-subliminal');
|
|
7
7
|
var process = require('./process.js');
|
|
8
8
|
var processLegacy = require('./processLegacy.js');
|
|
9
|
+
var utils = require('./utils.js');
|
|
9
10
|
|
|
10
11
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
11
12
|
|
|
@@ -17,89 +18,94 @@ var isInIframe = typeof window !== 'undefined';
|
|
|
17
18
|
try {
|
|
18
19
|
isInIframe = self !== top;
|
|
19
20
|
} catch (e) {}
|
|
21
|
+
function configurePostProcessor(i18next, options) {
|
|
22
|
+
i18next.use(i18nextSubliminal.PostProcessor);
|
|
23
|
+
if (typeof options.postProcess === 'string') {
|
|
24
|
+
options.postProcess = [options.postProcess, 'subliminal'];
|
|
25
|
+
} else if (Array.isArray(options.postProcess)) {
|
|
26
|
+
options.postProcess.push('subliminal');
|
|
27
|
+
} else {
|
|
28
|
+
options.postProcess = 'subliminal';
|
|
29
|
+
}
|
|
30
|
+
options.postProcessPassResolved = true;
|
|
31
|
+
}
|
|
32
|
+
function getImplementation(i18n) {
|
|
33
|
+
var impl = {
|
|
34
|
+
getResource: function getResource(lng, ns, key) {
|
|
35
|
+
return i18n.getResource(lng, ns, key);
|
|
36
|
+
},
|
|
37
|
+
setResource: function setResource(lng, ns, key, value) {
|
|
38
|
+
return i18n.addResource(lng, ns, key, value, {
|
|
39
|
+
silent: true
|
|
40
|
+
});
|
|
41
|
+
},
|
|
42
|
+
getResourceBundle: function getResourceBundle(lng, ns, cb) {
|
|
43
|
+
i18n.loadNamespaces(ns, function () {
|
|
44
|
+
cb(i18n.getResourceBundle(lng, ns));
|
|
45
|
+
});
|
|
46
|
+
},
|
|
47
|
+
getLng: function getLng() {
|
|
48
|
+
return i18n.languages[0];
|
|
49
|
+
},
|
|
50
|
+
getSourceLng: function getSourceLng() {
|
|
51
|
+
var fallback = i18n.options.fallbackLng;
|
|
52
|
+
if (typeof fallback === 'string') return fallback;
|
|
53
|
+
if (Array.isArray(fallback)) return fallback[fallback.length - 1];
|
|
54
|
+
if (fallback && fallback["default"]) {
|
|
55
|
+
if (typeof fallback["default"] === 'string') return fallback;
|
|
56
|
+
if (Array.isArray(fallback["default"])) return fallback["default"][fallback["default"].length - 1];
|
|
57
|
+
}
|
|
58
|
+
if (typeof fallback === 'function') {
|
|
59
|
+
var res = fallback(i18n.resolvedLanguage);
|
|
60
|
+
if (typeof res === 'string') return res;
|
|
61
|
+
if (Array.isArray(res)) return res[res.length - 1];
|
|
62
|
+
}
|
|
63
|
+
return 'dev';
|
|
64
|
+
},
|
|
65
|
+
getLocizeDetails: function getLocizeDetails() {
|
|
66
|
+
var backendName;
|
|
67
|
+
if (i18n.services.backendConnector.backend && i18n.services.backendConnector.backend.options && i18n.services.backendConnector.backend.options.loadPath && i18n.services.backendConnector.backend.options.loadPath.indexOf('.locize.') > 0) {
|
|
68
|
+
backendName = 'I18NextLocizeBackend';
|
|
69
|
+
} else {
|
|
70
|
+
backendName = i18n.services.backendConnector.backend ? i18n.services.backendConnector.backend.constructor.name : 'options.resources';
|
|
71
|
+
}
|
|
72
|
+
var opts = {
|
|
73
|
+
backendName: backendName,
|
|
74
|
+
sourceLng: impl.getSourceLng(),
|
|
75
|
+
i18nFormat: i18n.options.compatibilityJSON === 'v3' ? 'i18next_v3' : 'i18next_v4',
|
|
76
|
+
i18nFramework: 'i18next',
|
|
77
|
+
isLocizify: i18n.options.isLocizify,
|
|
78
|
+
defaultNS: i18n.options.defaultNS
|
|
79
|
+
};
|
|
80
|
+
if (!i18n.options.backend && !i18n.options.editor) return opts;
|
|
81
|
+
var pickFrom = i18n.options.backend || i18n.options.editor;
|
|
82
|
+
return _objectSpread(_objectSpread({}, opts), {}, {
|
|
83
|
+
projectId: pickFrom.projectId,
|
|
84
|
+
version: pickFrom.version
|
|
85
|
+
});
|
|
86
|
+
},
|
|
87
|
+
bindLanguageChange: function bindLanguageChange(cb) {
|
|
88
|
+
i18n.on('languageChanged', cb);
|
|
89
|
+
},
|
|
90
|
+
bindMissingKeyHandler: function bindMissingKeyHandler(cb) {
|
|
91
|
+
i18n.options.missingKeyHandler = function (lng, ns, k, val, isUpdate, opts) {
|
|
92
|
+
if (!isUpdate) cb(lng, ns, k, val);
|
|
93
|
+
};
|
|
94
|
+
},
|
|
95
|
+
triggerRerender: function triggerRerender() {
|
|
96
|
+
i18n.emit('editorSaved');
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
return impl;
|
|
100
|
+
}
|
|
20
101
|
var i18next;
|
|
21
102
|
var locizePlugin = {
|
|
22
103
|
type: '3rdParty',
|
|
23
104
|
init: function init(i18n) {
|
|
24
105
|
var options = i18n.options;
|
|
25
106
|
i18next = i18n;
|
|
26
|
-
if (!isInIframe)
|
|
27
|
-
|
|
28
|
-
if (typeof options.postProcess === 'string') {
|
|
29
|
-
options.postProcess = [options.postProcess, 'subliminal'];
|
|
30
|
-
} else if (Array.isArray(options.postProcess)) {
|
|
31
|
-
options.postProcess.push('subliminal');
|
|
32
|
-
} else {
|
|
33
|
-
options.postProcess = 'subliminal';
|
|
34
|
-
}
|
|
35
|
-
options.postProcessPassResolved = true;
|
|
36
|
-
}
|
|
37
|
-
var impl = {
|
|
38
|
-
getResource: function getResource(lng, ns, key) {
|
|
39
|
-
return i18n.getResource(lng, ns, key);
|
|
40
|
-
},
|
|
41
|
-
setResource: function setResource(lng, ns, key, value) {
|
|
42
|
-
return i18n.addResource(lng, ns, key, value, {
|
|
43
|
-
silent: true
|
|
44
|
-
});
|
|
45
|
-
},
|
|
46
|
-
getResourceBundle: function getResourceBundle(lng, ns, cb) {
|
|
47
|
-
i18n.loadNamespaces(ns, function () {
|
|
48
|
-
cb(i18n.getResourceBundle(lng, ns));
|
|
49
|
-
});
|
|
50
|
-
},
|
|
51
|
-
getLng: function getLng() {
|
|
52
|
-
return i18n.languages[0];
|
|
53
|
-
},
|
|
54
|
-
getSourceLng: function getSourceLng() {
|
|
55
|
-
var fallback = i18n.options.fallbackLng;
|
|
56
|
-
if (typeof fallback === 'string') return fallback;
|
|
57
|
-
if (Array.isArray(fallback)) return fallback[fallback.length - 1];
|
|
58
|
-
if (fallback && fallback["default"]) {
|
|
59
|
-
if (typeof fallback["default"] === 'string') return fallback;
|
|
60
|
-
if (Array.isArray(fallback["default"])) return fallback["default"][fallback["default"].length - 1];
|
|
61
|
-
}
|
|
62
|
-
if (typeof fallback === 'function') {
|
|
63
|
-
var res = fallback(i18n.resolvedLanguage);
|
|
64
|
-
if (typeof res === 'string') return res;
|
|
65
|
-
if (Array.isArray(res)) return res[res.length - 1];
|
|
66
|
-
}
|
|
67
|
-
return 'dev';
|
|
68
|
-
},
|
|
69
|
-
getLocizeDetails: function getLocizeDetails() {
|
|
70
|
-
var backendName;
|
|
71
|
-
if (i18n.services.backendConnector.backend && i18n.services.backendConnector.backend.options && i18n.services.backendConnector.backend.options.loadPath && i18n.services.backendConnector.backend.options.loadPath.indexOf('.locize.') > 0) {
|
|
72
|
-
backendName = 'I18NextLocizeBackend';
|
|
73
|
-
} else {
|
|
74
|
-
backendName = i18n.services.backendConnector.backend ? i18n.services.backendConnector.backend.constructor.name : 'options.resources';
|
|
75
|
-
}
|
|
76
|
-
var opts = {
|
|
77
|
-
backendName: backendName,
|
|
78
|
-
sourceLng: impl.getSourceLng(),
|
|
79
|
-
i18nFormat: i18n.options.compatibilityJSON === 'v3' ? 'i18next_v3' : 'i18next_v4',
|
|
80
|
-
i18nFramework: 'i18next',
|
|
81
|
-
isLocizify: i18n.options.isLocizify,
|
|
82
|
-
defaultNS: i18n.options.defaultNS
|
|
83
|
-
};
|
|
84
|
-
if (!i18n.options.backend && !i18n.options.editor) return opts;
|
|
85
|
-
var pickFrom = i18n.options.backend || i18n.options.editor;
|
|
86
|
-
return _objectSpread(_objectSpread({}, opts), {}, {
|
|
87
|
-
projectId: pickFrom.projectId,
|
|
88
|
-
version: pickFrom.version
|
|
89
|
-
});
|
|
90
|
-
},
|
|
91
|
-
bindLanguageChange: function bindLanguageChange(cb) {
|
|
92
|
-
i18n.on('languageChanged', cb);
|
|
93
|
-
},
|
|
94
|
-
bindMissingKeyHandler: function bindMissingKeyHandler(cb) {
|
|
95
|
-
i18n.options.missingKeyHandler = function (lng, ns, k, val, isUpdate, opts) {
|
|
96
|
-
if (!isUpdate) cb(lng, ns, k, val);
|
|
97
|
-
};
|
|
98
|
-
},
|
|
99
|
-
triggerRerender: function triggerRerender() {
|
|
100
|
-
i18n.emit('editorSaved');
|
|
101
|
-
}
|
|
102
|
-
};
|
|
107
|
+
if (!isInIframe) configurePostProcessor(i18next, options);
|
|
108
|
+
var impl = getImplementation(i18n);
|
|
103
109
|
if (!isInIframe) {
|
|
104
110
|
process.start(impl);
|
|
105
111
|
} else {
|
|
@@ -107,9 +113,29 @@ var locizePlugin = {
|
|
|
107
113
|
}
|
|
108
114
|
}
|
|
109
115
|
};
|
|
116
|
+
var locizeEditorPlugin = function locizeEditorPlugin() {
|
|
117
|
+
var opt = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
118
|
+
opt.qsProp = opt.qsProp || 'incontext';
|
|
119
|
+
return {
|
|
120
|
+
type: '3rdParty',
|
|
121
|
+
init: function init(i18n) {
|
|
122
|
+
var options = i18n.options;
|
|
123
|
+
i18next = i18n;
|
|
124
|
+
var showInContext = utils.getQsParameterByName(opt.qsProp) === 'true';
|
|
125
|
+
if (!isInIframe && showInContext) configurePostProcessor(i18next, options);
|
|
126
|
+
var impl = getImplementation(i18n);
|
|
127
|
+
if (!isInIframe && showInContext) {
|
|
128
|
+
process.start(impl);
|
|
129
|
+
} else {
|
|
130
|
+
processLegacy.startLegacy(impl);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
};
|
|
110
135
|
|
|
111
136
|
Object.defineProperty(exports, 'unwrap', {
|
|
112
137
|
enumerable: true,
|
|
113
138
|
get: function () { return i18nextSubliminal.unwrap; }
|
|
114
139
|
});
|
|
140
|
+
exports.locizeEditorPlugin = locizeEditorPlugin;
|
|
115
141
|
exports.locizePlugin = locizePlugin;
|
package/dist/cjs/observer.js
CHANGED
|
@@ -5,7 +5,18 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
5
5
|
var utils = require('./utils.js');
|
|
6
6
|
var vars = require('./vars.js');
|
|
7
7
|
|
|
8
|
+
var mutationTriggeringElements = {};
|
|
8
9
|
function ignoreMutation(ele) {
|
|
10
|
+
if (ele.uniqueID) {
|
|
11
|
+
var info = mutationTriggeringElements[ele.uniqueID];
|
|
12
|
+
if (info && info.triggered > 10 && info.lastTriggerDate + 500 < Date.now()) {
|
|
13
|
+
if (!info.warned && console) {
|
|
14
|
+
console.warn('locize ::: ignoring element change - an element is rerendering too often in short interval', '\n', 'consider adding the "data-locize-editor-ignore:" attribute to the element:', ele);
|
|
15
|
+
info.warned = true;
|
|
16
|
+
}
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
9
20
|
var ret = ele.dataset && (ele.dataset.i18nextEditorElement === 'true' || ele.dataset.locizeEditorIgnore === 'true');
|
|
10
21
|
if (!ret && ele.parentElement) return ignoreMutation(ele.parentElement);
|
|
11
22
|
return ret;
|
|
@@ -34,6 +45,12 @@ function createObserver(ele, handle) {
|
|
|
34
45
|
if (mutation.type === 'attributes' && !vars.validAttributes.includes(mutation.attributeName)) {
|
|
35
46
|
return;
|
|
36
47
|
}
|
|
48
|
+
Object.keys(mutationTriggeringElements).forEach(function (k) {
|
|
49
|
+
var info = mutationTriggeringElements[k];
|
|
50
|
+
if (info.lastTriggerDate + 60000 < Date.now()) {
|
|
51
|
+
delete mutationTriggeringElements[k];
|
|
52
|
+
}
|
|
53
|
+
});
|
|
37
54
|
if (mutation.type === 'childList') {
|
|
38
55
|
var notOurs = 0;
|
|
39
56
|
if (!ignoreMutation(mutation.target)) {
|
|
@@ -49,8 +66,18 @@ function createObserver(ele, handle) {
|
|
|
49
66
|
if (notOurs === 0) return;
|
|
50
67
|
}
|
|
51
68
|
triggerMutation = true;
|
|
69
|
+
if (mutation.target && mutation.target.uniqueID) {
|
|
70
|
+
var info = mutationTriggeringElements[mutation.target.uniqueID] || {
|
|
71
|
+
triggered: 0
|
|
72
|
+
};
|
|
73
|
+
info.triggered = info.triggered + 1;
|
|
74
|
+
info.lastTriggerDate = Date.now();
|
|
75
|
+
mutationTriggeringElements[mutation.target.uniqueID] = info;
|
|
76
|
+
}
|
|
52
77
|
var includedAlready = targetEles.reduce(function (mem, element) {
|
|
53
|
-
if (mem || element.contains(mutation.target) || !mutation.target.parentElement)
|
|
78
|
+
if (mem || element.contains(mutation.target) || !mutation.target.parentElement) {
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
54
81
|
return false;
|
|
55
82
|
}, false);
|
|
56
83
|
if (!includedAlready) {
|
package/dist/cjs/utils.js
CHANGED
|
@@ -127,12 +127,23 @@ function getElementNamespace(el) {
|
|
|
127
127
|
find(el);
|
|
128
128
|
return found;
|
|
129
129
|
}
|
|
130
|
+
function getQsParameterByName(name, url) {
|
|
131
|
+
if (typeof window === 'undefined') return null;
|
|
132
|
+
if (!url) url = window.location.href.toLowerCase();
|
|
133
|
+
name = name.replace(/[\[\]]/g, '\\$&');
|
|
134
|
+
var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)');
|
|
135
|
+
var results = regex.exec(url);
|
|
136
|
+
if (!results) return null;
|
|
137
|
+
if (!results[2]) return '';
|
|
138
|
+
return decodeURIComponent(results[2].replace(/\+/g, ' '));
|
|
139
|
+
}
|
|
130
140
|
|
|
131
141
|
exports.debounce = debounce;
|
|
132
142
|
exports.getClickedElement = getClickedElement;
|
|
133
143
|
exports.getElementI18nKey = getElementI18nKey;
|
|
134
144
|
exports.getElementNamespace = getElementNamespace;
|
|
135
145
|
exports.getElementText = getElementText;
|
|
146
|
+
exports.getQsParameterByName = getQsParameterByName;
|
|
136
147
|
exports.getWindow = getWindow;
|
|
137
148
|
exports.isWindow = isWindow;
|
|
138
149
|
exports.offset = offset;
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -1,15 +1,45 @@
|
|
|
1
1
|
export * from 'i18next-subliminal'
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* The i18next plugin for the locize incontext editor.
|
|
5
|
+
*/
|
|
3
6
|
export interface LocizePlugin {
|
|
4
7
|
type: '3rdParty';
|
|
5
8
|
init(i18next: any): () => void;
|
|
6
9
|
}
|
|
7
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Returns an i18next plugin that will show the incontext editor.
|
|
13
|
+
*/
|
|
8
14
|
export const locizePlugin: LocizePlugin
|
|
9
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Returns an i18next plugin that will only show the incontext editor if the qsProp in your url is set to true.
|
|
18
|
+
* @param opt defaults to: { qsProp: 'incontext' }
|
|
19
|
+
*/
|
|
20
|
+
export function locizeEditorPlugin(opt?: { qsProp?: string }): LocizePlugin
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Turn on programmatically.
|
|
24
|
+
*/
|
|
10
25
|
export function turnOn(): void;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Turn off programmatically.
|
|
29
|
+
*/
|
|
11
30
|
export function turnOff(): void;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Set the language for the editor.
|
|
34
|
+
*/
|
|
12
35
|
export function setEditorLng(lng: string): void;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* To load the translations somewhere.
|
|
39
|
+
*/
|
|
13
40
|
export function addLocizeSavedHandler(fn: (data: any) => void): void;
|
|
14
41
|
|
|
42
|
+
/**
|
|
43
|
+
* If used without i18next.
|
|
44
|
+
*/
|
|
15
45
|
export function startStandalone(): void;
|
package/dist/esm/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { locizePlugin } from './locizePlugin.js';
|
|
2
|
-
export { locizePlugin } from './locizePlugin.js';
|
|
1
|
+
import { locizePlugin, locizeEditorPlugin } from './locizePlugin.js';
|
|
2
|
+
export { locizeEditorPlugin, locizePlugin } from './locizePlugin.js';
|
|
3
3
|
import { startStandalone } from './startStandalone.js';
|
|
4
4
|
export { startStandalone } from './startStandalone.js';
|
|
5
5
|
import './api/handleEditKey.js';
|
|
@@ -24,6 +24,7 @@ var index = {
|
|
|
24
24
|
PostProcessor: PostProcessor,
|
|
25
25
|
addLocizeSavedHandler: addLocizeSavedHandler,
|
|
26
26
|
locizePlugin: locizePlugin,
|
|
27
|
+
locizeEditorPlugin: locizeEditorPlugin,
|
|
27
28
|
turnOn: turnOn,
|
|
28
29
|
turnOff: turnOff,
|
|
29
30
|
setEditorLng: setEditorLng,
|