@lionrapid/core 0.3.1 → 0.4.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/dist/browser/attribute-extractor.d.ts +54 -0
- package/dist/browser/attribute-extractor.d.ts.map +1 -0
- package/dist/browser/attribute-extractor.js +155 -0
- package/dist/browser/attribute-extractor.js.map +1 -0
- package/dist/browser/auto-init.d.ts +4 -0
- package/dist/browser/auto-init.d.ts.map +1 -1
- package/dist/browser/auto-init.js +6 -2
- package/dist/browser/auto-init.js.map +1 -1
- package/dist/browser/auto-translator.d.ts +23 -0
- package/dist/browser/auto-translator.d.ts.map +1 -1
- package/dist/browser/auto-translator.js +90 -5
- package/dist/browser/auto-translator.js.map +1 -1
- package/dist/browser/block-extractor.d.ts +8 -0
- package/dist/browser/block-extractor.d.ts.map +1 -1
- package/dist/browser/block-extractor.js +77 -0
- package/dist/browser/block-extractor.js.map +1 -1
- package/dist/browser/editor/editor-api.d.ts +22 -1
- package/dist/browser/editor/editor-api.d.ts.map +1 -1
- package/dist/browser/editor/editor-api.js +54 -19
- package/dist/browser/editor/editor-api.js.map +1 -1
- package/dist/browser/editor/editor-init.js +72 -3
- package/dist/browser/editor/editor-init.js.map +1 -1
- package/dist/browser/editor/editor-styles.d.ts +1 -1
- package/dist/browser/editor/editor-styles.d.ts.map +1 -1
- package/dist/browser/editor/editor-styles.js +38 -1
- package/dist/browser/editor/editor-styles.js.map +1 -1
- package/dist/browser/editor/inspector.d.ts +8 -0
- package/dist/browser/editor/inspector.d.ts.map +1 -1
- package/dist/browser/editor/inspector.js +14 -0
- package/dist/browser/editor/inspector.js.map +1 -1
- package/dist/browser/editor/live-preview.d.ts +1 -1
- package/dist/browser/editor/live-preview.d.ts.map +1 -1
- package/dist/browser/editor/live-preview.js +27 -16
- package/dist/browser/editor/live-preview.js.map +1 -1
- package/dist/browser/editor/locale-url.d.ts +18 -0
- package/dist/browser/editor/locale-url.d.ts.map +1 -0
- package/dist/browser/editor/locale-url.js +37 -0
- package/dist/browser/editor/locale-url.js.map +1 -0
- package/dist/browser/editor/sidebar.d.ts +6 -0
- package/dist/browser/editor/sidebar.d.ts.map +1 -1
- package/dist/browser/editor/sidebar.js +133 -4
- package/dist/browser/editor/sidebar.js.map +1 -1
- package/dist/browser/editor/toolbar.d.ts +8 -1
- package/dist/browser/editor/toolbar.d.ts.map +1 -1
- package/dist/browser/editor/toolbar.js +49 -4
- package/dist/browser/editor/toolbar.js.map +1 -1
- package/dist/browser/index.d.ts +2 -0
- package/dist/browser/index.d.ts.map +1 -1
- package/dist/browser/index.js +1 -0
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/lionrapid.auto.dev.js +320 -12
- package/dist/browser/lionrapid.auto.dev.js.map +4 -4
- package/dist/browser/lionrapid.auto.js +320 -12
- package/dist/browser/lionrapid.auto.js.map +4 -4
- package/dist/browser/lionrapid.auto.min.js +3 -3
- package/dist/browser/lionrapid.auto.min.js.map +4 -4
- package/dist/browser/lionrapid.editor.js +371 -36
- package/dist/browser/lionrapid.editor.js.map +3 -3
- package/dist/browser/lionrapid.editor.min.js +41 -4
- package/dist/browser/lionrapid.editor.min.js.map +4 -4
- package/dist/browser/lionrapid.esm.js +36 -2
- package/dist/browser/lionrapid.esm.js.map +2 -2
- package/dist/browser/lionrapid.esm.min.js +2 -2
- package/dist/browser/lionrapid.esm.min.js.map +3 -3
- package/dist/browser/lionrapid.iife.dev.js +36 -2
- package/dist/browser/lionrapid.iife.dev.js.map +2 -2
- package/dist/browser/lionrapid.iife.js +36 -2
- package/dist/browser/lionrapid.iife.js.map +2 -2
- package/dist/browser/lionrapid.iife.min.js +2 -2
- package/dist/browser/lionrapid.iife.min.js.map +3 -3
- package/dist/browser/lionrapid.umd.js +36 -2
- package/dist/browser/lionrapid.umd.js.map +2 -2
- package/dist/browser/lionrapid.umd.min.js +2 -2
- package/dist/browser/lionrapid.umd.min.js.map +3 -3
- package/dist/browser/md5.d.ts +3 -2
- package/dist/browser/md5.d.ts.map +1 -1
- package/dist/browser/md5.js +41 -6
- package/dist/browser/md5.js.map +1 -1
- package/dist/content/parser/MarkupParser.d.ts +0 -10
- package/dist/content/parser/MarkupParser.d.ts.map +1 -1
- package/dist/content/parser/MarkupParser.js +45 -3
- package/dist/content/parser/MarkupParser.js.map +1 -1
- package/dist/content/types.d.ts +30 -0
- package/dist/content/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -13,14 +13,18 @@ export class Toolbar {
|
|
|
13
13
|
onLanguageChange;
|
|
14
14
|
onExit;
|
|
15
15
|
onCaptureSnapshot;
|
|
16
|
+
onBrowseToggle;
|
|
17
|
+
browsing = false;
|
|
18
|
+
browseBtnEl = null;
|
|
16
19
|
// Drag state
|
|
17
20
|
dragging = false;
|
|
18
21
|
dragOffsetX = 0;
|
|
19
22
|
dragOffsetY = 0;
|
|
20
|
-
constructor(shadowRoot, languages, currentLocale, onLanguageChange, onExit, onCaptureSnapshot = null, captureOptions = {}) {
|
|
23
|
+
constructor(shadowRoot, languages, currentLocale, onLanguageChange, onExit, onCaptureSnapshot = null, captureOptions = {}, onBrowseToggle = null) {
|
|
21
24
|
this.onLanguageChange = onLanguageChange;
|
|
22
25
|
this.onExit = onExit;
|
|
23
26
|
this.onCaptureSnapshot = onCaptureSnapshot;
|
|
27
|
+
this.onBrowseToggle = onBrowseToggle;
|
|
24
28
|
this.currentLocale = currentLocale;
|
|
25
29
|
const captureMode = captureOptions.mode ?? 'capture';
|
|
26
30
|
this.el = document.createElement('div');
|
|
@@ -36,7 +40,10 @@ export class Toolbar {
|
|
|
36
40
|
e.stopPropagation();
|
|
37
41
|
this.toggle();
|
|
38
42
|
});
|
|
39
|
-
this.el
|
|
43
|
+
// Note: fabBtn is appended to this.el at the END (after panel), so flex
|
|
44
|
+
// lays out panel-then-button — i.e. the panel expands to the LEFT of the
|
|
45
|
+
// button. The button's default position is near the right edge of the
|
|
46
|
+
// viewport, so leftward expansion keeps the panel on-screen.
|
|
40
47
|
// Expanded panel
|
|
41
48
|
const panel = document.createElement('div');
|
|
42
49
|
panel.className = 'lr-fab-panel';
|
|
@@ -95,6 +102,22 @@ export class Toolbar {
|
|
|
95
102
|
});
|
|
96
103
|
panel.appendChild(captureBtn);
|
|
97
104
|
}
|
|
105
|
+
// Browse-mode toggle — suspends the inspector so the PM can click the
|
|
106
|
+
// site's own nav links to reach another page without every click opening
|
|
107
|
+
// the edit drawer. Only shown when a handler is wired (live-page editing,
|
|
108
|
+
// not snapshot viewer mode).
|
|
109
|
+
if (this.onBrowseToggle) {
|
|
110
|
+
const browseBtn = document.createElement('button');
|
|
111
|
+
browseBtn.className = 'lr-fab-browse';
|
|
112
|
+
browseBtn.textContent = 'Browse';
|
|
113
|
+
browseBtn.title = 'Pause editing so you can click links and navigate to another page';
|
|
114
|
+
browseBtn.addEventListener('click', (e) => {
|
|
115
|
+
e.stopPropagation();
|
|
116
|
+
this.setBrowsing(!this.browsing);
|
|
117
|
+
});
|
|
118
|
+
this.browseBtnEl = browseBtn;
|
|
119
|
+
panel.appendChild(browseBtn);
|
|
120
|
+
}
|
|
98
121
|
// Progress
|
|
99
122
|
this.progressEl = document.createElement('span');
|
|
100
123
|
this.progressEl.className = 'lr-fab-progress';
|
|
@@ -106,6 +129,7 @@ export class Toolbar {
|
|
|
106
129
|
exitBtn.addEventListener('click', () => this.onExit());
|
|
107
130
|
panel.appendChild(exitBtn);
|
|
108
131
|
this.el.appendChild(panel);
|
|
132
|
+
this.el.appendChild(fabBtn);
|
|
109
133
|
shadowRoot.appendChild(this.el);
|
|
110
134
|
// Dragging
|
|
111
135
|
this.handleMouseDown = this.handleMouseDown.bind(this);
|
|
@@ -117,6 +141,19 @@ export class Toolbar {
|
|
|
117
141
|
this.expanded = !this.expanded;
|
|
118
142
|
this.el.classList.toggle('expanded', this.expanded);
|
|
119
143
|
}
|
|
144
|
+
setBrowsing(browsing) {
|
|
145
|
+
this.browsing = browsing;
|
|
146
|
+
if (this.browseBtnEl) {
|
|
147
|
+
this.browseBtnEl.textContent = browsing ? 'Editing' : 'Browse';
|
|
148
|
+
this.browseBtnEl.classList.toggle('active', browsing);
|
|
149
|
+
this.browseBtnEl.title = browsing
|
|
150
|
+
? 'Resume editing — clicks open the edit drawer again'
|
|
151
|
+
: 'Pause editing so you can click links and navigate to another page';
|
|
152
|
+
}
|
|
153
|
+
this.el.classList.toggle('lr-fab--browsing', browsing);
|
|
154
|
+
if (this.onBrowseToggle)
|
|
155
|
+
this.onBrowseToggle(browsing);
|
|
156
|
+
}
|
|
120
157
|
updateProgress(translated, total) {
|
|
121
158
|
this.progressEl.textContent = `${translated}/${total}`;
|
|
122
159
|
}
|
|
@@ -139,9 +176,17 @@ export class Toolbar {
|
|
|
139
176
|
this.dragging = true;
|
|
140
177
|
const x = Math.max(0, Math.min(e.clientX - this.dragOffsetX, window.innerWidth - this.el.offsetWidth));
|
|
141
178
|
const y = Math.max(0, Math.min(e.clientY - this.dragOffsetY, window.innerHeight - this.el.offsetHeight));
|
|
142
|
-
|
|
179
|
+
// Anchor by `right` (not `left`) so the FAB grows the panel LEFTWARD
|
|
180
|
+
// when expanded, keeping the button visually fixed where the user
|
|
181
|
+
// dropped it. With `left`-anchoring the container's left edge stays
|
|
182
|
+
// pinned and the panel pushes the button rightward on expand — that's
|
|
183
|
+
// the "FAB jumps off-screen after drag" bug. Switching to `right`
|
|
184
|
+
// here means the button's right edge stays put across the drag /
|
|
185
|
+
// expand / language-switch cycle.
|
|
186
|
+
const rightOffset = window.innerWidth - x - this.el.offsetWidth;
|
|
187
|
+
this.el.style.right = `${Math.max(0, rightOffset)}px`;
|
|
143
188
|
this.el.style.top = `${y}px`;
|
|
144
|
-
this.el.style.
|
|
189
|
+
this.el.style.left = 'auto';
|
|
145
190
|
this.el.style.bottom = 'auto';
|
|
146
191
|
}
|
|
147
192
|
handleMouseUp() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toolbar.js","sourceRoot":"","sources":["../../../src/browser/editor/toolbar.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"toolbar.js","sourceRoot":"","sources":["../../../src/browser/editor/toolbar.ts"],"names":[],"mappings":"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"}
|
package/dist/browser/index.d.ts
CHANGED
|
@@ -17,6 +17,8 @@ export { LanguageSwitcher } from './language-switcher.js';
|
|
|
17
17
|
export type { Language, SwitcherStyle } from './language-switcher.js';
|
|
18
18
|
export { BlockExtractor } from './block-extractor.js';
|
|
19
19
|
export type { ExtractedBlock } from './block-extractor.js';
|
|
20
|
+
export { AttributeExtractor } from './attribute-extractor.js';
|
|
21
|
+
export type { ExtractedAttribute } from './attribute-extractor.js';
|
|
20
22
|
export { parseBlockElement } from './markup-parser.js';
|
|
21
23
|
export { ExcludeFilter } from './exclude-filter.js';
|
|
22
24
|
export type { ExcludePatterns } from './exclude-filter.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAG/E,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAEjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEtE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAG9D,OAAO,EAAE,GAAG,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAGhD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAC9E,YAAY,EAAE,4BAA4B,EAAE,MAAM,sCAAsC,CAAC;AAEzF,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,YAAY,EAAE,4BAA4B,EAAE,MAAM,uCAAuC,CAAC;AAG1F,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACvD,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAG/E,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAEjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEtE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,YAAY,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAG9D,OAAO,EAAE,GAAG,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAGhD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAC9E,YAAY,EAAE,4BAA4B,EAAE,MAAM,sCAAsC,CAAC;AAEzF,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,YAAY,EAAE,4BAA4B,EAAE,MAAM,uCAAuC,CAAC;AAG1F,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACvD,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/browser/index.js
CHANGED
|
@@ -16,6 +16,7 @@ export { MemoryRepository, NetworkRepository } from '../repositories/index.js';
|
|
|
16
16
|
export { AutoTranslator } from './auto-translator.js';
|
|
17
17
|
export { LanguageSwitcher } from './language-switcher.js';
|
|
18
18
|
export { BlockExtractor } from './block-extractor.js';
|
|
19
|
+
export { AttributeExtractor } from './attribute-extractor.js';
|
|
19
20
|
export { parseBlockElement } from './markup-parser.js';
|
|
20
21
|
export { ExcludeFilter } from './exclude-filter.js';
|
|
21
22
|
export { DOMObserver } from './dom-observer.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,kCAAkC;AAClC,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE/E,2BAA2B;AAC3B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAG1D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIhD,OAAO,EAAE,GAAG,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAEhD,kBAAkB;AAClB,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAG9E,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAG/E,kCAAkC;AAClC,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,kCAAkC;AAClC,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE/E,2BAA2B;AAC3B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAG1D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAG9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIhD,OAAO,EAAE,GAAG,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAEhD,kBAAkB;AAClB,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAG9E,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAG/E,kCAAkC;AAClC,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -23,6 +23,7 @@ var LionRapid = (() => {
|
|
|
23
23
|
// src/browser/index.ts
|
|
24
24
|
var index_exports = {};
|
|
25
25
|
__export(index_exports, {
|
|
26
|
+
AttributeExtractor: () => AttributeExtractor,
|
|
26
27
|
AutoTranslator: () => AutoTranslator,
|
|
27
28
|
BlockExtractor: () => BlockExtractor,
|
|
28
29
|
CacheStorageRepository: () => CacheStorageRepository,
|
|
@@ -2179,10 +2180,44 @@ var LionRapid = (() => {
|
|
|
2179
2180
|
}
|
|
2180
2181
|
|
|
2181
2182
|
// src/content/parser/MarkupParser.ts
|
|
2183
|
+
function decodeEntities(text) {
|
|
2184
|
+
const named = {
|
|
2185
|
+
amp: "&",
|
|
2186
|
+
lt: "<",
|
|
2187
|
+
gt: ">",
|
|
2188
|
+
quot: '"',
|
|
2189
|
+
apos: "'",
|
|
2190
|
+
nbsp: " ",
|
|
2191
|
+
rsquo: "\u2019",
|
|
2192
|
+
lsquo: "\u2018",
|
|
2193
|
+
rdquo: "\u201D",
|
|
2194
|
+
ldquo: "\u201C",
|
|
2195
|
+
hellip: "\u2026",
|
|
2196
|
+
mdash: "\u2014",
|
|
2197
|
+
ndash: "\u2013",
|
|
2198
|
+
copy: "\xA9",
|
|
2199
|
+
reg: "\xAE",
|
|
2200
|
+
trade: "\u2122"
|
|
2201
|
+
};
|
|
2202
|
+
return text.replace(/&(#x[0-9a-f]+|#[0-9]+|[a-z][a-z0-9]*);/gi, (m, body) => {
|
|
2203
|
+
if (body[0] === "#") {
|
|
2204
|
+
const cp = body[1] === "x" || body[1] === "X" ? parseInt(body.slice(2), 16) : parseInt(body.slice(1), 10);
|
|
2205
|
+
if (Number.isFinite(cp) && cp > 0) {
|
|
2206
|
+
try {
|
|
2207
|
+
return String.fromCodePoint(cp);
|
|
2208
|
+
} catch {
|
|
2209
|
+
return m;
|
|
2210
|
+
}
|
|
2211
|
+
}
|
|
2212
|
+
return m;
|
|
2213
|
+
}
|
|
2214
|
+
return named[body.toLowerCase()] ?? m;
|
|
2215
|
+
});
|
|
2216
|
+
}
|
|
2182
2217
|
var MarkupParser = class {
|
|
2183
2218
|
parse(input) {
|
|
2184
2219
|
if (/<\/?[0-9]+>/.test(input)) {
|
|
2185
|
-
return { text: input, styles: {} };
|
|
2220
|
+
return { text: decodeEntities(input), styles: {} };
|
|
2186
2221
|
}
|
|
2187
2222
|
const styles = {};
|
|
2188
2223
|
let tagIndex = 0;
|
|
@@ -2227,7 +2262,7 @@ var LionRapid = (() => {
|
|
|
2227
2262
|
const unclosed = tagStack.pop();
|
|
2228
2263
|
result += `</${unclosed.index}>`;
|
|
2229
2264
|
}
|
|
2230
|
-
return { text: result, styles };
|
|
2265
|
+
return { text: decodeEntities(result), styles };
|
|
2231
2266
|
}
|
|
2232
2267
|
matchTag(input, startPos) {
|
|
2233
2268
|
const tagStart = input.indexOf("<", startPos);
|
|
@@ -4204,15 +4239,46 @@ var LionRapid = (() => {
|
|
|
4204
4239
|
}
|
|
4205
4240
|
return str;
|
|
4206
4241
|
}
|
|
4207
|
-
function
|
|
4242
|
+
function utf8Bytes(str) {
|
|
4243
|
+
if (typeof TextEncoder !== "undefined") {
|
|
4244
|
+
return new TextEncoder().encode(str);
|
|
4245
|
+
}
|
|
4246
|
+
const out = [];
|
|
4247
|
+
for (let i = 0; i < str.length; i++) {
|
|
4248
|
+
const c = str.charCodeAt(i);
|
|
4249
|
+
if (c < 128) {
|
|
4250
|
+
out.push(c);
|
|
4251
|
+
} else if (c < 2048) {
|
|
4252
|
+
out.push(192 | c >> 6, 128 | c & 63);
|
|
4253
|
+
} else if (c >= 55296 && c < 56320 && i + 1 < str.length) {
|
|
4254
|
+
const c2 = str.charCodeAt(++i);
|
|
4255
|
+
const cp = 65536 + (c - 55296 << 10) + (c2 - 56320);
|
|
4256
|
+
out.push(
|
|
4257
|
+
240 | cp >> 18,
|
|
4258
|
+
128 | cp >> 12 & 63,
|
|
4259
|
+
128 | cp >> 6 & 63,
|
|
4260
|
+
128 | cp & 63
|
|
4261
|
+
);
|
|
4262
|
+
} else {
|
|
4263
|
+
out.push(
|
|
4264
|
+
224 | c >> 12,
|
|
4265
|
+
128 | c >> 6 & 63,
|
|
4266
|
+
128 | c & 63
|
|
4267
|
+
);
|
|
4268
|
+
}
|
|
4269
|
+
}
|
|
4270
|
+
return new Uint8Array(out);
|
|
4271
|
+
}
|
|
4272
|
+
function bytes2binl(bytes) {
|
|
4208
4273
|
const bin = [];
|
|
4209
|
-
for (let i = 0; i <
|
|
4210
|
-
bin[i >>
|
|
4274
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
4275
|
+
bin[i >> 2] |= bytes[i] << i % 4 * 8;
|
|
4211
4276
|
}
|
|
4212
4277
|
return bin;
|
|
4213
4278
|
}
|
|
4214
4279
|
function md5(str) {
|
|
4215
|
-
|
|
4280
|
+
const bytes = utf8Bytes(str);
|
|
4281
|
+
return binl2hex(binlMD5(bytes2binl(bytes), bytes.length * 8));
|
|
4216
4282
|
}
|
|
4217
4283
|
function generateAutoKey(text) {
|
|
4218
4284
|
const trimmed = text.trim();
|
|
@@ -4221,6 +4287,7 @@ var LionRapid = (() => {
|
|
|
4221
4287
|
|
|
4222
4288
|
// src/browser/block-extractor.ts
|
|
4223
4289
|
var BLOCK_SELECTOR = "p,h1,h2,h3,h4,h5,h6,li,td,th,label,button,figcaption,dt,dd,summary,caption";
|
|
4290
|
+
var INLINE_BLOCK_SELECTOR = "a";
|
|
4224
4291
|
var SKIP_TAGS = /* @__PURE__ */ new Set([
|
|
4225
4292
|
"SCRIPT",
|
|
4226
4293
|
"STYLE",
|
|
@@ -4309,8 +4376,60 @@ var LionRapid = (() => {
|
|
|
4309
4376
|
}
|
|
4310
4377
|
results.push({ element: el, unit, key });
|
|
4311
4378
|
}
|
|
4379
|
+
this.extractOrphanInline(root, results, includeTranslated);
|
|
4312
4380
|
return results;
|
|
4313
4381
|
}
|
|
4382
|
+
/**
|
|
4383
|
+
* Second pass: extract inline elements (currently <a>) that have no block
|
|
4384
|
+
* ancestor. These would otherwise slip through both the block pass (not in
|
|
4385
|
+
* BLOCK_SELECTOR) and the inline-style capture (no parent block to host
|
|
4386
|
+
* them as `<1>...</1>`). Common shape: a `<div>` action group containing
|
|
4387
|
+
* only links.
|
|
4388
|
+
*/
|
|
4389
|
+
extractOrphanInline(root, results, includeTranslated) {
|
|
4390
|
+
const candidates = root.querySelectorAll(INLINE_BLOCK_SELECTOR);
|
|
4391
|
+
const elements = [];
|
|
4392
|
+
if (root instanceof Element && root.matches(INLINE_BLOCK_SELECTOR)) {
|
|
4393
|
+
elements.push(root);
|
|
4394
|
+
}
|
|
4395
|
+
for (let i = 0; i < candidates.length; i++) {
|
|
4396
|
+
elements.push(candidates[i]);
|
|
4397
|
+
}
|
|
4398
|
+
for (let i = 0; i < elements.length; i++) {
|
|
4399
|
+
const el = elements[i];
|
|
4400
|
+
if (this.isInsideSkipTag(el)) continue;
|
|
4401
|
+
if (!includeTranslated && this.hasSkipAttribute(el)) continue;
|
|
4402
|
+
if (this.matchesExcludeSelector(el)) continue;
|
|
4403
|
+
if (el.getAttribute("translate") === "no") continue;
|
|
4404
|
+
if (el.parentElement?.closest(BLOCK_SELECTOR)) continue;
|
|
4405
|
+
if (el.parentElement?.closest(INLINE_BLOCK_SELECTOR)) continue;
|
|
4406
|
+
if (el.querySelector(BLOCK_SELECTOR)) continue;
|
|
4407
|
+
const lrOriginal = el.getAttribute("data-lr-original");
|
|
4408
|
+
let unit;
|
|
4409
|
+
if (lrOriginal) {
|
|
4410
|
+
const temp = document.createElement(el.tagName);
|
|
4411
|
+
temp.innerHTML = lrOriginal;
|
|
4412
|
+
unit = parseBlockElement(temp);
|
|
4413
|
+
} else {
|
|
4414
|
+
unit = parseBlockElement(el);
|
|
4415
|
+
}
|
|
4416
|
+
const strippedText = unit.text.replace(/<\/?[0-9]+\/?>/g, "");
|
|
4417
|
+
if (this.excludeFilter.shouldExclude(strippedText)) continue;
|
|
4418
|
+
const lrBlock = el.getAttribute("data-lr-block");
|
|
4419
|
+
let key;
|
|
4420
|
+
if (lrBlock) {
|
|
4421
|
+
key = lrBlock;
|
|
4422
|
+
} else {
|
|
4423
|
+
const dataI18n = el.getAttribute("data-i18n");
|
|
4424
|
+
if (dataI18n) {
|
|
4425
|
+
key = dataI18n.includes(":") ? dataI18n : `common:${dataI18n}`;
|
|
4426
|
+
} else {
|
|
4427
|
+
key = generateAutoKey(unit.text);
|
|
4428
|
+
}
|
|
4429
|
+
}
|
|
4430
|
+
results.push({ element: el, unit, key });
|
|
4431
|
+
}
|
|
4432
|
+
}
|
|
4314
4433
|
isInsideSkipTag(element) {
|
|
4315
4434
|
let current = element.parentElement;
|
|
4316
4435
|
while (current) {
|
|
@@ -4346,6 +4465,116 @@ var LionRapid = (() => {
|
|
|
4346
4465
|
}
|
|
4347
4466
|
};
|
|
4348
4467
|
|
|
4468
|
+
// src/browser/attribute-extractor.ts
|
|
4469
|
+
var TARGETS = [
|
|
4470
|
+
{ selector: 'img[alt], area[alt], input[type="image"][alt]', attr: "alt", type: "alt" },
|
|
4471
|
+
{ selector: "[title]", attr: "title", type: "title" },
|
|
4472
|
+
{ selector: "input[placeholder], textarea[placeholder]", attr: "placeholder", type: "placeholder" },
|
|
4473
|
+
{ selector: 'meta[name="description"][content]', attr: "content", type: "meta-description" },
|
|
4474
|
+
{
|
|
4475
|
+
selector: 'input[type="submit"][value], input[type="button"][value], input[type="reset"][value]',
|
|
4476
|
+
attr: "value",
|
|
4477
|
+
type: "input-value"
|
|
4478
|
+
}
|
|
4479
|
+
];
|
|
4480
|
+
var SKIP_TAGS2 = /* @__PURE__ */ new Set([
|
|
4481
|
+
"SCRIPT",
|
|
4482
|
+
"STYLE",
|
|
4483
|
+
"CODE",
|
|
4484
|
+
"PRE",
|
|
4485
|
+
"NOSCRIPT",
|
|
4486
|
+
"SVG"
|
|
4487
|
+
]);
|
|
4488
|
+
var SKIP_ATTRIBUTES2 = [
|
|
4489
|
+
"data-lionrapid-translated",
|
|
4490
|
+
"data-lionrapid-client",
|
|
4491
|
+
"data-no-translate"
|
|
4492
|
+
];
|
|
4493
|
+
function stampAttrName(attrName) {
|
|
4494
|
+
return `data-lr-attr-${attrName.toLowerCase()}`;
|
|
4495
|
+
}
|
|
4496
|
+
var AttributeExtractor = class {
|
|
4497
|
+
constructor(excludePatterns = {}, excludeSelectors = [], minTextLength = 2) {
|
|
4498
|
+
__publicField(this, "excludeFilter");
|
|
4499
|
+
__publicField(this, "excludeSelectors");
|
|
4500
|
+
this.excludeFilter = new ExcludeFilter(excludePatterns, minTextLength);
|
|
4501
|
+
this.excludeSelectors = excludeSelectors;
|
|
4502
|
+
}
|
|
4503
|
+
/**
|
|
4504
|
+
* Walk the DOM under `root` and return every translatable attribute.
|
|
4505
|
+
*
|
|
4506
|
+
* @param root Element or Document to scan
|
|
4507
|
+
* @param includeStamped When true, elements already carrying
|
|
4508
|
+
* `data-lr-attr-{name}` are returned anyway —
|
|
4509
|
+
* the editor uses this to surface server-handled
|
|
4510
|
+
* attributes for inspection. The runtime keeps
|
|
4511
|
+
* the default `false` so it doesn't re-extract
|
|
4512
|
+
* what the server already keyed.
|
|
4513
|
+
*/
|
|
4514
|
+
extract(root, includeStamped = false) {
|
|
4515
|
+
const results = [];
|
|
4516
|
+
for (const target of TARGETS) {
|
|
4517
|
+
const candidates = root.querySelectorAll(target.selector);
|
|
4518
|
+
const all = [];
|
|
4519
|
+
if (root instanceof Element && root.matches(target.selector)) {
|
|
4520
|
+
all.push(root);
|
|
4521
|
+
}
|
|
4522
|
+
for (let i = 0; i < candidates.length; i++) {
|
|
4523
|
+
all.push(candidates[i]);
|
|
4524
|
+
}
|
|
4525
|
+
for (let i = 0; i < all.length; i++) {
|
|
4526
|
+
const el = all[i];
|
|
4527
|
+
if (this.isInsideSkipTag(el)) continue;
|
|
4528
|
+
if (this.hasSkipAncestor(el)) continue;
|
|
4529
|
+
if (this.matchesExcludeSelector(el)) continue;
|
|
4530
|
+
if (el.getAttribute("translate") === "no") continue;
|
|
4531
|
+
const rawValue = el.getAttribute(target.attr);
|
|
4532
|
+
if (rawValue === null) continue;
|
|
4533
|
+
const trimmed = rawValue.trim();
|
|
4534
|
+
if (this.excludeFilter.shouldExclude(trimmed)) continue;
|
|
4535
|
+
const stampName = stampAttrName(target.attr);
|
|
4536
|
+
const stamped = el.getAttribute(stampName);
|
|
4537
|
+
if (!includeStamped && stamped) {
|
|
4538
|
+
continue;
|
|
4539
|
+
}
|
|
4540
|
+
const unit = { text: rawValue, type: target.type };
|
|
4541
|
+
const key = stamped ?? generateAutoKey(rawValue);
|
|
4542
|
+
results.push({ element: el, attrName: target.attr, unit, key });
|
|
4543
|
+
}
|
|
4544
|
+
}
|
|
4545
|
+
return results;
|
|
4546
|
+
}
|
|
4547
|
+
isInsideSkipTag(element) {
|
|
4548
|
+
let current = element.parentElement;
|
|
4549
|
+
while (current) {
|
|
4550
|
+
if (SKIP_TAGS2.has(current.tagName)) return true;
|
|
4551
|
+
current = current.parentElement;
|
|
4552
|
+
}
|
|
4553
|
+
return false;
|
|
4554
|
+
}
|
|
4555
|
+
hasSkipAncestor(element) {
|
|
4556
|
+
let current = element;
|
|
4557
|
+
while (current) {
|
|
4558
|
+
for (const attr of SKIP_ATTRIBUTES2) {
|
|
4559
|
+
if (current.hasAttribute(attr)) return true;
|
|
4560
|
+
}
|
|
4561
|
+
current = current.parentElement;
|
|
4562
|
+
}
|
|
4563
|
+
return false;
|
|
4564
|
+
}
|
|
4565
|
+
matchesExcludeSelector(element) {
|
|
4566
|
+
for (const selector of this.excludeSelectors) {
|
|
4567
|
+
try {
|
|
4568
|
+
if (element.matches(selector) || element.closest(selector)) {
|
|
4569
|
+
return true;
|
|
4570
|
+
}
|
|
4571
|
+
} catch {
|
|
4572
|
+
}
|
|
4573
|
+
}
|
|
4574
|
+
return false;
|
|
4575
|
+
}
|
|
4576
|
+
};
|
|
4577
|
+
|
|
4349
4578
|
// src/browser/dom-observer.ts
|
|
4350
4579
|
var DOMObserver = class {
|
|
4351
4580
|
constructor(callbacks, debounceMs = 50) {
|
|
@@ -4450,6 +4679,7 @@ var LionRapid = (() => {
|
|
|
4450
4679
|
constructor(config = {}) {
|
|
4451
4680
|
__publicField(this, "core", null);
|
|
4452
4681
|
__publicField(this, "blockExtractor");
|
|
4682
|
+
__publicField(this, "attributeExtractor");
|
|
4453
4683
|
__publicField(this, "domObserver", null);
|
|
4454
4684
|
__publicField(this, "locale", "");
|
|
4455
4685
|
__publicField(this, "sourceLocale", "");
|
|
@@ -4463,6 +4693,11 @@ var LionRapid = (() => {
|
|
|
4463
4693
|
config.excludeSelectors,
|
|
4464
4694
|
config.minTextLength
|
|
4465
4695
|
);
|
|
4696
|
+
this.attributeExtractor = new AttributeExtractor(
|
|
4697
|
+
config.excludePatterns,
|
|
4698
|
+
config.excludeSelectors,
|
|
4699
|
+
config.minTextLength
|
|
4700
|
+
);
|
|
4466
4701
|
this.debounceMs = config.debounceMs ?? 100;
|
|
4467
4702
|
}
|
|
4468
4703
|
/**
|
|
@@ -4511,8 +4746,9 @@ var LionRapid = (() => {
|
|
|
4511
4746
|
if (!this.core) {
|
|
4512
4747
|
return 0;
|
|
4513
4748
|
}
|
|
4514
|
-
const
|
|
4515
|
-
|
|
4749
|
+
const blockCount = this.translateBlocks(this.blockExtractor.extract(element));
|
|
4750
|
+
const attrCount = this.translateAttributesIn(this.attributeExtractor.extract(element));
|
|
4751
|
+
return blockCount + attrCount;
|
|
4516
4752
|
}
|
|
4517
4753
|
/**
|
|
4518
4754
|
* Translate the entire page
|
|
@@ -4610,12 +4846,79 @@ var LionRapid = (() => {
|
|
|
4610
4846
|
}
|
|
4611
4847
|
return count;
|
|
4612
4848
|
}
|
|
4849
|
+
/**
|
|
4850
|
+
* Translate extracted attribute units against the cache.
|
|
4851
|
+
*
|
|
4852
|
+
* Mirrors translateBlocks but for attribute values. For each hit, the
|
|
4853
|
+
* original attribute value is preserved in `data-lr-orig-{name}` so
|
|
4854
|
+
* retranslate() can restore source. The element accumulates a comma-
|
|
4855
|
+
* separated `data-lionrapid-client-attrs` list naming every attr the
|
|
4856
|
+
* client touched — so we can find them all on retranslate without
|
|
4857
|
+
* iterating a fixed selector set.
|
|
4858
|
+
*
|
|
4859
|
+
* Cache misses emit `translation:not-found` with empty styles, so the
|
|
4860
|
+
* existing MissingTranslationQueue + NetworkRepository sync queue
|
|
4861
|
+
* picks them up unchanged.
|
|
4862
|
+
*/
|
|
4863
|
+
translateAttributesIn(extracted) {
|
|
4864
|
+
if (!this.core) return 0;
|
|
4865
|
+
let count = 0;
|
|
4866
|
+
for (const { element, attrName, unit, key } of extracted) {
|
|
4867
|
+
const fullKey = `${this.locale}:${this.namespace}:${key}`;
|
|
4868
|
+
const cached = this.core.cache.get(fullKey);
|
|
4869
|
+
if (cached && cached.value !== unit.text && cached.value !== key) {
|
|
4870
|
+
const lower = attrName.toLowerCase();
|
|
4871
|
+
const origAttr = `data-lr-orig-${lower}`;
|
|
4872
|
+
if (!element.hasAttribute(origAttr)) {
|
|
4873
|
+
element.setAttribute(origAttr, unit.text);
|
|
4874
|
+
}
|
|
4875
|
+
element.setAttribute(attrName, cached.value);
|
|
4876
|
+
element.setAttribute(`data-lr-attr-${lower}`, key);
|
|
4877
|
+
const existing = element.getAttribute("data-lionrapid-client-attrs") ?? "";
|
|
4878
|
+
const set = new Set(existing.split(",").filter(Boolean));
|
|
4879
|
+
set.add(lower);
|
|
4880
|
+
element.setAttribute("data-lionrapid-client-attrs", Array.from(set).join(","));
|
|
4881
|
+
count++;
|
|
4882
|
+
} else {
|
|
4883
|
+
this.core.bus.emit("translation:not-found", {
|
|
4884
|
+
payload: {
|
|
4885
|
+
key,
|
|
4886
|
+
fallbackValue: unit.text,
|
|
4887
|
+
locale: this.sourceLocale,
|
|
4888
|
+
namespace: this.namespace,
|
|
4889
|
+
status: 404,
|
|
4890
|
+
styles: {}
|
|
4891
|
+
}
|
|
4892
|
+
});
|
|
4893
|
+
}
|
|
4894
|
+
}
|
|
4895
|
+
return count;
|
|
4896
|
+
}
|
|
4613
4897
|
/**
|
|
4614
4898
|
* Get translated count
|
|
4615
4899
|
*/
|
|
4616
4900
|
getTranslatedCount() {
|
|
4617
4901
|
return this.translatedCount;
|
|
4618
4902
|
}
|
|
4903
|
+
/**
|
|
4904
|
+
* Restore every client-translated attribute on `el` from its
|
|
4905
|
+
* `data-lr-orig-*` backup, then strip the stamps. Mirrors the block-side
|
|
4906
|
+
* restoration in retranslate() so language switch / editor reset clears
|
|
4907
|
+
* attributes too.
|
|
4908
|
+
*/
|
|
4909
|
+
restoreClientAttributes(el) {
|
|
4910
|
+
const list = el.getAttribute("data-lionrapid-client-attrs");
|
|
4911
|
+
if (list === null) return;
|
|
4912
|
+
for (const name of list.split(",").filter(Boolean)) {
|
|
4913
|
+
const orig = el.getAttribute(`data-lr-orig-${name}`);
|
|
4914
|
+
if (orig !== null) {
|
|
4915
|
+
el.setAttribute(name, orig);
|
|
4916
|
+
el.removeAttribute(`data-lr-orig-${name}`);
|
|
4917
|
+
}
|
|
4918
|
+
el.removeAttribute(`data-lr-attr-${name}`);
|
|
4919
|
+
}
|
|
4920
|
+
el.removeAttribute("data-lionrapid-client-attrs");
|
|
4921
|
+
}
|
|
4619
4922
|
/**
|
|
4620
4923
|
* Re-translate a single element (for editor live preview reset)
|
|
4621
4924
|
*/
|
|
@@ -4624,14 +4927,15 @@ var LionRapid = (() => {
|
|
|
4624
4927
|
if (original !== null) element.innerHTML = original;
|
|
4625
4928
|
element.removeAttribute("data-lionrapid-client");
|
|
4626
4929
|
element.removeAttribute("data-lr-block");
|
|
4930
|
+
this.restoreClientAttributes(element);
|
|
4627
4931
|
this.translateElement(element);
|
|
4628
4932
|
}
|
|
4629
4933
|
/**
|
|
4630
4934
|
* Re-translate the page (after language change)
|
|
4631
4935
|
*/
|
|
4632
4936
|
retranslate() {
|
|
4633
|
-
const
|
|
4634
|
-
|
|
4937
|
+
const translatedBlocks = document.querySelectorAll("[data-lionrapid-client]");
|
|
4938
|
+
translatedBlocks.forEach((el) => {
|
|
4635
4939
|
const original = el.getAttribute("data-lr-original");
|
|
4636
4940
|
if (original !== null) {
|
|
4637
4941
|
el.innerHTML = original;
|
|
@@ -4639,6 +4943,8 @@ var LionRapid = (() => {
|
|
|
4639
4943
|
el.removeAttribute("data-lionrapid-client");
|
|
4640
4944
|
el.removeAttribute("data-lr-block");
|
|
4641
4945
|
});
|
|
4946
|
+
const translatedAttrs = document.querySelectorAll("[data-lionrapid-client-attrs]");
|
|
4947
|
+
translatedAttrs.forEach((el) => this.restoreClientAttributes(el));
|
|
4642
4948
|
this.translatedCount = 0;
|
|
4643
4949
|
if (this.locale !== this.sourceLocale) {
|
|
4644
4950
|
this.translatePage();
|
|
@@ -5368,6 +5674,7 @@ var LionRapid = (() => {
|
|
|
5368
5674
|
const switcherShowFlags = script.dataset.switcherShowFlags !== "false";
|
|
5369
5675
|
const switcherShowNames = script.dataset.switcherShowNames === "true";
|
|
5370
5676
|
const switcherCustomCss = script.dataset.switcherCustomCss || void 0;
|
|
5677
|
+
const editorCdnUrl = script.dataset.editorCdn || void 0;
|
|
5371
5678
|
return {
|
|
5372
5679
|
apiKey,
|
|
5373
5680
|
baseUrl,
|
|
@@ -5381,7 +5688,8 @@ var LionRapid = (() => {
|
|
|
5381
5688
|
switcherPosition,
|
|
5382
5689
|
switcherShowFlags,
|
|
5383
5690
|
switcherShowNames,
|
|
5384
|
-
switcherCustomCss
|
|
5691
|
+
switcherCustomCss,
|
|
5692
|
+
editorCdnUrl
|
|
5385
5693
|
};
|
|
5386
5694
|
}
|
|
5387
5695
|
function readLocaleCookie(availableLanguages) {
|
|
@@ -5563,7 +5871,7 @@ var LionRapid = (() => {
|
|
|
5563
5871
|
};
|
|
5564
5872
|
window.LionRapid = instance;
|
|
5565
5873
|
const editorParam = new URLSearchParams(window.location.search).get("__lr_editor");
|
|
5566
|
-
if (editorParam && !document.querySelector("script[data-grant]")) {
|
|
5874
|
+
if (editorParam && !document.querySelector("script[data-grant], script[data-lr-editor]")) {
|
|
5567
5875
|
const editorScript = document.createElement("script");
|
|
5568
5876
|
editorScript.src = config.editorCdnUrl || "https://cdn.lionrapid.com/lionrapid.editor.min.js";
|
|
5569
5877
|
editorScript.dataset.grant = editorParam;
|