@scrider/formatter 1.10.6 → 1.10.8
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/index.cjs +82 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +82 -20
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2597,6 +2597,10 @@ var imageFormat = {
|
|
|
2597
2597
|
if (element.tagName.toLowerCase() !== "img") return null;
|
|
2598
2598
|
const src = element.getAttribute("src");
|
|
2599
2599
|
if (!src) return null;
|
|
2600
|
+
const style = element.getAttribute("style") || "";
|
|
2601
|
+
if (/(?:^|;)\s*opacity\s*:\s*0(?:\.0+)?\s*(?:;|$)/i.test(style)) {
|
|
2602
|
+
return null;
|
|
2603
|
+
}
|
|
2600
2604
|
const attrs = {};
|
|
2601
2605
|
const alt = element.getAttribute("alt");
|
|
2602
2606
|
const width = element.getAttribute("width");
|
|
@@ -3870,15 +3874,6 @@ function renderInlineText(text, attributes) {
|
|
|
3870
3874
|
if (!text) return "";
|
|
3871
3875
|
let html = escapeHtml(text);
|
|
3872
3876
|
if (!attributes) return html;
|
|
3873
|
-
const styles = [];
|
|
3874
|
-
for (const [format, cssProperty] of Object.entries(INLINE_STYLE_FORMATS)) {
|
|
3875
|
-
if (format in attributes) {
|
|
3876
|
-
styles.push(`${cssProperty}: ${String(attributes[format])}`);
|
|
3877
|
-
}
|
|
3878
|
-
}
|
|
3879
|
-
if (styles.length > 0) {
|
|
3880
|
-
html = `<span style="${styles.join("; ")}">${html}</span>`;
|
|
3881
|
-
}
|
|
3882
3877
|
for (let i = INLINE_FORMAT_ORDER.length - 1; i >= 0; i--) {
|
|
3883
3878
|
const format = INLINE_FORMAT_ORDER[i];
|
|
3884
3879
|
if (!format) continue;
|
|
@@ -3892,6 +3887,15 @@ function renderInlineText(text, attributes) {
|
|
|
3892
3887
|
html = `<${tag}>${html}</${tag}>`;
|
|
3893
3888
|
}
|
|
3894
3889
|
}
|
|
3890
|
+
const styles = [];
|
|
3891
|
+
for (const [format, cssProperty] of Object.entries(INLINE_STYLE_FORMATS)) {
|
|
3892
|
+
if (format in attributes) {
|
|
3893
|
+
styles.push(`${cssProperty}: ${String(attributes[format])}`);
|
|
3894
|
+
}
|
|
3895
|
+
}
|
|
3896
|
+
if (styles.length > 0) {
|
|
3897
|
+
html = `<span style="${styles.join("; ")}">${html}</span>`;
|
|
3898
|
+
}
|
|
3895
3899
|
return html;
|
|
3896
3900
|
}
|
|
3897
3901
|
function renderEmbed(value, attributes, renderers, blockHandlers, options) {
|
|
@@ -3937,6 +3941,44 @@ function renderEmbed(value, attributes, renderers, blockHandlers, options) {
|
|
|
3937
3941
|
|
|
3938
3942
|
// src/conversion/html/html-to-delta.ts
|
|
3939
3943
|
import { Delta as Delta8 } from "@scrider/delta";
|
|
3944
|
+
function isCssWideKeyword(value) {
|
|
3945
|
+
return /^(inherit|initial|unset|revert|revert-layer)$/i.test(value.trim());
|
|
3946
|
+
}
|
|
3947
|
+
function cleanPastedFontFamily(value) {
|
|
3948
|
+
if (value == null) return null;
|
|
3949
|
+
const trimmed = value.trim();
|
|
3950
|
+
if (!trimmed || isCssWideKeyword(trimmed)) return null;
|
|
3951
|
+
const first = trimmed.split(",").map((part) => part.trim().replace(/^["']|["']$/g, "")).find((part) => part && !isCssWideKeyword(part) && !part.startsWith("var("));
|
|
3952
|
+
if (!first) return null;
|
|
3953
|
+
const lower = first.toLowerCase();
|
|
3954
|
+
if (lower === "serif" || lower === "sans-serif" || lower === "monospace" || lower === "cursive" || lower === "fantasy" || lower === "system-ui") {
|
|
3955
|
+
return null;
|
|
3956
|
+
}
|
|
3957
|
+
return first;
|
|
3958
|
+
}
|
|
3959
|
+
function cleanPastedFontSize(value) {
|
|
3960
|
+
if (value == null) return null;
|
|
3961
|
+
const trimmed = value.trim();
|
|
3962
|
+
if (!trimmed || isCssWideKeyword(trimmed)) return null;
|
|
3963
|
+
if (/^(medium|smaller|larger|xx-small|x-small|small|large|x-large|xx-large)$/i.test(trimmed)) {
|
|
3964
|
+
return null;
|
|
3965
|
+
}
|
|
3966
|
+
const px = trimmed.match(/^([\d.]+)\s*px$/i);
|
|
3967
|
+
if (px?.[1]) {
|
|
3968
|
+
const pt = Math.round(Number(px[1]) * 72 / 96);
|
|
3969
|
+
return pt > 0 ? `${pt}pt` : null;
|
|
3970
|
+
}
|
|
3971
|
+
return trimmed;
|
|
3972
|
+
}
|
|
3973
|
+
function isSelectionBackgroundColor(value) {
|
|
3974
|
+
const m = value.trim().match(/^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/i);
|
|
3975
|
+
if (!m) return false;
|
|
3976
|
+
const r = Number(m[1]);
|
|
3977
|
+
const g = Number(m[2]);
|
|
3978
|
+
const b = Number(m[3]);
|
|
3979
|
+
if (![r, g, b].every((n) => Number.isFinite(n))) return false;
|
|
3980
|
+
return r >= 180 && g >= 180 && b >= 180 && b >= r - 5 && b >= g - 5 && b - Math.min(r, g) <= 40;
|
|
3981
|
+
}
|
|
3940
3982
|
function htmlToDelta(html, options = {}) {
|
|
3941
3983
|
const adapter = options.adapter ?? getAdapter();
|
|
3942
3984
|
const normalizeWhitespace = options.normalizeWhitespace ?? true;
|
|
@@ -3998,6 +4040,12 @@ function htmlToDelta(html, options = {}) {
|
|
|
3998
4040
|
pendingText = "";
|
|
3999
4041
|
}
|
|
4000
4042
|
}
|
|
4043
|
+
function beginBlockEmbedLine() {
|
|
4044
|
+
flushText();
|
|
4045
|
+
if (!atLineStart) {
|
|
4046
|
+
context.pushNewline();
|
|
4047
|
+
}
|
|
4048
|
+
}
|
|
4001
4049
|
function processNode(node) {
|
|
4002
4050
|
if (node.nodeType === NODE_TYPE.TEXT_NODE) {
|
|
4003
4051
|
const text = node.textContent ?? "";
|
|
@@ -4285,20 +4333,30 @@ function htmlToDelta(html, options = {}) {
|
|
|
4285
4333
|
flushText();
|
|
4286
4334
|
const prevAttrs = { ...currentAttributes };
|
|
4287
4335
|
const color = element.style?.color || element.style?.getPropertyValue?.("color");
|
|
4288
|
-
if (color) {
|
|
4336
|
+
if (color && !isCssWideKeyword(color)) {
|
|
4289
4337
|
currentAttributes.color = color;
|
|
4290
4338
|
}
|
|
4291
4339
|
const bg = element.style?.backgroundColor || element.style?.getPropertyValue?.("background-color");
|
|
4292
|
-
if (bg) {
|
|
4340
|
+
if (bg && !isCssWideKeyword(bg) && !isSelectionBackgroundColor(bg)) {
|
|
4293
4341
|
currentAttributes.background = bg;
|
|
4294
4342
|
}
|
|
4295
4343
|
const fontFamily = element.style?.fontFamily || element.style?.getPropertyValue?.("font-family");
|
|
4296
|
-
|
|
4297
|
-
|
|
4344
|
+
const cleanedFont = cleanPastedFontFamily(fontFamily);
|
|
4345
|
+
if (cleanedFont) {
|
|
4346
|
+
currentAttributes.font = cleanedFont;
|
|
4298
4347
|
}
|
|
4299
4348
|
const fontSize = element.style?.fontSize || element.style?.getPropertyValue?.("font-size");
|
|
4300
|
-
|
|
4301
|
-
|
|
4349
|
+
const cleanedSize = cleanPastedFontSize(fontSize);
|
|
4350
|
+
if (cleanedSize) {
|
|
4351
|
+
currentAttributes.size = cleanedSize;
|
|
4352
|
+
}
|
|
4353
|
+
const fontWeight = element.style?.fontWeight || element.style?.getPropertyValue?.("font-weight");
|
|
4354
|
+
if (fontWeight === "bold" || fontWeight === "bolder" || fontWeight != null && Number.parseInt(String(fontWeight), 10) >= 600) {
|
|
4355
|
+
currentAttributes.bold = true;
|
|
4356
|
+
}
|
|
4357
|
+
const fontStyle = element.style?.fontStyle || element.style?.getPropertyValue?.("font-style");
|
|
4358
|
+
if (fontStyle === "italic" || fontStyle === "oblique") {
|
|
4359
|
+
currentAttributes.italic = true;
|
|
4302
4360
|
}
|
|
4303
4361
|
processChildren(element);
|
|
4304
4362
|
flushText();
|
|
@@ -4307,6 +4365,10 @@ function htmlToDelta(html, options = {}) {
|
|
|
4307
4365
|
function processImageElement(element) {
|
|
4308
4366
|
const src = element.getAttribute("src");
|
|
4309
4367
|
if (!src) return;
|
|
4368
|
+
const style = element.getAttribute("style") || "";
|
|
4369
|
+
if (/(?:^|;)\s*opacity\s*:\s*0(?:\.0+)?\s*(?:;|$)/i.test(style)) {
|
|
4370
|
+
return;
|
|
4371
|
+
}
|
|
4310
4372
|
const attrs = {};
|
|
4311
4373
|
const alt = element.getAttribute("alt");
|
|
4312
4374
|
const width = element.getAttribute("width");
|
|
@@ -4350,7 +4412,7 @@ function htmlToDelta(html, options = {}) {
|
|
|
4350
4412
|
};
|
|
4351
4413
|
const data = footnotesHandler.fromHtml(section, blockContext);
|
|
4352
4414
|
if (data) {
|
|
4353
|
-
|
|
4415
|
+
beginBlockEmbedLine();
|
|
4354
4416
|
delta.insert({ block: data });
|
|
4355
4417
|
delta.insert("\n");
|
|
4356
4418
|
atLineStart = true;
|
|
@@ -4372,7 +4434,7 @@ function htmlToDelta(html, options = {}) {
|
|
|
4372
4434
|
};
|
|
4373
4435
|
const data = alertHandler.fromHtml(element, blockContext);
|
|
4374
4436
|
if (data) {
|
|
4375
|
-
|
|
4437
|
+
beginBlockEmbedLine();
|
|
4376
4438
|
delta.insert({ block: data });
|
|
4377
4439
|
delta.insert("\n");
|
|
4378
4440
|
atLineStart = true;
|
|
@@ -4394,7 +4456,7 @@ function htmlToDelta(html, options = {}) {
|
|
|
4394
4456
|
};
|
|
4395
4457
|
const data = columnsHandler.fromHtml(element, blockContext);
|
|
4396
4458
|
if (data) {
|
|
4397
|
-
|
|
4459
|
+
beginBlockEmbedLine();
|
|
4398
4460
|
delta.insert({ block: data });
|
|
4399
4461
|
delta.insert("\n");
|
|
4400
4462
|
atLineStart = true;
|
|
@@ -4416,7 +4478,7 @@ function htmlToDelta(html, options = {}) {
|
|
|
4416
4478
|
};
|
|
4417
4479
|
const data = boxHandler.fromHtml(element, blockContext);
|
|
4418
4480
|
if (data) {
|
|
4419
|
-
|
|
4481
|
+
beginBlockEmbedLine();
|
|
4420
4482
|
const opAttrs = {};
|
|
4421
4483
|
const dataFloat = element.getAttribute("data-float");
|
|
4422
4484
|
if (dataFloat) opAttrs.float = dataFloat;
|
|
@@ -4465,7 +4527,7 @@ function htmlToDelta(html, options = {}) {
|
|
|
4465
4527
|
let data = tableHandler.fromHtml(table, makeTableBlockParseContext());
|
|
4466
4528
|
if (!data) return false;
|
|
4467
4529
|
if (host) data = enrichTableBlockFromHost(data, host);
|
|
4468
|
-
|
|
4530
|
+
beginBlockEmbedLine();
|
|
4469
4531
|
delta.insert({ block: data });
|
|
4470
4532
|
delta.insert("\n");
|
|
4471
4533
|
atLineStart = true;
|