@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.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
- if (fontFamily) {
4297
- currentAttributes.font = fontFamily.replace(/^["']|["']$/g, "");
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
- if (fontSize) {
4301
- currentAttributes.size = fontSize;
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
- flushText();
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
- flushText();
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
- flushText();
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
- flushText();
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
- flushText();
4530
+ beginBlockEmbedLine();
4469
4531
  delta.insert({ block: data });
4470
4532
  delta.insert("\n");
4471
4533
  atLineStart = true;