tiptap-markdown-react 1.3.3 → 1.5.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/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { Markdown, MarkdownManager } from "@tiptap/markdown";
3
- import { g as getLocaleBundle, S as SearchIcon, d as ChevronUpIcon, e as ChevronDownIcon, X as XIcon, h as ReplaceIcon, i as ReplaceAllIcon, j as renderOrUpdateChart, k as destroyChart, l as CheckIcon, T as TrashIcon, n as CopyIcon, o as ChevronsUpDownIcon, G as GripIcon, E as EraserIcon, D as DownloadIcon, u as useIsMobile, K as KeyboardIcon, p as EditorToc, I as ImagePreviewHost, q as sameTocItems$1, A as AlignRightIcon, t as AlignCenterIcon, v as AlignLeftIcon, w as CropIcon, x as CaptionsIcon, y as ExpandIcon, z as requestImagePreview, B as RotateCcwIcon, F as ExternalLinkIcon, H as TableDeleteIcon, J as ColumnBeforeIcon, L as ColumnAfterIcon, M as ColumnDeleteIcon, N as RowBeforeIcon, O as RowAfterIcon, P as RowDeleteIcon, U as UndoIcon, Q as RedoIcon, V as BoldIcon, W as ItalicIcon, Y as UnderlineIcon, Z as StrikethroughIcon, _ as CodeIcon, $ as LinkIcon, a0 as ImageIcon, a1 as DetailsIcon, a2 as AlignJustifyIcon, a3 as IndentIncreaseIcon, a4 as IndentDecreaseIcon, a5 as LineHeightIcon, a6 as ListUnorderedIcon, a7 as ListOrderedIcon, a8 as ListChecksIcon } from "./ReportContentWithCharts-BOskBjBI.js";
4
- import { C, a9, aa, a, ab, ac, ad, ae, b, c, af, ag, ah, f, m, r, s } from "./ReportContentWithCharts-BOskBjBI.js";
3
+ import { g as getLocaleBundle, S as SearchIcon, d as ChevronUpIcon, e as ChevronDownIcon, X as XIcon, h as ReplaceIcon, i as ReplaceAllIcon, j as renderOrUpdateChart, k as destroyChart, l as CheckIcon, T as TrashIcon, n as CopyIcon, o as ChevronsUpDownIcon, G as GripIcon, E as EraserIcon, D as DownloadIcon, u as useIsMobile, K as KeyboardIcon, p as EditorToc, I as ImagePreviewHost, q as sameTocItems$1, A as AlignRightIcon, t as AlignCenterIcon, v as AlignLeftIcon, w as CropIcon, x as CaptionsIcon, y as ExpandIcon, z as requestImagePreview, B as RotateCcwIcon, F as ExternalLinkIcon, H as TableDeleteIcon, J as ColumnBeforeIcon, L as ColumnAfterIcon, M as ColumnDeleteIcon, N as RowBeforeIcon, O as RowAfterIcon, P as RowDeleteIcon, U as UndoIcon, Q as RedoIcon, V as PaintbrushIcon, W as BoldIcon, Y as ItalicIcon, Z as UnderlineIcon, _ as StrikethroughIcon, $ as CodeIcon, a0 as LinkIcon, a1 as ImageIcon, a2 as DetailsIcon, a3 as AlignJustifyIcon, a4 as IndentIncreaseIcon, a5 as IndentDecreaseIcon, a6 as LineHeightIcon, a7 as ListUnorderedIcon, a8 as ListOrderedIcon, a9 as ListChecksIcon } from "./ReportContentWithCharts-CMMUE51M.js";
4
+ import { C, aa, ab, a, ac, ad, ae, af, b, c, ag, ah, ai, f, m, r, s } from "./ReportContentWithCharts-CMMUE51M.js";
5
5
  import { jsx, jsxs, Fragment as Fragment$2 } from "react/jsx-runtime";
6
6
  import CodeBlockLowlight from "@tiptap/extension-code-block-lowlight";
7
7
  import FindAndReplace, { FindAndReplacePluginKey, createSearchRegex } from "@tiptap/extension-find-and-replace";
@@ -14,10 +14,10 @@ import { NodeViewWrapper, ReactNodeViewRenderer, useEditorState, ReactRenderer,
14
14
  import { Extension, Node as Node$1, mergeAttributes } from "@tiptap/core";
15
15
  import { createPortal } from "react-dom";
16
16
  import { useState, useEffect, useCallback, useRef, useMemo, useSyncExternalStore, useLayoutEffect, forwardRef, useId, useImperativeHandle, Fragment as Fragment$1, useContext, createContext } from "react";
17
- import { q as normalizeImageAlign, l as normalizeImageCrop, m as cropImageBox, e as enrichMarkdownCitations, o as styles$e, i as imageMarkdownTokenizer, c as imageParseMarkdown, d as imageRenderMarkdown, f as imageNodeHtml, g as imageFigureParseRule, h as imageCropAttribute, j as imageCaptionAttribute, k as imageAlignAttribute, r as normalizeImageCaption } from "./ReportContent-Bc5q1bYp.js";
18
- import { R, a as a2, b as b2, s as s2 } from "./ReportContent-Bc5q1bYp.js";
19
- import { C as CitationRef, i as mergeCommentIntervals, h as mapCommentAnchors, p as prepareChartMarkdown, j as reportChart, f as CommentMark, b as baseExtensions, l as lowlight, m as makeTocGetId, k as parseCodeTokenAsChartOrCodeBlock, a as pureCodeBlock, c as pureImage, n as renderMathInto, o as readCurrentNumberingFormat, q as subscribeMathClick, t as applyNumberingFormat, N as NUMBERING_FORMAT_IDS, u as NUMBERING_FORMAT_LABELS, v as NUMBERING_FORMAT_PREVIEWS, d as pureChart } from "./extractToc-DiI2437D.js";
20
- import { P, g, e, s as s3 } from "./extractToc-DiI2437D.js";
17
+ import { q as normalizeImageAlign, l as normalizeImageCrop, m as cropImageBox, e as enrichMarkdownCitations, o as styles$e, i as imageMarkdownTokenizer, c as imageParseMarkdown, d as imageRenderMarkdown, f as imageNodeHtml, g as imageFigureParseRule, h as imageCropAttribute, j as imageCaptionAttribute, k as imageAlignAttribute, r as normalizeImageCaption } from "./ReportContent-DUvhic0o.js";
18
+ import { R, a as a2, b as b2, s as s2 } from "./ReportContent-DUvhic0o.js";
19
+ import { C as CitationRef, i as mergeCommentIntervals, h as mapCommentAnchors, p as prepareChartMarkdown, j as reportChart, f as CommentMark, b as baseExtensions, l as lowlight, m as makeTocGetId, k as parseCodeTokenAsChartOrCodeBlock, a as pureCodeBlock, c as pureImage, n as renderMathInto, o as readCurrentNumberingFormat, q as subscribeMathClick, t as applyNumberingFormat, N as NUMBERING_FORMAT_IDS, u as NUMBERING_FORMAT_LABELS, v as NUMBERING_FORMAT_PREVIEWS, d as pureChart } from "./extractToc-B-hg0XuH.js";
20
+ import { P, g, e, s as s3 } from "./extractToc-B-hg0XuH.js";
21
21
  import { Slice, Fragment } from "@tiptap/pm/model";
22
22
  import { PluginKey, Plugin, Selection, TextSelection, NodeSelection } from "@tiptap/pm/state";
23
23
  import { DecorationSet, Decoration } from "@tiptap/pm/view";
@@ -4292,57 +4292,61 @@ function splitTopLevelBlocks(markdown) {
4292
4292
  function stripToPlainText(markdown) {
4293
4293
  return markdown.replace(/!\[[^\]]*\]\([^)]+\)/g, "").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/^#{1,6}\s+/gm, "").replace(/^[ \t]*[-*+]\s+/gm, "").replace(/^[ \t]*\d+\.\s+/gm, "").replace(/[*_~`]+/g, "").replace(/<[^>]+>/g, "").replace(/\|/g, " ").replace(/\s+/g, " ").trim();
4294
4294
  }
4295
- const toolbar = "_toolbar_1l6t0_2";
4296
- const inner = "_inner_1l6t0_15";
4297
- const btn$2 = "_btn_1l6t0_35";
4298
- const btnActive$1 = "_btnActive_1l6t0_58";
4299
- const txtIcon = "_txtIcon_1l6t0_74";
4300
- const colorIcon = "_colorIcon_1l6t0_82";
4301
- const colorIconGlyph = "_colorIconGlyph_1l6t0_90";
4302
- const colorIconBar = "_colorIconBar_1l6t0_96";
4303
- const scriptTrigger = "_scriptTrigger_1l6t0_103";
4304
- const scriptTriggerGlyph = "_scriptTriggerGlyph_1l6t0_123";
4305
- const divider$2 = "_divider_1l6t0_131";
4306
- const styleTrigger = "_styleTrigger_1l6t0_140";
4307
- const styleTriggerLabel = "_styleTriggerLabel_1l6t0_174";
4308
- const styleTriggerCaret = "_styleTriggerCaret_1l6t0_183";
4309
- const iconTrigger = "_iconTrigger_1l6t0_190";
4310
- const styleItem = "_styleItem_1l6t0_198";
4311
- const styleIcon = "_styleIcon_1l6t0_204";
4312
- const scriptGlyph = "_scriptGlyph_1l6t0_214";
4313
- const menu = "_menu_1l6t0_226";
4314
- const menuItem = "_menuItem_1l6t0_237";
4315
- const menuItemSelected = "_menuItemSelected_1l6t0_264";
4316
- const listSplit = "_listSplit_1l6t0_279";
4317
- const listSplitActive = "_listSplitActive_1l6t0_285";
4318
- const numberingCaret = "_numberingCaret_1l6t0_297";
4319
- const numberingCaretActive = "_numberingCaretActive_1l6t0_327";
4320
- const numberingMenu = "_numberingMenu_1l6t0_331";
4321
- const numberingGrid = "_numberingGrid_1l6t0_341";
4322
- const numberingOption = "_numberingOption_1l6t0_347";
4323
- const numberingOptionActive = "_numberingOptionActive_1l6t0_362";
4324
- const numberingPreview = "_numberingPreview_1l6t0_367";
4325
- const numberingPreviewRow = "_numberingPreviewRow_1l6t0_373";
4326
- const numberingPreviewMarker = "_numberingPreviewMarker_1l6t0_388";
4327
- const numberingPreviewLine = "_numberingPreviewLine_1l6t0_396";
4328
- const tableInsertCaret = "_tableInsertCaret_1l6t0_402";
4329
- const tableSizePicker = "_tableSizePicker_1l6t0_410";
4330
- const tableSizeGrid = "_tableSizeGrid_1l6t0_420";
4331
- const tableSizeCell = "_tableSizeCell_1l6t0_425";
4332
- const tableSizeCellActive = "_tableSizeCellActive_1l6t0_435";
4333
- const tableSizeLabel = "_tableSizeLabel_1l6t0_440";
4334
- const popoverContent$1 = "_popoverContent_1l6t0_449";
4335
- const mathLayer = "_mathLayer_1l6t0_453";
4336
- const mathStack = "_mathStack_1l6t0_458";
4337
- const mathStackBlock = "_mathStackBlock_1l6t0_465";
4338
- const mathHint = "_mathHint_1l6t0_470";
4339
- const mathHintBlock = "_mathHintBlock_1l6t0_482";
4340
- const mathHintIcon = "_mathHintIcon_1l6t0_488";
4341
- const mathField = "_mathField_1l6t0_519";
4342
- const mathFieldBlock = "_mathFieldBlock_1l6t0_531";
4343
- const mathInput = "_mathInput_1l6t0_538";
4344
- const mathDone = "_mathDone_1l6t0_556";
4345
- const mathDoneKbd = "_mathDoneKbd_1l6t0_581";
4295
+ const toolbar = "_toolbar_1vr0x_2";
4296
+ const inner = "_inner_1vr0x_15";
4297
+ const btn$2 = "_btn_1vr0x_35";
4298
+ const btnActive$1 = "_btnActive_1vr0x_58";
4299
+ const txtIcon = "_txtIcon_1vr0x_74";
4300
+ const colorIcon = "_colorIcon_1vr0x_82";
4301
+ const colorIconGlyph = "_colorIconGlyph_1vr0x_90";
4302
+ const colorIconBar = "_colorIconBar_1vr0x_96";
4303
+ const scriptTrigger = "_scriptTrigger_1vr0x_103";
4304
+ const scriptTriggerGlyph = "_scriptTriggerGlyph_1vr0x_123";
4305
+ const divider$2 = "_divider_1vr0x_131";
4306
+ const styleTrigger = "_styleTrigger_1vr0x_140";
4307
+ const styleTriggerLabel = "_styleTriggerLabel_1vr0x_174";
4308
+ const styleTriggerStable = "_styleTriggerStable_1vr0x_184";
4309
+ const styleTriggerLabelStable = "_styleTriggerLabelStable_1vr0x_188";
4310
+ const styleTriggerSizer = "_styleTriggerSizer_1vr0x_193";
4311
+ const styleTriggerValue = "_styleTriggerValue_1vr0x_194";
4312
+ const styleTriggerCaret = "_styleTriggerCaret_1vr0x_209";
4313
+ const iconTrigger = "_iconTrigger_1vr0x_216";
4314
+ const styleItem = "_styleItem_1vr0x_224";
4315
+ const styleIcon = "_styleIcon_1vr0x_230";
4316
+ const scriptGlyph = "_scriptGlyph_1vr0x_240";
4317
+ const menu = "_menu_1vr0x_252";
4318
+ const menuItem = "_menuItem_1vr0x_263";
4319
+ const menuItemSelected = "_menuItemSelected_1vr0x_290";
4320
+ const listSplit = "_listSplit_1vr0x_305";
4321
+ const listSplitActive = "_listSplitActive_1vr0x_311";
4322
+ const numberingCaret = "_numberingCaret_1vr0x_323";
4323
+ const numberingCaretActive = "_numberingCaretActive_1vr0x_353";
4324
+ const numberingMenu = "_numberingMenu_1vr0x_357";
4325
+ const numberingGrid = "_numberingGrid_1vr0x_367";
4326
+ const numberingOption = "_numberingOption_1vr0x_373";
4327
+ const numberingOptionActive = "_numberingOptionActive_1vr0x_388";
4328
+ const numberingPreview = "_numberingPreview_1vr0x_393";
4329
+ const numberingPreviewRow = "_numberingPreviewRow_1vr0x_399";
4330
+ const numberingPreviewMarker = "_numberingPreviewMarker_1vr0x_414";
4331
+ const numberingPreviewLine = "_numberingPreviewLine_1vr0x_422";
4332
+ const tableInsertCaret = "_tableInsertCaret_1vr0x_428";
4333
+ const tableSizePicker = "_tableSizePicker_1vr0x_436";
4334
+ const tableSizeGrid = "_tableSizeGrid_1vr0x_446";
4335
+ const tableSizeCell = "_tableSizeCell_1vr0x_451";
4336
+ const tableSizeCellActive = "_tableSizeCellActive_1vr0x_461";
4337
+ const tableSizeLabel = "_tableSizeLabel_1vr0x_466";
4338
+ const popoverContent$1 = "_popoverContent_1vr0x_475";
4339
+ const mathLayer = "_mathLayer_1vr0x_479";
4340
+ const mathStack = "_mathStack_1vr0x_484";
4341
+ const mathStackBlock = "_mathStackBlock_1vr0x_491";
4342
+ const mathHint = "_mathHint_1vr0x_496";
4343
+ const mathHintBlock = "_mathHintBlock_1vr0x_508";
4344
+ const mathHintIcon = "_mathHintIcon_1vr0x_514";
4345
+ const mathField = "_mathField_1vr0x_545";
4346
+ const mathFieldBlock = "_mathFieldBlock_1vr0x_557";
4347
+ const mathInput = "_mathInput_1vr0x_564";
4348
+ const mathDone = "_mathDone_1vr0x_582";
4349
+ const mathDoneKbd = "_mathDoneKbd_1vr0x_607";
4346
4350
  const styles$6 = {
4347
4351
  toolbar,
4348
4352
  inner,
@@ -4357,6 +4361,10 @@ const styles$6 = {
4357
4361
  divider: divider$2,
4358
4362
  styleTrigger,
4359
4363
  styleTriggerLabel,
4364
+ styleTriggerStable,
4365
+ styleTriggerLabelStable,
4366
+ styleTriggerSizer,
4367
+ styleTriggerValue,
4360
4368
  styleTriggerCaret,
4361
4369
  iconTrigger,
4362
4370
  styleItem,
@@ -4396,6 +4404,263 @@ const styles$6 = {
4396
4404
  mathDone,
4397
4405
  mathDoneKbd
4398
4406
  };
4407
+ const FORMAT_MARKS = /* @__PURE__ */ new Set([
4408
+ "bold",
4409
+ "italic",
4410
+ "underline",
4411
+ "strike",
4412
+ "code",
4413
+ "highlight",
4414
+ "textStyle",
4415
+ "superscript",
4416
+ "subscript"
4417
+ ]);
4418
+ const PLAIN_BLOCK = {
4419
+ type: "paragraph",
4420
+ level: null,
4421
+ textAlign: null,
4422
+ indent: null,
4423
+ lineHeight: null
4424
+ };
4425
+ function isFormatMark(name) {
4426
+ return FORMAT_MARKS.has(name);
4427
+ }
4428
+ function isStyleBlock(node) {
4429
+ return node.type.name === "paragraph" || node.type.name === "heading";
4430
+ }
4431
+ function readBlock(node) {
4432
+ const indent = Number(node.attrs.indent);
4433
+ const lineHeight = Number(node.attrs.lineHeight);
4434
+ return {
4435
+ type: node.type.name === "heading" ? "heading" : "paragraph",
4436
+ level: node.type.name === "heading" ? Number(node.attrs.level) || 1 : null,
4437
+ textAlign: typeof node.attrs.textAlign === "string" && node.attrs.textAlign ? node.attrs.textAlign : null,
4438
+ indent: Number.isFinite(indent) && indent > 0 ? indent : null,
4439
+ lineHeight: Number.isFinite(lineHeight) && lineHeight > 0 ? lineHeight : null
4440
+ };
4441
+ }
4442
+ function sameMarkSet(a3, b3) {
4443
+ if (a3.length !== b3.length) return false;
4444
+ return a3.every((mark) => b3.some((other) => mark.eq(other)));
4445
+ }
4446
+ function anchorTextblock(doc, from, to) {
4447
+ const $from = doc.resolve(from);
4448
+ if ($from.parent.isTextblock && !$from.parent.type.spec.code) {
4449
+ return { node: $from.parent, pos: $from.before() };
4450
+ }
4451
+ if (from === to) return null;
4452
+ let found = null;
4453
+ doc.nodesBetween(from, to, (node, pos) => {
4454
+ if (found) return false;
4455
+ if (node.isTextblock && !node.type.spec.code) {
4456
+ found = { node, pos };
4457
+ return false;
4458
+ }
4459
+ });
4460
+ return found;
4461
+ }
4462
+ function blockIsCovered(node, pos, from, to) {
4463
+ const contentFrom = pos + 1;
4464
+ const contentTo = pos + node.nodeSize - 1;
4465
+ return from <= contentFrom && to >= contentTo;
4466
+ }
4467
+ function sourceMarks(doc, from, to, stored) {
4468
+ var _a;
4469
+ if (from === to) {
4470
+ if (stored) return stored;
4471
+ return doc.resolve(from).marks();
4472
+ }
4473
+ const $from = doc.resolve(from);
4474
+ if ((_a = $from.nodeAfter) == null ? void 0 : _a.isText) return $from.nodeAfter.marks;
4475
+ return $from.marks();
4476
+ }
4477
+ function captureFormat(editor) {
4478
+ if (!editor.isEditable) return null;
4479
+ const { selection, storedMarks, doc } = editor.state;
4480
+ const anchor = anchorTextblock(doc, selection.from, selection.to);
4481
+ if (!anchor) return null;
4482
+ const marks = sourceMarks(doc, selection.from, selection.to, storedMarks).filter((mark) => isFormatMark(mark.type.name)).map((mark) => ({ type: mark.type.name, attrs: { ...mark.attrs } }));
4483
+ const block = isStyleBlock(anchor.node) && (selection.empty || blockIsCovered(anchor.node, anchor.pos, selection.from, selection.to)) ? readBlock(anchor.node) : null;
4484
+ return { marks, block };
4485
+ }
4486
+ function canPaint(doc, from, to) {
4487
+ return anchorTextblock(doc, from, to) != null;
4488
+ }
4489
+ function removeFormatMarks(tr, from, to) {
4490
+ if (from >= to) return;
4491
+ for (const name of FORMAT_MARKS) {
4492
+ const type = tr.doc.type.schema.marks[name];
4493
+ if (type) tr.removeMark(from, to, type);
4494
+ }
4495
+ }
4496
+ function addFormatMarks(tr, from, to, marks) {
4497
+ if (from >= to) return;
4498
+ for (const mark of marks) {
4499
+ const type = tr.doc.type.schema.marks[mark.type];
4500
+ if (!type || !isFormatMark(mark.type)) continue;
4501
+ tr.addMark(from, to, type.create(mark.attrs));
4502
+ }
4503
+ }
4504
+ function marksForNextInput(tr, stateStored) {
4505
+ if (tr.storedMarksSet) return tr.storedMarks ?? [];
4506
+ if (stateStored) return stateStored;
4507
+ return tr.selection.$from.marks();
4508
+ }
4509
+ function setFormatStoredMarks(tr, marks, stateStored) {
4510
+ const current = marksForNextInput(tr, stateStored);
4511
+ const kept = current.filter((mark) => !isFormatMark(mark.type.name));
4512
+ const next = [
4513
+ ...kept,
4514
+ ...marks.flatMap((mark) => {
4515
+ const type = tr.doc.type.schema.marks[mark.type];
4516
+ return type && isFormatMark(mark.type) ? [type.create(mark.attrs)] : [];
4517
+ })
4518
+ ];
4519
+ if (sameMarkSet(current, next)) return;
4520
+ tr.setStoredMarks(next);
4521
+ }
4522
+ function stripFormatStoredMarks(tr, stateStored) {
4523
+ const current = marksForNextInput(tr, stateStored);
4524
+ const next = current.filter((mark) => !isFormatMark(mark.type.name));
4525
+ if (sameMarkSet(current, next)) return;
4526
+ tr.setStoredMarks(next);
4527
+ }
4528
+ function applyBlockAt(tr, pos, block) {
4529
+ var _a, _b, _c;
4530
+ const node = tr.doc.nodeAt(pos);
4531
+ if (!node || !isStyleBlock(node)) return;
4532
+ const $pos = tr.doc.resolve(pos);
4533
+ let typeName = node.type.name;
4534
+ if (block.type === "heading") {
4535
+ const heading = tr.doc.type.schema.nodes.heading;
4536
+ if (heading && $pos.parent.canReplaceWith($pos.index(), $pos.index() + 1, heading)) {
4537
+ typeName = "heading";
4538
+ }
4539
+ } else if (node.type.name === "heading") {
4540
+ const paragraph = tr.doc.type.schema.nodes.paragraph;
4541
+ if (paragraph && $pos.parent.canReplaceWith($pos.index(), $pos.index() + 1, paragraph)) {
4542
+ typeName = "paragraph";
4543
+ }
4544
+ }
4545
+ const type = tr.doc.type.schema.nodes[typeName];
4546
+ if (!type) return;
4547
+ const indent = Number(node.attrs.indent);
4548
+ const lineHeight = Number(node.attrs.lineHeight);
4549
+ const sameType = node.type === type;
4550
+ const sameLevel = typeName !== "heading" || Number(node.attrs.level) === (block.level ?? 1);
4551
+ const sameAlign = (node.attrs.textAlign || null) === block.textAlign;
4552
+ const sameIndent = (Number.isFinite(indent) && indent > 0 ? indent : null) === block.indent;
4553
+ const sameLine = (Number.isFinite(lineHeight) && lineHeight > 0 ? lineHeight : null) === block.lineHeight;
4554
+ if (sameType && sameLevel && sameAlign && sameIndent && sameLine) return;
4555
+ const attrs = { ...node.attrs };
4556
+ if (typeName === "heading") attrs.level = block.level ?? 1;
4557
+ else delete attrs.level;
4558
+ if ((_a = type.spec.attrs) == null ? void 0 : _a.textAlign) attrs.textAlign = block.textAlign;
4559
+ if ((_b = type.spec.attrs) == null ? void 0 : _b.indent) attrs.indent = block.indent;
4560
+ if ((_c = type.spec.attrs) == null ? void 0 : _c.lineHeight) attrs.lineHeight = block.lineHeight;
4561
+ tr.setNodeMarkup(pos, type, attrs);
4562
+ }
4563
+ function coveredStyleBlockPositions(doc, from, to) {
4564
+ const positions = [];
4565
+ doc.nodesBetween(from, to, (node, pos) => {
4566
+ if (!isStyleBlock(node)) return;
4567
+ if (blockIsCovered(node, pos, from, to)) positions.push(pos);
4568
+ });
4569
+ return positions;
4570
+ }
4571
+ function mutateFormatting(tr, mode, format, stateStored) {
4572
+ const docBefore = tr.doc;
4573
+ const ranges = tr.selection.ranges.map((range) => ({
4574
+ from: range.$from.pos,
4575
+ to: range.$to.pos
4576
+ }));
4577
+ const caretOnly = ranges.every((range) => range.from === range.to);
4578
+ if (caretOnly) {
4579
+ for (const range of ranges) {
4580
+ const $pos = tr.doc.resolve(range.from);
4581
+ const parent = $pos.parent;
4582
+ if (!parent.isTextblock || parent.type.spec.code) continue;
4583
+ if (mode === "clear") {
4584
+ removeFormatMarks(tr, $pos.start(), $pos.end());
4585
+ if (isStyleBlock(parent)) applyBlockAt(tr, $pos.before(), PLAIN_BLOCK);
4586
+ } else if ((format == null ? void 0 : format.block) && isStyleBlock(parent)) {
4587
+ applyBlockAt(tr, $pos.before(), format.block);
4588
+ }
4589
+ }
4590
+ if (mode === "clear") stripFormatStoredMarks(tr, stateStored);
4591
+ else if (format) setFormatStoredMarks(tr, format.marks, stateStored);
4592
+ } else {
4593
+ for (const range of ranges) {
4594
+ removeFormatMarks(tr, range.from, range.to);
4595
+ if (mode === "paint" && format) addFormatMarks(tr, range.from, range.to, format.marks);
4596
+ }
4597
+ const positions = /* @__PURE__ */ new Set();
4598
+ for (const range of ranges) {
4599
+ for (const pos of coveredStyleBlockPositions(tr.doc, range.from, range.to)) {
4600
+ positions.add(pos);
4601
+ }
4602
+ }
4603
+ const ordered = [...positions].sort((a3, b3) => b3 - a3);
4604
+ for (const pos of ordered) {
4605
+ if (mode === "clear") applyBlockAt(tr, pos, PLAIN_BLOCK);
4606
+ else if (format == null ? void 0 : format.block) applyBlockAt(tr, pos, format.block);
4607
+ }
4608
+ if (mode === "clear") stripFormatStoredMarks(tr, stateStored);
4609
+ else if (format) setFormatStoredMarks(tr, format.marks, stateStored);
4610
+ }
4611
+ const docChanged = !tr.doc.eq(docBefore);
4612
+ const storedChanged = tr.storedMarksSet && !sameMarkSet(tr.storedMarks ?? [], stateStored ?? []);
4613
+ return docChanged || storedChanged;
4614
+ }
4615
+ function runFormatCommand(editor, mutate) {
4616
+ return editor.chain().focus().command(({ tr }) => mutate(tr)).run();
4617
+ }
4618
+ function pinCursorMarks(editor, desired) {
4619
+ if (!editor.state.selection.empty) return;
4620
+ const current = editor.state.storedMarks ?? editor.state.selection.$from.marks();
4621
+ if (sameMarkSet(current, desired)) return;
4622
+ editor.view.dispatch(
4623
+ editor.state.tr.setStoredMarks(desired).setMeta("addToHistory", false)
4624
+ );
4625
+ }
4626
+ function storedMarksFor(editor, captured) {
4627
+ const current = editor.state.storedMarks ?? editor.state.selection.$from.marks();
4628
+ const kept = current.filter((mark) => !isFormatMark(mark.type.name));
4629
+ if (!captured) return kept;
4630
+ return [
4631
+ ...kept,
4632
+ ...captured.flatMap((mark) => {
4633
+ const type = editor.schema.marks[mark.type];
4634
+ return type && isFormatMark(mark.type) ? [type.create(mark.attrs)] : [];
4635
+ })
4636
+ ];
4637
+ }
4638
+ function clearFormatting(editor) {
4639
+ if (!editor.isEditable) return false;
4640
+ const { selection, doc } = editor.state;
4641
+ if (!canPaint(doc, selection.from, selection.to)) return false;
4642
+ const stateStored = editor.state.storedMarks;
4643
+ const ok = runFormatCommand(
4644
+ editor,
4645
+ (tr) => mutateFormatting(tr, "clear", null, stateStored)
4646
+ );
4647
+ if (editor.state.selection.empty) pinCursorMarks(editor, storedMarksFor(editor, null));
4648
+ return ok;
4649
+ }
4650
+ function applyCapturedFormat(editor, format) {
4651
+ if (!editor.isEditable) return false;
4652
+ const { selection, doc } = editor.state;
4653
+ if (!canPaint(doc, selection.from, selection.to)) return false;
4654
+ const stateStored = editor.state.storedMarks;
4655
+ runFormatCommand(
4656
+ editor,
4657
+ (tr) => mutateFormatting(tr, "paint", format, stateStored)
4658
+ );
4659
+ if (editor.state.selection.empty) {
4660
+ pinCursorMarks(editor, storedMarksFor(editor, format.marks));
4661
+ }
4662
+ return true;
4663
+ }
4399
4664
  const palette = "_palette_x5lrq_2";
4400
4665
  const noneRow = "_noneRow_x5lrq_11";
4401
4666
  const noneIcon = "_noneIcon_x5lrq_23";
@@ -6454,6 +6719,63 @@ function EditorToolbar({
6454
6719
  editor.off("blur", onBlur);
6455
6720
  };
6456
6721
  }, [editor]);
6722
+ const [painter, setPainter] = useState("off");
6723
+ const [paintSample, setPaintSample] = useState(null);
6724
+ const painterClickAt = useRef(0);
6725
+ const painterEditor = useRef(editor);
6726
+ const disarmPainter = () => {
6727
+ painterClickAt.current = 0;
6728
+ setPainter("off");
6729
+ setPaintSample(null);
6730
+ };
6731
+ useEffect(() => {
6732
+ if (painterEditor.current === editor) return;
6733
+ painterEditor.current = editor;
6734
+ disarmPainter();
6735
+ }, [editor]);
6736
+ useEffect(() => {
6737
+ if (editor.isDestroyed) return;
6738
+ const dom = editor.view.dom;
6739
+ dom.classList.toggle("tmr-format-painter", painter !== "off");
6740
+ return () => {
6741
+ if (!editor.isDestroyed) dom.classList.remove("tmr-format-painter");
6742
+ };
6743
+ }, [editor, painter]);
6744
+ useEffect(() => {
6745
+ if (painter === "off" || !paintSample || editor.isDestroyed) return;
6746
+ const dom = editor.view.dom;
6747
+ const apply2 = () => {
6748
+ const handled = applyCapturedFormat(editor, paintSample);
6749
+ if (handled && painter === "once") disarmPainter();
6750
+ };
6751
+ const onKeyDown = (event) => {
6752
+ if (event.key !== "Escape") return;
6753
+ disarmPainter();
6754
+ };
6755
+ dom.addEventListener("mouseup", apply2);
6756
+ document.addEventListener("keydown", onKeyDown);
6757
+ return () => {
6758
+ dom.removeEventListener("mouseup", apply2);
6759
+ document.removeEventListener("keydown", onKeyDown);
6760
+ };
6761
+ }, [editor, painter, paintSample]);
6762
+ const onFormatPainterClick = () => {
6763
+ const now = Date.now();
6764
+ const quick = now - painterClickAt.current < 300;
6765
+ painterClickAt.current = now;
6766
+ if (painter !== "off") {
6767
+ if (quick && painter === "once") {
6768
+ setPainter("locked");
6769
+ return;
6770
+ }
6771
+ disarmPainter();
6772
+ return;
6773
+ }
6774
+ const captured = captureFormat(editor);
6775
+ if (!captured) return;
6776
+ setPaintSample(captured);
6777
+ setPainter(quick ? "locked" : "once");
6778
+ };
6457
6779
  const fileInputRef = useRef(null);
6458
6780
  const chain = () => editor.chain().focus();
6459
6781
  const imageUploadEnabled = hasImageUpload(editor);
@@ -6660,6 +6982,23 @@ function EditorToolbar({
6660
6982
  children: /* @__PURE__ */ jsx(RedoIcon, {})
6661
6983
  }
6662
6984
  ),
6985
+ /* @__PURE__ */ jsx(
6986
+ ToolbarButton,
6987
+ {
6988
+ title: t.formatPainter,
6989
+ active: painter !== "off",
6990
+ onClick: onFormatPainterClick,
6991
+ children: /* @__PURE__ */ jsx(PaintbrushIcon, {})
6992
+ }
6993
+ ),
6994
+ /* @__PURE__ */ jsx(
6995
+ ToolbarButton,
6996
+ {
6997
+ title: t.clearFormatting,
6998
+ onClick: () => clearFormatting(editor),
6999
+ children: /* @__PURE__ */ jsx(EraserIcon, {})
7000
+ }
7001
+ ),
6663
7002
  /* @__PURE__ */ jsx(Divider, {}),
6664
7003
  /* @__PURE__ */ jsxs(
6665
7004
  MenuPopover,
@@ -6668,11 +7007,18 @@ function EditorToolbar({
6668
7007
  "button",
6669
7008
  {
6670
7009
  type: "button",
6671
- className: styles$6.styleTrigger,
6672
- title: t.style,
7010
+ className: `${styles$6.styleTrigger} ${styles$6.styleTriggerStable}`,
7011
+ title: state.headingLevel ? t.headingLabel(state.headingLevel) : t.normalText,
7012
+ "aria-label": t.style,
6673
7013
  onMouseDown: (e2) => e2.preventDefault(),
6674
7014
  children: [
6675
- /* @__PURE__ */ jsx("span", { className: styles$6.styleTriggerLabel, children: t.style }),
7015
+ /* @__PURE__ */ jsxs("span", { className: `${styles$6.styleTriggerLabel} ${styles$6.styleTriggerLabelStable}`, children: [
7016
+ /* @__PURE__ */ jsxs("span", { className: styles$6.styleTriggerSizer, "aria-hidden": "true", children: [
7017
+ /* @__PURE__ */ jsx("span", { children: t.normalText }),
7018
+ HEADING_LEVELS.map((lv) => /* @__PURE__ */ jsx("span", { children: `H${lv}` }, lv))
7019
+ ] }),
7020
+ /* @__PURE__ */ jsx("span", { className: styles$6.styleTriggerValue, children: state.headingLevel ? `H${state.headingLevel}` : t.normalText })
7021
+ ] }),
6676
7022
  /* @__PURE__ */ jsx(ChevronDownIcon, { size: 12, className: styles$6.styleTriggerCaret })
6677
7023
  ]
6678
7024
  }
@@ -6711,13 +7057,19 @@ function EditorToolbar({
6711
7057
  "button",
6712
7058
  {
6713
7059
  type: "button",
6714
- className: styles$6.styleTrigger,
6715
- title: t.fontSize,
7060
+ className: `${styles$6.styleTrigger} ${styles$6.styleTriggerStable}`,
7061
+ title: state.fontSize || t.fontSize,
6716
7062
  "aria-label": t.fontSize,
6717
7063
  disabled: !canEditFontSize,
6718
7064
  onMouseDown: (e2) => e2.preventDefault(),
6719
7065
  children: [
6720
- /* @__PURE__ */ jsx("span", { className: styles$6.styleTriggerLabel, children: state.fontSize || t.fontSize }),
7066
+ /* @__PURE__ */ jsxs("span", { className: `${styles$6.styleTriggerLabel} ${styles$6.styleTriggerLabelStable}`, children: [
7067
+ /* @__PURE__ */ jsxs("span", { className: styles$6.styleTriggerSizer, "aria-hidden": "true", children: [
7068
+ /* @__PURE__ */ jsx("span", { children: t.fontSize }),
7069
+ FONT_SIZES.map((size) => /* @__PURE__ */ jsx("span", { children: size }, size))
7070
+ ] }),
7071
+ /* @__PURE__ */ jsx("span", { className: styles$6.styleTriggerValue, children: state.fontSize || t.fontSize })
7072
+ ] }),
6721
7073
  /* @__PURE__ */ jsx(ChevronDownIcon, { size: 12, className: styles$6.styleTriggerCaret })
6722
7074
  ]
6723
7075
  }
@@ -7408,8 +7760,8 @@ export {
7408
7760
  C as ChartMount,
7409
7761
  CheckIcon,
7410
7762
  ChevronDownIcon,
7411
- a9 as ChevronLeftIcon,
7412
- aa as ChevronRightIcon,
7763
+ aa as ChevronLeftIcon,
7764
+ ab as ChevronRightIcon,
7413
7765
  ChevronUpIcon,
7414
7766
  ChevronsUpDownIcon,
7415
7767
  a as CitationInteractive,
@@ -7433,12 +7785,12 @@ export {
7433
7785
  FIND_DEBOUNCE_MS,
7434
7786
  default2 as FindAndReplace,
7435
7787
  FindReplaceBar,
7436
- ab as FitIcon,
7788
+ ac as FitIcon,
7437
7789
  GripIcon,
7438
7790
  ImageAlignTools,
7439
7791
  ImageIcon,
7440
7792
  ImageUploadNode,
7441
- ac as ImportIcon,
7793
+ ad as ImportIcon,
7442
7794
  ImportPlaceholder,
7443
7795
  IndentDecreaseIcon,
7444
7796
  IndentIncreaseIcon,
@@ -7450,13 +7802,14 @@ export {
7450
7802
  ListChecksIcon,
7451
7803
  ListOrderedIcon,
7452
7804
  ListUnorderedIcon,
7453
- ad as LockIcon,
7805
+ ae as LockIcon,
7454
7806
  MarkdownFileDrop,
7455
7807
  MarkdownPaste,
7456
7808
  MarkdownPreview,
7457
7809
  MarkdownWysiwygEditor,
7458
- ae as MenuIcon,
7810
+ af as MenuIcon,
7459
7811
  PENDING_ANCHOR_CLASS,
7812
+ PaintbrushIcon,
7460
7813
  P as ParagraphStyles,
7461
7814
  RedoIcon,
7462
7815
  ReplaceAllIcon,
@@ -7465,7 +7818,7 @@ export {
7465
7818
  b as ReportContentInteractive,
7466
7819
  c as ReportContentWithCharts,
7467
7820
  RotateCcwIcon,
7468
- af as RotateCwIcon,
7821
+ ag as RotateCwIcon,
7469
7822
  RowAfterIcon,
7470
7823
  RowBeforeIcon,
7471
7824
  RowDeleteIcon,
@@ -7478,8 +7831,8 @@ export {
7478
7831
  UnderlineIcon,
7479
7832
  UndoIcon,
7480
7833
  XIcon,
7481
- ag as ZoomInIcon,
7482
- ah as ZoomOutIcon,
7834
+ ah as ZoomInIcon,
7835
+ ai as ZoomOutIcon,
7483
7836
  a2 as applyCitationSources,
7484
7837
  applyCommentAnchorsToEditor,
7485
7838
  applyLink,