locize 3.2.5 → 4.0.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.
Files changed (99) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/README.md +74 -36
  3. package/dist/cjs/{processLegacy.js → _processLegacy.js} +1 -2
  4. package/dist/cjs/{startStandalone.js → _startStandalone.js} +2 -2
  5. package/dist/cjs/api/handleCommitKeys.js +7 -0
  6. package/dist/cjs/api/handleEditKey.js +1 -1
  7. package/dist/cjs/api/handleIsLocizeEnabled.js +2 -2
  8. package/dist/cjs/api/handleRequestPopupChanges.js +11 -0
  9. package/dist/cjs/api/handleSendMatchedUninstrumented.js +26 -0
  10. package/dist/cjs/api/postMessage.js +32 -45
  11. package/dist/cjs/clickHandler.js +11 -4
  12. package/dist/cjs/implementations/dummyImplementation.js +35 -0
  13. package/dist/cjs/implementations/i18nextImplementation.js +94 -0
  14. package/dist/cjs/index.d.ts +9 -16
  15. package/dist/cjs/index.js +4 -9
  16. package/dist/cjs/locizePlugin.js +6 -90
  17. package/dist/cjs/observer.js +1 -0
  18. package/dist/cjs/parser.js +100 -14
  19. package/dist/cjs/process.js +37 -5
  20. package/dist/cjs/store.js +1 -0
  21. package/dist/cjs/ui/elements/highlightBox.js +13 -0
  22. package/dist/cjs/ui/elements/icons.js +1 -17
  23. package/dist/cjs/ui/elements/popup.js +3 -3
  24. package/dist/cjs/ui/elements/ribbonBox.js +3 -6
  25. package/dist/cjs/ui/highlightNode.js +28 -77
  26. package/dist/cjs/ui/popup.js +10 -0
  27. package/dist/cjs/ui/utils.js +18 -0
  28. package/dist/cjs/uninstrumentedStore.js +18 -2
  29. package/dist/cjs/utils.js +54 -0
  30. package/dist/cjs/vars.js +5 -2
  31. package/dist/esm/{processLegacy.js → _processLegacy.js} +1 -2
  32. package/dist/esm/{startStandalone.js → _startStandalone.js} +1 -1
  33. package/dist/esm/api/handleCommitKeys.js +7 -0
  34. package/dist/esm/api/handleEditKey.js +1 -1
  35. package/dist/esm/api/handleIsLocizeEnabled.js +2 -2
  36. package/dist/esm/api/handleRequestPopupChanges.js +11 -0
  37. package/dist/esm/api/handleSendMatchedUninstrumented.js +20 -0
  38. package/dist/esm/api/postMessage.js +33 -44
  39. package/dist/esm/clickHandler.js +11 -4
  40. package/dist/esm/implementations/dummyImplementation.js +31 -0
  41. package/dist/esm/implementations/i18nextImplementation.js +85 -0
  42. package/dist/esm/index.d.ts +9 -16
  43. package/dist/esm/index.js +5 -8
  44. package/dist/esm/locizePlugin.js +5 -85
  45. package/dist/esm/observer.js +1 -0
  46. package/dist/esm/parser.js +101 -16
  47. package/dist/esm/process.js +38 -6
  48. package/dist/esm/store.js +1 -0
  49. package/dist/esm/ui/elements/highlightBox.js +9 -0
  50. package/dist/esm/ui/elements/icons.js +2 -16
  51. package/dist/esm/ui/elements/popup.js +3 -3
  52. package/dist/esm/ui/elements/ribbonBox.js +4 -7
  53. package/dist/esm/ui/highlightNode.js +28 -78
  54. package/dist/esm/ui/popup.js +10 -0
  55. package/dist/esm/ui/utils.js +18 -1
  56. package/dist/esm/uninstrumentedStore.js +18 -2
  57. package/dist/esm/utils.js +53 -1
  58. package/dist/esm/vars.js +5 -3
  59. package/dist/umd/locize.js +736 -500
  60. package/dist/umd/locize.min.js +1 -1
  61. package/index.d.ts +9 -16
  62. package/locize.js +736 -500
  63. package/locize.min.js +1 -1
  64. package/package.json +1 -1
  65. package/src/_startStandalone.js +22 -0
  66. package/src/api/handleCommitKeys.js +9 -0
  67. package/src/api/handleEditKey.js +5 -11
  68. package/src/api/handleIsLocizeEnabled.js +7 -2
  69. package/src/api/handleRequestPopupChanges.js +27 -0
  70. package/src/api/handleSendMatchedUninstrumented.js +38 -0
  71. package/src/api/index.js +1 -4
  72. package/src/api/postMessage.js +37 -53
  73. package/src/clickHandler.js +30 -8
  74. package/src/implementations/dummyImplementation.js +29 -0
  75. package/src/implementations/i18nextImplementation.js +114 -0
  76. package/src/implementations/index.js +2 -0
  77. package/src/index.js +8 -7
  78. package/src/locizePlugin.js +51 -28
  79. package/src/observer.js +1 -0
  80. package/src/parser.js +207 -19
  81. package/src/process.js +52 -5
  82. package/src/startStandalone.js +4 -17
  83. package/src/store.js +2 -0
  84. package/src/ui/elements/highlightBox.js +17 -0
  85. package/src/ui/elements/popup.js +4 -4
  86. package/src/ui/elements/ribbonBox.js +12 -8
  87. package/src/ui/highlightNode.js +102 -71
  88. package/src/ui/popup.js +33 -5
  89. package/src/ui/utils.js +28 -1
  90. package/src/uninstrumentedStore.js +18 -2
  91. package/src/utils.js +72 -5
  92. package/src/vars.js +6 -4
  93. package/dist/cjs/api/handleTurnOff.js +0 -8
  94. package/dist/cjs/api/handleTurnOn.js +0 -8
  95. package/dist/esm/api/handleTurnOff.js +0 -6
  96. package/dist/esm/api/handleTurnOn.js +0 -6
  97. /package/src/{processLegacy.js → _processLegacy.js} +0 -0
  98. /package/src/api/{handleTurnOff.js → _handleTurnOff.js} +0 -0
  99. /package/src/api/{handleTurnOn.js → _handleTurnOn.js} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ### 3.3.0
2
+
3
+ - support i18next-subliminal in clickHandler used in locize iframe
4
+
1
5
  ### 3.2.5
2
6
 
3
7
  - fix startStandalone: added handler for committed message
package/README.md CHANGED
@@ -2,68 +2,93 @@
2
2
 
3
3
  # locize
4
4
 
5
- The locize script enables you to directly connect content from your website / application with your content on your localization project on locize.
5
+ The locize script enables the [incontext editing](https://www.locize.com/docs/context#incontext) feature provided by [locize](https://locize.com).
6
6
 
7
7
  ## Getting started
8
8
 
9
9
  Source can be loaded via [npm](https://www.npmjs.com/package/locize), [downloaded](https://github.com/locize/locize/blob/master/locize.min.js) from this repo or loaded from the npm CDN [unpkg.com/locize](https://unpkg.com/locize/locize.min.js).
10
10
 
11
- Adding the script or importing it is enough.
11
+ ```html
12
+ <script src="https://unpkg.com/locize/locize.min.js"></script>
13
+ ```
14
+
15
+ Using a module bundler simplest will be adding the script using npm (or yarn).
12
16
 
13
17
  ```bash
14
18
  npm i locize
15
19
  ```
16
20
 
17
- **Hint:** This module runs only in browser.
21
+ **Hint:** This module works only in the browser environment.
18
22
 
19
- ### InContext variants
20
23
 
21
- For i18next based solutions (i18next, react-i18next, locizify, ...) there are two options to work with locize incontext:
24
+ # How it works
22
25
 
23
- #### a) Iframe on your page
26
+ The script will parse the page content and pass found segments to locize using the browsers postMessage API. To work a text on your page has to be exactly matched to a segment in the editor by determing the matching namespace and key.
24
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
+ There are three ways to get the namespace and key:
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
+ ## 1) Using subliminal
28
31
 
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)
32
+ By default using [locizify](https://github.com/locize/locizify) or the `locizePlugin` the translations on your page will contain hidden text containing that information by using [subliminal](https://github.com/i18next/i18next-subliminal)
30
33
 
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.
34
+ ## 2) Using data-attributes
32
35
 
33
- #### b) Opening it on https://locize.app
36
+ Extend your html to contain that information
37
+
38
+ `data-i18n` -> will pass exact key
34
39
 
35
- Details for setting this up can be found [here](https://docs.locize.com/different-views/incontext)
40
+ `data-i18n-ns` -> will pass namespace name
36
41
 
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.
42
+ eg.:
38
43
 
39
- **hint** To get exact matches you can add following attributes to the element or it's parent:
44
+ ```html
45
+ <div data-i18n-ns="usedNamespace">
46
+ <p data-i18n="usedKey">
47
+ Some translated text
48
+ </p>
49
+ </div>
50
+
51
+ // or using ns:key
52
+ <p data-i18n="ns:key">
53
+ Some translated text
54
+ </p>
55
+ ```
40
56
 
41
- `data-i18n` -> will pass exact key
42
- `data-i18n-ns` -> will pass namespace name
57
+ Specifing content as [html](https://github.com/i18next/jquery-i18next?tab=readme-ov-file#set-innerhtml-attributes) or [title/placeholder attribute](https://github.com/i18next/jquery-i18next?tab=readme-ov-file#set-different-attribute) is also supported like used in `jquery-i18next`
43
58
 
44
- # Using
59
+ ## 3) Lookup in locize
60
+
61
+ If not using recommended 1) or 2) the script will send the raw texts to the editor which will try an exact search for that text and send the found exact match back (only one result with 100% exact match).
62
+
63
+ # Setup
45
64
 
46
65
  ## with locizify
47
66
 
48
67
  This plugin is already included in [locizify](https://github.com/locize/locizify) >= v4.1.0
49
68
 
69
+ ** Hint: ** show the incontext editor popup by adding incontext=true query paramenter, i.e. http://localhost:8080?incontext=true
70
+
50
71
  ## with i18next
51
72
 
52
- ### 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
73
+ For i18next we provide a plugin to be used.
74
+
53
75
  ```js
54
76
  import { locizePlugin } from 'locize'
55
77
 
56
78
  i18next.use(locizePlugin)
57
79
  ```
58
80
 
59
- ### this will show the locize incontext editor as a popup in your website
81
+ ** Hint: ** 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
82
+
83
+ Open as default:
84
+
60
85
  ```js
61
86
  import { locizeEditorPlugin } from 'locize'
62
87
 
63
88
  i18next.use(locizeEditorPlugin({ show: true }))
64
89
  ```
65
90
 
66
- Using react-i18next you might want to bind the editorSaved event to trigger a rerender:
91
+ Using `react-i18next` you might want to bind the editorSaved event to trigger a rerender each time you save changes in the editor:
67
92
 
68
93
  ```js
69
94
  i18next.init({
@@ -74,15 +99,30 @@ i18next.init({
74
99
  })
75
100
  ```
76
101
 
77
- ## without i18next
102
+ **Hint** you can match the integration to a locize project by:
103
+
104
+ Having [i18next-locize-backend[(https://github.com/locize/i18next-locize-backend) configured or adding
105
+
106
+ ```js
107
+ i18next.init({
108
+ // ...
109
+ editor: {
110
+ projectId="5e9ed7da-51ab-4b15-888b-27903f06be09"
111
+ version="latest"
112
+ }
113
+ })
114
+ ```
115
+
116
+ ## not using i18next (messageformat, fluent, ...)
78
117
 
79
118
  Not using i18next currently only the option to show your website inside the locize incontext solution (https://locize.app) is available.
80
119
 
81
- ### with other as module
120
+ ### using import
82
121
 
83
122
  ```js
84
123
  import { addLocizeSavedHandler, startStandalone, setEditorLng } from 'locize'
85
124
 
125
+ // optional
86
126
  addLocizeSavedHandler(res => {
87
127
  res.updated.forEach(item => {
88
128
  const { lng, ns, key, data } = item
@@ -98,7 +138,17 @@ startStandalone()
98
138
  setEditorLng(lng)
99
139
  ```
100
140
 
101
- ### with other in vanilla javascript
141
+
142
+ **Hint** you can match the integration to a locize project by adding:
143
+
144
+ ```js
145
+ startStandalone({
146
+ projectId="5e9ed7da-51ab-4b15-888b-27903f06be09"
147
+ version="latest"
148
+ })
149
+ ```
150
+
151
+ ### vanilla javascript
102
152
 
103
153
  Only relevant when your website is shown inside the locize incontext solution on https://locize.app.
104
154
 
@@ -118,7 +168,7 @@ window.locizeSavedHandler = res => {
118
168
  window.locizeStartStandalone()
119
169
  ```
120
170
 
121
- **Hint** you can fix the integration to a locize project by adding:
171
+ **Hint** you can match the integration to a locize project by adding:
122
172
 
123
173
  ```js
124
174
  <script
@@ -128,15 +178,3 @@ window.locizeStartStandalone()
128
178
  src="https://unpkg.com/locize/locize.min.js"
129
179
  >
130
180
  ```
131
-
132
- ### turn on/off click interception programmatically
133
-
134
- ```js
135
- import { turnOn, turnOff } from 'locize'
136
-
137
- let isOff
138
-
139
- // or use window.locize.turnOn
140
- isOff = turnOff() // -> true
141
- isOff = turnOn() // -> false
142
- ```
@@ -11,8 +11,7 @@ require('./api/handleRequestPopupChanges.js');
11
11
  require('./api/handleRequestResourceBundle.js');
12
12
  require('./api/handleSelectedKeys.js');
13
13
  require('./api/handleIsLocizeEnabled.js');
14
- require('./api/handleTurnOn.js');
15
- require('./api/handleTurnOff.js');
14
+ require('./api/handleSendMatchedUninstrumented.js');
16
15
  var postMessage = require('./api/postMessage.js');
17
16
  var clickHandler = require('./clickHandler.js');
18
17
 
@@ -2,10 +2,10 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var processLegacy = require('./processLegacy.js');
5
+ var _processLegacy = require('./_processLegacy.js');
6
6
 
7
7
  function startStandalone() {
8
- processLegacy.startLegacy({
8
+ _processLegacy.startLegacy({
9
9
  getLocizeDetails: function getLocizeDetails() {
10
10
  return {};
11
11
  },
@@ -4,6 +4,7 @@ var _toConsumableArray = require('@babel/runtime/helpers/toConsumableArray');
4
4
  var postMessage = require('./postMessage.js');
5
5
  var store = require('../store.js');
6
6
  var handleEditKey = require('./handleEditKey.js');
7
+ var highlightNode = require('../ui/highlightNode.js');
7
8
 
8
9
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
9
10
 
@@ -25,6 +26,12 @@ function handler(payload) {
25
26
  });
26
27
  }
27
28
  postMessage.api.i18n.setResource(lng, ns, key, data.value);
29
+ if (metas) {
30
+ Object.values(metas).forEach(function (m) {
31
+ var sItem = store.store.get(m.eleUniqueID);
32
+ highlightNode.recalcSelectedHighlight(sItem, sItem.node, sItem.keys);
33
+ });
34
+ }
28
35
  });
29
36
  Object.values(store.store.data).forEach(function (item) {
30
37
  if (item.originalChildNodes) {
@@ -9,7 +9,7 @@ var store = require('../store.js');
9
9
  function setValueOnNode(meta, value) {
10
10
  var item = store.store.get(meta.eleUniqueID);
11
11
  if (!item || !item.keys[meta.textType]) return;
12
- var txtWithHiddenMeta = i18nextSubliminal.wrap(value, item.subliminal);
12
+ var txtWithHiddenMeta = item.subliminal ? i18nextSubliminal.wrap(value, item.subliminal) : value;
13
13
  if (meta.textType === 'text') {
14
14
  item.node.textContent = txtWithHiddenMeta;
15
15
  } else if (meta.textType.indexOf('attr:') === 0) {
@@ -5,7 +5,7 @@ var postMessage = require('./postMessage.js');
5
5
  function handler(payload, e) {
6
6
  postMessage.api.source = e.source;
7
7
  postMessage.api.origin = e.origin;
8
- postMessage.api.legacy = true;
9
- postMessage.api.sendLocizeIsEnabled();
8
+ postMessage.api.sendLocizeIsEnabled(payload);
9
+ postMessage.api.requestInitialize(postMessage.api.config);
10
10
  }
11
11
  postMessage.api.addHandler('isLocizeEnabled', handler);
@@ -7,6 +7,15 @@ function handler(payload) {
7
7
  var containerStyle = payload.containerStyle;
8
8
  if (containerStyle) {
9
9
  var popup$1 = document.getElementById(popup.popupId);
10
+ if (!popup$1) return;
11
+ var storedPos = localStorage.getItem('locize_popup_pos');
12
+ if (storedPos) storedPos = JSON.parse(storedPos);
13
+ var storedSize = localStorage.getItem('locize_popup_size');
14
+ if (storedSize) storedSize = JSON.parse(storedSize);
15
+ if (storedSize && storedSize.height && storedSize.width) {
16
+ containerStyle.height = storedSize.height + 'px';
17
+ containerStyle.width = storedSize.width + 'px';
18
+ }
10
19
  if (containerStyle.height) {
11
20
  var diff = "calc(".concat(containerStyle.height, " - ").concat(popup$1.style.height, ")");
12
21
  popup$1.style.setProperty('top', "calc(".concat(popup$1.style.top, " - ").concat(diff, ")"));
@@ -17,6 +26,8 @@ function handler(payload) {
17
26
  popup$1.style.setProperty('left', "calc(".concat(popup$1.style.left, " - ").concat(_diff, ")"));
18
27
  popup$1.style.setProperty('width', containerStyle.width);
19
28
  }
29
+ if (storedPos && storedPos.top && storedPos.top < window.innerHeight - containerStyle.height.replace('px', '')) popup$1.style.setProperty('top', storedPos.top + 'px');
30
+ if (storedPos && storedPos.left && storedPos.left < window.innerWidth - containerStyle.width.replace('px', '')) popup$1.style.setProperty('left', storedPos.left + 'px');
20
31
  }
21
32
  }
22
33
  postMessage.api.addHandler('requestPopupChanges', handler);
@@ -0,0 +1,26 @@
1
+ 'use strict';
2
+
3
+ var _defineProperty = require('@babel/runtime/helpers/defineProperty');
4
+ var postMessage = require('./postMessage.js');
5
+ var store = require('../store.js');
6
+ var uninstrumentedStore = require('../uninstrumentedStore.js');
7
+ var parser = require('../parser.js');
8
+
9
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
10
+
11
+ var _defineProperty__default = /*#__PURE__*/_interopDefaultLegacy(_defineProperty);
12
+
13
+ function handler(payload) {
14
+ if (!payload.length) return;
15
+ payload.forEach(function (item) {
16
+ var uni = uninstrumentedStore.uninstrumentedStore.get(item.eleUniqueID);
17
+ store.store.save(item.eleUniqueID, undefined, item.textType, parser.extractNodeMeta(item.eleUniqueID, item.textType, _defineProperty__default["default"]({}, "".concat(item.textType), {
18
+ ns: item.ns,
19
+ key: item.key
20
+ }), item.value), uni === null || uni === void 0 ? void 0 : uni.node);
21
+ delete uni.keys["".concat(item.textType)];
22
+ if (!Object.keys(uni.keys).length) uninstrumentedStore.uninstrumentedStore.remove(item.eleUniqueID, uni.node);
23
+ });
24
+ postMessage.api.sendCurrentParsedContent();
25
+ }
26
+ postMessage.api.addHandler('sendMatchedUninstrumented', handler);
@@ -5,6 +5,8 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var _defineProperty = require('@babel/runtime/helpers/defineProperty');
6
6
  var vars = require('../vars.js');
7
7
  var store = require('../store.js');
8
+ var uninstrumentedStore = require('../uninstrumentedStore.js');
9
+ var utils = require('../utils.js');
8
10
 
9
11
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
10
12
 
@@ -22,27 +24,18 @@ function getMappedLegacyEvent(msg) {
22
24
  function addLocizeSavedHandler(handler) {
23
25
  api.locizeSavedHandler = handler;
24
26
  }
25
- function turnOn() {
26
- api.scriptTurnedOff = false;
27
- api.turnOn();
28
- return api.scriptTurnedOff;
29
- }
30
- function turnOff() {
31
- api.turnOff();
32
- api.scriptTurnedOff = true;
33
- return api.scriptTurnedOff;
34
- }
35
27
  function setEditorLng(lng) {
36
28
  api.sendCurrentTargetLanguage(lng);
37
29
  }
38
30
  var pendingMsgs = [];
31
+ var allowedActionsBeforeInit = ['locizeIsEnabled', 'requestInitialize'];
39
32
  function sendMessage(action, payload) {
40
33
  if (!api.source) {
41
34
  var _document$getElementB;
42
35
  api.source = (_document$getElementB = document.getElementById('i18next-editor-iframe')) === null || _document$getElementB === void 0 ? void 0 : _document$getElementB.contentWindow;
43
36
  }
44
37
  if (!api.origin) api.origin = vars.getIframeUrl();
45
- if (!api.source || !api.source.postMessage) {
38
+ if (!api.source || !api.source.postMessage || !api.initialized && allowedActionsBeforeInit.indexOf(action) < 0) {
46
39
  pendingMsgs.push({
47
40
  action: action,
48
41
  payload: payload
@@ -56,7 +49,7 @@ function sendMessage(action, payload) {
56
49
  } else {
57
50
  api.source.postMessage({
58
51
  sender: 'i18next-editor',
59
- senderAPIVersion: 'v1',
52
+ senderAPIVersion: 'v2',
60
53
  action: action,
61
54
  message: action,
62
55
  payload: payload
@@ -70,6 +63,22 @@ function sendMessage(action, payload) {
70
63
  sendMessage(action, payload);
71
64
  });
72
65
  }
66
+ var sendCurrentParsedContentDebounced = function sendCurrentParsedContentDebounced() {
67
+ sendMessage('sendCurrentParsedContent', {
68
+ content: Object.values(store.store.data).map(function (item) {
69
+ return {
70
+ id: item.id,
71
+ keys: item.keys
72
+ };
73
+ }),
74
+ uninstrumented: Object.values(uninstrumentedStore.uninstrumentedStore.data).map(function (item) {
75
+ return {
76
+ id: item.id,
77
+ keys: item.keys
78
+ };
79
+ })
80
+ });
81
+ };
73
82
  var handlers = {};
74
83
  var repeat = 5;
75
84
  var api = {
@@ -87,7 +96,7 @@ var api = {
87
96
  clearInterval(api.initInterval);
88
97
  delete api.initInterval;
89
98
  }
90
- }, 1000);
99
+ }, 2000);
91
100
  },
92
101
  selectKey: function selectKey(meta) {
93
102
  sendMessage('selectKey', meta);
@@ -95,45 +104,25 @@ var api = {
95
104
  confirmResourceBundle: function confirmResourceBundle(payload) {
96
105
  sendMessage('confirmResourceBundle', payload);
97
106
  },
98
- sendCurrentParsedContent: function sendCurrentParsedContent() {
99
- sendMessage('sendCurrentParsedContent', {
100
- content: Object.values(store.store.data).map(function (item) {
101
- return {
102
- id: item.id,
103
- keys: item.keys
104
- };
105
- })
106
- });
107
- },
107
+ sendCurrentParsedContent: utils.debounce(sendCurrentParsedContentDebounced, 500),
108
108
  sendCurrentTargetLanguage: function sendCurrentTargetLanguage(lng) {
109
109
  sendMessage('sendCurrentTargetLanguage', {
110
110
  targetLng: lng || api.i18n.getLng()
111
111
  });
112
112
  },
113
+ sendHrefchanged: function sendHrefchanged(href) {
114
+ sendMessage('hrefChanged', {
115
+ href: href
116
+ });
117
+ },
113
118
  addHandler: function addHandler(action, fc) {
114
119
  if (!handlers[action]) handlers[action] = [];
115
120
  handlers[action].push(fc);
116
121
  },
117
- sendLocizeIsEnabled: function sendLocizeIsEnabled() {
118
- sendMessage('locizeIsEnabled', {
122
+ sendLocizeIsEnabled: function sendLocizeIsEnabled(payload) {
123
+ sendMessage('locizeIsEnabled', _objectSpread(_objectSpread({}, payload), {}, {
119
124
  enabled: true
120
- });
121
- },
122
- turnOn: function turnOn() {
123
- if (api.scriptTurnedOff) return sendMessage('forcedOff');
124
- if (!api.clickInterceptionEnabled) {
125
- window.document.body.addEventListener('click', api.clickHandler, true);
126
- }
127
- api.clickInterceptionEnabled = true;
128
- sendMessage('turnedOn');
129
- },
130
- turnOff: function turnOff() {
131
- if (api.scriptTurnedOff) return sendMessage('forcedOff');
132
- if (api.clickInterceptionEnabled) {
133
- window.document.body.removeEventListener('click', api.clickHandler, true);
134
- }
135
- api.clickInterceptionEnabled = false;
136
- sendMessage('turnedOff');
125
+ }));
137
126
  },
138
127
  onAddedKey: function onAddedKey(lng, ns, key, value) {
139
128
  var msg = {
@@ -161,7 +150,7 @@ if (typeof window !== 'undefined') {
161
150
  }
162
151
  } else if (sender === 'i18next-editor-frame' && handlers[action]) {
163
152
  handlers[action].forEach(function (fc) {
164
- fc(payload);
153
+ fc(payload, e);
165
154
  });
166
155
  }
167
156
  });
@@ -171,5 +160,3 @@ exports.addLocizeSavedHandler = addLocizeSavedHandler;
171
160
  exports.api = api;
172
161
  exports.sendMessage = sendMessage;
173
162
  exports.setEditorLng = setEditorLng;
174
- exports.turnOff = turnOff;
175
- exports.turnOn = turnOn;
@@ -2,6 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
+ var i18nextSubliminal = require('i18next-subliminal');
5
6
  var utils = require('./utils.js');
6
7
 
7
8
  function createClickHandler(cb) {
@@ -11,8 +12,17 @@ function createClickHandler(cb) {
11
12
  if (!el) return {};
12
13
  e.preventDefault();
13
14
  e.stopPropagation();
15
+ function getFallbackNS() {
16
+ if (options.isLocizify) return options.defaultNS;
17
+ }
14
18
  var text = utils.getElementText(el);
15
19
  var key = utils.getElementI18nKey(el);
20
+ var ns = utils.getElementNamespace(el) || getFallbackNS();
21
+ if (i18nextSubliminal.containsHiddenMeta(text)) {
22
+ var meta = i18nextSubliminal.unwrap(text);
23
+ if (meta && meta.invisibleMeta && meta.invisibleMeta.key) key = meta.invisibleMeta.key;
24
+ if (meta && meta.invisibleMeta && meta.invisibleMeta.ns) ns = meta.invisibleMeta.ns;
25
+ }
16
26
  var rectEl = el.getBoundingClientRect ? el : el.parentElement;
17
27
  var _rectEl$getBoundingCl = rectEl.getBoundingClientRect(),
18
28
  top = _rectEl$getBoundingCl.top,
@@ -25,14 +35,11 @@ function createClickHandler(cb) {
25
35
  var pR = parseFloat(style.getPropertyValue('padding-right'));
26
36
  var pL = parseFloat(style.getPropertyValue('padding-left'));
27
37
  var sizing = style.getPropertyValue('box-sizing');
28
- function getFallbackNS() {
29
- if (options.isLocizify) return options.defaultNS;
30
- }
31
38
  cb({
32
39
  tagName: rectEl.tagName,
33
40
  text: text,
34
41
  key: key,
35
- ns: utils.getElementNamespace(el) || getFallbackNS(),
42
+ ns: ns,
36
43
  box: {
37
44
  top: top,
38
45
  left: left,
@@ -0,0 +1,35 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ function getImplementation() {
6
+ var impl = {
7
+ getResource: function getResource(lng, ns, key) {
8
+ return {};
9
+ },
10
+ setResource: function setResource(lng, ns, key, value) {
11
+ return;
12
+ },
13
+ getResourceBundle: function getResourceBundle(lng, ns, cb) {
14
+ cb({});
15
+ },
16
+ getDefaultNS: function getDefaultNS() {
17
+ return;
18
+ },
19
+ getLng: function getLng() {
20
+ return;
21
+ },
22
+ getSourceLng: function getSourceLng() {
23
+ return;
24
+ },
25
+ getLocizeDetails: function getLocizeDetails() {
26
+ return {};
27
+ },
28
+ bindLanguageChange: function bindLanguageChange(cb) {},
29
+ bindMissingKeyHandler: function bindMissingKeyHandler(cb) {},
30
+ triggerRerender: function triggerRerender() {}
31
+ };
32
+ return impl;
33
+ }
34
+
35
+ exports.getImplementation = getImplementation;
@@ -0,0 +1,94 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var _defineProperty = require('@babel/runtime/helpers/defineProperty');
6
+ var _toConsumableArray = require('@babel/runtime/helpers/toConsumableArray');
7
+
8
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
9
+
10
+ var _defineProperty__default = /*#__PURE__*/_interopDefaultLegacy(_defineProperty);
11
+ var _toConsumableArray__default = /*#__PURE__*/_interopDefaultLegacy(_toConsumableArray);
12
+
13
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
14
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty__default["default"](e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
15
+ function getImplementation(i18n) {
16
+ var impl = {
17
+ getResource: function getResource(lng, ns, key) {
18
+ return i18n.getResource && i18n.getResource(lng, ns, key);
19
+ },
20
+ setResource: function setResource(lng, ns, key, value) {
21
+ return i18n.addResource(lng, ns, key, value, {
22
+ silent: true
23
+ });
24
+ },
25
+ getResourceBundle: function getResourceBundle(lng, ns, cb) {
26
+ i18n.loadNamespaces(ns, function () {
27
+ cb(i18n.getResourceBundle(lng, ns));
28
+ });
29
+ },
30
+ getDefaultNS: function getDefaultNS() {
31
+ return i18n.options.defaultNS;
32
+ },
33
+ getLng: function getLng() {
34
+ return i18n.resolvedLanguage || i18n.languages && i18n.languages[0] || i18n.options.lng;
35
+ },
36
+ getSourceLng: function getSourceLng() {
37
+ var fallback = i18n.options.fallbackLng;
38
+ if (typeof fallback === 'string') return fallback;
39
+ if (Array.isArray(fallback)) return fallback[fallback.length - 1];
40
+ if (fallback && fallback["default"]) {
41
+ if (typeof fallback["default"] === 'string') return fallback;
42
+ if (Array.isArray(fallback["default"])) return fallback["default"][fallback["default"].length - 1];
43
+ }
44
+ if (typeof fallback === 'function') {
45
+ var res = fallback(i18n.resolvedLanguage);
46
+ if (typeof res === 'string') return res;
47
+ if (Array.isArray(res)) return res[res.length - 1];
48
+ }
49
+ return 'dev';
50
+ },
51
+ getLocizeDetails: function getLocizeDetails() {
52
+ var backendName;
53
+ 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) {
54
+ backendName = 'I18nextLocizeBackend';
55
+ } else {
56
+ backendName = i18n.services.backendConnector.backend ? i18n.services.backendConnector.backend.constructor.name : 'options.resources';
57
+ }
58
+ var opts = {
59
+ backendName: backendName,
60
+ sourceLng: impl.getSourceLng(),
61
+ i18nFormat: i18n.options.compatibilityJSON === 'v3' ? 'i18next_v3' : 'i18next_v4',
62
+ i18nFramework: 'i18next',
63
+ isLocizify: i18n.options.isLocizify,
64
+ defaultNS: i18n.options.defaultNS,
65
+ targetLngs: _toConsumableArray__default["default"](new Set([].concat(i18n.options.preload, i18n.options.supportedLngs, [impl.getLng()]))).filter(function (l) {
66
+ return l !== 'cimode' && l !== false && l !== 'false' && l !== undefined && l !== impl.getSourceLng();
67
+ }),
68
+ ns: _toConsumableArray__default["default"](new Set([].concat(i18n.options.ns, i18n.options.fallbackNS, i18n.options.defaultNS))).filter(function (n) {
69
+ return n !== false && n !== 'false';
70
+ })
71
+ };
72
+ if (!i18n.options.backend && !i18n.options.editor) return opts;
73
+ var pickFrom = i18n.options.editor || i18n.options.backend;
74
+ return _objectSpread(_objectSpread({}, opts), {}, {
75
+ projectId: pickFrom.projectId,
76
+ version: pickFrom.version
77
+ });
78
+ },
79
+ bindLanguageChange: function bindLanguageChange(cb) {
80
+ i18n.on('languageChanged', cb);
81
+ },
82
+ bindMissingKeyHandler: function bindMissingKeyHandler(cb) {
83
+ i18n.options.missingKeyHandler = function (lng, ns, k, val, isUpdate, opts) {
84
+ if (!isUpdate) cb(lng, ns, k, val);
85
+ };
86
+ },
87
+ triggerRerender: function triggerRerender() {
88
+ i18n.emit('editorSaved');
89
+ }
90
+ };
91
+ return impl;
92
+ }
93
+
94
+ exports.getImplementation = getImplementation;