tiptap-markdown-react 1.4.0 → 1.6.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-3cn7_5Tz.js";
4
- import { C, a9, aa, a, ab, ac, ad, ae, b, c, af, ag, ah, f, m, r, s } from "./ReportContentWithCharts-3cn7_5Tz.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, aa as MinimizeIcon } from "./ReportContentWithCharts-BaBitkZX.js";
4
+ import { C, ab, ac, a, ad, ae, af, ag, b, c, ah, ai, aj, f, m, r, s } from "./ReportContentWithCharts-BaBitkZX.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-B0HdrWAi.js";
18
- import { R, a as a2, b as b2, s as s2 } from "./ReportContent-B0HdrWAi.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-Bz924Nh4.js";
20
- import { P, g, e, s as s3 } from "./extractToc-Bz924Nh4.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";
@@ -4224,6 +4224,122 @@ function MarkdownPreview({
4224
4224
  ) })
4225
4225
  ] });
4226
4226
  }
4227
+ const FULLSCREEN_ATTR = "data-tmr-fullscreen";
4228
+ const ROOT_ATTR = "data-tmr-fullscreen-root";
4229
+ const ESCAPE_GUARDS = [
4230
+ "[data-radix-popper-content-wrapper]",
4231
+ "[data-table-menu]",
4232
+ "[data-block-drag-menu]",
4233
+ "[data-find-bar]",
4234
+ "[data-image-lightbox]",
4235
+ "[data-crop-box]",
4236
+ '[role="dialog"]',
4237
+ '[role="listbox"]',
4238
+ '[role="menu"]'
4239
+ ].join(",");
4240
+ let savedBodyOverflow = null;
4241
+ function readExplicitTarget(target) {
4242
+ if (typeof target === "function") return target();
4243
+ if (target instanceof HTMLElement) return target;
4244
+ if (target && typeof target === "object" && "current" in target) {
4245
+ return target.current instanceof HTMLElement ? target.current : null;
4246
+ }
4247
+ return null;
4248
+ }
4249
+ function defaultFullscreenElement(toolbarRoot) {
4250
+ let node = toolbarRoot.parentElement;
4251
+ while (node && node !== document.body && node !== document.documentElement) {
4252
+ if (node.querySelector(".ProseMirror")) return node;
4253
+ node = node.parentElement;
4254
+ }
4255
+ return toolbarRoot.parentElement;
4256
+ }
4257
+ function resolveFullscreenElement(target, toolbarRoot) {
4258
+ const explicit = readExplicitTarget(target);
4259
+ if (explicit) return explicit;
4260
+ if (!toolbarRoot) return null;
4261
+ return defaultFullscreenElement(toolbarRoot);
4262
+ }
4263
+ function enterFullscreen(el) {
4264
+ el.setAttribute(FULLSCREEN_ATTR, "");
4265
+ document.documentElement.setAttribute(ROOT_ATTR, "");
4266
+ if (savedBodyOverflow === null) {
4267
+ savedBodyOverflow = document.body.style.overflow;
4268
+ document.body.style.overflow = "hidden";
4269
+ }
4270
+ }
4271
+ function leaveFullscreen(el) {
4272
+ el == null ? void 0 : el.removeAttribute(FULLSCREEN_ATTR);
4273
+ if (document.querySelector(`[${FULLSCREEN_ATTR}]`)) return;
4274
+ document.documentElement.removeAttribute(ROOT_ATTR);
4275
+ if (savedBodyOverflow !== null) {
4276
+ document.body.style.overflow = savedBodyOverflow;
4277
+ savedBodyOverflow = null;
4278
+ }
4279
+ }
4280
+ function useToolbarFullscreen({
4281
+ enabled,
4282
+ target,
4283
+ toolbarRootRef,
4284
+ editor,
4285
+ onChange
4286
+ }) {
4287
+ const [fullscreen, setFullscreen] = useState(false);
4288
+ const activeRef = useRef(null);
4289
+ const onChangeRef = useRef(onChange);
4290
+ onChangeRef.current = onChange;
4291
+ const exit = useCallback(() => {
4292
+ var _a;
4293
+ if (!activeRef.current) return;
4294
+ leaveFullscreen(activeRef.current);
4295
+ activeRef.current = null;
4296
+ setFullscreen(false);
4297
+ (_a = onChangeRef.current) == null ? void 0 : _a.call(onChangeRef, false);
4298
+ }, []);
4299
+ const toggleFullscreen = useCallback(() => {
4300
+ var _a;
4301
+ if (activeRef.current) {
4302
+ exit();
4303
+ return;
4304
+ }
4305
+ const el = resolveFullscreenElement(target, toolbarRootRef.current);
4306
+ if (!el) return;
4307
+ enterFullscreen(el);
4308
+ activeRef.current = el;
4309
+ setFullscreen(true);
4310
+ (_a = onChangeRef.current) == null ? void 0 : _a.call(onChangeRef, true);
4311
+ if (!editor.isDestroyed) editor.commands.focus();
4312
+ }, [editor, exit, target, toolbarRootRef]);
4313
+ useEffect(() => {
4314
+ if (enabled) return;
4315
+ exit();
4316
+ }, [enabled, exit]);
4317
+ useEffect(() => {
4318
+ if (!fullscreen) return;
4319
+ const onKey = (event) => {
4320
+ if (event.key !== "Escape" || isComposingKeyEvent(event)) return;
4321
+ if (document.querySelector(ESCAPE_GUARDS)) return;
4322
+ if (!editor.isDestroyed && editor.view.dom.classList.contains("tmr-format-painter")) {
4323
+ return;
4324
+ }
4325
+ event.preventDefault();
4326
+ event.stopPropagation();
4327
+ exit();
4328
+ };
4329
+ document.addEventListener("keydown", onKey, true);
4330
+ return () => document.removeEventListener("keydown", onKey, true);
4331
+ }, [fullscreen, editor, exit]);
4332
+ useEffect(() => {
4333
+ return () => {
4334
+ var _a;
4335
+ if (!activeRef.current) return;
4336
+ leaveFullscreen(activeRef.current);
4337
+ activeRef.current = null;
4338
+ (_a = onChangeRef.current) == null ? void 0 : _a.call(onChangeRef, false);
4339
+ };
4340
+ }, []);
4341
+ return { fullscreen, toggleFullscreen };
4342
+ }
4227
4343
  const MD_FILE_RE = /\.(md|markdown)$/i;
4228
4344
  const MD_ACCEPT = ".md,.markdown,text/markdown";
4229
4345
  function resolveImportMenuItems({
@@ -4292,61 +4408,61 @@ function splitTopLevelBlocks(markdown) {
4292
4408
  function stripToPlainText(markdown) {
4293
4409
  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
4410
  }
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";
4411
+ const toolbar = "_toolbar_1y8hn_2";
4412
+ const inner = "_inner_1y8hn_20";
4413
+ const btn$2 = "_btn_1y8hn_47";
4414
+ const btnActive$1 = "_btnActive_1y8hn_70";
4415
+ const txtIcon = "_txtIcon_1y8hn_86";
4416
+ const colorIcon = "_colorIcon_1y8hn_94";
4417
+ const colorIconGlyph = "_colorIconGlyph_1y8hn_102";
4418
+ const colorIconBar = "_colorIconBar_1y8hn_108";
4419
+ const scriptTrigger = "_scriptTrigger_1y8hn_115";
4420
+ const scriptTriggerGlyph = "_scriptTriggerGlyph_1y8hn_135";
4421
+ const divider$2 = "_divider_1y8hn_143";
4422
+ const styleTrigger = "_styleTrigger_1y8hn_152";
4423
+ const styleTriggerLabel = "_styleTriggerLabel_1y8hn_185";
4424
+ const styleTriggerStable = "_styleTriggerStable_1y8hn_195";
4425
+ const styleTriggerLabelStable = "_styleTriggerLabelStable_1y8hn_199";
4426
+ const styleTriggerSizer = "_styleTriggerSizer_1y8hn_204";
4427
+ const styleTriggerValue = "_styleTriggerValue_1y8hn_205";
4428
+ const styleTriggerCaret = "_styleTriggerCaret_1y8hn_220";
4429
+ const iconTrigger = "_iconTrigger_1y8hn_227";
4430
+ const styleItem = "_styleItem_1y8hn_235";
4431
+ const styleIcon = "_styleIcon_1y8hn_241";
4432
+ const scriptGlyph = "_scriptGlyph_1y8hn_251";
4433
+ const menu = "_menu_1y8hn_263";
4434
+ const menuItem = "_menuItem_1y8hn_274";
4435
+ const menuItemSelected = "_menuItemSelected_1y8hn_301";
4436
+ const listSplit = "_listSplit_1y8hn_316";
4437
+ const listSplitActive = "_listSplitActive_1y8hn_322";
4438
+ const numberingCaret = "_numberingCaret_1y8hn_334";
4439
+ const numberingCaretActive = "_numberingCaretActive_1y8hn_364";
4440
+ const numberingMenu = "_numberingMenu_1y8hn_368";
4441
+ const numberingGrid = "_numberingGrid_1y8hn_378";
4442
+ const numberingOption = "_numberingOption_1y8hn_384";
4443
+ const numberingOptionActive = "_numberingOptionActive_1y8hn_399";
4444
+ const numberingPreview = "_numberingPreview_1y8hn_404";
4445
+ const numberingPreviewRow = "_numberingPreviewRow_1y8hn_410";
4446
+ const numberingPreviewMarker = "_numberingPreviewMarker_1y8hn_425";
4447
+ const numberingPreviewLine = "_numberingPreviewLine_1y8hn_433";
4448
+ const tableInsertCaret = "_tableInsertCaret_1y8hn_439";
4449
+ const tableSizePicker = "_tableSizePicker_1y8hn_447";
4450
+ const tableSizeGrid = "_tableSizeGrid_1y8hn_457";
4451
+ const tableSizeCell = "_tableSizeCell_1y8hn_462";
4452
+ const tableSizeCellActive = "_tableSizeCellActive_1y8hn_472";
4453
+ const tableSizeLabel = "_tableSizeLabel_1y8hn_477";
4454
+ const popoverContent$1 = "_popoverContent_1y8hn_486";
4455
+ const mathLayer = "_mathLayer_1y8hn_490";
4456
+ const mathStack = "_mathStack_1y8hn_495";
4457
+ const mathStackBlock = "_mathStackBlock_1y8hn_502";
4458
+ const mathHint = "_mathHint_1y8hn_507";
4459
+ const mathHintBlock = "_mathHintBlock_1y8hn_519";
4460
+ const mathHintIcon = "_mathHintIcon_1y8hn_525";
4461
+ const mathField = "_mathField_1y8hn_556";
4462
+ const mathFieldBlock = "_mathFieldBlock_1y8hn_568";
4463
+ const mathInput = "_mathInput_1y8hn_575";
4464
+ const mathDone = "_mathDone_1y8hn_593";
4465
+ const mathDoneKbd = "_mathDoneKbd_1y8hn_618";
4350
4466
  const styles$6 = {
4351
4467
  toolbar,
4352
4468
  inner,
@@ -4404,6 +4520,263 @@ const styles$6 = {
4404
4520
  mathDone,
4405
4521
  mathDoneKbd
4406
4522
  };
4523
+ const FORMAT_MARKS = /* @__PURE__ */ new Set([
4524
+ "bold",
4525
+ "italic",
4526
+ "underline",
4527
+ "strike",
4528
+ "code",
4529
+ "highlight",
4530
+ "textStyle",
4531
+ "superscript",
4532
+ "subscript"
4533
+ ]);
4534
+ const PLAIN_BLOCK = {
4535
+ type: "paragraph",
4536
+ level: null,
4537
+ textAlign: null,
4538
+ indent: null,
4539
+ lineHeight: null
4540
+ };
4541
+ function isFormatMark(name) {
4542
+ return FORMAT_MARKS.has(name);
4543
+ }
4544
+ function isStyleBlock(node) {
4545
+ return node.type.name === "paragraph" || node.type.name === "heading";
4546
+ }
4547
+ function readBlock(node) {
4548
+ const indent = Number(node.attrs.indent);
4549
+ const lineHeight = Number(node.attrs.lineHeight);
4550
+ return {
4551
+ type: node.type.name === "heading" ? "heading" : "paragraph",
4552
+ level: node.type.name === "heading" ? Number(node.attrs.level) || 1 : null,
4553
+ textAlign: typeof node.attrs.textAlign === "string" && node.attrs.textAlign ? node.attrs.textAlign : null,
4554
+ indent: Number.isFinite(indent) && indent > 0 ? indent : null,
4555
+ lineHeight: Number.isFinite(lineHeight) && lineHeight > 0 ? lineHeight : null
4556
+ };
4557
+ }
4558
+ function sameMarkSet(a3, b3) {
4559
+ if (a3.length !== b3.length) return false;
4560
+ return a3.every((mark) => b3.some((other) => mark.eq(other)));
4561
+ }
4562
+ function anchorTextblock(doc, from, to) {
4563
+ const $from = doc.resolve(from);
4564
+ if ($from.parent.isTextblock && !$from.parent.type.spec.code) {
4565
+ return { node: $from.parent, pos: $from.before() };
4566
+ }
4567
+ if (from === to) return null;
4568
+ let found = null;
4569
+ doc.nodesBetween(from, to, (node, pos) => {
4570
+ if (found) return false;
4571
+ if (node.isTextblock && !node.type.spec.code) {
4572
+ found = { node, pos };
4573
+ return false;
4574
+ }
4575
+ });
4576
+ return found;
4577
+ }
4578
+ function blockIsCovered(node, pos, from, to) {
4579
+ const contentFrom = pos + 1;
4580
+ const contentTo = pos + node.nodeSize - 1;
4581
+ return from <= contentFrom && to >= contentTo;
4582
+ }
4583
+ function sourceMarks(doc, from, to, stored) {
4584
+ var _a;
4585
+ if (from === to) {
4586
+ if (stored) return stored;
4587
+ return doc.resolve(from).marks();
4588
+ }
4589
+ const $from = doc.resolve(from);
4590
+ if ((_a = $from.nodeAfter) == null ? void 0 : _a.isText) return $from.nodeAfter.marks;
4591
+ return $from.marks();
4592
+ }
4593
+ function captureFormat(editor) {
4594
+ if (!editor.isEditable) return null;
4595
+ const { selection, storedMarks, doc } = editor.state;
4596
+ const anchor = anchorTextblock(doc, selection.from, selection.to);
4597
+ if (!anchor) return null;
4598
+ const marks = sourceMarks(doc, selection.from, selection.to, storedMarks).filter((mark) => isFormatMark(mark.type.name)).map((mark) => ({ type: mark.type.name, attrs: { ...mark.attrs } }));
4599
+ const block = isStyleBlock(anchor.node) && (selection.empty || blockIsCovered(anchor.node, anchor.pos, selection.from, selection.to)) ? readBlock(anchor.node) : null;
4600
+ return { marks, block };
4601
+ }
4602
+ function canPaint(doc, from, to) {
4603
+ return anchorTextblock(doc, from, to) != null;
4604
+ }
4605
+ function removeFormatMarks(tr, from, to) {
4606
+ if (from >= to) return;
4607
+ for (const name of FORMAT_MARKS) {
4608
+ const type = tr.doc.type.schema.marks[name];
4609
+ if (type) tr.removeMark(from, to, type);
4610
+ }
4611
+ }
4612
+ function addFormatMarks(tr, from, to, marks) {
4613
+ if (from >= to) return;
4614
+ for (const mark of marks) {
4615
+ const type = tr.doc.type.schema.marks[mark.type];
4616
+ if (!type || !isFormatMark(mark.type)) continue;
4617
+ tr.addMark(from, to, type.create(mark.attrs));
4618
+ }
4619
+ }
4620
+ function marksForNextInput(tr, stateStored) {
4621
+ if (tr.storedMarksSet) return tr.storedMarks ?? [];
4622
+ if (stateStored) return stateStored;
4623
+ return tr.selection.$from.marks();
4624
+ }
4625
+ function setFormatStoredMarks(tr, marks, stateStored) {
4626
+ const current = marksForNextInput(tr, stateStored);
4627
+ const kept = current.filter((mark) => !isFormatMark(mark.type.name));
4628
+ const next = [
4629
+ ...kept,
4630
+ ...marks.flatMap((mark) => {
4631
+ const type = tr.doc.type.schema.marks[mark.type];
4632
+ return type && isFormatMark(mark.type) ? [type.create(mark.attrs)] : [];
4633
+ })
4634
+ ];
4635
+ if (sameMarkSet(current, next)) return;
4636
+ tr.setStoredMarks(next);
4637
+ }
4638
+ function stripFormatStoredMarks(tr, stateStored) {
4639
+ const current = marksForNextInput(tr, stateStored);
4640
+ const next = current.filter((mark) => !isFormatMark(mark.type.name));
4641
+ if (sameMarkSet(current, next)) return;
4642
+ tr.setStoredMarks(next);
4643
+ }
4644
+ function applyBlockAt(tr, pos, block) {
4645
+ var _a, _b, _c;
4646
+ const node = tr.doc.nodeAt(pos);
4647
+ if (!node || !isStyleBlock(node)) return;
4648
+ const $pos = tr.doc.resolve(pos);
4649
+ let typeName = node.type.name;
4650
+ if (block.type === "heading") {
4651
+ const heading = tr.doc.type.schema.nodes.heading;
4652
+ if (heading && $pos.parent.canReplaceWith($pos.index(), $pos.index() + 1, heading)) {
4653
+ typeName = "heading";
4654
+ }
4655
+ } else if (node.type.name === "heading") {
4656
+ const paragraph = tr.doc.type.schema.nodes.paragraph;
4657
+ if (paragraph && $pos.parent.canReplaceWith($pos.index(), $pos.index() + 1, paragraph)) {
4658
+ typeName = "paragraph";
4659
+ }
4660
+ }
4661
+ const type = tr.doc.type.schema.nodes[typeName];
4662
+ if (!type) return;
4663
+ const indent = Number(node.attrs.indent);
4664
+ const lineHeight = Number(node.attrs.lineHeight);
4665
+ const sameType = node.type === type;
4666
+ const sameLevel = typeName !== "heading" || Number(node.attrs.level) === (block.level ?? 1);
4667
+ const sameAlign = (node.attrs.textAlign || null) === block.textAlign;
4668
+ const sameIndent = (Number.isFinite(indent) && indent > 0 ? indent : null) === block.indent;
4669
+ const sameLine = (Number.isFinite(lineHeight) && lineHeight > 0 ? lineHeight : null) === block.lineHeight;
4670
+ if (sameType && sameLevel && sameAlign && sameIndent && sameLine) return;
4671
+ const attrs = { ...node.attrs };
4672
+ if (typeName === "heading") attrs.level = block.level ?? 1;
4673
+ else delete attrs.level;
4674
+ if ((_a = type.spec.attrs) == null ? void 0 : _a.textAlign) attrs.textAlign = block.textAlign;
4675
+ if ((_b = type.spec.attrs) == null ? void 0 : _b.indent) attrs.indent = block.indent;
4676
+ if ((_c = type.spec.attrs) == null ? void 0 : _c.lineHeight) attrs.lineHeight = block.lineHeight;
4677
+ tr.setNodeMarkup(pos, type, attrs);
4678
+ }
4679
+ function coveredStyleBlockPositions(doc, from, to) {
4680
+ const positions = [];
4681
+ doc.nodesBetween(from, to, (node, pos) => {
4682
+ if (!isStyleBlock(node)) return;
4683
+ if (blockIsCovered(node, pos, from, to)) positions.push(pos);
4684
+ });
4685
+ return positions;
4686
+ }
4687
+ function mutateFormatting(tr, mode, format, stateStored) {
4688
+ const docBefore = tr.doc;
4689
+ const ranges = tr.selection.ranges.map((range) => ({
4690
+ from: range.$from.pos,
4691
+ to: range.$to.pos
4692
+ }));
4693
+ const caretOnly = ranges.every((range) => range.from === range.to);
4694
+ if (caretOnly) {
4695
+ for (const range of ranges) {
4696
+ const $pos = tr.doc.resolve(range.from);
4697
+ const parent = $pos.parent;
4698
+ if (!parent.isTextblock || parent.type.spec.code) continue;
4699
+ if (mode === "clear") {
4700
+ removeFormatMarks(tr, $pos.start(), $pos.end());
4701
+ if (isStyleBlock(parent)) applyBlockAt(tr, $pos.before(), PLAIN_BLOCK);
4702
+ } else if ((format == null ? void 0 : format.block) && isStyleBlock(parent)) {
4703
+ applyBlockAt(tr, $pos.before(), format.block);
4704
+ }
4705
+ }
4706
+ if (mode === "clear") stripFormatStoredMarks(tr, stateStored);
4707
+ else if (format) setFormatStoredMarks(tr, format.marks, stateStored);
4708
+ } else {
4709
+ for (const range of ranges) {
4710
+ removeFormatMarks(tr, range.from, range.to);
4711
+ if (mode === "paint" && format) addFormatMarks(tr, range.from, range.to, format.marks);
4712
+ }
4713
+ const positions = /* @__PURE__ */ new Set();
4714
+ for (const range of ranges) {
4715
+ for (const pos of coveredStyleBlockPositions(tr.doc, range.from, range.to)) {
4716
+ positions.add(pos);
4717
+ }
4718
+ }
4719
+ const ordered = [...positions].sort((a3, b3) => b3 - a3);
4720
+ for (const pos of ordered) {
4721
+ if (mode === "clear") applyBlockAt(tr, pos, PLAIN_BLOCK);
4722
+ else if (format == null ? void 0 : format.block) applyBlockAt(tr, pos, format.block);
4723
+ }
4724
+ if (mode === "clear") stripFormatStoredMarks(tr, stateStored);
4725
+ else if (format) setFormatStoredMarks(tr, format.marks, stateStored);
4726
+ }
4727
+ const docChanged = !tr.doc.eq(docBefore);
4728
+ const storedChanged = tr.storedMarksSet && !sameMarkSet(tr.storedMarks ?? [], stateStored ?? []);
4729
+ return docChanged || storedChanged;
4730
+ }
4731
+ function runFormatCommand(editor, mutate) {
4732
+ return editor.chain().focus().command(({ tr }) => mutate(tr)).run();
4733
+ }
4734
+ function pinCursorMarks(editor, desired) {
4735
+ if (!editor.state.selection.empty) return;
4736
+ const current = editor.state.storedMarks ?? editor.state.selection.$from.marks();
4737
+ if (sameMarkSet(current, desired)) return;
4738
+ editor.view.dispatch(
4739
+ editor.state.tr.setStoredMarks(desired).setMeta("addToHistory", false)
4740
+ );
4741
+ }
4742
+ function storedMarksFor(editor, captured) {
4743
+ const current = editor.state.storedMarks ?? editor.state.selection.$from.marks();
4744
+ const kept = current.filter((mark) => !isFormatMark(mark.type.name));
4745
+ if (!captured) return kept;
4746
+ return [
4747
+ ...kept,
4748
+ ...captured.flatMap((mark) => {
4749
+ const type = editor.schema.marks[mark.type];
4750
+ return type && isFormatMark(mark.type) ? [type.create(mark.attrs)] : [];
4751
+ })
4752
+ ];
4753
+ }
4754
+ function clearFormatting(editor) {
4755
+ if (!editor.isEditable) return false;
4756
+ const { selection, doc } = editor.state;
4757
+ if (!canPaint(doc, selection.from, selection.to)) return false;
4758
+ const stateStored = editor.state.storedMarks;
4759
+ const ok = runFormatCommand(
4760
+ editor,
4761
+ (tr) => mutateFormatting(tr, "clear", null, stateStored)
4762
+ );
4763
+ if (editor.state.selection.empty) pinCursorMarks(editor, storedMarksFor(editor, null));
4764
+ return ok;
4765
+ }
4766
+ function applyCapturedFormat(editor, format) {
4767
+ if (!editor.isEditable) return false;
4768
+ const { selection, doc } = editor.state;
4769
+ if (!canPaint(doc, selection.from, selection.to)) return false;
4770
+ const stateStored = editor.state.storedMarks;
4771
+ runFormatCommand(
4772
+ editor,
4773
+ (tr) => mutateFormatting(tr, "paint", format, stateStored)
4774
+ );
4775
+ if (editor.state.selection.empty) {
4776
+ pinCursorMarks(editor, storedMarksFor(editor, format.marks));
4777
+ }
4778
+ return true;
4779
+ }
4407
4780
  const palette = "_palette_x5lrq_2";
4408
4781
  const noneRow = "_noneRow_x5lrq_11";
4409
4782
  const noneIcon = "_noneIcon_x5lrq_23";
@@ -6213,6 +6586,7 @@ function MenuPopover({
6213
6586
  function MenuItem({
6214
6587
  selected,
6215
6588
  disabled,
6589
+ label,
6216
6590
  onSelect,
6217
6591
  children
6218
6592
  }) {
@@ -6222,6 +6596,8 @@ function MenuItem({
6222
6596
  {
6223
6597
  type: "button",
6224
6598
  disabled,
6599
+ "aria-label": label,
6600
+ "aria-pressed": selected || void 0,
6225
6601
  className: `${styles$6.menuItem} ${selected ? styles$6.menuItemSelected : ""}`,
6226
6602
  onMouseDown: (e2) => e2.preventDefault(),
6227
6603
  onClick: () => {
@@ -6415,10 +6791,21 @@ function EditorToolbar({
6415
6791
  locale = "en",
6416
6792
  onSearch,
6417
6793
  searchActive = false,
6794
+ showFullscreen = true,
6795
+ fullscreenTarget,
6796
+ onFullscreenChange,
6418
6797
  extraToolbarItems,
6419
6798
  className
6420
6799
  }) {
6421
6800
  const t = getLocaleBundle(locale).toolbar;
6801
+ const toolbarRootRef = useRef(null);
6802
+ const { fullscreen, toggleFullscreen } = useToolbarFullscreen({
6803
+ enabled: showFullscreen,
6804
+ target: fullscreenTarget,
6805
+ toolbarRootRef,
6806
+ editor,
6807
+ onChange: onFullscreenChange
6808
+ });
6422
6809
  const state = useEditorState({
6423
6810
  editor,
6424
6811
  selector: ({ editor: e2 }) => ({
@@ -6462,6 +6849,63 @@ function EditorToolbar({
6462
6849
  editor.off("blur", onBlur);
6463
6850
  };
6464
6851
  }, [editor]);
6852
+ const [painter, setPainter] = useState("off");
6853
+ const [paintSample, setPaintSample] = useState(null);
6854
+ const painterClickAt = useRef(0);
6855
+ const painterEditor = useRef(editor);
6856
+ const disarmPainter = () => {
6857
+ painterClickAt.current = 0;
6858
+ setPainter("off");
6859
+ setPaintSample(null);
6860
+ };
6861
+ useEffect(() => {
6862
+ if (painterEditor.current === editor) return;
6863
+ painterEditor.current = editor;
6864
+ disarmPainter();
6865
+ }, [editor]);
6866
+ useEffect(() => {
6867
+ if (editor.isDestroyed) return;
6868
+ const dom = editor.view.dom;
6869
+ dom.classList.toggle("tmr-format-painter", painter !== "off");
6870
+ return () => {
6871
+ if (!editor.isDestroyed) dom.classList.remove("tmr-format-painter");
6872
+ };
6873
+ }, [editor, painter]);
6874
+ useEffect(() => {
6875
+ if (painter === "off" || !paintSample || editor.isDestroyed) return;
6876
+ const dom = editor.view.dom;
6877
+ const apply2 = () => {
6878
+ const handled = applyCapturedFormat(editor, paintSample);
6879
+ if (handled && painter === "once") disarmPainter();
6880
+ };
6881
+ const onKeyDown = (event) => {
6882
+ if (event.key !== "Escape") return;
6883
+ disarmPainter();
6884
+ };
6885
+ dom.addEventListener("mouseup", apply2);
6886
+ document.addEventListener("keydown", onKeyDown);
6887
+ return () => {
6888
+ dom.removeEventListener("mouseup", apply2);
6889
+ document.removeEventListener("keydown", onKeyDown);
6890
+ };
6891
+ }, [editor, painter, paintSample]);
6892
+ const onFormatPainterClick = () => {
6893
+ const now = Date.now();
6894
+ const quick = now - painterClickAt.current < 300;
6895
+ painterClickAt.current = now;
6896
+ if (painter !== "off") {
6897
+ if (quick && painter === "once") {
6898
+ setPainter("locked");
6899
+ return;
6900
+ }
6901
+ disarmPainter();
6902
+ return;
6903
+ }
6904
+ const captured = captureFormat(editor);
6905
+ if (!captured) return;
6906
+ setPaintSample(captured);
6907
+ setPainter(quick ? "locked" : "once");
6908
+ };
6465
6909
  const fileInputRef = useRef(null);
6466
6910
  const chain = () => editor.chain().focus();
6467
6911
  const imageUploadEnabled = hasImageUpload(editor);
@@ -6648,6 +7092,8 @@ function EditorToolbar({
6648
7092
  /* @__PURE__ */ jsx(
6649
7093
  "div",
6650
7094
  {
7095
+ ref: toolbarRootRef,
7096
+ "data-tmr-toolbar": "",
6651
7097
  className: className ? `${styles$6.toolbar} ${className}` : styles$6.toolbar,
6652
7098
  children: /* @__PURE__ */ jsxs("div", { className: styles$6.inner, children: [
6653
7099
  /* @__PURE__ */ jsx(
@@ -6668,6 +7114,23 @@ function EditorToolbar({
6668
7114
  children: /* @__PURE__ */ jsx(RedoIcon, {})
6669
7115
  }
6670
7116
  ),
7117
+ /* @__PURE__ */ jsx(
7118
+ ToolbarButton,
7119
+ {
7120
+ title: t.formatPainter,
7121
+ active: painter !== "off",
7122
+ onClick: onFormatPainterClick,
7123
+ children: /* @__PURE__ */ jsx(PaintbrushIcon, {})
7124
+ }
7125
+ ),
7126
+ /* @__PURE__ */ jsx(
7127
+ ToolbarButton,
7128
+ {
7129
+ title: t.clearFormatting,
7130
+ onClick: () => clearFormatting(editor),
7131
+ children: /* @__PURE__ */ jsx(EraserIcon, {})
7132
+ }
7133
+ ),
6671
7134
  /* @__PURE__ */ jsx(Divider, {}),
6672
7135
  /* @__PURE__ */ jsxs(
6673
7136
  MenuPopover,
@@ -7199,6 +7662,18 @@ function EditorToolbar({
7199
7662
  onInsert: (rows, cols) => chain().insertTable({ rows, cols, withHeaderRow: true }).run()
7200
7663
  }
7201
7664
  ),
7665
+ showFullscreen ? /* @__PURE__ */ jsx(
7666
+ MenuItem,
7667
+ {
7668
+ selected: fullscreen,
7669
+ label: fullscreen ? t.exitFullscreen : t.fullscreen,
7670
+ onSelect: toggleFullscreen,
7671
+ children: /* @__PURE__ */ jsxs("span", { className: styles$6.styleItem, children: [
7672
+ /* @__PURE__ */ jsx("span", { className: styles$6.styleIcon, children: fullscreen ? /* @__PURE__ */ jsx(MinimizeIcon, { size: 14 }) : /* @__PURE__ */ jsx(ExpandIcon, { size: 14 }) }),
7673
+ fullscreen ? t.exitFullscreen : t.fullscreen
7674
+ ] })
7675
+ }
7676
+ ) : null,
7202
7677
  extraToolbarItems == null ? void 0 : extraToolbarItems.map((item2) => /* @__PURE__ */ jsx(
7203
7678
  MenuItem,
7204
7679
  {
@@ -7429,8 +7904,8 @@ export {
7429
7904
  C as ChartMount,
7430
7905
  CheckIcon,
7431
7906
  ChevronDownIcon,
7432
- a9 as ChevronLeftIcon,
7433
- aa as ChevronRightIcon,
7907
+ ab as ChevronLeftIcon,
7908
+ ac as ChevronRightIcon,
7434
7909
  ChevronUpIcon,
7435
7910
  ChevronsUpDownIcon,
7436
7911
  a as CitationInteractive,
@@ -7454,12 +7929,12 @@ export {
7454
7929
  FIND_DEBOUNCE_MS,
7455
7930
  default2 as FindAndReplace,
7456
7931
  FindReplaceBar,
7457
- ab as FitIcon,
7932
+ ad as FitIcon,
7458
7933
  GripIcon,
7459
7934
  ImageAlignTools,
7460
7935
  ImageIcon,
7461
7936
  ImageUploadNode,
7462
- ac as ImportIcon,
7937
+ ae as ImportIcon,
7463
7938
  ImportPlaceholder,
7464
7939
  IndentDecreaseIcon,
7465
7940
  IndentIncreaseIcon,
@@ -7471,13 +7946,15 @@ export {
7471
7946
  ListChecksIcon,
7472
7947
  ListOrderedIcon,
7473
7948
  ListUnorderedIcon,
7474
- ad as LockIcon,
7949
+ af as LockIcon,
7475
7950
  MarkdownFileDrop,
7476
7951
  MarkdownPaste,
7477
7952
  MarkdownPreview,
7478
7953
  MarkdownWysiwygEditor,
7479
- ae as MenuIcon,
7954
+ ag as MenuIcon,
7955
+ MinimizeIcon,
7480
7956
  PENDING_ANCHOR_CLASS,
7957
+ PaintbrushIcon,
7481
7958
  P as ParagraphStyles,
7482
7959
  RedoIcon,
7483
7960
  ReplaceAllIcon,
@@ -7486,7 +7963,7 @@ export {
7486
7963
  b as ReportContentInteractive,
7487
7964
  c as ReportContentWithCharts,
7488
7965
  RotateCcwIcon,
7489
- af as RotateCwIcon,
7966
+ ah as RotateCwIcon,
7490
7967
  RowAfterIcon,
7491
7968
  RowBeforeIcon,
7492
7969
  RowDeleteIcon,
@@ -7499,8 +7976,8 @@ export {
7499
7976
  UnderlineIcon,
7500
7977
  UndoIcon,
7501
7978
  XIcon,
7502
- ag as ZoomInIcon,
7503
- ah as ZoomOutIcon,
7979
+ ai as ZoomInIcon,
7980
+ aj as ZoomOutIcon,
7504
7981
  a2 as applyCitationSources,
7505
7982
  applyCommentAnchorsToEditor,
7506
7983
  applyLink,