@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.cjs
CHANGED
|
@@ -2740,6 +2740,10 @@ var imageFormat = {
|
|
|
2740
2740
|
if (element.tagName.toLowerCase() !== "img") return null;
|
|
2741
2741
|
const src = element.getAttribute("src");
|
|
2742
2742
|
if (!src) return null;
|
|
2743
|
+
const style = element.getAttribute("style") || "";
|
|
2744
|
+
if (/(?:^|;)\s*opacity\s*:\s*0(?:\.0+)?\s*(?:;|$)/i.test(style)) {
|
|
2745
|
+
return null;
|
|
2746
|
+
}
|
|
2743
2747
|
const attrs = {};
|
|
2744
2748
|
const alt = element.getAttribute("alt");
|
|
2745
2749
|
const width = element.getAttribute("width");
|
|
@@ -4013,15 +4017,6 @@ function renderInlineText(text, attributes) {
|
|
|
4013
4017
|
if (!text) return "";
|
|
4014
4018
|
let html = escapeHtml(text);
|
|
4015
4019
|
if (!attributes) return html;
|
|
4016
|
-
const styles = [];
|
|
4017
|
-
for (const [format, cssProperty] of Object.entries(INLINE_STYLE_FORMATS)) {
|
|
4018
|
-
if (format in attributes) {
|
|
4019
|
-
styles.push(`${cssProperty}: ${String(attributes[format])}`);
|
|
4020
|
-
}
|
|
4021
|
-
}
|
|
4022
|
-
if (styles.length > 0) {
|
|
4023
|
-
html = `<span style="${styles.join("; ")}">${html}</span>`;
|
|
4024
|
-
}
|
|
4025
4020
|
for (let i = INLINE_FORMAT_ORDER.length - 1; i >= 0; i--) {
|
|
4026
4021
|
const format = INLINE_FORMAT_ORDER[i];
|
|
4027
4022
|
if (!format) continue;
|
|
@@ -4035,6 +4030,15 @@ function renderInlineText(text, attributes) {
|
|
|
4035
4030
|
html = `<${tag}>${html}</${tag}>`;
|
|
4036
4031
|
}
|
|
4037
4032
|
}
|
|
4033
|
+
const styles = [];
|
|
4034
|
+
for (const [format, cssProperty] of Object.entries(INLINE_STYLE_FORMATS)) {
|
|
4035
|
+
if (format in attributes) {
|
|
4036
|
+
styles.push(`${cssProperty}: ${String(attributes[format])}`);
|
|
4037
|
+
}
|
|
4038
|
+
}
|
|
4039
|
+
if (styles.length > 0) {
|
|
4040
|
+
html = `<span style="${styles.join("; ")}">${html}</span>`;
|
|
4041
|
+
}
|
|
4038
4042
|
return html;
|
|
4039
4043
|
}
|
|
4040
4044
|
function renderEmbed(value, attributes, renderers, blockHandlers, options) {
|
|
@@ -4080,6 +4084,44 @@ function renderEmbed(value, attributes, renderers, blockHandlers, options) {
|
|
|
4080
4084
|
|
|
4081
4085
|
// src/conversion/html/html-to-delta.ts
|
|
4082
4086
|
var import_delta9 = require("@scrider/delta");
|
|
4087
|
+
function isCssWideKeyword(value) {
|
|
4088
|
+
return /^(inherit|initial|unset|revert|revert-layer)$/i.test(value.trim());
|
|
4089
|
+
}
|
|
4090
|
+
function cleanPastedFontFamily(value) {
|
|
4091
|
+
if (value == null) return null;
|
|
4092
|
+
const trimmed = value.trim();
|
|
4093
|
+
if (!trimmed || isCssWideKeyword(trimmed)) return null;
|
|
4094
|
+
const first = trimmed.split(",").map((part) => part.trim().replace(/^["']|["']$/g, "")).find((part) => part && !isCssWideKeyword(part) && !part.startsWith("var("));
|
|
4095
|
+
if (!first) return null;
|
|
4096
|
+
const lower = first.toLowerCase();
|
|
4097
|
+
if (lower === "serif" || lower === "sans-serif" || lower === "monospace" || lower === "cursive" || lower === "fantasy" || lower === "system-ui") {
|
|
4098
|
+
return null;
|
|
4099
|
+
}
|
|
4100
|
+
return first;
|
|
4101
|
+
}
|
|
4102
|
+
function cleanPastedFontSize(value) {
|
|
4103
|
+
if (value == null) return null;
|
|
4104
|
+
const trimmed = value.trim();
|
|
4105
|
+
if (!trimmed || isCssWideKeyword(trimmed)) return null;
|
|
4106
|
+
if (/^(medium|smaller|larger|xx-small|x-small|small|large|x-large|xx-large)$/i.test(trimmed)) {
|
|
4107
|
+
return null;
|
|
4108
|
+
}
|
|
4109
|
+
const px = trimmed.match(/^([\d.]+)\s*px$/i);
|
|
4110
|
+
if (px?.[1]) {
|
|
4111
|
+
const pt = Math.round(Number(px[1]) * 72 / 96);
|
|
4112
|
+
return pt > 0 ? `${pt}pt` : null;
|
|
4113
|
+
}
|
|
4114
|
+
return trimmed;
|
|
4115
|
+
}
|
|
4116
|
+
function isSelectionBackgroundColor(value) {
|
|
4117
|
+
const m = value.trim().match(/^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/i);
|
|
4118
|
+
if (!m) return false;
|
|
4119
|
+
const r = Number(m[1]);
|
|
4120
|
+
const g = Number(m[2]);
|
|
4121
|
+
const b = Number(m[3]);
|
|
4122
|
+
if (![r, g, b].every((n) => Number.isFinite(n))) return false;
|
|
4123
|
+
return r >= 180 && g >= 180 && b >= 180 && b >= r - 5 && b >= g - 5 && b - Math.min(r, g) <= 40;
|
|
4124
|
+
}
|
|
4083
4125
|
function htmlToDelta(html, options = {}) {
|
|
4084
4126
|
const adapter = options.adapter ?? getAdapter();
|
|
4085
4127
|
const normalizeWhitespace = options.normalizeWhitespace ?? true;
|
|
@@ -4141,6 +4183,12 @@ function htmlToDelta(html, options = {}) {
|
|
|
4141
4183
|
pendingText = "";
|
|
4142
4184
|
}
|
|
4143
4185
|
}
|
|
4186
|
+
function beginBlockEmbedLine() {
|
|
4187
|
+
flushText();
|
|
4188
|
+
if (!atLineStart) {
|
|
4189
|
+
context.pushNewline();
|
|
4190
|
+
}
|
|
4191
|
+
}
|
|
4144
4192
|
function processNode(node) {
|
|
4145
4193
|
if (node.nodeType === NODE_TYPE.TEXT_NODE) {
|
|
4146
4194
|
const text = node.textContent ?? "";
|
|
@@ -4428,20 +4476,30 @@ function htmlToDelta(html, options = {}) {
|
|
|
4428
4476
|
flushText();
|
|
4429
4477
|
const prevAttrs = { ...currentAttributes };
|
|
4430
4478
|
const color = element.style?.color || element.style?.getPropertyValue?.("color");
|
|
4431
|
-
if (color) {
|
|
4479
|
+
if (color && !isCssWideKeyword(color)) {
|
|
4432
4480
|
currentAttributes.color = color;
|
|
4433
4481
|
}
|
|
4434
4482
|
const bg = element.style?.backgroundColor || element.style?.getPropertyValue?.("background-color");
|
|
4435
|
-
if (bg) {
|
|
4483
|
+
if (bg && !isCssWideKeyword(bg) && !isSelectionBackgroundColor(bg)) {
|
|
4436
4484
|
currentAttributes.background = bg;
|
|
4437
4485
|
}
|
|
4438
4486
|
const fontFamily = element.style?.fontFamily || element.style?.getPropertyValue?.("font-family");
|
|
4439
|
-
|
|
4440
|
-
|
|
4487
|
+
const cleanedFont = cleanPastedFontFamily(fontFamily);
|
|
4488
|
+
if (cleanedFont) {
|
|
4489
|
+
currentAttributes.font = cleanedFont;
|
|
4441
4490
|
}
|
|
4442
4491
|
const fontSize = element.style?.fontSize || element.style?.getPropertyValue?.("font-size");
|
|
4443
|
-
|
|
4444
|
-
|
|
4492
|
+
const cleanedSize = cleanPastedFontSize(fontSize);
|
|
4493
|
+
if (cleanedSize) {
|
|
4494
|
+
currentAttributes.size = cleanedSize;
|
|
4495
|
+
}
|
|
4496
|
+
const fontWeight = element.style?.fontWeight || element.style?.getPropertyValue?.("font-weight");
|
|
4497
|
+
if (fontWeight === "bold" || fontWeight === "bolder" || fontWeight != null && Number.parseInt(String(fontWeight), 10) >= 600) {
|
|
4498
|
+
currentAttributes.bold = true;
|
|
4499
|
+
}
|
|
4500
|
+
const fontStyle = element.style?.fontStyle || element.style?.getPropertyValue?.("font-style");
|
|
4501
|
+
if (fontStyle === "italic" || fontStyle === "oblique") {
|
|
4502
|
+
currentAttributes.italic = true;
|
|
4445
4503
|
}
|
|
4446
4504
|
processChildren(element);
|
|
4447
4505
|
flushText();
|
|
@@ -4450,6 +4508,10 @@ function htmlToDelta(html, options = {}) {
|
|
|
4450
4508
|
function processImageElement(element) {
|
|
4451
4509
|
const src = element.getAttribute("src");
|
|
4452
4510
|
if (!src) return;
|
|
4511
|
+
const style = element.getAttribute("style") || "";
|
|
4512
|
+
if (/(?:^|;)\s*opacity\s*:\s*0(?:\.0+)?\s*(?:;|$)/i.test(style)) {
|
|
4513
|
+
return;
|
|
4514
|
+
}
|
|
4453
4515
|
const attrs = {};
|
|
4454
4516
|
const alt = element.getAttribute("alt");
|
|
4455
4517
|
const width = element.getAttribute("width");
|
|
@@ -4493,7 +4555,7 @@ function htmlToDelta(html, options = {}) {
|
|
|
4493
4555
|
};
|
|
4494
4556
|
const data = footnotesHandler.fromHtml(section, blockContext);
|
|
4495
4557
|
if (data) {
|
|
4496
|
-
|
|
4558
|
+
beginBlockEmbedLine();
|
|
4497
4559
|
delta.insert({ block: data });
|
|
4498
4560
|
delta.insert("\n");
|
|
4499
4561
|
atLineStart = true;
|
|
@@ -4515,7 +4577,7 @@ function htmlToDelta(html, options = {}) {
|
|
|
4515
4577
|
};
|
|
4516
4578
|
const data = alertHandler.fromHtml(element, blockContext);
|
|
4517
4579
|
if (data) {
|
|
4518
|
-
|
|
4580
|
+
beginBlockEmbedLine();
|
|
4519
4581
|
delta.insert({ block: data });
|
|
4520
4582
|
delta.insert("\n");
|
|
4521
4583
|
atLineStart = true;
|
|
@@ -4537,7 +4599,7 @@ function htmlToDelta(html, options = {}) {
|
|
|
4537
4599
|
};
|
|
4538
4600
|
const data = columnsHandler.fromHtml(element, blockContext);
|
|
4539
4601
|
if (data) {
|
|
4540
|
-
|
|
4602
|
+
beginBlockEmbedLine();
|
|
4541
4603
|
delta.insert({ block: data });
|
|
4542
4604
|
delta.insert("\n");
|
|
4543
4605
|
atLineStart = true;
|
|
@@ -4559,7 +4621,7 @@ function htmlToDelta(html, options = {}) {
|
|
|
4559
4621
|
};
|
|
4560
4622
|
const data = boxHandler.fromHtml(element, blockContext);
|
|
4561
4623
|
if (data) {
|
|
4562
|
-
|
|
4624
|
+
beginBlockEmbedLine();
|
|
4563
4625
|
const opAttrs = {};
|
|
4564
4626
|
const dataFloat = element.getAttribute("data-float");
|
|
4565
4627
|
if (dataFloat) opAttrs.float = dataFloat;
|
|
@@ -4608,7 +4670,7 @@ function htmlToDelta(html, options = {}) {
|
|
|
4608
4670
|
let data = tableHandler.fromHtml(table, makeTableBlockParseContext());
|
|
4609
4671
|
if (!data) return false;
|
|
4610
4672
|
if (host) data = enrichTableBlockFromHost(data, host);
|
|
4611
|
-
|
|
4673
|
+
beginBlockEmbedLine();
|
|
4612
4674
|
delta.insert({ block: data });
|
|
4613
4675
|
delta.insert("\n");
|
|
4614
4676
|
atLineStart = true;
|