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/src/parser.js CHANGED
@@ -1,7 +1,12 @@
1
- import { unwrap, containsHiddenMeta, containsHiddenStartMarker } from 'i18next-subliminal'
1
+ import {
2
+ unwrap,
3
+ containsHiddenMeta,
4
+ containsHiddenStartMarker
5
+ } from 'i18next-subliminal'
2
6
  import { store } from './store.js'
3
7
  import { uninstrumentedStore } from './uninstrumentedStore.js'
4
- import { validAttributes } from './vars.js'
8
+ import { validAttributes, ignoreElements } from './vars.js'
9
+ import { getI18nMetaFromNode } from './utils'
5
10
 
6
11
  import './shims/uniqueID.js'
7
12
 
@@ -15,27 +20,44 @@ export function setImplementation (impl) {
15
20
 
16
21
  function walk (node, func) {
17
22
  if (node.dataset && node.dataset.i18nextEditorElement === 'true') return
23
+
24
+ // parse node
18
25
  func(node)
19
26
 
20
- const children = node.childNodes
27
+ // check if it is is any store - if so remove parent from uninstrumented
28
+ // this avoids situations where a div has inner text (not instrumented) and some children that are instrumented showing a big box around all
29
+ const instr = store.get(node.uniqueID)
30
+ const uninstr = uninstrumentedStore.get(node.uniqueID)
31
+
32
+ if (instr || uninstr) {
33
+ const id = node.parentElement?.uniqueID
34
+ uninstrumentedStore.remove(id, node.parentElement)
35
+ }
21
36
 
37
+ // parse children
38
+ const children = node.childNodes
22
39
  for (
23
40
  let i = 0;
24
41
  i < children.length;
25
42
  i++ // Children are siblings to each other
26
- ) { walk(children[i], func) }
43
+ ) {
44
+ walk(children[i], func)
45
+ }
27
46
  }
28
47
 
29
- function extractMeta (id, type, meta, children) {
48
+ function extractHiddenMeta (id, type, meta, children) {
30
49
  const { invisibleMeta, text } = meta
31
50
  if (!invisibleMeta || !invisibleMeta.key || !invisibleMeta.ns) return
32
51
 
33
- if (!currentSourceLng) currentSourceLng = i18n?.getSourceLng()
52
+ if (!currentSourceLng) currentSourceLng = i18n.getSourceLng()
34
53
 
35
54
  return {
36
55
  eleUniqueID: id,
37
56
  textType: type,
38
- children: children ? children.map(c => c.childIndex).join(',') : null,
57
+ children:
58
+ children && children.map
59
+ ? children.map(c => c.childIndex).join(',')
60
+ : null,
39
61
  qualifiedKey: `${invisibleMeta.ns}:${invisibleMeta.key}`,
40
62
  ...invisibleMeta,
41
63
  extractedText: text,
@@ -44,11 +66,57 @@ function extractMeta (id, type, meta, children) {
44
66
  i18nRawText: {
45
67
  [`${invisibleMeta.lng}`]:
46
68
  invisibleMeta.source === 'translation' && i18n
47
- ? i18n.getResource(invisibleMeta.lng, invisibleMeta.ns, invisibleMeta.key)
69
+ ? i18n?.getResource(
70
+ invisibleMeta.lng,
71
+ invisibleMeta.ns,
72
+ invisibleMeta.key
73
+ )
48
74
  : null,
49
75
  [`${currentSourceLng}`]:
50
76
  invisibleMeta.source === 'translation' && i18n
51
- ? i18n.getResource(currentSourceLng, invisibleMeta.ns, invisibleMeta.key)
77
+ ? i18n?.getResource(
78
+ currentSourceLng,
79
+ invisibleMeta.ns,
80
+ invisibleMeta.key
81
+ )
82
+ : null
83
+ }
84
+ }
85
+ }
86
+
87
+ export function extractNodeMeta (id, type, nodeMeta = {}, text, children) {
88
+ const meta = nodeMeta[type]
89
+ if (!meta) return
90
+
91
+ if (!currentSourceLng) currentSourceLng = i18n.getSourceLng()
92
+ const i18nTargetLng = i18n.getLng()
93
+
94
+ // console.warn('lng', i18nTargetLng)
95
+
96
+ return {
97
+ eleUniqueID: id,
98
+ textType: type,
99
+ children:
100
+ children && children.map
101
+ ? children.map(c => c.childIndex).join(',')
102
+ : null,
103
+ qualifiedKey:
104
+ meta.key && (meta.ns || i18n?.getDefaultNS())
105
+ ? `${meta.ns || i18n?.getDefaultNS()}:${meta.key}`
106
+ : null,
107
+ key: meta.key,
108
+ ns: meta.ns || i18n?.getDefaultNS(),
109
+ extractedText: text,
110
+ i18nTargetLng,
111
+ i18nSourceLng: currentSourceLng,
112
+ i18nRawText: {
113
+ [`${i18nTargetLng}`]:
114
+ i18n && meta.ns && meta.key
115
+ ? i18n?.getResource(i18nTargetLng, meta.ns, meta.key) || text
116
+ : text,
117
+ [`${currentSourceLng}`]:
118
+ i18n && meta.ns && meta.key
119
+ ? i18n?.getResource(currentSourceLng, meta.ns, meta.key)
52
120
  : null
53
121
  }
54
122
  }
@@ -58,40 +126,79 @@ function containsOnlySpaces (str) {
58
126
  return /^\s*$/.test(str)
59
127
  }
60
128
 
129
+ function storeIfQualifiedKey (
130
+ id,
131
+ subliminal,
132
+ type,
133
+ nodeI18nMeta,
134
+ node,
135
+ children,
136
+ txt
137
+ ) {
138
+ // if we got some key, ns from locize and stored that - reuse it on this run
139
+ const stored = store.get(id)
140
+ const storedMeta = (stored && stored.keys[`${type}`]) || {}
141
+ const typeMeta = nodeI18nMeta[`${type}`] || {}
142
+
143
+ if (!typeMeta.key && storedMeta.key) typeMeta.key = storedMeta.key
144
+ if (!typeMeta.ns && storedMeta.ns) typeMeta.ns = storedMeta.ns
145
+ nodeI18nMeta[`${type}`] = typeMeta
146
+
147
+ // extract metas
148
+ const meta = extractNodeMeta(id, type, nodeI18nMeta, txt, children)
149
+
150
+ // if we can 100% identify that ns:key store - else uninstrumented
151
+ if (meta.qualifiedKey) {
152
+ store.save(id, null, type, meta, node, children)
153
+ uninstrumentedStore.removeKey(i, type, node)
154
+ } else {
155
+ uninstrumentedStore.save(id, type, node, txt)
156
+ }
157
+ }
158
+
61
159
  function handleNode (node) {
160
+ if (ignoreElements.indexOf(node.nodeName) > -1) return
161
+
162
+ const nodeI18nMeta = getI18nMetaFromNode(node)
163
+ let usedSubliminalForText = false
164
+
62
165
  // test for inner text - but ignore text for elements merged to html containing translation
63
166
  if (node.childNodes && !ignoreMergedEleUniqueIds.includes(node.uniqueID)) {
64
167
  let merge = []
168
+
65
169
  node.childNodes.forEach((child, i) => {
66
170
  if (merge.length && child.nodeName !== '#text') {
67
171
  ignoreMergedEleUniqueIds.push(child.uniqueID)
68
172
  merge.push({ childIndex: i, child })
69
173
  }
70
- if (child.nodeName !== '#text') return
71
174
 
175
+ if (child.nodeName !== '#text') return
72
176
  const txt = child.textContent
73
177
  if (containsOnlySpaces(txt)) return
74
178
 
75
179
  const hasHiddenMeta = containsHiddenMeta(txt)
76
180
  const hasHiddenStartMarker = containsHiddenStartMarker(txt)
77
181
 
182
+ if (hasHiddenMeta) usedSubliminalForText = true
183
+
78
184
  // console.warn(
79
185
  // 'child',
80
186
  // child,
81
187
  // child.nodeName,
82
188
  // child.innerText,
83
189
  // hasHiddenStartMarker,
84
- // hasHiddenMeta,
85
- // );
190
+ // hasHiddenMeta
191
+ // )
86
192
 
87
193
  if (hasHiddenStartMarker && hasHiddenMeta) {
88
194
  const meta = unwrap(txt)
89
195
 
196
+ uninstrumentedStore.remove(node.uniqueID, node) // might be instrumented later and already in uninstrumentedStore - so remove it there first
90
197
  store.save(
91
198
  node.uniqueID,
92
199
  meta.invisibleMeta,
93
200
  'text',
94
- extractMeta(node.uniqueID, 'text', meta),
201
+ extractHiddenMeta(node.uniqueID, 'text', meta),
95
202
  node
96
203
  )
97
204
  } else if (hasHiddenStartMarker) {
@@ -107,21 +214,87 @@ function handleNode (node) {
107
214
  }, '')
108
215
  )
109
216
 
217
+ uninstrumentedStore.removeKey(node.uniqueID, 'html', node, txt) // might be instrumented later and already in uninstrumentedStore - so remove it there first
110
218
  store.save(
111
219
  node.uniqueID,
112
220
  meta.invisibleMeta,
113
221
  'html',
114
- extractMeta(node.uniqueID, 'html', meta, merge),
222
+ extractHiddenMeta(node.uniqueID, 'html', meta, merge),
115
223
  node,
116
224
  merge
117
225
  )
118
226
 
119
227
  // reset
120
228
  merge = []
121
- } else if (txt) {
122
- uninstrumentedStore.save(node.uniqueID, 'text', node)
123
229
  }
124
230
  })
231
+
232
+ // no subliminal in text
233
+ if (!usedSubliminalForText) {
234
+ node.childNodes.forEach((child, i) => {
235
+ if (merge.length && child.nodeName !== '#text') {
236
+ ignoreMergedEleUniqueIds.push(child.uniqueID)
237
+ // merge.push({ childIndex: i, child }) // will be pushed regular below with txt
238
+ }
239
+
240
+ // if (child.nodeName !== '#text') return
241
+ const txt = child.textContent
242
+ // if (containsOnlySpaces(txt)) return
243
+
244
+ // merge and add data-i18n=[html]key
245
+ if (
246
+ nodeI18nMeta &&
247
+ nodeI18nMeta['html'] &&
248
+ i < node.childNodes.length - 1
249
+ ) {
250
+ merge.push({ childIndex: i, child, text: txt })
251
+ } else if (
252
+ nodeI18nMeta &&
253
+ nodeI18nMeta['html'] &&
254
+ i === node.childNodes.length - 1
255
+ ) {
256
+ merge.push({ childIndex: i, child, text: txt })
257
+
258
+ storeIfQualifiedKey(
259
+ node.uniqueID,
260
+ null,
261
+ 'html',
262
+ nodeI18nMeta,
263
+ node,
264
+ merge,
265
+ node.innerHTML
266
+ )
267
+
268
+ // reset
269
+ merge = []
270
+ } else if (txt) {
271
+ // console.warn(
272
+ // 'nodeI18nMeta',
273
+ // txt,
274
+ // nodeI18nMeta,
275
+ // hasHiddenMeta,
276
+ // hasHiddenStartMarker
277
+ // )
278
+
279
+ // add data-i18n=key (inner text)
280
+ if (nodeI18nMeta && nodeI18nMeta['text']) {
281
+ storeIfQualifiedKey(
282
+ node.uniqueID,
283
+ null,
284
+ 'text',
285
+ nodeI18nMeta,
286
+ node,
287
+ undefined,
288
+ txt
289
+ )
290
+ } else if (child.nodeName === '#text' && !containsOnlySpaces(txt)) {
291
+ // if no metas at all and is a text node that is not just some spaces (html indent)
292
+ // add to uninstrumented for a lookup (locize search)
293
+ uninstrumentedStore.save(node.uniqueID, 'text', node, txt)
294
+ }
295
+ }
296
+ })
297
+ }
125
298
  }
126
299
 
127
300
  // test attibutes
@@ -132,18 +305,33 @@ function handleNode (node) {
132
305
  if (containsHiddenMeta(txt)) {
133
306
  const meta = unwrap(txt)
134
307
 
308
+ uninstrumentedStore.removeKey(node.uniqueID, attr, node) // might be instrumented later and already in uninstrumentedStore - so remove it there first
135
309
  store.save(
136
310
  node.uniqueID,
137
311
  meta.invisibleMeta,
138
- `attr:${attr}`,
139
- extractMeta(node.uniqueID, `attr:${attr}`, meta),
312
+ attr,
313
+ extractHiddenMeta(node.uniqueID, `${attr}`, meta),
140
314
  node
141
315
  )
142
316
  } else if (txt) {
143
- uninstrumentedStore.save(node.uniqueID, `attr:${attr}`, node)
317
+ if (nodeI18nMeta && nodeI18nMeta[attr]) {
318
+ storeIfQualifiedKey(
319
+ node.uniqueID,
320
+ null,
321
+ attr,
322
+ nodeI18nMeta,
323
+ node,
324
+ undefined,
325
+ txt
326
+ )
327
+ } else {
328
+ uninstrumentedStore.save(node.uniqueID, attr, node, txt)
329
+ }
144
330
  }
145
331
  })
146
332
 
333
+ // console.warn('store', store)
334
+
147
335
  // TODO: how to handle react Trans things?!?
148
336
  }
149
337
 
package/src/process.js CHANGED
@@ -5,17 +5,34 @@ import { initDragElement, initResizeElement } from './ui/popup.js'
5
5
  import { Popup, popupId } from './ui/elements/popup.js'
6
6
  import { getIframeUrl } from './vars.js'
7
7
  import { api } from './api/index.js'
8
+ import { getQsParameterByName } from './utils.js'
9
+ import * as implementations from './implementations/index.js'
10
+
11
+ const dummyImplementation = implementations.dummy.getImplementation()
12
+
13
+ let isInIframe = typeof window !== 'undefined'
14
+ try {
15
+ // eslint-disable-next-line no-undef, no-restricted-globals
16
+ isInIframe = self !== top
17
+ // eslint-disable-next-line no-empty
18
+ } catch (e) {}
8
19
 
9
20
  // eslint-disable-next-line no-unused-vars
10
21
  let data = []
11
22
 
12
- export function start (implementation = {}) {
23
+ export function start (
24
+ implementation = dummyImplementation,
25
+ opt = { show: false, qsProp: 'incontext' }
26
+ ) {
13
27
  if (typeof document === 'undefined') return
28
+
29
+ const showInContext = opt.show || getQsParameterByName(opt.qsProp) === 'true'
30
+
14
31
  // get locize id, version
15
32
  const scriptEle = document.getElementById('locize')
16
33
 
17
- let config = {};
18
- ['projectId', 'version'].forEach(attr => {
34
+ let config = {}
35
+ ;['projectId', 'version'].forEach(attr => {
19
36
  if (!scriptEle) return
20
37
  let value =
21
38
  scriptEle.getAttribute(attr.toLowerCase()) ||
@@ -24,9 +41,10 @@ export function start (implementation = {}) {
24
41
  if (value === 'false') value = false
25
42
  if (value !== undefined && value !== null) config[attr] = value
26
43
  })
27
- config = { ...implementation.getLocizeDetails(), ...config }
44
+ config = { ...implementation.getLocizeDetails(), ...config, ...opt }
28
45
 
29
46
  // init stuff
47
+ api.config = config
30
48
  api.init(implementation)
31
49
  setImplementation(implementation)
32
50
 
@@ -36,6 +54,9 @@ export function start (implementation = {}) {
36
54
  })
37
55
 
38
56
  function continueToStart () {
57
+ // don't show if not in iframe and no qs
58
+ if (!isInIframe && !showInContext) return
59
+
39
60
  const observer = createObserver(document.body, eles => {
40
61
  eles.forEach(ele => {
41
62
  data = parseTree(ele)
@@ -47,7 +68,7 @@ export function start (implementation = {}) {
47
68
  startMouseTracking(observer)
48
69
 
49
70
  // append popup
50
- if (!document.getElementById(popupId)) {
71
+ if (!isInIframe && !document.getElementById(popupId)) {
51
72
  document.body.append(
52
73
  Popup(getIframeUrl(), () => {
53
74
  api.requestInitialize(config)
@@ -56,6 +77,32 @@ export function start (implementation = {}) {
56
77
  initDragElement()
57
78
  initResizeElement()
58
79
  }
80
+
81
+ // propagate url changes
82
+ if (typeof window !== 'undefined') {
83
+ let oldHref = window.document.location.href
84
+ api.sendHrefchanged(oldHref)
85
+
86
+ const bodyList = window.document.querySelector('body')
87
+
88
+ const observer = new window.MutationObserver(mutations => {
89
+ mutations.forEach(mutation => {
90
+ if (oldHref !== window.document.location.href) {
91
+ // console.warn('url changed', oldHref, document.location.href);
92
+ oldHref = window.document.location.href
93
+
94
+ api.sendHrefchanged(oldHref)
95
+ }
96
+ })
97
+ })
98
+
99
+ const config = {
100
+ childList: true,
101
+ subtree: true
102
+ }
103
+
104
+ observer.observe(bodyList, config)
105
+ }
59
106
  }
60
107
 
61
108
  if (document.body) return continueToStart()
@@ -1,21 +1,8 @@
1
- import { startLegacy } from './processLegacy.js'
1
+ import { start } from './process.js'
2
2
 
3
- export function startStandalone () {
4
- startLegacy({
5
- getLocizeDetails: () => {
6
- return {}
7
- },
8
- getLng: () => {
9
- return undefined
10
- },
11
- setResource: () => {},
12
- triggerRerender: () => {},
13
- getResourceBundle: () => {
14
- return {}
15
- },
16
- bindMissingKeyHandler: () => {},
17
- bindLanguageChange: () => {}
18
- })
3
+ export function startStandalone (options) {
4
+ const { implementation, ...rest } = options
5
+ start(implementation, rest)
19
6
  }
20
7
 
21
8
  if (typeof window !== 'undefined')
package/src/store.js CHANGED
@@ -22,6 +22,8 @@ function save (id, subliminal, type, meta, node, children) {
22
22
  }
23
23
  }
24
24
 
25
+ if (subliminal) data[id].subliminal = subliminal
26
+
25
27
  data[id].keys = {
26
28
  ...data[id].keys,
27
29
  [`${type}`]: meta
@@ -0,0 +1,17 @@
1
+ export function HighlightBox (ele, borderColor, shadowColor) {
2
+ const rect = ele.getBoundingClientRect()
3
+
4
+ const box = document.createElement('div')
5
+ box.style = `position: absolute; top: ${
6
+ rect.top - 2 + window.scrollY
7
+ }px; left: ${rect.left - 2 + window.scrollX}px; height: ${
8
+ rect.height + 4
9
+ }px; width: ${
10
+ rect.width + 4
11
+ }px; border: 1px solid ${borderColor}; border-radius: 2px; ${
12
+ shadowColor ? `box-shadow: 0 0 20px 0 ${shadowColor};` : ''
13
+ }`
14
+ box.setAttribute('data-i18next-editor-element', 'true')
15
+
16
+ return box
17
+ }
@@ -95,7 +95,7 @@ function Ribbon (popupEle, onMaximize) {
95
95
  background-color: rgba(249, 249, 249, 0.2);
96
96
  backdrop-filter: blur(3px);
97
97
  box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
98
- border-radius: 50%
98
+ border-radius: 50%;
99
99
  `
100
100
 
101
101
  ribbon.onclick = () => {
@@ -155,8 +155,8 @@ export function Popup (url, cb) {
155
155
  min-width: 300px;
156
156
  --i18next-editor-popup-width: 400px;
157
157
  width: var(--i18next-editor-popup-width);
158
- max-height: 600px;
159
- max-width: 800px;
158
+ max-height: 800px;
159
+ max-width: 1000px;
160
160
 
161
161
  position: fixed;
162
162
  --i18next-editor-popup-position-top: calc(100vh - var(--i18next-editor-popup-height) - 10px);
@@ -205,7 +205,7 @@ export function Popup (url, cb) {
205
205
  iframe.style = `
206
206
  z-index: 100;
207
207
  width: 100%;
208
- height: calc(100% - 28px);
208
+ height: calc(100% - 32px);
209
209
  border: none;
210
210
  background: #fff;
211
211
  `
@@ -2,18 +2,18 @@ import { colors } from '../../vars.js'
2
2
  import { sheet } from '../stylesheet.js'
3
3
  import { api } from '../../api/index.js'
4
4
 
5
- import { RibbonLogo, EditIcon } from './icons.js'
5
+ import { EditIcon } from './icons.js'
6
6
 
7
7
  if (sheet) {
8
8
  sheet.insertRule(
9
- '.i18next-editor-button:hover { background-color: rgba(38, 166, 154, 1) !important; }'
9
+ '.i18next-editor-button:hover { background-color: rgba(21, 65, 154, 1) !important; }'
10
10
  )
11
11
  }
12
12
  export function RibbonButton (text, attrTitle, onClick) {
13
13
  const btn = document.createElement('button')
14
14
 
15
15
  btn.style =
16
- 'font-family: Arial; position: relative; backdrop-filter: blur(3px); cursor: pointer; padding: 2px 10px 2px 20px; font-size: 15px; font-weight: 300; text-transform: uppercase; color: #fff; background-color: rgba(38, 166, 154, 0.8); border: none; border-radius: 12px'
16
+ 'font-family: Arial; position: relative; backdrop-filter: blur(3px); cursor: pointer; padding: 2px 10px 2px 20px; font-size: 15px; font-weight: 300; text-transform: uppercase; color: #fff; background-color: rgba(25, 118, 210, 0.8); border: none; border-radius: 12px; z-index: 99999;'
17
17
  btn.classList.add('i18next-editor-button')
18
18
  btn.setAttribute('data-i18next-editor-element', 'true')
19
19
  btn.setAttribute('title', attrTitle)
@@ -53,8 +53,8 @@ export function RibbonBox (keys = {}) {
53
53
  `
54
54
  box.appendChild(arrow)
55
55
 
56
- const logo = RibbonLogo()
57
- box.appendChild(logo)
56
+ // const logo = RibbonLogo()
57
+ // box.appendChild(logo)
58
58
 
59
59
  const btnbox = document.createElement('div')
60
60
  btnbox.style =
@@ -63,9 +63,13 @@ export function RibbonBox (keys = {}) {
63
63
  Object.keys(keys).forEach(k => {
64
64
  const data = keys[k]
65
65
 
66
- const btn = RibbonButton(k.replace('attr:', ''), `${data.ns}:${data.key}`, () => {
67
- api.selectKey(data)
68
- })
66
+ const btn = RibbonButton(
67
+ k.replace('attr:', ''),
68
+ `${data.ns}:${data.key}`,
69
+ () => {
70
+ api.selectKey(data)
71
+ }
72
+ )
69
73
  btn.style.marginBottom = '2px'
70
74
  btnbox.appendChild(btn)
71
75
  })