@lionrapid/core 0.2.1 → 0.3.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/auto-translator.d.ts.map +1 -1
- package/dist/browser/auto-translator.js +15 -4
- package/dist/browser/auto-translator.js.map +1 -1
- package/dist/browser/block-extractor.d.ts.map +1 -1
- package/dist/browser/block-extractor.js +6 -0
- package/dist/browser/block-extractor.js.map +1 -1
- package/dist/browser/editor/editor-api.d.ts +31 -1
- package/dist/browser/editor/editor-api.d.ts.map +1 -1
- package/dist/browser/editor/editor-api.js +43 -1
- package/dist/browser/editor/editor-api.js.map +1 -1
- package/dist/browser/editor/editor-init.js +25 -0
- 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 +55 -0
- package/dist/browser/editor/editor-styles.js.map +1 -1
- package/dist/browser/editor/live-preview.d.ts.map +1 -1
- package/dist/browser/editor/live-preview.js +20 -3
- package/dist/browser/editor/live-preview.js.map +1 -1
- package/dist/browser/editor/sidebar.d.ts +20 -1
- package/dist/browser/editor/sidebar.d.ts.map +1 -1
- package/dist/browser/editor/sidebar.js +147 -9
- package/dist/browser/editor/sidebar.js.map +1 -1
- package/dist/browser/lionrapid.auto.dev.js +125 -311
- package/dist/browser/lionrapid.auto.dev.js.map +3 -3
- package/dist/browser/lionrapid.auto.js +125 -311
- package/dist/browser/lionrapid.auto.js.map +3 -3
- 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 +274 -181
- package/dist/browser/lionrapid.editor.js.map +3 -3
- package/dist/browser/lionrapid.editor.min.js +58 -3
- package/dist/browser/lionrapid.editor.min.js.map +4 -4
- package/dist/browser/lionrapid.esm.js +108 -294
- package/dist/browser/lionrapid.esm.js.map +3 -3
- package/dist/browser/lionrapid.esm.min.js +2 -2
- package/dist/browser/lionrapid.esm.min.js.map +4 -4
- package/dist/browser/lionrapid.iife.dev.js +108 -294
- package/dist/browser/lionrapid.iife.dev.js.map +3 -3
- package/dist/browser/lionrapid.iife.js +108 -294
- package/dist/browser/lionrapid.iife.js.map +3 -3
- package/dist/browser/lionrapid.iife.min.js +2 -2
- package/dist/browser/lionrapid.iife.min.js.map +4 -4
- package/dist/browser/lionrapid.umd.js +108 -294
- package/dist/browser/lionrapid.umd.js.map +3 -3
- package/dist/browser/lionrapid.umd.min.js +2 -2
- package/dist/browser/lionrapid.umd.min.js.map +4 -4
- package/dist/browser/markup-parser.d.ts +9 -5
- package/dist/browser/markup-parser.d.ts.map +1 -1
- package/dist/browser/markup-parser.js +19 -23
- package/dist/browser/markup-parser.js.map +1 -1
- package/dist/content/canonical-tag.d.ts +34 -0
- package/dist/content/canonical-tag.d.ts.map +1 -0
- package/dist/content/canonical-tag.js +57 -0
- package/dist/content/canonical-tag.js.map +1 -0
- package/dist/content/index.d.ts +1 -4
- package/dist/content/index.d.ts.map +1 -1
- package/dist/content/index.js +3 -1
- package/dist/content/index.js.map +1 -1
- package/dist/content/parser/MarkupParser.d.ts +9 -49
- package/dist/content/parser/MarkupParser.d.ts.map +1 -1
- package/dist/content/parser/MarkupParser.js +37 -157
- package/dist/content/parser/MarkupParser.js.map +1 -1
- package/dist/content/serializer/HTMLSerializer.d.ts +10 -43
- package/dist/content/serializer/HTMLSerializer.d.ts.map +1 -1
- package/dist/content/serializer/HTMLSerializer.js +29 -69
- package/dist/content/serializer/HTMLSerializer.js.map +1 -1
- package/dist/content/types.d.ts +21 -12
- package/dist/content/types.d.ts.map +1 -1
- package/dist/content/validator/ContentValidator.d.ts +2 -2
- package/dist/content/validator/ContentValidator.js +2 -2
- package/dist/index.d.ts +2 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/lionRapid.d.ts +1 -1
- package/dist/lionRapid.js +4 -4
- package/dist/lionRapid.js.map +1 -1
- package/dist/repositories/network-repository.d.ts +14 -0
- package/dist/repositories/network-repository.d.ts.map +1 -1
- package/dist/repositories/network-repository.js +26 -4
- package/dist/repositories/network-repository.js.map +1 -1
- package/package.json +1 -1
- package/dist/content/safe-href.d.ts +0 -22
- package/dist/content/safe-href.d.ts.map +0 -1
- package/dist/content/safe-href.js +0 -48
- package/dist/content/safe-href.js.map +0 -1
- package/dist/content/style-mapper/DefaultStyleMapper.d.ts +0 -59
- package/dist/content/style-mapper/DefaultStyleMapper.d.ts.map +0 -1
- package/dist/content/style-mapper/DefaultStyleMapper.js +0 -132
- package/dist/content/style-mapper/DefaultStyleMapper.js.map +0 -1
- package/dist/content/style-mapper/IStyleMapper.d.ts +0 -50
- package/dist/content/style-mapper/IStyleMapper.d.ts.map +0 -1
- package/dist/content/style-mapper/IStyleMapper.js +0 -6
- package/dist/content/style-mapper/IStyleMapper.js.map +0 -1
|
@@ -27,7 +27,6 @@ var LionRapid = (() => {
|
|
|
27
27
|
CacheStorageRepository: () => CacheStorageRepository,
|
|
28
28
|
Colors: () => Colors,
|
|
29
29
|
ContentValidator: () => ContentValidator,
|
|
30
|
-
DefaultStyleMapper: () => DefaultStyleMapper,
|
|
31
30
|
EventEmitter: () => EventEmitter,
|
|
32
31
|
HTMLSerializer: () => HTMLSerializer,
|
|
33
32
|
HandlerChain: () => HandlerChain,
|
|
@@ -46,7 +45,9 @@ var LionRapid = (() => {
|
|
|
46
45
|
TranslationLockedError: () => TranslationLockedError,
|
|
47
46
|
TranslationNotFoundError: () => TranslationNotFoundError,
|
|
48
47
|
VERSION: () => VERSION,
|
|
48
|
+
VOID_TAGS: () => VOID_TAGS,
|
|
49
49
|
createPackageLogger: () => createPackageLogger,
|
|
50
|
+
extractTagName: () => extractTagName,
|
|
50
51
|
isClientError: () => isClientError,
|
|
51
52
|
isRetryableError: () => isRetryableError,
|
|
52
53
|
isTranslationError: () => isTranslationError,
|
|
@@ -54,7 +55,9 @@ var LionRapid = (() => {
|
|
|
54
55
|
measure: () => measure,
|
|
55
56
|
parseKeyPath: () => parseKeyPath,
|
|
56
57
|
prepareTranslationRequest: () => prepareTranslationRequest,
|
|
57
|
-
|
|
58
|
+
readRawStyle: () => readRawStyle,
|
|
59
|
+
resolveNestedKey: () => resolveNestedKey,
|
|
60
|
+
serializeOpeningTag: () => serializeOpeningTag
|
|
58
61
|
});
|
|
59
62
|
|
|
60
63
|
// src/config/logger.config.ts
|
|
@@ -2213,153 +2216,51 @@ var LionRapid = (() => {
|
|
|
2213
2216
|
}
|
|
2214
2217
|
};
|
|
2215
2218
|
|
|
2216
|
-
// src/content/
|
|
2217
|
-
var
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
return
|
|
2219
|
+
// src/content/canonical-tag.ts
|
|
2220
|
+
var VOID_TAGS = /* @__PURE__ */ new Set([
|
|
2221
|
+
"area",
|
|
2222
|
+
"base",
|
|
2223
|
+
"br",
|
|
2224
|
+
"col",
|
|
2225
|
+
"embed",
|
|
2226
|
+
"hr",
|
|
2227
|
+
"img",
|
|
2228
|
+
"input",
|
|
2229
|
+
"link",
|
|
2230
|
+
"meta",
|
|
2231
|
+
"param",
|
|
2232
|
+
"source",
|
|
2233
|
+
"track",
|
|
2234
|
+
"wbr"
|
|
2235
|
+
]);
|
|
2236
|
+
function escapeAttrValue(value) {
|
|
2237
|
+
return value.replace(/"/g, """);
|
|
2235
2238
|
}
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
strike: "strikethrough",
|
|
2253
|
-
code: "code",
|
|
2254
|
-
mark: "highlight",
|
|
2255
|
-
sub: "subscript",
|
|
2256
|
-
sup: "superscript"
|
|
2257
|
-
});
|
|
2258
|
-
/**
|
|
2259
|
-
* Style → Element mapping (reverse)
|
|
2260
|
-
* Uses simple, familiar elements for developer convenience
|
|
2261
|
-
* Also accepts element names directly (strong, em, etc.)
|
|
2262
|
-
*/
|
|
2263
|
-
__publicField(this, "styleToElement", {
|
|
2264
|
-
// Semantic style names → simple elements
|
|
2265
|
-
bold: "b",
|
|
2266
|
-
italic: "i",
|
|
2267
|
-
underline: "u",
|
|
2268
|
-
strikethrough: "s",
|
|
2269
|
-
code: "code",
|
|
2270
|
-
highlight: "mark",
|
|
2271
|
-
subscript: "sub",
|
|
2272
|
-
superscript: "sup",
|
|
2273
|
-
// Element names (for servers that store styles as element names)
|
|
2274
|
-
strong: "b",
|
|
2275
|
-
b: "b",
|
|
2276
|
-
em: "i",
|
|
2277
|
-
i: "i",
|
|
2278
|
-
u: "u",
|
|
2279
|
-
s: "s",
|
|
2280
|
-
del: "s",
|
|
2281
|
-
strike: "s",
|
|
2282
|
-
mark: "mark",
|
|
2283
|
-
sub: "sub",
|
|
2284
|
-
sup: "sup"
|
|
2285
|
-
});
|
|
2286
|
-
}
|
|
2287
|
-
/**
|
|
2288
|
-
* Convert HTML element to style properties
|
|
2289
|
-
*
|
|
2290
|
-
* @param element - Tag name (e.g., "b", "a", "strong")
|
|
2291
|
-
* @param attrs - Element attributes (e.g., { href: "/url" })
|
|
2292
|
-
* @returns Array of style strings
|
|
2293
|
-
*/
|
|
2294
|
-
mapElementToStyles(element, attrs) {
|
|
2295
|
-
const styles = [];
|
|
2296
|
-
const tag = element.toLowerCase();
|
|
2297
|
-
const mappedStyle = this.elementToStyles[tag];
|
|
2298
|
-
if (mappedStyle) {
|
|
2299
|
-
styles.push(mappedStyle);
|
|
2300
|
-
}
|
|
2301
|
-
if (tag === "a" && attrs.href) {
|
|
2302
|
-
styles.push(`hyperlink:${attrs.href}`);
|
|
2303
|
-
}
|
|
2304
|
-
return styles;
|
|
2305
|
-
}
|
|
2306
|
-
/**
|
|
2307
|
-
* Convert style properties to HTML element
|
|
2308
|
-
*
|
|
2309
|
-
* Priority order:
|
|
2310
|
-
* 1. Hyperlink (becomes wrapper element with href)
|
|
2311
|
-
* 2. First recognized style property
|
|
2312
|
-
* 3. Fallback to span
|
|
2313
|
-
*
|
|
2314
|
-
* @param styles - Array of style strings
|
|
2315
|
-
* @returns Element info for serialization
|
|
2316
|
-
*/
|
|
2317
|
-
mapStylesToElement(styles) {
|
|
2318
|
-
for (const style of styles) {
|
|
2319
|
-
if (style.startsWith("hyperlink:")) {
|
|
2320
|
-
return {
|
|
2321
|
-
element: "a",
|
|
2322
|
-
attrs: { href: safeHref(style.slice("hyperlink:".length)) }
|
|
2323
|
-
};
|
|
2324
|
-
}
|
|
2325
|
-
}
|
|
2326
|
-
for (const style of styles) {
|
|
2327
|
-
const element = this.styleToElement[style];
|
|
2328
|
-
if (element) {
|
|
2329
|
-
return {
|
|
2330
|
-
element,
|
|
2331
|
-
attrs: {}
|
|
2332
|
-
};
|
|
2333
|
-
}
|
|
2334
|
-
}
|
|
2335
|
-
return { element: "span", attrs: {} };
|
|
2239
|
+
function serializeOpeningTag(tagName, attrs) {
|
|
2240
|
+
const tag = tagName.toLowerCase();
|
|
2241
|
+
let result = `<${tag}`;
|
|
2242
|
+
for (const [name, value] of Object.entries(attrs)) {
|
|
2243
|
+
result += ` ${name.toLowerCase()}="${escapeAttrValue(value)}"`;
|
|
2244
|
+
}
|
|
2245
|
+
result += ">";
|
|
2246
|
+
return result;
|
|
2247
|
+
}
|
|
2248
|
+
function extractTagName(rawOpenTag) {
|
|
2249
|
+
const end = rawOpenTag.search(/[\s>]/);
|
|
2250
|
+
return rawOpenTag.slice(1, end === -1 ? rawOpenTag.length : end).toLowerCase();
|
|
2251
|
+
}
|
|
2252
|
+
function readRawStyle(styles) {
|
|
2253
|
+
for (const s of styles) {
|
|
2254
|
+
if (s.startsWith("raw:")) return s.slice(4);
|
|
2336
2255
|
}
|
|
2337
|
-
|
|
2256
|
+
return null;
|
|
2257
|
+
}
|
|
2338
2258
|
|
|
2339
2259
|
// src/content/parser/MarkupParser.ts
|
|
2340
2260
|
var MarkupParser = class {
|
|
2341
|
-
constructor(options = {}) {
|
|
2342
|
-
__publicField(this, "styleMapper");
|
|
2343
|
-
this.styleMapper = options.styleMapper ?? new DefaultStyleMapper();
|
|
2344
|
-
}
|
|
2345
|
-
/**
|
|
2346
|
-
* Parse HTML string into ContentUnit
|
|
2347
|
-
*
|
|
2348
|
-
* Handles two input formats:
|
|
2349
|
-
* 1. HTML tags: `<b>text</b>` → converts to indexed `<1>text</1>` with styles
|
|
2350
|
-
* 2. Already indexed: `<1>text</1>` → passes through as-is (from server)
|
|
2351
|
-
*
|
|
2352
|
-
* @param input - HTML string with inline elements or already indexed
|
|
2353
|
-
* @returns ContentUnit with indexed tags and styles
|
|
2354
|
-
*/
|
|
2355
2261
|
parse(input) {
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
return {
|
|
2359
|
-
text: input,
|
|
2360
|
-
styles: {}
|
|
2361
|
-
// Empty - styles determined by children
|
|
2362
|
-
};
|
|
2262
|
+
if (/<\/?[0-9]+>/.test(input)) {
|
|
2263
|
+
return { text: input, styles: {} };
|
|
2363
2264
|
}
|
|
2364
2265
|
const styles = {};
|
|
2365
2266
|
let tagIndex = 0;
|
|
@@ -2367,88 +2268,45 @@ var LionRapid = (() => {
|
|
|
2367
2268
|
let result = "";
|
|
2368
2269
|
let pos = 0;
|
|
2369
2270
|
while (pos < input.length) {
|
|
2370
|
-
const
|
|
2371
|
-
if (!
|
|
2271
|
+
const tag = this.matchTag(input, pos);
|
|
2272
|
+
if (!tag) {
|
|
2372
2273
|
result += input.slice(pos);
|
|
2373
2274
|
break;
|
|
2374
2275
|
}
|
|
2375
|
-
result += input.slice(pos,
|
|
2376
|
-
if (
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
const stackIndex = tagStack.findIndex(
|
|
2384
|
-
(t) => t.index === matchingOpen
|
|
2385
|
-
);
|
|
2386
|
-
if (stackIndex !== -1) {
|
|
2387
|
-
tagStack.splice(stackIndex, 1);
|
|
2276
|
+
result += input.slice(pos, tag.startIndex);
|
|
2277
|
+
if (tag.isClosing) {
|
|
2278
|
+
let matchIdx = null;
|
|
2279
|
+
for (let i = tagStack.length - 1; i >= 0; i--) {
|
|
2280
|
+
if (tagStack[i].tag === tag.tag.toLowerCase()) {
|
|
2281
|
+
matchIdx = tagStack[i].index;
|
|
2282
|
+
tagStack.splice(i, 1);
|
|
2283
|
+
break;
|
|
2388
2284
|
}
|
|
2389
|
-
} else {
|
|
2390
|
-
result += input.slice(tagMatch.startIndex, tagMatch.endIndex);
|
|
2391
2285
|
}
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
const styleList = this.styleMapper.mapElementToStyles(
|
|
2395
|
-
tagMatch.tag,
|
|
2396
|
-
tagMatch.attrs
|
|
2397
|
-
);
|
|
2398
|
-
if (styleList.length > 0) {
|
|
2399
|
-
styles[String(tagIndex)] = styleList;
|
|
2400
|
-
result += `<${tagIndex}/>`;
|
|
2286
|
+
if (matchIdx !== null) {
|
|
2287
|
+
result += `</${matchIdx}>`;
|
|
2401
2288
|
}
|
|
2402
2289
|
} else {
|
|
2403
|
-
const
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
result += `<${tagIndex}>`;
|
|
2411
|
-
tagStack.push({ tag: tagMatch.tag.toLowerCase(), index: tagIndex });
|
|
2290
|
+
const tagName = tag.tag.toLowerCase();
|
|
2291
|
+
const isVoid = VOID_TAGS.has(tagName);
|
|
2292
|
+
const isSelfClosing = tag.isSelfClosing || isVoid;
|
|
2293
|
+
tagIndex++;
|
|
2294
|
+
styles[String(tagIndex)] = [`raw:${serializeOpeningTag(tagName, tag.attrs)}`];
|
|
2295
|
+
if (isSelfClosing) {
|
|
2296
|
+
result += `<${tagIndex}/>`;
|
|
2412
2297
|
} else {
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
tagMatch.endIndex,
|
|
2416
|
-
tagMatch.tag
|
|
2417
|
-
);
|
|
2418
|
-
if (closingIndex !== -1) {
|
|
2419
|
-
const innerContent = input.slice(tagMatch.endIndex, closingIndex);
|
|
2420
|
-
const innerUnit = this.parse(innerContent);
|
|
2421
|
-
const baseIndex = tagIndex;
|
|
2422
|
-
for (const [key, value] of Object.entries(innerUnit.styles)) {
|
|
2423
|
-
const adjustedKey = String(baseIndex + parseInt(key, 10));
|
|
2424
|
-
styles[adjustedKey] = value;
|
|
2425
|
-
}
|
|
2426
|
-
result += innerUnit.text.replace(/<(\/?)\d+>/g, (match, slash) => {
|
|
2427
|
-
const num = parseInt(match.replace(/[</>]/g, ""), 10);
|
|
2428
|
-
return `<${slash}${baseIndex + num}>`;
|
|
2429
|
-
});
|
|
2430
|
-
const closingMatch = this.matchTag(input, closingIndex);
|
|
2431
|
-
pos = closingMatch ? closingMatch.endIndex : closingIndex;
|
|
2432
|
-
const maxInnerIndex = Object.keys(innerUnit.styles).length > 0 ? Math.max(...Object.keys(innerUnit.styles).map(Number)) : 0;
|
|
2433
|
-
tagIndex = baseIndex + maxInnerIndex;
|
|
2434
|
-
continue;
|
|
2435
|
-
}
|
|
2298
|
+
result += `<${tagIndex}>`;
|
|
2299
|
+
tagStack.push({ tag: tagName, index: tagIndex });
|
|
2436
2300
|
}
|
|
2437
2301
|
}
|
|
2438
|
-
pos =
|
|
2302
|
+
pos = tag.endIndex;
|
|
2439
2303
|
}
|
|
2440
2304
|
while (tagStack.length > 0) {
|
|
2441
2305
|
const unclosed = tagStack.pop();
|
|
2442
2306
|
result += `</${unclosed.index}>`;
|
|
2443
2307
|
}
|
|
2444
|
-
return {
|
|
2445
|
-
text: result,
|
|
2446
|
-
styles
|
|
2447
|
-
};
|
|
2308
|
+
return { text: result, styles };
|
|
2448
2309
|
}
|
|
2449
|
-
/**
|
|
2450
|
-
* Match an HTML tag at the given position
|
|
2451
|
-
*/
|
|
2452
2310
|
matchTag(input, startPos) {
|
|
2453
2311
|
const tagStart = input.indexOf("<", startPos);
|
|
2454
2312
|
if (tagStart === -1) return null;
|
|
@@ -2471,9 +2329,6 @@ var LionRapid = (() => {
|
|
|
2471
2329
|
endIndex: tagStart + fullMatch.length
|
|
2472
2330
|
};
|
|
2473
2331
|
}
|
|
2474
|
-
/**
|
|
2475
|
-
* Parse HTML attributes string into key-value pairs
|
|
2476
|
-
*/
|
|
2477
2332
|
parseAttributes(attrsString) {
|
|
2478
2333
|
const attrs = {};
|
|
2479
2334
|
if (!attrsString.trim()) return attrs;
|
|
@@ -2481,60 +2336,14 @@ var LionRapid = (() => {
|
|
|
2481
2336
|
let match;
|
|
2482
2337
|
while ((match = attrPattern.exec(attrsString)) !== null) {
|
|
2483
2338
|
const [, name, doubleQuoted, singleQuoted, unquoted] = match;
|
|
2484
|
-
|
|
2485
|
-
attrs[name.toLowerCase()] = value;
|
|
2339
|
+
attrs[name.toLowerCase()] = doubleQuoted ?? singleQuoted ?? unquoted ?? "";
|
|
2486
2340
|
}
|
|
2487
2341
|
return attrs;
|
|
2488
2342
|
}
|
|
2489
|
-
/**
|
|
2490
|
-
* Find matching opening tag in the stack
|
|
2491
|
-
*/
|
|
2492
|
-
findMatchingOpenTag(stack, tagName) {
|
|
2493
|
-
for (let i = stack.length - 1; i >= 0; i--) {
|
|
2494
|
-
if (stack[i].tag === tagName) {
|
|
2495
|
-
return stack[i].index;
|
|
2496
|
-
}
|
|
2497
|
-
}
|
|
2498
|
-
return null;
|
|
2499
|
-
}
|
|
2500
|
-
/**
|
|
2501
|
-
* Find the closing tag index for a given opening tag
|
|
2502
|
-
*/
|
|
2503
|
-
findClosingTagIndex(input, startPos, tagName) {
|
|
2504
|
-
const lowerTag = tagName.toLowerCase();
|
|
2505
|
-
let depth = 1;
|
|
2506
|
-
let pos = startPos;
|
|
2507
|
-
while (pos < input.length && depth > 0) {
|
|
2508
|
-
const tagMatch = this.matchTag(input, pos);
|
|
2509
|
-
if (!tagMatch) break;
|
|
2510
|
-
if (tagMatch.tag.toLowerCase() === lowerTag) {
|
|
2511
|
-
if (tagMatch.isClosing) {
|
|
2512
|
-
depth--;
|
|
2513
|
-
if (depth === 0) {
|
|
2514
|
-
return tagMatch.startIndex;
|
|
2515
|
-
}
|
|
2516
|
-
} else if (!tagMatch.isSelfClosing) {
|
|
2517
|
-
depth++;
|
|
2518
|
-
}
|
|
2519
|
-
}
|
|
2520
|
-
pos = tagMatch.endIndex;
|
|
2521
|
-
}
|
|
2522
|
-
return -1;
|
|
2523
|
-
}
|
|
2524
2343
|
};
|
|
2525
2344
|
|
|
2526
2345
|
// src/content/serializer/HTMLSerializer.ts
|
|
2527
2346
|
var HTMLSerializer = class {
|
|
2528
|
-
constructor(options = {}) {
|
|
2529
|
-
__publicField(this, "styleMapper");
|
|
2530
|
-
this.styleMapper = options.styleMapper ?? new DefaultStyleMapper();
|
|
2531
|
-
}
|
|
2532
|
-
/**
|
|
2533
|
-
* Serialize ContentUnit to HTML string
|
|
2534
|
-
*
|
|
2535
|
-
* @param unit - ContentUnit with indexed tags and styles
|
|
2536
|
-
* @returns HTML string with semantic elements
|
|
2537
|
-
*/
|
|
2538
2347
|
serialize(unit) {
|
|
2539
2348
|
const { text, styles } = unit;
|
|
2540
2349
|
const tagPattern = /<(\/?)?(\d+)(\/)?>/g;
|
|
@@ -2543,40 +2352,25 @@ var LionRapid = (() => {
|
|
|
2543
2352
|
let match;
|
|
2544
2353
|
while ((match = tagPattern.exec(text)) !== null) {
|
|
2545
2354
|
result += text.slice(lastIndex, match.index);
|
|
2546
|
-
const [fullMatch, closingSlash, indexStr
|
|
2547
|
-
const
|
|
2548
|
-
const
|
|
2549
|
-
if (
|
|
2550
|
-
const
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2355
|
+
const [fullMatch, closingSlash, indexStr] = match;
|
|
2356
|
+
const styleList = styles[indexStr] ?? [];
|
|
2357
|
+
const rawOpen = readRawStyle(styleList);
|
|
2358
|
+
if (rawOpen) {
|
|
2359
|
+
const tagName = extractTagName(rawOpen);
|
|
2360
|
+
const isVoid = VOID_TAGS.has(tagName);
|
|
2361
|
+
if (closingSlash) {
|
|
2362
|
+
if (!isVoid) result += `</${tagName}>`;
|
|
2363
|
+
} else {
|
|
2364
|
+
result += rawOpen;
|
|
2365
|
+
}
|
|
2556
2366
|
} else {
|
|
2557
|
-
|
|
2558
|
-
const attrs = this.formatAttributes(mapping.attrs);
|
|
2559
|
-
result += `<${mapping.element}${attrs}>`;
|
|
2367
|
+
result += fullMatch;
|
|
2560
2368
|
}
|
|
2561
2369
|
lastIndex = match.index + fullMatch.length;
|
|
2562
2370
|
}
|
|
2563
2371
|
result += text.slice(lastIndex);
|
|
2564
2372
|
return result;
|
|
2565
2373
|
}
|
|
2566
|
-
/**
|
|
2567
|
-
* Format attributes object into HTML attribute string
|
|
2568
|
-
*/
|
|
2569
|
-
formatAttributes(attrs) {
|
|
2570
|
-
const entries = Object.entries(attrs);
|
|
2571
|
-
if (entries.length === 0) return "";
|
|
2572
|
-
return " " + entries.map(([key, value]) => `${key}="${this.escapeAttributeValue(value)}"`).join(" ");
|
|
2573
|
-
}
|
|
2574
|
-
/**
|
|
2575
|
-
* Escape special characters in attribute values
|
|
2576
|
-
*/
|
|
2577
|
-
escapeAttributeValue(value) {
|
|
2578
|
-
return value.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
2579
|
-
}
|
|
2580
2374
|
};
|
|
2581
2375
|
|
|
2582
2376
|
// src/cache/CacheManager.ts
|
|
@@ -2810,7 +2604,7 @@ var LionRapid = (() => {
|
|
|
2810
2604
|
};
|
|
2811
2605
|
|
|
2812
2606
|
// src/lionRapid.ts
|
|
2813
|
-
var INDEXED_TAG_REGEX = /<\/?[0-9]
|
|
2607
|
+
var INDEXED_TAG_REGEX = /<\/?[0-9]+\/?>/;
|
|
2814
2608
|
var HTML_TAG_REGEX = /<[a-z][a-z0-9]*(?:\s+[^>]*)?\/?>/i;
|
|
2815
2609
|
var LionRapidCore = class {
|
|
2816
2610
|
constructor(eventEmitter, handlerChain, defaultLocale = "en", fallbackLocale = "en", defaultNamespace) {
|
|
@@ -3035,7 +2829,7 @@ var LionRapid = (() => {
|
|
|
3035
2829
|
*/
|
|
3036
2830
|
processIndexedValue(value, request) {
|
|
3037
2831
|
const processedText = this.processTranslationValue(value, request);
|
|
3038
|
-
return processedText.replace(/<\/?[0-9]
|
|
2832
|
+
return processedText.replace(/<\/?[0-9]+\/?>/g, "");
|
|
3039
2833
|
}
|
|
3040
2834
|
/**
|
|
3041
2835
|
* 📦 Get styles for a translation key from namespace cache (fallback)
|
|
@@ -3081,7 +2875,7 @@ var LionRapid = (() => {
|
|
|
3081
2875
|
try {
|
|
3082
2876
|
const unit = this.markupParser.parse(value);
|
|
3083
2877
|
const processedText = this.processTranslationValue(unit.text, request);
|
|
3084
|
-
return processedText.replace(/<\/?[0-9]
|
|
2878
|
+
return processedText.replace(/<\/?[0-9]+\/?>/g, "");
|
|
3085
2879
|
} catch (error) {
|
|
3086
2880
|
logger.warn(`ContentUnit processing failed for "${value}":`, error);
|
|
3087
2881
|
return this.processTranslationValue(value, request);
|
|
@@ -3150,7 +2944,7 @@ var LionRapid = (() => {
|
|
|
3150
2944
|
* @example
|
|
3151
2945
|
* ```typescript
|
|
3152
2946
|
* const unit = i18n.getContentUnit('terms', {}, 'Read our <b>Terms</b>.');
|
|
3153
|
-
* // → { text: "Read our <1>Terms</1>.", styles: {"1": ["
|
|
2947
|
+
* // → { text: "Read our <1>Terms</1>.", styles: {"1": ["raw:<b>"]} }
|
|
3154
2948
|
* ```
|
|
3155
2949
|
*/
|
|
3156
2950
|
getContentUnit(key, params, defaultValue) {
|
|
@@ -3759,7 +3553,7 @@ var LionRapid = (() => {
|
|
|
3759
3553
|
logger.debug("API base URL is not set");
|
|
3760
3554
|
throw new NetworkError("API base URL is not set");
|
|
3761
3555
|
}
|
|
3762
|
-
const url = this.buildUrl("getTranslation", { key });
|
|
3556
|
+
const url = this.withDraftsParam(this.buildUrl("getTranslation", { key }));
|
|
3763
3557
|
logger.debug(`API GET: ${url}`);
|
|
3764
3558
|
try {
|
|
3765
3559
|
const response = await this.makeRequest(url, "GET");
|
|
@@ -3795,7 +3589,7 @@ var LionRapid = (() => {
|
|
|
3795
3589
|
logger.debug("API base URL is not set");
|
|
3796
3590
|
throw new NetworkError("API base URL is not set");
|
|
3797
3591
|
}
|
|
3798
|
-
const url = this.buildUrl("getTranslation", { key });
|
|
3592
|
+
const url = this.withDraftsParam(this.buildUrl("getTranslation", { key }));
|
|
3799
3593
|
logger.debug(`API GET ContentUnit: ${url}`);
|
|
3800
3594
|
try {
|
|
3801
3595
|
const response = await this.makeRequest(url, "GET");
|
|
@@ -3836,7 +3630,7 @@ var LionRapid = (() => {
|
|
|
3836
3630
|
logger.debug("API base URL is not set");
|
|
3837
3631
|
throw new NetworkError("API base URL is not set");
|
|
3838
3632
|
}
|
|
3839
|
-
const url = this.buildUrl("getNamespace", { locale, namespace });
|
|
3633
|
+
const url = this.withDraftsParam(this.buildUrl("getNamespace", { locale, namespace }));
|
|
3840
3634
|
logger.debug(`API GET Namespace: ${url}`);
|
|
3841
3635
|
const namespaceKey = `${locale}:${namespace}`;
|
|
3842
3636
|
try {
|
|
@@ -3950,7 +3744,7 @@ var LionRapid = (() => {
|
|
|
3950
3744
|
logger.debug("API base URL is not set");
|
|
3951
3745
|
throw new NetworkError("API base URL is not set");
|
|
3952
3746
|
}
|
|
3953
|
-
const url = this.buildUrl("getNamespace", { locale, namespace });
|
|
3747
|
+
const url = this.withDraftsParam(this.buildUrl("getNamespace", { locale, namespace }));
|
|
3954
3748
|
logger.debug(`API GET Namespace ContentUnits: ${url}`);
|
|
3955
3749
|
const namespaceKey = `${locale}:${namespace}`;
|
|
3956
3750
|
try {
|
|
@@ -4162,6 +3956,26 @@ var LionRapid = (() => {
|
|
|
4162
3956
|
}
|
|
4163
3957
|
return `${baseUrl}${path}`;
|
|
4164
3958
|
}
|
|
3959
|
+
/**
|
|
3960
|
+
* Check whether the current page is running inside an active visual-editor
|
|
3961
|
+
* session. The editor JS sets `__lr_editor_active=1` as a session cookie
|
|
3962
|
+
* when its JWT is established; we read it here so client-side translation
|
|
3963
|
+
* fetches request draft content too, matching what the edge proxy does
|
|
3964
|
+
* server-side. Outside a browser (Node/SSR) this is always false.
|
|
3965
|
+
*/
|
|
3966
|
+
isEditorPreviewSession() {
|
|
3967
|
+
if (typeof document === "undefined") return false;
|
|
3968
|
+
return document.cookie.split("; ").some((c) => c === "__lr_editor_active=1");
|
|
3969
|
+
}
|
|
3970
|
+
/**
|
|
3971
|
+
* Append `include_drafts=true` to a built URL when an editor session is
|
|
3972
|
+
* active. Leaves the URL unchanged for normal visitors so the delivery
|
|
3973
|
+
* gate continues to apply in production.
|
|
3974
|
+
*/
|
|
3975
|
+
withDraftsParam(url) {
|
|
3976
|
+
if (!this.isEditorPreviewSession()) return url;
|
|
3977
|
+
return url + (url.includes("?") ? "&" : "?") + "include_drafts=true";
|
|
3978
|
+
}
|
|
4165
3979
|
/**
|
|
4166
3980
|
* Make HTTP request with timeout and headers
|
|
4167
3981
|
*/
|