@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 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
- if (fontFamily) {
4440
- currentAttributes.font = fontFamily.replace(/^["']|["']$/g, "");
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
- if (fontSize) {
4444
- currentAttributes.size = fontSize;
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
- flushText();
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
- flushText();
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
- flushText();
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
- flushText();
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
- flushText();
4673
+ beginBlockEmbedLine();
4612
4674
  delta.insert({ block: data });
4613
4675
  delta.insert("\n");
4614
4676
  atLineStart = true;