oasis-editor 0.0.12 → 0.0.14

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.
Files changed (31) hide show
  1. package/dist/{OasisEditorApp-DsSNl4Fj.js → OasisEditorApp-BtRbOf8l.js} +249 -19
  2. package/dist/app/controllers/useEditorLayout.d.ts +2 -1
  3. package/dist/assets/{importDocxWorker-CtcRQ7NG.js → importDocxWorker-cjz15bhS.js} +1 -1
  4. package/dist/core/commands/builtinCommands.d.ts +1 -1
  5. package/dist/core/commands/publicCommandTypes.d.ts +5 -0
  6. package/dist/core/editorState.d.ts +1 -0
  7. package/dist/core/model/index.d.ts +1 -0
  8. package/dist/core/model/types/document.d.ts +7 -0
  9. package/dist/core/model/types/documentComments.d.ts +50 -0
  10. package/dist/export/docx/commentsXml.d.ts +34 -0
  11. package/dist/export/docx/docxTypes.d.ts +7 -0
  12. package/dist/i18n/locales/en.d.ts +4 -0
  13. package/dist/i18n/locales/pt-BR.d.ts +4 -0
  14. package/dist/import/docx/comments.d.ts +12 -0
  15. package/dist/import/docx/commentsXml.d.ts +14 -0
  16. package/dist/import/docx/runs/types.d.ts +10 -0
  17. package/dist/import/docx/runs.d.ts +5 -1
  18. package/dist/{index-BUOuw27s.js → index-4CDpujGG.js} +541 -117
  19. package/dist/index.d.ts +1 -1
  20. package/dist/oasis-editor.css +1 -1
  21. package/dist/oasis-editor.js +1 -1
  22. package/dist/oasis-editor.umd.cjs +4 -4
  23. package/dist/plugins/internal/createEssentialsPlugin.d.ts +1 -0
  24. package/dist/ui/OasisEditorEditor.d.ts +2 -1
  25. package/dist/ui/app/buildEditorViewProps.d.ts +2 -1
  26. package/dist/ui/canvas/CanvasCommentGeometry.d.ts +13 -0
  27. package/dist/ui/components/CommentHighlightOverlay.d.ts +16 -0
  28. package/dist/ui/components/Toolbar/presets/builtinToolbarIds.d.ts +1 -0
  29. package/dist/ui/components/Toolbar/schema/items.d.ts +2 -0
  30. package/dist/ui/editorUiTypes.d.ts +8 -0
  31. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
- import { n as normalizeSelection, g as getParagraphs, c as createEditorParagraphFromRuns, a as getParagraphLength, b as createEditorRun, d as getDocumentSections, e as createEditorStyledRun, f as getParagraphText, h as getActiveZone, i as getActiveSectionIndex, p as positionToParagraphOffset, j as paragraphOffsetToPosition, k as clampPosition, l as findParagraphIndex, m as createCollapsedSelection, o as isSelectionCollapsed, q as createEditorParagraph, r as getBlockParagraphs, s as findParagraphTableLocation, t as buildTableCellLayout, u as createEditorTableCell, v as createEditorTable, w as createEditorTableRow, x as underlineStyleToCssDecorationStyle, y as resolveImageSrc, z as createEditorFootnote, A as createFootnoteReferenceRun, B as renumberFootnotes, C as iterateFootnoteReferenceRuns, D as getFootnoteDisplayMarker, E as createSignal, F as createEffect, G as onCleanup, H as buildCanvasLayoutSnapshot, I as on, J as onMount, K as debounce, L as unwrap, M as getDocumentParagraphs, N as getDocumentSectionsCanonical, O as createEditorDocument, P as getPageContentWidth, Q as getDocumentPageSettings, R as getTableCellContentWidthForParagraph, S as resolveResizedDimensions, T as resolveTextBoxRenderHeight, U as resolveEffectiveParagraphStyle, V as resolveEffectiveTextStyleForParagraph, W as iterateEndnoteReferenceRuns, X as JSZip, Y as imageContentTypeDefaults, Z as imageExtensionFromMime, _ as pxToPt$1, $ as buildSegmentTable, a0 as buildCanvasTableLayout, a1 as resolveFloatingObjectRect, a2 as getTextBoxFloatingGeometry, a3 as getPresetPathSegments, a4 as projectBlocksLayout, a5 as textStyleToFontSizePt, a6 as PX_PER_POINT, a7 as DEFAULT_FONT_SIZE_PX, a8 as isDoubleUnderlineStyle, a9 as isWavyUnderlineStyle, aa as underlineStyleLineWidthPx, ab as underlineStyleDashArray, ac as getListLabelInset, ad as getParagraphBorderInsets, ae as normalizeFamily, af as ROBOTO_FONT_FILES, ag as loadFontAsset, ah as OFFICE_COMPAT_FONT_FAMILIES, ai as buildSfnt, aj as defaultFontDecoderRegistry, ak as SfntFontProgram, al as collectPdfFontFamilies, am as projectDocumentLayout, an as getPageHeaderZoneTop, ao as getPageBodyTop, ap as findFootnoteReference, aq as FOOTNOTE_MARKER_GUTTER_PX, ar as resolveImporterForFile, as as createEditorStateFromDocument, at as getDocumentParagraphsCanonical, au as getToolbarStyleState, av as STANDARD_FONT_SIZES_PT, aw as fontSizePxToPt, ax as probeLocalFontFamilies, ay as createInitialEditorState, az as parseFontSizePtToPx, aA as formatFontSizePt, aB as listKindForTag, aC as isParagraphTag, aD as collectInlineRuns, aE as parseParagraphStyle, aF as t, aG as preciseFontModeVersion, aH as isPreciseFontModeEnabled, aI as togglePreciseFontMode, aJ as nextFontSizePt, aK as previousFontSizePt, aL as fontSizePtToPx, aM as createDefaultToolbarPreset, aN as defaultMenuItems, aO as MenuRegistry, aP as createToolbarRegistry, aQ as Editor, aR as resolveCommandRef, aS as commandRefName, aT as InlineShell, aU as BalloonShell, aV as DocumentShell, aW as createMemo, aX as getCaretRectFromSnapshot, aY as getParagraphRectFromSnapshot, aZ as createComponent, a_ as CaretOverlay, a$ as Show, b0 as createRenderEffect, b1 as style, b2 as setAttribute, b3 as setStyleProperty, b4 as memo, b5 as template, b6 as insert, b7 as use, b8 as addEventListener, b9 as Dialog, ba as delegateEvents, bb as className, bc as For, bd as UNDERLINE_STYLE_OPTIONS, be as Tabs, bf as measureParagraphMinContentWidthPx, bg as getEditableBlocksForZone, bh as findParagraphLocation, bi as createSectionBoundaryParagraph, bj as normalizePageSettings, bk as DEFAULT_EDITOR_PAGE_SETTINGS, bl as markStart, bm as markEnd, bn as getParagraphEntries, bo as getParagraphById, bp as PluginUiHost, bq as OasisEditorEditor, br as perfTimer, bs as OasisBrandMark, bt as setPreciseFontPreference, bu as setWelcomeSeen, bv as enablePreciseFontMode, bw as createOasisEditorClient, bx as setLocale, by as startLongTaskObserver, bz as installGlobalReport, bA as applyStoredPreciseFontPreference, bB as getWelcomeSeen, bC as isLocalFontAccessSupported, bD as EDITOR_SCROLL_PADDING_PX, bE as Toolbar, bF as OasisEditorLoading, bG as createEditorLogger, bH as getCachedCanvasImage, bI as registerDomStatsSurface } from "./index-BUOuw27s.js";
4
+ import { n as normalizeSelection, g as getParagraphs, c as createEditorParagraphFromRuns, a as getParagraphLength, b as createEditorRun, d as getDocumentSections, e as createEditorStyledRun, f as getParagraphText, h as getActiveZone, i as getActiveSectionIndex, p as positionToParagraphOffset, j as paragraphOffsetToPosition, k as clampPosition, l as findParagraphIndex, m as createCollapsedSelection, o as isSelectionCollapsed, q as createEditorParagraph, r as getBlockParagraphs, s as findParagraphTableLocation, t as buildTableCellLayout, u as createEditorTableCell, v as createEditorTable, w as createEditorTableRow, x as underlineStyleToCssDecorationStyle, y as resolveImageSrc, z as createEditorFootnote, A as createFootnoteReferenceRun, B as renumberFootnotes, C as iterateFootnoteReferenceRuns, D as getFootnoteDisplayMarker, E as createSignal, F as createEffect, G as onCleanup, H as buildCanvasLayoutSnapshot, I as on, J as onMount, K as debounce, L as unwrap, M as getDocumentParagraphs, N as getDocumentSectionsCanonical, O as createEditorDocument, P as getPageContentWidth, Q as getDocumentPageSettings, R as getTableCellContentWidthForParagraph, S as resolveResizedDimensions, T as resolveTextBoxRenderHeight, U as resolveEffectiveParagraphStyle, V as resolveEffectiveTextStyleForParagraph, W as iterateEndnoteReferenceRuns, X as JSZip, Y as imageContentTypeDefaults, Z as imageExtensionFromMime, _ as pxToPt$1, $ as buildSegmentTable, a0 as buildCanvasTableLayout, a1 as resolveFloatingObjectRect, a2 as getTextBoxFloatingGeometry, a3 as getPresetPathSegments, a4 as projectBlocksLayout, a5 as textStyleToFontSizePt, a6 as PX_PER_POINT, a7 as DEFAULT_FONT_SIZE_PX, a8 as isDoubleUnderlineStyle, a9 as isWavyUnderlineStyle, aa as underlineStyleLineWidthPx, ab as underlineStyleDashArray, ac as getListLabelInset, ad as getParagraphBorderInsets, ae as normalizeFamily, af as ROBOTO_FONT_FILES, ag as loadFontAsset, ah as OFFICE_COMPAT_FONT_FAMILIES, ai as buildSfnt, aj as defaultFontDecoderRegistry, ak as SfntFontProgram, al as collectPdfFontFamilies, am as projectDocumentLayout, an as getPageHeaderZoneTop, ao as getPageBodyTop, ap as findFootnoteReference, aq as FOOTNOTE_MARKER_GUTTER_PX, ar as resolveImporterForFile, as as createEditorStateFromDocument, at as getDocumentParagraphsCanonical, au as getToolbarStyleState, av as STANDARD_FONT_SIZES_PT, aw as fontSizePxToPt, ax as probeLocalFontFamilies, ay as createInitialEditorState, az as parseFontSizePtToPx, aA as formatFontSizePt, aB as listKindForTag, aC as isParagraphTag, aD as collectInlineRuns, aE as parseParagraphStyle, aF as t, aG as preciseFontModeVersion, aH as isPreciseFontModeEnabled, aI as togglePreciseFontMode, aJ as nextFontSizePt, aK as previousFontSizePt, aL as fontSizePtToPx, aM as createDefaultToolbarPreset, aN as defaultMenuItems, aO as MenuRegistry, aP as createToolbarRegistry, aQ as Editor, aR as resolveCommandRef, aS as commandRefName, aT as InlineShell, aU as BalloonShell, aV as DocumentShell, aW as createMemo, aX as getCaretRectFromSnapshot, aY as getParagraphRectFromSnapshot, aZ as createComponent, a_ as CaretOverlay, a$ as Show, b0 as createRenderEffect, b1 as style, b2 as setAttribute, b3 as setStyleProperty, b4 as memo, b5 as template, b6 as insert, b7 as use, b8 as addEventListener, b9 as Dialog, ba as delegateEvents, bb as className, bc as For, bd as UNDERLINE_STYLE_OPTIONS, be as Tabs, bf as measureParagraphMinContentWidthPx, bg as getEditableBlocksForZone, bh as findParagraphLocation, bi as createSectionBoundaryParagraph, bj as normalizePageSettings, bk as DEFAULT_EDITOR_PAGE_SETTINGS, bl as markStart, bm as markEnd, bn as getParagraphEntries, bo as getParagraphById, bp as PluginUiHost, bq as OasisEditorEditor, br as perfTimer, bs as OasisBrandMark, bt as setPreciseFontPreference, bu as setWelcomeSeen, bv as enablePreciseFontMode, bw as createOasisEditorClient, bx as setLocale, by as startLongTaskObserver, bz as installGlobalReport, bA as applyStoredPreciseFontPreference, bB as getWelcomeSeen, bC as isLocalFontAccessSupported, bD as EDITOR_SCROLL_PADDING_PX, bE as Toolbar, bF as OasisEditorLoading, bG as createEditorLogger, bH as getCachedCanvasImage, bI as registerDomStatsSurface } from "./index-4CDpujGG.js";
5
5
  function getSelectedObjectRun(state, predicate) {
6
6
  const normalized = normalizeSelection(state);
7
7
  if (normalized.isCollapsed || normalized.startIndex !== normalized.endIndex || normalized.endParagraphOffset - normalized.startParagraphOffset !== 1) {
@@ -5392,6 +5392,63 @@ function computeCanvasSelectionGeometry(snapshot, state) {
5392
5392
  selectedTextBoxBox
5393
5393
  };
5394
5394
  }
5395
+ function computeCommentHighlights(snapshot, state) {
5396
+ const registry = state.document.comments;
5397
+ if (!registry || registry.order.length === 0) {
5398
+ return [];
5399
+ }
5400
+ const surfaceRect = snapshot.surfaceRect;
5401
+ const paragraphIndexById = new Map(
5402
+ getParagraphs(state).map(
5403
+ (paragraph, index) => [paragraph.id, index]
5404
+ )
5405
+ );
5406
+ const boxes = [];
5407
+ for (const id of registry.order) {
5408
+ const comment = registry.items[id];
5409
+ if (!(comment == null ? void 0 : comment.start) || !(comment == null ? void 0 : comment.end)) {
5410
+ continue;
5411
+ }
5412
+ const startIndex = paragraphIndexById.get(comment.start.paragraphId);
5413
+ const endIndex = paragraphIndexById.get(comment.end.paragraphId);
5414
+ if (startIndex === void 0 || endIndex === void 0) {
5415
+ continue;
5416
+ }
5417
+ for (const segment of snapshot.paragraphs) {
5418
+ const segmentIndex = paragraphIndexById.get(segment.paragraphId);
5419
+ if (segmentIndex === void 0 || segmentIndex < startIndex || segmentIndex > endIndex) {
5420
+ continue;
5421
+ }
5422
+ const rangeStart = segmentIndex === startIndex ? comment.start.offset : 0;
5423
+ const rangeEnd = segmentIndex === endIndex ? comment.end.offset : Number.POSITIVE_INFINITY;
5424
+ const segStart = Math.max(rangeStart, segment.startOffset);
5425
+ const segEnd = Math.min(rangeEnd, segment.endOffset);
5426
+ if (segStart >= segEnd) {
5427
+ continue;
5428
+ }
5429
+ for (const line of segment.lines) {
5430
+ const lineStart = Math.max(segStart, line.startOffset);
5431
+ const lineEnd = Math.min(segEnd, line.endOffset);
5432
+ if (lineStart >= lineEnd) {
5433
+ continue;
5434
+ }
5435
+ const startSlot = line.slots.find((slot) => slot.offset === lineStart);
5436
+ const endSlot = line.slots.find((slot) => slot.offset === lineEnd) ?? line.slots[line.slots.length - 1];
5437
+ if (!startSlot || !endSlot) {
5438
+ continue;
5439
+ }
5440
+ boxes.push({
5441
+ commentId: id,
5442
+ left: startSlot.left - surfaceRect.left,
5443
+ top: line.top - surfaceRect.top,
5444
+ width: Math.max(1, endSlot.left - startSlot.left),
5445
+ height: line.height
5446
+ });
5447
+ }
5448
+ }
5449
+ }
5450
+ return boxes;
5451
+ }
5395
5452
  function scheduleFrame(callback) {
5396
5453
  if (typeof window !== "undefined" && typeof window.requestAnimationFrame === "function") {
5397
5454
  return window.requestAnimationFrame(() => callback());
@@ -5417,6 +5474,7 @@ function useEditorLayout(props) {
5417
5474
  height: 28
5418
5475
  });
5419
5476
  const [selectionBoxes, setSelectionBoxes] = createSignal([]);
5477
+ const [commentHighlights, setCommentHighlights] = createSignal([]);
5420
5478
  const [selectedImageBox, setSelectedImageBox] = createSignal(null);
5421
5479
  const [selectedTextBoxBox, setSelectedTextBoxBox] = createSignal(null);
5422
5480
  const [caretBox, setCaretBox] = createSignal({
@@ -5433,6 +5491,7 @@ function useEditorLayout(props) {
5433
5491
  const surface = props.surfaceRef();
5434
5492
  if (!surface) {
5435
5493
  setSelectionBoxes([]);
5494
+ setCommentHighlights([]);
5436
5495
  setSelectedImageBox(null);
5437
5496
  setSelectedTextBoxBox(null);
5438
5497
  setCaretBox((current) => ({ ...current, visible: false }));
@@ -5446,6 +5505,7 @@ function useEditorLayout(props) {
5446
5505
  });
5447
5506
  if (!snapshot) {
5448
5507
  setSelectionBoxes([]);
5508
+ setCommentHighlights([]);
5449
5509
  setSelectedImageBox(null);
5450
5510
  setSelectedTextBoxBox(null);
5451
5511
  setCaretBox((current) => ({ ...current, visible: false }));
@@ -5453,6 +5513,7 @@ function useEditorLayout(props) {
5453
5513
  }
5454
5514
  const geometry = computeCanvasSelectionGeometry(snapshot, props.state);
5455
5515
  setSelectionBoxes(geometry.selectionBoxes);
5516
+ setCommentHighlights(computeCommentHighlights(snapshot, props.state));
5456
5517
  setSelectedImageBox(geometry.selectedImageBox);
5457
5518
  setSelectedTextBoxBox(geometry.selectedTextBoxBox);
5458
5519
  setInputBox(geometry.inputBox);
@@ -5552,6 +5613,7 @@ function useEditorLayout(props) {
5552
5613
  measuredParagraphLayouts,
5553
5614
  inputBox,
5554
5615
  selectionBoxes,
5616
+ commentHighlights,
5555
5617
  selectedImageBox,
5556
5618
  selectedTextBoxBox,
5557
5619
  caretBox,
@@ -7787,6 +7849,105 @@ function serializeBookmarkEvent(event) {
7787
7849
  event.name ?? ""
7788
7850
  )}"${col}/>`;
7789
7851
  }
7852
+ const WORD15_NS = "http://schemas.microsoft.com/office/word/2012/wordml";
7853
+ function buildCommentExportPlan(document2) {
7854
+ const registry = document2.comments;
7855
+ if (!registry || registry.order.length === 0) {
7856
+ return void 0;
7857
+ }
7858
+ const assignedId = /* @__PURE__ */ new Map();
7859
+ const used = /* @__PURE__ */ new Set();
7860
+ for (const id of registry.order) {
7861
+ const c = registry.items[id];
7862
+ if (!c) continue;
7863
+ const hint = c.docxIdHint;
7864
+ if (hint !== void 0 && hint >= 0 && !used.has(hint)) {
7865
+ assignedId.set(id, hint);
7866
+ used.add(hint);
7867
+ }
7868
+ }
7869
+ let next = 0;
7870
+ for (const id of registry.order) {
7871
+ if (assignedId.has(id)) continue;
7872
+ while (used.has(next)) next += 1;
7873
+ assignedId.set(id, next);
7874
+ used.add(next);
7875
+ next += 1;
7876
+ }
7877
+ const eventsByParagraph = /* @__PURE__ */ new Map();
7878
+ const push = (paragraphId, event) => {
7879
+ const list = eventsByParagraph.get(paragraphId);
7880
+ if (list) {
7881
+ list.push(event);
7882
+ } else {
7883
+ eventsByParagraph.set(paragraphId, [event]);
7884
+ }
7885
+ };
7886
+ const comments = [];
7887
+ registry.order.forEach((id, index) => {
7888
+ const comment = registry.items[id];
7889
+ if (!comment) return;
7890
+ const wId = assignedId.get(id);
7891
+ const paraId = (1073741824 + index).toString(16).toUpperCase();
7892
+ comments.push({ comment, wId, paraId });
7893
+ if (comment.start) {
7894
+ push(comment.start.paragraphId, {
7895
+ kind: "start",
7896
+ offset: comment.start.offset,
7897
+ seq: comment.start.seq ?? 0,
7898
+ wId
7899
+ });
7900
+ }
7901
+ if (comment.end) {
7902
+ push(comment.end.paragraphId, {
7903
+ kind: "end",
7904
+ offset: comment.end.offset,
7905
+ seq: comment.end.seq ?? 0,
7906
+ wId
7907
+ });
7908
+ push(comment.end.paragraphId, {
7909
+ kind: "reference",
7910
+ offset: comment.end.offset,
7911
+ seq: (comment.end.seq ?? 0) + 0.5,
7912
+ wId
7913
+ });
7914
+ }
7915
+ });
7916
+ return { eventsByParagraph, comments };
7917
+ }
7918
+ function serializeCommentRangeEvent(event) {
7919
+ switch (event.kind) {
7920
+ case "start":
7921
+ return `<w:commentRangeStart w:id="${event.wId}"/>`;
7922
+ case "end":
7923
+ return `<w:commentRangeEnd w:id="${event.wId}"/>`;
7924
+ case "reference":
7925
+ return `<w:r><w:commentReference w:id="${event.wId}"/></w:r>`;
7926
+ }
7927
+ }
7928
+ const COMMENTS_XMLNS = `xmlns:w="${WORD_NS$1}" xmlns:w14="${WORD14_NS}" xmlns:w15="${WORD15_NS}"`;
7929
+ function serializeCommentBody(text) {
7930
+ const lines = text.split("\n");
7931
+ const runs = lines.map((line, i) => {
7932
+ const brk = i > 0 ? "<w:br/>" : "";
7933
+ return `${brk}<w:t xml:space="preserve">${escapeXml(line)}</w:t>`;
7934
+ }).join("");
7935
+ return `<w:r>${runs}</w:r>`;
7936
+ }
7937
+ function buildCommentsPartXml(plan) {
7938
+ const body = plan.comments.map(({ comment, wId, paraId }) => {
7939
+ const dateAttr = comment.date !== void 0 ? ` w:date="${new Date(comment.date).toISOString().replace(/\.\d{3}Z$/, "Z")}"` : "";
7940
+ const initialsAttr = comment.initials ? ` w:initials="${escapeXml(comment.initials)}"` : "";
7941
+ return `<w:comment w:id="${wId}" w:author="${escapeXml(comment.author)}"${dateAttr}${initialsAttr}><w:p w14:paraId="${paraId}">${serializeCommentBody(comment.text)}</w:p></w:comment>`;
7942
+ }).join("");
7943
+ return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><w:comments ${COMMENTS_XMLNS}>${body}</w:comments>`;
7944
+ }
7945
+ function buildCommentsExtendedPartXml(plan) {
7946
+ const body = plan.comments.map(
7947
+ ({ comment, paraId }) => `<w15:commentEx w15:paraId="${paraId}" w15:done="${comment.resolved ? "1" : "0"}"/>`
7948
+ ).join("");
7949
+ return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><w15:commentsEx ${COMMENTS_XMLNS}>${body}</w15:commentsEx>`;
7950
+ }
7790
7951
  function serializeDocxBorderAttrs(border, colorFallback = "000000") {
7791
7952
  if (border.type === "none" || border.width <= 0) {
7792
7953
  return 'w:val="nil"/>';
@@ -8958,8 +9119,8 @@ function stripRpr(rPr) {
8958
9119
  function isSplittableTextRun(run) {
8959
9120
  return !run.image && !run.textBox && !run.field && !run.fieldChar && run.fieldInstruction === void 0 && !run.footnoteReference && !run.endnoteReference;
8960
9121
  }
8961
- function serializeRunsWithBookmarks(runs, events, context, paragraphStyleId, styles) {
8962
- const sorted = [...events].sort(
9122
+ function serializeRunsWithBoundaries(runs, tokens, context, paragraphStyleId, styles) {
9123
+ const sorted = [...tokens].sort(
8963
9124
  (a, b) => a.offset - b.offset || a.seq - b.seq
8964
9125
  );
8965
9126
  let ei = 0;
@@ -8967,7 +9128,7 @@ function serializeRunsWithBookmarks(runs, events, context, paragraphStyleId, sty
8967
9128
  let out = "";
8968
9129
  const flushUpTo = (limit) => {
8969
9130
  while (ei < sorted.length && sorted[ei].offset <= limit) {
8970
- out += serializeBookmarkEvent(sorted[ei]);
9131
+ out += sorted[ei].xml;
8971
9132
  ei += 1;
8972
9133
  }
8973
9134
  };
@@ -8978,21 +9139,21 @@ function serializeRunsWithBookmarks(runs, events, context, paragraphStyleId, sty
8978
9139
  if (isSplittableTextRun(run) && run.text.length > 0) {
8979
9140
  let cursor = runStart;
8980
9141
  while (ei < sorted.length && sorted[ei].offset < runEnd) {
8981
- const event = sorted[ei];
8982
- if (event.offset > cursor) {
9142
+ const token = sorted[ei];
9143
+ if (token.offset > cursor) {
8983
9144
  out += serializeRunWithRelationships(
8984
9145
  {
8985
9146
  ...run,
8986
- text: run.text.slice(cursor - runStart, event.offset - runStart)
9147
+ text: run.text.slice(cursor - runStart, token.offset - runStart)
8987
9148
  },
8988
9149
  context,
8989
9150
  paragraphStyleId,
8990
9151
  styles
8991
9152
  );
8992
9153
  }
8993
- out += serializeBookmarkEvent(event);
9154
+ out += token.xml;
8994
9155
  ei += 1;
8995
- cursor = event.offset;
9156
+ cursor = token.offset;
8996
9157
  }
8997
9158
  if (cursor < runEnd) {
8998
9159
  out += serializeRunWithRelationships(
@@ -9034,15 +9195,28 @@ function serializeBlocksXml(blocks, context, styles) {
9034
9195
  }).join("");
9035
9196
  }
9036
9197
  function serializeParagraphXml(paragraph, context, styles, overrides) {
9037
- var _a, _b;
9198
+ var _a, _b, _c;
9038
9199
  const runs = paragraph.runs.length > 0 ? paragraph.runs : [{ id: "", text: "" }];
9039
9200
  const dropCapFrame = paragraph.dropCap ? serializeDropCapFrameParagraph(paragraph.dropCap) : "";
9040
9201
  const bookmarkEvents = (_a = context.bookmarkEventsByParagraph) == null ? void 0 : _a.get(paragraph.id);
9041
- const runsXml = bookmarkEvents && bookmarkEvents.length > 0 ? serializeRunsWithBookmarks(
9202
+ const commentEvents = (_b = context.commentEventsByParagraph) == null ? void 0 : _b.get(paragraph.id);
9203
+ const boundaryTokens = [
9204
+ ...(bookmarkEvents ?? []).map((e) => ({
9205
+ offset: e.offset,
9206
+ seq: e.seq,
9207
+ xml: serializeBookmarkEvent(e)
9208
+ })),
9209
+ ...(commentEvents ?? []).map((e) => ({
9210
+ offset: e.offset,
9211
+ seq: e.seq,
9212
+ xml: serializeCommentRangeEvent(e)
9213
+ }))
9214
+ ];
9215
+ const runsXml = boundaryTokens.length > 0 ? serializeRunsWithBoundaries(
9042
9216
  runs,
9043
- bookmarkEvents,
9217
+ boundaryTokens,
9044
9218
  context,
9045
- (_b = paragraph.style) == null ? void 0 : _b.styleId,
9219
+ (_c = paragraph.style) == null ? void 0 : _c.styleId,
9046
9220
  styles
9047
9221
  ) : runs.map(
9048
9222
  (run) => {
@@ -9579,19 +9753,19 @@ function buildHeaderFooterXml(kind, blocks, context, styles) {
9579
9753
  const tag = kind === "header" ? "hdr" : "ftr";
9580
9754
  return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><w:${tag} ${DOCUMENT_XMLNS}>${serializeBlocksXml(blocks, context, styles)}</w:${tag}>`;
9581
9755
  }
9582
- function buildContentTypesXml(hasNumbering, imageExtensions, hasSettings, parts, hasFootnotes, hasEndnotes, hasStyles) {
9756
+ function buildContentTypesXml(hasNumbering, imageExtensions, hasSettings, parts, hasFootnotes, hasEndnotes, hasStyles, hasComments) {
9583
9757
  const overrides = parts.map((part) => {
9584
9758
  const contentType = part.kind === "header" ? "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml" : "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml";
9585
9759
  return `<Override PartName="/word/${part.path}" ContentType="${contentType}"/>`;
9586
9760
  }).join("");
9587
9761
  return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/>${imageContentTypeDefaults(
9588
9762
  imageExtensions
9589
- )}<Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/>${hasStyles ? '<Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/>' : ""}${hasNumbering ? '<Override PartName="/word/numbering.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml"/>' : ""}${hasSettings ? '<Override PartName="/word/settings.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"/>' : ""}${hasFootnotes ? '<Override PartName="/word/footnotes.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml"/>' : ""}${hasEndnotes ? '<Override PartName="/word/endnotes.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml"/>' : ""}${overrides}</Types>`;
9763
+ )}<Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/>${hasStyles ? '<Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/>' : ""}${hasNumbering ? '<Override PartName="/word/numbering.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml"/>' : ""}${hasSettings ? '<Override PartName="/word/settings.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"/>' : ""}${hasFootnotes ? '<Override PartName="/word/footnotes.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml"/>' : ""}${hasEndnotes ? '<Override PartName="/word/endnotes.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml"/>' : ""}${hasComments ? '<Override PartName="/word/comments.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml"/><Override PartName="/word/commentsExtended.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.commentsExtended+xml"/>' : ""}${overrides}</Types>`;
9590
9764
  }
9591
9765
  function buildRootRelationshipsXml() {
9592
9766
  return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Relationships xmlns="${PACKAGE_REL_NS}"><Relationship Id="rId1" Type="${OFFICE_REL_NS}/officeDocument" Target="word/document.xml"/></Relationships>`;
9593
9767
  }
9594
- function buildDocumentRelationshipsXml(hasNumbering, hasSettings, images, hyperlinks, parts, hasFootnotes, hasEndnotes, hasStyles) {
9768
+ function buildDocumentRelationshipsXml(hasNumbering, hasSettings, images, hyperlinks, parts, hasFootnotes, hasEndnotes, hasStyles, hasComments) {
9595
9769
  let rels = "";
9596
9770
  if (hasStyles)
9597
9771
  rels += `<Relationship Id="rIdStyles" Type="${OFFICE_REL_NS}/styles" Target="styles.xml"/>`;
@@ -9616,6 +9790,10 @@ function buildDocumentRelationshipsXml(hasNumbering, hasSettings, images, hyperl
9616
9790
  if (hasEndnotes) {
9617
9791
  rels += `<Relationship Id="rIdEndnotes" Type="${OFFICE_REL_NS}/endnotes" Target="endnotes.xml"/>`;
9618
9792
  }
9793
+ if (hasComments) {
9794
+ rels += `<Relationship Id="rIdComments" Type="${OFFICE_REL_NS}/comments" Target="comments.xml"/>`;
9795
+ rels += `<Relationship Id="rIdCommentsExtended" Type="http://schemas.microsoft.com/office/2011/relationships/commentsExtended" Target="commentsExtended.xml"/>`;
9796
+ }
9619
9797
  return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Relationships xmlns="${PACKAGE_REL_NS}">${rels}</Relationships>`;
9620
9798
  }
9621
9799
  function buildSettingsXml(hasEvenAndOddHeaders, defaultTabStop, footnoteSettings, endnoteSettings) {
@@ -9703,6 +9881,9 @@ async function exportEditorDocumentToDocx(document2) {
9703
9881
  bodyContext.endnoteIdMap = endnoteIdMap;
9704
9882
  const bookmarkEvents = buildBookmarkExportPlan(document2);
9705
9883
  bodyContext.bookmarkEventsByParagraph = bookmarkEvents;
9884
+ const commentPlan = buildCommentExportPlan(document2);
9885
+ bodyContext.commentEventsByParagraph = commentPlan == null ? void 0 : commentPlan.eventsByParagraph;
9886
+ const hasComments = commentPlan !== void 0;
9706
9887
  const parts = [];
9707
9888
  const sectionReferences = sections.map(
9708
9889
  () => ({})
@@ -9728,6 +9909,7 @@ async function exportEditorDocumentToDocx(document2) {
9728
9909
  context.footnoteIdMap = footnoteIdMap;
9729
9910
  context.endnoteIdMap = endnoteIdMap;
9730
9911
  context.bookmarkEventsByParagraph = bookmarkEvents;
9912
+ context.commentEventsByParagraph = commentPlan == null ? void 0 : commentPlan.eventsByParagraph;
9731
9913
  parts.push({
9732
9914
  kind,
9733
9915
  type,
@@ -9801,7 +9983,8 @@ async function exportEditorDocumentToDocx(document2) {
9801
9983
  parts,
9802
9984
  hasFootnotes,
9803
9985
  hasEndnotes,
9804
- hasStyles
9986
+ hasStyles,
9987
+ hasComments
9805
9988
  )
9806
9989
  );
9807
9990
  zip.file("_rels/.rels", buildRootRelationshipsXml());
@@ -9818,7 +10001,7 @@ async function exportEditorDocumentToDocx(document2) {
9818
10001
  buildNumberingXml(numberingContext.definitions)
9819
10002
  );
9820
10003
  }
9821
- if (hasStyles || hasNumbering || hasDocumentSettings || bodyContext.images.length > 0 || bodyContext.hyperlinks.length > 0 || parts.length > 0 || hasFootnotes || hasEndnotes) {
10004
+ if (hasStyles || hasNumbering || hasDocumentSettings || bodyContext.images.length > 0 || bodyContext.hyperlinks.length > 0 || parts.length > 0 || hasFootnotes || hasEndnotes || hasComments) {
9822
10005
  zip.file(
9823
10006
  "word/_rels/document.xml.rels",
9824
10007
  buildDocumentRelationshipsXml(
@@ -9829,7 +10012,8 @@ async function exportEditorDocumentToDocx(document2) {
9829
10012
  parts,
9830
10013
  hasFootnotes,
9831
10014
  hasEndnotes,
9832
- hasStyles
10015
+ hasStyles,
10016
+ hasComments
9833
10017
  )
9834
10018
  );
9835
10019
  }
@@ -9885,6 +10069,13 @@ async function exportEditorDocumentToDocx(document2) {
9885
10069
  );
9886
10070
  }
9887
10071
  }
10072
+ if (commentPlan) {
10073
+ zip.file("word/comments.xml", buildCommentsPartXml(commentPlan));
10074
+ zip.file(
10075
+ "word/commentsExtended.xml",
10076
+ buildCommentsExtendedPartXml(commentPlan)
10077
+ );
10078
+ }
9888
10079
  for (const img of allImages) {
9889
10080
  if (img.kind === "embedded" && img.base64) {
9890
10081
  zip.file(`word/${img.target}`, img.base64, { base64: true });
@@ -40940,6 +41131,25 @@ function buildParagraphAndSectionCommands({
40940
41131
  (p) => (paragraph.setIndentHanging(numOrNull(p)), true),
40941
41132
  () => s().indentHanging
40942
41133
  ),
41134
+ setSpecialIndent: actionCommand(
41135
+ "setSpecialIndent",
41136
+ (p) => {
41137
+ const payload = p ?? {};
41138
+ paragraph.setSpecialIndent(
41139
+ payload.kind ?? "none",
41140
+ numOrNull(payload.value)
41141
+ );
41142
+ },
41143
+ () => {
41144
+ const firstLine = Number(s().indentFirstLine);
41145
+ const hanging = Number(s().indentHanging);
41146
+ const kind = Number.isFinite(hanging) && hanging > 0 ? "hanging" : Number.isFinite(firstLine) && firstLine > 0 ? "firstLine" : "none";
41147
+ return {
41148
+ isActive: kind !== "none",
41149
+ value: kind
41150
+ };
41151
+ }
41152
+ ),
40943
41153
  setParagraphShading: valueCommand(
40944
41154
  "setParagraphShading",
40945
41155
  (p) => (paragraph.setShading(p ?? null), true),
@@ -41325,6 +41535,23 @@ function createEditorEssentialsRuntimePlugin(options) {
41325
41535
  "indentHanging",
41326
41536
  value
41327
41537
  ),
41538
+ setSpecialIndent: (kind, value) => {
41539
+ const resolvedValue = value ?? 48;
41540
+ options.applyTransactionalState(
41541
+ (current) => {
41542
+ let next = setParagraphStyle(current, "indentFirstLine", null);
41543
+ next = setParagraphStyle(next, "indentHanging", null);
41544
+ if (kind === "firstLine") {
41545
+ next = setParagraphStyle(next, "indentFirstLine", resolvedValue);
41546
+ } else if (kind === "hanging") {
41547
+ next = setParagraphStyle(next, "indentHanging", resolvedValue);
41548
+ }
41549
+ return next;
41550
+ },
41551
+ { mergeKey: "specialIndent" }
41552
+ );
41553
+ options.focusInput();
41554
+ },
41328
41555
  setShading: (value) => options.commandsController.applyParagraphStyleCommand("shading", value),
41329
41556
  applyBorders: () => {
41330
41557
  const border = {
@@ -45698,6 +45925,7 @@ function buildEditorViewProps(ctx) {
45698
45925
  };
45699
45926
  const overlays = {
45700
45927
  selectionBoxes: ctx.selectionBoxes,
45928
+ commentHighlights: ctx.commentHighlights,
45701
45929
  selectedImageBox: ctx.selectedImageBox,
45702
45930
  selectedTextBoxBox: ctx.selectedTextBoxBox,
45703
45931
  layoutOptions: ctx.layoutOptions,
@@ -46141,6 +46369,7 @@ function OasisEditorApp(props = {}) {
46141
46369
  measuredParagraphLayouts,
46142
46370
  inputBox,
46143
46371
  selectionBoxes,
46372
+ commentHighlights,
46144
46373
  selectedImageBox,
46145
46374
  selectedTextBoxBox,
46146
46375
  caretBox,
@@ -46661,6 +46890,7 @@ function OasisEditorApp(props = {}) {
46661
46890
  className: ui().class,
46662
46891
  style: ui().style,
46663
46892
  selectionBoxes,
46893
+ commentHighlights,
46664
46894
  selectedImageBox,
46665
46895
  selectedTextBoxBox,
46666
46896
  layoutOptions: layoutOptionsOverlay,
@@ -1,5 +1,5 @@
1
1
  import { EditorLayoutParagraph, EditorState } from '../../../../core/model.js';
2
- import { CaretBox, InputBox, SelectionBox } from '../../../../ui/editorUiTypes.js';
2
+ import { CaretBox, CommentHighlightBox, InputBox, SelectionBox } from '../../../../ui/editorUiTypes.js';
3
3
  import { SelectedImageSelectionBox, SelectedTextBoxSelectionBox } from '../../../../ui/canvas/CanvasSelectionGeometry.js';
4
4
 
5
5
  interface UseEditorLayoutProps {
@@ -19,6 +19,7 @@ export declare function useEditorLayout(props: UseEditorLayoutProps): {
19
19
  measuredParagraphLayouts: import('../../solid-js').Accessor<Record<string, EditorLayoutParagraph>>;
20
20
  inputBox: import('../../solid-js').Accessor<InputBox>;
21
21
  selectionBoxes: import('../../solid-js').Accessor<SelectionBox[]>;
22
+ commentHighlights: import('../../solid-js').Accessor<CommentHighlightBox[]>;
22
23
  selectedImageBox: import('../../solid-js').Accessor<SelectedImageSelectionBox | null>;
23
24
  selectedTextBoxBox: import('../../solid-js').Accessor<SelectedTextBoxSelectionBox | null>;
24
25
  caretBox: import('../../solid-js').Accessor<CaretBox>;