oasis-editor 0.0.11 → 0.0.12

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.
@@ -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 createEditorStyledRun, b as getParagraphLength, d as getParagraphText, e as getActiveZone, f as getDocumentSections, h as getActiveSectionIndex, p as positionToParagraphOffset, i as paragraphOffsetToPosition, j as clampPosition, k as findParagraphIndex, l as createCollapsedSelection, m as isSelectionCollapsed, o as createEditorParagraph, q as getBlockParagraphs, r as findParagraphTableLocation, s as buildTableCellLayout, t as createEditorTableCell, u as createEditorTable, v as createEditorTableRow, w as underlineStyleToCssDecorationStyle, x as resolveImageSrc, y as createEditorFootnote, z as createFootnoteReferenceRun, A as renumberFootnotes, B as iterateFootnoteReferenceRuns, C as getFootnoteDisplayMarker, D as createSignal, E as createEffect, F as onCleanup, G as buildCanvasLayoutSnapshot, H as on, I as onMount, J as debounce, K as unwrap, L as getDocumentParagraphs, M as getDocumentSectionsCanonical, N as createEditorDocument, O as getPageContentWidth, P as getDocumentPageSettings, Q as getTableCellContentWidthForParagraph, R as resolveResizedDimensions, S as resolveTextBoxRenderHeight, T as resolveEffectiveParagraphStyle, U as resolveEffectiveTextStyleForParagraph, V as iterateEndnoteReferenceRuns, W as JSZip, X as imageContentTypeDefaults, Y as imageExtensionFromMime, Z as pxToPt$1, _ as buildSegmentTable, $ as buildCanvasTableLayout, a0 as resolveFloatingObjectRect, a1 as getTextBoxFloatingGeometry, a2 as getPresetPathSegments, a3 as projectBlocksLayout, a4 as textStyleToFontSizePt, a5 as PX_PER_POINT, a6 as DEFAULT_FONT_SIZE_PX, a7 as isDoubleUnderlineStyle, a8 as isWavyUnderlineStyle, a9 as underlineStyleLineWidthPx, aa as underlineStyleDashArray, ab as getListLabelInset, ac as getParagraphBorderInsets, ad as normalizeFamily, ae as ROBOTO_FONT_FILES, af as loadFontAsset, ag as OFFICE_COMPAT_FONT_FAMILIES, ah as buildSfnt, ai as defaultFontDecoderRegistry, aj as SfntFontProgram, ak as collectPdfFontFamilies, al as projectDocumentLayout, am as getPageHeaderZoneTop, an as getPageBodyTop, ao as findFootnoteReference, ap as FOOTNOTE_MARKER_GUTTER_PX, aq as resolveImporterForFile, ar as createEditorStateFromDocument, as as getDocumentParagraphsCanonical, at as getToolbarStyleState, au as STANDARD_FONT_SIZES_PT, av as fontSizePxToPt, aw as probeLocalFontFamilies, ax as createInitialEditorState, ay as parseFontSizePtToPx, az as formatFontSizePt, aA as listKindForTag, aB as isParagraphTag, aC as collectInlineRuns, aD as parseParagraphStyle, aE as t, aF as preciseFontModeVersion, aG as isPreciseFontModeEnabled, aH as togglePreciseFontMode, aI as nextFontSizePt, aJ as previousFontSizePt, aK as fontSizePtToPx, aL as createDefaultToolbarPreset, aM as defaultMenuItems, aN as MenuRegistry, aO as createToolbarRegistry, aP as Editor, aQ as resolveCommandRef, aR as commandRefName, aS as InlineShell, aT as BalloonShell, aU as DocumentShell, aV as createMemo, aW as getCaretRectFromSnapshot, aX as getParagraphRectFromSnapshot, aY as createComponent, aZ as CaretOverlay, a_ as Show, a$ as createRenderEffect, b0 as style, b1 as setAttribute, b2 as setStyleProperty, b3 as memo, b4 as template, b5 as insert, b6 as use, b7 as addEventListener, b8 as Dialog, b9 as delegateEvents, ba as className, bb as For, bc as UNDERLINE_STYLE_OPTIONS, bd as Tabs, be as measureParagraphMinContentWidthPx, bf as getEditableBlocksForZone, bg as findParagraphLocation, bh as createSectionBoundaryParagraph, bi as normalizePageSettings, bj as DEFAULT_EDITOR_PAGE_SETTINGS, bk as markStart, bl as markEnd, bm as getParagraphEntries, bn as getParagraphById, bo as PluginUiHost, bp as OasisEditorEditor, bq as perfTimer, br as OasisBrandMark, bs as setPreciseFontPreference, bt as setWelcomeSeen, bu as enablePreciseFontMode, bv as createOasisEditorClient, bw as setLocale, bx as startLongTaskObserver, by as installGlobalReport, bz as applyStoredPreciseFontPreference, bA as getWelcomeSeen, bB as isLocalFontAccessSupported, bC as EDITOR_SCROLL_PADDING_PX, bD as Toolbar, bE as OasisEditorLoading, bF as createEditorLogger, bG as getCachedCanvasImage, bH as registerDomStatsSurface } from "./index-L71R0x7D.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-BUOuw27s.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) {
@@ -135,6 +135,7 @@ function cloneRun(run) {
135
135
  image: run.image ? { ...run.image } : void 0,
136
136
  textBox: run.textBox ? cloneTextBox(run.textBox) : void 0,
137
137
  field: run.field ? { ...run.field } : void 0,
138
+ fieldChar: run.fieldChar ? { ...run.fieldChar } : void 0,
138
139
  revision: run.revision ? { ...run.revision } : void 0,
139
140
  footnoteReference: run.footnoteReference ? { ...run.footnoteReference } : void 0,
140
141
  endnoteReference: run.endnoteReference ? { ...run.endnoteReference } : void 0
@@ -186,6 +187,164 @@ function cloneBlocks(blocks) {
186
187
  };
187
188
  });
188
189
  }
190
+ const IMAGE_CAPTION_STYLE_ID = "Caption";
191
+ const IMAGE_CAPTION_FIELD_IDENTIFIER = "Figure";
192
+ const IMAGE_CAPTION_FIELD_INSTRUCTION = " SEQ Figure \\* ARABIC ";
193
+ function createFieldCharRun(kind) {
194
+ const run = createEditorRun("");
195
+ run.fieldChar = { kind };
196
+ return run;
197
+ }
198
+ function createFieldInstructionRun(instruction) {
199
+ const run = createEditorRun("");
200
+ run.fieldInstruction = instruction;
201
+ return run;
202
+ }
203
+ function createImageCaptionParagraph(captionText, label, sequenceNumber) {
204
+ const paragraph = createEditorParagraphFromRuns([
205
+ { text: `${label} ` },
206
+ { text: String(sequenceNumber) },
207
+ { text: captionText ? `: ${captionText}` : "" }
208
+ ]);
209
+ paragraph.style = { styleId: IMAGE_CAPTION_STYLE_ID, align: "center" };
210
+ paragraph.runs = [
211
+ paragraph.runs[0],
212
+ createFieldCharRun("begin"),
213
+ createFieldInstructionRun(IMAGE_CAPTION_FIELD_INSTRUCTION),
214
+ createFieldCharRun("separate"),
215
+ paragraph.runs[1],
216
+ createFieldCharRun("end"),
217
+ paragraph.runs[2]
218
+ ];
219
+ return paragraph;
220
+ }
221
+ function isImageCaptionParagraph(paragraph) {
222
+ var _a, _b;
223
+ if (!paragraph) {
224
+ return false;
225
+ }
226
+ const styleId = (_b = (_a = paragraph.style) == null ? void 0 : _a.styleId) == null ? void 0 : _b.toLowerCase();
227
+ if (styleId !== "caption") {
228
+ return false;
229
+ }
230
+ return paragraph.runs.some(
231
+ (run) => run.fieldInstruction !== void 0 && new RegExp(`\\bSEQ\\s+${IMAGE_CAPTION_FIELD_IDENTIFIER}\\b`, "i").test(
232
+ run.fieldInstruction
233
+ )
234
+ );
235
+ }
236
+ function getImageCaptionText(paragraph) {
237
+ var _a;
238
+ if (!isImageCaptionParagraph(paragraph)) {
239
+ return "";
240
+ }
241
+ let afterField = false;
242
+ let value = "";
243
+ for (const run of paragraph.runs) {
244
+ if (afterField) {
245
+ value += run.text;
246
+ continue;
247
+ }
248
+ if (((_a = run.fieldChar) == null ? void 0 : _a.kind) === "end") {
249
+ afterField = true;
250
+ }
251
+ }
252
+ return value.replace(/^[:\-\s]+/, "");
253
+ }
254
+ function updateImageCaptionParagraph(paragraph, captionText, label) {
255
+ var _a;
256
+ const currentNumber = ((_a = paragraph.runs.find((run) => /^\d+$/.test(run.text))) == null ? void 0 : _a.text) ?? "1";
257
+ const next = createImageCaptionParagraph(
258
+ captionText,
259
+ label,
260
+ Number.parseInt(currentNumber, 10) || 1
261
+ );
262
+ next.id = paragraph.id;
263
+ return next;
264
+ }
265
+ function renumberCaptionParagraph(paragraph, sequenceNumber) {
266
+ if (!isImageCaptionParagraph(paragraph)) {
267
+ return cloneParagraph(paragraph);
268
+ }
269
+ let insideSeqResult = false;
270
+ let changed = false;
271
+ const nextRuns = paragraph.runs.map((run) => {
272
+ var _a, _b;
273
+ if (((_a = run.fieldChar) == null ? void 0 : _a.kind) === "separate") {
274
+ insideSeqResult = true;
275
+ return { ...run, fieldChar: { ...run.fieldChar } };
276
+ }
277
+ if (((_b = run.fieldChar) == null ? void 0 : _b.kind) === "end") {
278
+ insideSeqResult = false;
279
+ return { ...run, fieldChar: { ...run.fieldChar } };
280
+ }
281
+ if (insideSeqResult && run.text !== "") {
282
+ if (run.text === String(sequenceNumber)) {
283
+ return { ...run };
284
+ }
285
+ changed = true;
286
+ return { ...run, text: String(sequenceNumber) };
287
+ }
288
+ return { ...run };
289
+ });
290
+ if (!changed) {
291
+ return cloneParagraph(paragraph);
292
+ }
293
+ return {
294
+ ...cloneParagraph(paragraph),
295
+ runs: nextRuns
296
+ };
297
+ }
298
+ function renumberImageCaptionParagraphs(paragraphs) {
299
+ let nextSequence = 1;
300
+ return paragraphs.map((paragraph) => {
301
+ if (!isImageCaptionParagraph(paragraph)) {
302
+ return cloneParagraph(paragraph);
303
+ }
304
+ return renumberCaptionParagraph(paragraph, nextSequence++);
305
+ });
306
+ }
307
+ function renumberBlocks(blocks, sequence) {
308
+ return blocks.map((block) => {
309
+ if (block.type === "paragraph") {
310
+ if (!isImageCaptionParagraph(block)) {
311
+ return cloneParagraph(block);
312
+ }
313
+ return renumberCaptionParagraph(block, sequence.next++);
314
+ }
315
+ return {
316
+ ...block,
317
+ rows: block.rows.map((row) => ({
318
+ ...row,
319
+ cells: row.cells.map((cell) => ({
320
+ ...cell,
321
+ blocks: renumberBlocks(
322
+ cell.blocks,
323
+ sequence
324
+ )
325
+ }))
326
+ }))
327
+ };
328
+ });
329
+ }
330
+ function renumberImageCaptionsInDocument(document2) {
331
+ const sequence = { next: 1 };
332
+ const sections = getDocumentSections(document2).map(
333
+ (section) => ({
334
+ ...section,
335
+ blocks: renumberBlocks(section.blocks, sequence),
336
+ header: section.header ? cloneBlocks(section.header) : void 0,
337
+ footer: section.footer ? cloneBlocks(section.footer) : void 0
338
+ })
339
+ );
340
+ return {
341
+ ...document2,
342
+ sections
343
+ };
344
+ }
345
+ function getCaptionSelectionOffset(paragraph) {
346
+ return getParagraphLength(paragraph);
347
+ }
189
348
  function isObjectRun(run) {
190
349
  return Boolean(run.image || run.textBox);
191
350
  }
@@ -983,6 +1142,48 @@ function setSelectedImageAlt(state, alt) {
983
1142
  )
984
1143
  );
985
1144
  }
1145
+ function getSelectedImageCaption(state) {
1146
+ const selectedImage = getSelectedImageRun(state);
1147
+ if (!(selectedImage == null ? void 0 : selectedImage.run.image)) {
1148
+ return null;
1149
+ }
1150
+ const paragraphs = getParagraphs(state);
1151
+ return getImageCaptionText(paragraphs[selectedImage.paragraphIndex + 1]);
1152
+ }
1153
+ function setSelectedImageCaption(state, captionText, label) {
1154
+ const selectedImage = getSelectedImageRun(state);
1155
+ if (!(selectedImage == null ? void 0 : selectedImage.run.image)) {
1156
+ return state;
1157
+ }
1158
+ const paragraphs = getParagraphs(state);
1159
+ const captionIndex = selectedImage.paragraphIndex + 1;
1160
+ const nextParagraph = captionIndex < paragraphs.length && isImageCaptionParagraph(paragraphs[captionIndex]) ? updateImageCaptionParagraph(
1161
+ paragraphs[captionIndex],
1162
+ captionText,
1163
+ label
1164
+ ) : createImageCaptionParagraph(captionText, label, 1);
1165
+ const nextParagraphs = captionIndex < paragraphs.length && isImageCaptionParagraph(paragraphs[captionIndex]) ? [
1166
+ ...cloneParagraphs(paragraphs.slice(0, captionIndex)),
1167
+ nextParagraph,
1168
+ ...cloneParagraphs(paragraphs.slice(captionIndex + 1))
1169
+ ] : [
1170
+ ...cloneParagraphs(paragraphs.slice(0, captionIndex)),
1171
+ nextParagraph,
1172
+ ...cloneParagraphs(paragraphs.slice(captionIndex))
1173
+ ];
1174
+ const renumberedParagraphs = renumberImageCaptionParagraphs(nextParagraphs);
1175
+ const insertedCaption = renumberedParagraphs[captionIndex] ?? nextParagraph;
1176
+ return cloneStateWithParagraphs(
1177
+ state,
1178
+ renumberedParagraphs,
1179
+ withSelection(
1180
+ paragraphOffsetToPosition(
1181
+ insertedCaption,
1182
+ getCaptionSelectionOffset(insertedCaption)
1183
+ )
1184
+ )
1185
+ );
1186
+ }
986
1187
  function moveSelectedImageToPosition(state, targetPosition) {
987
1188
  const selectedImage = getSelectedImageRun(state);
988
1189
  if (!selectedImage) {
@@ -4254,6 +4455,26 @@ function createEditorCommandsController(deps) {
4254
4455
  const currentAlt = ((_a = run.run.image) == null ? void 0 : _a.alt) ?? "";
4255
4456
  deps.openImageAltDialog(currentAlt);
4256
4457
  };
4458
+ const applyImageCaptionCommand = (caption) => {
4459
+ const run = selectedImageRun();
4460
+ if (!run) {
4461
+ return;
4462
+ }
4463
+ clearPreferredColumn();
4464
+ resetTransactionGrouping();
4465
+ applyTransactionalState(
4466
+ (current) => setSelectedImageCaption(current, caption, deps.imageCaptionLabel()),
4467
+ { mergeKey: "imageCaption" }
4468
+ );
4469
+ focusInput();
4470
+ };
4471
+ const promptForImageCaption = () => {
4472
+ const run = selectedImageRun();
4473
+ if (!run) {
4474
+ return;
4475
+ }
4476
+ deps.openImageCaptionDialog(getSelectedImageCaption(state) ?? "");
4477
+ };
4257
4478
  return {
4258
4479
  applyBooleanStyleCommand,
4259
4480
  applyValueStyleCommand,
@@ -4280,6 +4501,8 @@ function createEditorCommandsController(deps) {
4280
4501
  removeLinkCommand,
4281
4502
  applyImageAltCommand,
4282
4503
  promptForImageAlt,
4504
+ applyImageCaptionCommand,
4505
+ promptForImageCaption,
4283
4506
  handleListTab,
4284
4507
  handleListEnter,
4285
4508
  handleListBoundaryBackspace
@@ -8058,10 +8281,13 @@ function serializeParagraphStyleXml(style2) {
8058
8281
  return parts.length > 0 ? `<w:pPr>${parts.join("")}</w:pPr>` : "";
8059
8282
  }
8060
8283
  function serializeParagraphProperties(paragraph, numberingInfo, styles, overrides) {
8061
- var _a;
8284
+ var _a, _b;
8062
8285
  const parts = [];
8063
8286
  const style2 = materializeParagraphStyle(paragraph, styles);
8064
8287
  const align = ((_a = paragraph.style) == null ? void 0 : _a.align) ?? (overrides == null ? void 0 : overrides.align) ?? style2.align;
8288
+ if ((_b = paragraph.style) == null ? void 0 : _b.styleId) {
8289
+ parts.push(`<w:pStyle w:val="${escapeXml(paragraph.style.styleId)}"/>`);
8290
+ }
8065
8291
  if (align) {
8066
8292
  parts.push(`<w:jc w:val="${align}"/>`);
8067
8293
  }
@@ -9310,14 +9536,24 @@ function buildPartContext(blocks, numberingContext, state, document2) {
9310
9536
  };
9311
9537
  }
9312
9538
  function buildNumberingXml(definitions) {
9313
- const abstractNums = definitions.map(({ kind, level, abstractNumId, format, startAt, bulletGlyph, bulletFont }) => {
9314
- const numFmtVal = kind === "bullet" ? "bullet" : format ?? "decimal";
9315
- const levelText = kind === "bullet" ? bulletGlyph ?? "" : `%${level + 1}.`;
9316
- const startVal = startAt ?? 1;
9317
- const fontName = kind === "bullet" ? bulletFont ?? "Symbol" : void 0;
9318
- const runFonts = fontName ? `<w:rPr><w:rFonts w:ascii="${escapeXml(fontName)}" w:hAnsi="${escapeXml(fontName)}" w:hint="default"/></w:rPr>` : "";
9319
- return `<w:abstractNum w:abstractNumId="${abstractNumId}"><w:lvl w:ilvl="${level}"><w:start w:val="${startVal}"/><w:numFmt w:val="${numFmtVal}"/><w:lvlText w:val="${escapeXml(levelText)}"/><w:lvlJc w:val="left"/>${runFonts}</w:lvl></w:abstractNum>`;
9320
- }).join("");
9539
+ const abstractNums = definitions.map(
9540
+ ({
9541
+ kind,
9542
+ level,
9543
+ abstractNumId,
9544
+ format,
9545
+ startAt,
9546
+ bulletGlyph,
9547
+ bulletFont
9548
+ }) => {
9549
+ const numFmtVal = kind === "bullet" ? "bullet" : format ?? "decimal";
9550
+ const levelText = kind === "bullet" ? bulletGlyph ?? "" : `%${level + 1}.`;
9551
+ const startVal = startAt ?? 1;
9552
+ const fontName = kind === "bullet" ? bulletFont ?? "Symbol" : void 0;
9553
+ const runFonts = fontName ? `<w:rPr><w:rFonts w:ascii="${escapeXml(fontName)}" w:hAnsi="${escapeXml(fontName)}" w:hint="default"/></w:rPr>` : "";
9554
+ return `<w:abstractNum w:abstractNumId="${abstractNumId}"><w:lvl w:ilvl="${level}"><w:start w:val="${startVal}"/><w:numFmt w:val="${numFmtVal}"/><w:lvlText w:val="${escapeXml(levelText)}"/><w:lvlJc w:val="left"/>${runFonts}</w:lvl></w:abstractNum>`;
9555
+ }
9556
+ ).join("");
9321
9557
  const nums = definitions.map(
9322
9558
  ({ abstractNumId, numId }) => `<w:num w:numId="${numId}"><w:abstractNumId w:val="${abstractNumId}"/></w:num>`
9323
9559
  ).join("");
@@ -9442,6 +9678,7 @@ function buildPartRelationshipsXml(images, hyperlinks) {
9442
9678
  }
9443
9679
  async function exportEditorDocumentToDocx(document2) {
9444
9680
  var _a, _b, _c, _d, _e, _f;
9681
+ document2 = renumberImageCaptionsInDocument(document2);
9445
9682
  const zip = new JSZip();
9446
9683
  const numberingContext = buildNumberingContext(document2);
9447
9684
  const buildState = {
@@ -11891,6 +12128,7 @@ endobj
11891
12128
  }
11892
12129
  const FOOTNOTE_BLOCK_GAP_PX = 2;
11893
12130
  async function exportEditorDocumentToPdf(document2) {
12131
+ document2 = renumberImageCaptionsInDocument(document2);
11894
12132
  const fontRegistry = new PdfFontRegistry();
11895
12133
  await fontRegistry.loadBundledUnicodeFaces({
11896
12134
  families: collectPdfFontFamilies(document2)
@@ -38993,6 +39231,10 @@ function createEditorDialogs() {
38993
39231
  isOpen: false,
38994
39232
  initialAlt: ""
38995
39233
  });
39234
+ const [imageCaptionDialog, setImageCaptionDialog] = createSignal({
39235
+ isOpen: false,
39236
+ initialCaption: ""
39237
+ });
38996
39238
  const [contextMenu, setContextMenu] = createSignal({ isOpen: false, x: 0, y: 0 });
38997
39239
  const [fontDialog, setFontDialog] = createSignal({
38998
39240
  isOpen: false,
@@ -39090,6 +39332,8 @@ function createEditorDialogs() {
39090
39332
  setLinkDialog,
39091
39333
  imageAltDialog,
39092
39334
  setImageAltDialog,
39335
+ imageCaptionDialog,
39336
+ setImageCaptionDialog,
39093
39337
  contextMenu,
39094
39338
  setContextMenu,
39095
39339
  fontDialog,
@@ -40634,6 +40878,14 @@ function buildDocumentAndBrowserCommands({
40634
40878
  isEnabled: image.isSelected(),
40635
40879
  isActive: image.isSelected()
40636
40880
  })
40881
+ ),
40882
+ insertImageCaption: actionCommand(
40883
+ "insertImageCaption",
40884
+ () => image.promptCaption(),
40885
+ () => ({
40886
+ isEnabled: image.isSelected(),
40887
+ isActive: image.isSelected()
40888
+ })
40637
40889
  )
40638
40890
  };
40639
40891
  }
@@ -41037,6 +41289,7 @@ function createEditorEssentialsRuntimePlugin(options) {
41037
41289
  };
41038
41290
  const essentialsImage = {
41039
41291
  promptAlt: () => options.commandsController.promptForImageAlt(),
41292
+ promptCaption: () => options.commandsController.promptForImageCaption(),
41040
41293
  isSelected: () => Boolean(options.selectedImageRun())
41041
41294
  };
41042
41295
  const essentialsBrowser = {
@@ -41579,14 +41832,14 @@ function DropCaret(props) {
41579
41832
  })
41580
41833
  });
41581
41834
  }
41582
- var _tmpl$$d = /* @__PURE__ */ template(`<div class=oasis-editor-table-resize-guide>`), _tmpl$2$8 = /* @__PURE__ */ template(`<img class=oasis-editor-image-ghost>`), _tmpl$3$6 = /* @__PURE__ */ template(`<div class=oasis-editor-table-ghost>`);
41835
+ var _tmpl$$e = /* @__PURE__ */ template(`<div class=oasis-editor-table-resize-guide>`), _tmpl$2$9 = /* @__PURE__ */ template(`<img class=oasis-editor-image-ghost>`), _tmpl$3$7 = /* @__PURE__ */ template(`<div class=oasis-editor-table-ghost>`);
41583
41836
  function EditorDragLayers(props) {
41584
41837
  return [createComponent(Show, {
41585
41838
  get when() {
41586
41839
  return props.tableResize.resizing();
41587
41840
  },
41588
41841
  children: (resizing) => (() => {
41589
- var _el$ = _tmpl$$d();
41842
+ var _el$ = _tmpl$$e();
41590
41843
  createRenderEffect((_p$) => {
41591
41844
  var _v$ = !!(resizing().type === "column"), _v$2 = !!(resizing().type === "row"), _v$3 = {
41592
41845
  ...resizing().type === "column" ? {
@@ -41617,7 +41870,7 @@ function EditorDragLayers(props) {
41617
41870
  return memo(() => !!props.imageOps.dragging())() && props.imageOps.draggedImageInfo();
41618
41871
  },
41619
41872
  children: (info) => (() => {
41620
- var _el$2 = _tmpl$2$8();
41873
+ var _el$2 = _tmpl$2$9();
41621
41874
  createRenderEffect((_p$) => {
41622
41875
  var _v$4 = info().src, _v$5 = `${info().width}px`, _v$6 = `${info().height}px`, _v$7 = `${props.imageOps.mousePos().x - info().offsetX}px`, _v$8 = `${props.imageOps.mousePos().y - info().offsetY}px`;
41623
41876
  _v$4 !== _p$.e && setAttribute(_el$2, "src", _p$.e = _v$4);
@@ -41640,7 +41893,7 @@ function EditorDragLayers(props) {
41640
41893
  return memo(() => !!props.tableDrag.dragging())() && props.tableDrag.draggedTableInfo();
41641
41894
  },
41642
41895
  children: (info) => (() => {
41643
- var _el$3 = _tmpl$3$6();
41896
+ var _el$3 = _tmpl$3$7();
41644
41897
  createRenderEffect((_p$) => {
41645
41898
  var _v$9 = `${info().width}px`, _v$0 = `${info().height}px`, _v$1 = `${props.tableDrag.mousePos().x - info().offsetX}px`, _v$10 = `${props.tableDrag.mousePos().y - info().offsetY}px`;
41646
41899
  _v$9 !== _p$.e && setStyleProperty(_el$3, "width", _p$.e = _v$9);
@@ -41703,7 +41956,7 @@ function EditorDragLayers(props) {
41703
41956
  })
41704
41957
  })];
41705
41958
  }
41706
- var _tmpl$$c = /* @__PURE__ */ template(`<div class=oasis-editor-dialog-input-group><label class=oasis-editor-dialog-label></label><input type=text class=oasis-editor-dialog-input data-testid=editor-link-dialog-input>`), _tmpl$2$7 = /* @__PURE__ */ template(`<button class="oasis-editor-dialog-button oasis-editor-dialog-button-secondary"data-testid=editor-link-dialog-cancel>`), _tmpl$3$5 = /* @__PURE__ */ template(`<button class="oasis-editor-dialog-button oasis-editor-dialog-button-primary"data-testid=editor-link-dialog-apply>`);
41959
+ var _tmpl$$d = /* @__PURE__ */ template(`<div class=oasis-editor-dialog-input-group><label class=oasis-editor-dialog-label></label><input type=text class=oasis-editor-dialog-input data-testid=editor-link-dialog-input>`), _tmpl$2$8 = /* @__PURE__ */ template(`<button class="oasis-editor-dialog-button oasis-editor-dialog-button-secondary"data-testid=editor-link-dialog-cancel>`), _tmpl$3$6 = /* @__PURE__ */ template(`<button class="oasis-editor-dialog-button oasis-editor-dialog-button-primary"data-testid=editor-link-dialog-apply>`);
41707
41960
  function LinkDialog(props) {
41708
41961
  const [href, setHref] = createSignal(props.initialHref);
41709
41962
  let inputRef;
@@ -41729,19 +41982,19 @@ function LinkDialog(props) {
41729
41982
  },
41730
41983
  get footer() {
41731
41984
  return [(() => {
41732
- var _el$4 = _tmpl$2$7();
41985
+ var _el$4 = _tmpl$2$8();
41733
41986
  addEventListener(_el$4, "click", props.onClose, true);
41734
41987
  insert(_el$4, () => t("generic.cancel"));
41735
41988
  return _el$4;
41736
41989
  })(), (() => {
41737
- var _el$5 = _tmpl$3$5();
41990
+ var _el$5 = _tmpl$3$6();
41738
41991
  _el$5.$$click = handleConfirm;
41739
41992
  insert(_el$5, () => t("generic.apply"));
41740
41993
  return _el$5;
41741
41994
  })()];
41742
41995
  },
41743
41996
  get children() {
41744
- var _el$ = _tmpl$$c(), _el$2 = _el$.firstChild, _el$3 = _el$2.nextSibling;
41997
+ var _el$ = _tmpl$$d(), _el$2 = _el$.firstChild, _el$3 = _el$2.nextSibling;
41745
41998
  insert(_el$2, () => t("dialog.link.label"));
41746
41999
  _el$3.$$keydown = (e) => e.key === "Enter" && handleConfirm();
41747
42000
  _el$3.$$input = (e) => setHref(e.currentTarget.value);
@@ -41754,7 +42007,7 @@ function LinkDialog(props) {
41754
42007
  });
41755
42008
  }
41756
42009
  delegateEvents(["input", "keydown", "click"]);
41757
- var _tmpl$$b = /* @__PURE__ */ template(`<div class=oasis-editor-dialog-input-group><label class=oasis-editor-dialog-label></label><input type=text class=oasis-editor-dialog-input>`), _tmpl$2$6 = /* @__PURE__ */ template(`<button class="oasis-editor-dialog-button oasis-editor-dialog-button-secondary">`), _tmpl$3$4 = /* @__PURE__ */ template(`<button class="oasis-editor-dialog-button oasis-editor-dialog-button-primary">`);
42010
+ var _tmpl$$c = /* @__PURE__ */ template(`<div class=oasis-editor-dialog-input-group><label class=oasis-editor-dialog-label></label><input type=text class=oasis-editor-dialog-input>`), _tmpl$2$7 = /* @__PURE__ */ template(`<button class="oasis-editor-dialog-button oasis-editor-dialog-button-secondary">`), _tmpl$3$5 = /* @__PURE__ */ template(`<button class="oasis-editor-dialog-button oasis-editor-dialog-button-primary">`);
41758
42011
  function ImageAltDialog(props) {
41759
42012
  const [alt, setAlt] = createSignal(props.initialAlt);
41760
42013
  let inputRef;
@@ -41780,19 +42033,19 @@ function ImageAltDialog(props) {
41780
42033
  },
41781
42034
  get footer() {
41782
42035
  return [(() => {
41783
- var _el$4 = _tmpl$2$6();
42036
+ var _el$4 = _tmpl$2$7();
41784
42037
  addEventListener(_el$4, "click", props.onClose, true);
41785
42038
  insert(_el$4, () => t("generic.cancel"));
41786
42039
  return _el$4;
41787
42040
  })(), (() => {
41788
- var _el$5 = _tmpl$3$4();
42041
+ var _el$5 = _tmpl$3$5();
41789
42042
  _el$5.$$click = handleConfirm;
41790
42043
  insert(_el$5, () => t("generic.save"));
41791
42044
  return _el$5;
41792
42045
  })()];
41793
42046
  },
41794
42047
  get children() {
41795
- var _el$ = _tmpl$$b(), _el$2 = _el$.firstChild, _el$3 = _el$2.nextSibling;
42048
+ var _el$ = _tmpl$$c(), _el$2 = _el$.firstChild, _el$3 = _el$2.nextSibling;
41796
42049
  insert(_el$2, () => t("dialog.imageAlt.label"));
41797
42050
  _el$3.$$keydown = (e) => e.key === "Enter" && handleConfirm();
41798
42051
  _el$3.$$input = (e) => setAlt(e.currentTarget.value);
@@ -41805,6 +42058,57 @@ function ImageAltDialog(props) {
41805
42058
  });
41806
42059
  }
41807
42060
  delegateEvents(["input", "keydown", "click"]);
42061
+ var _tmpl$$b = /* @__PURE__ */ template(`<div class=oasis-editor-dialog-input-group><label class=oasis-editor-dialog-label></label><input type=text class=oasis-editor-dialog-input>`), _tmpl$2$6 = /* @__PURE__ */ template(`<button class="oasis-editor-dialog-button oasis-editor-dialog-button-secondary">`), _tmpl$3$4 = /* @__PURE__ */ template(`<button class="oasis-editor-dialog-button oasis-editor-dialog-button-primary">`);
42062
+ function ImageCaptionDialog(props) {
42063
+ const [caption, setCaption] = createSignal(props.initialCaption);
42064
+ let inputRef;
42065
+ createEffect(() => {
42066
+ if (props.isOpen) {
42067
+ setCaption(props.initialCaption);
42068
+ setTimeout(() => inputRef == null ? void 0 : inputRef.focus(), 50);
42069
+ }
42070
+ });
42071
+ const handleConfirm = () => {
42072
+ props.onConfirm(caption());
42073
+ props.onClose();
42074
+ };
42075
+ return createComponent(Dialog, {
42076
+ get isOpen() {
42077
+ return props.isOpen;
42078
+ },
42079
+ get title() {
42080
+ return t("dialog.imageCaption.title");
42081
+ },
42082
+ get onClose() {
42083
+ return props.onClose;
42084
+ },
42085
+ get footer() {
42086
+ return [(() => {
42087
+ var _el$4 = _tmpl$2$6();
42088
+ addEventListener(_el$4, "click", props.onClose, true);
42089
+ insert(_el$4, () => t("generic.cancel"));
42090
+ return _el$4;
42091
+ })(), (() => {
42092
+ var _el$5 = _tmpl$3$4();
42093
+ _el$5.$$click = handleConfirm;
42094
+ insert(_el$5, () => t("generic.save"));
42095
+ return _el$5;
42096
+ })()];
42097
+ },
42098
+ get children() {
42099
+ var _el$ = _tmpl$$b(), _el$2 = _el$.firstChild, _el$3 = _el$2.nextSibling;
42100
+ insert(_el$2, () => t("dialog.imageCaption.label"));
42101
+ _el$3.$$keydown = (e) => e.key === "Enter" && handleConfirm();
42102
+ _el$3.$$input = (e) => setCaption(e.currentTarget.value);
42103
+ var _ref$ = inputRef;
42104
+ typeof _ref$ === "function" ? use(_ref$, _el$3) : inputRef = _el$3;
42105
+ createRenderEffect(() => setAttribute(_el$3, "placeholder", t("dialog.imageCaption.placeholder")));
42106
+ createRenderEffect(() => _el$3.value = caption());
42107
+ return _el$;
42108
+ }
42109
+ });
42110
+ }
42111
+ delegateEvents(["input", "keydown", "click"]);
41808
42112
  const DEFAULT_COLOR = "#111827";
41809
42113
  const DEFAULT_HIGHLIGHT = "#fef08a";
41810
42114
  const DEFAULT_SHADING = "#fef3c7";
@@ -43308,6 +43612,8 @@ function EditorDialogsLayer(props) {
43308
43612
  setLinkDialog,
43309
43613
  imageAltDialog,
43310
43614
  setImageAltDialog,
43615
+ imageCaptionDialog,
43616
+ setImageCaptionDialog,
43311
43617
  contextMenu,
43312
43618
  fontDialog,
43313
43619
  setFontDialog,
@@ -43346,6 +43652,21 @@ function EditorDialogsLayer(props) {
43346
43652
  props.focusInput();
43347
43653
  },
43348
43654
  onConfirm: (alt) => props.applyImageAltCommand(alt.trim())
43655
+ }), createComponent(ImageCaptionDialog, {
43656
+ get isOpen() {
43657
+ return imageCaptionDialog().isOpen;
43658
+ },
43659
+ get initialCaption() {
43660
+ return imageCaptionDialog().initialCaption;
43661
+ },
43662
+ onClose: () => {
43663
+ setImageCaptionDialog({
43664
+ ...imageCaptionDialog(),
43665
+ isOpen: false
43666
+ });
43667
+ props.focusInput();
43668
+ },
43669
+ onConfirm: (caption) => props.applyImageCaptionCommand(caption.trim())
43349
43670
  }), createComponent(FindReplaceDialog, {
43350
43671
  get fr() {
43351
43672
  return props.findReplace;
@@ -45782,6 +46103,8 @@ function OasisEditorApp(props = {}) {
45782
46103
  setLinkDialog,
45783
46104
  imageAltDialog,
45784
46105
  setImageAltDialog,
46106
+ imageCaptionDialog,
46107
+ setImageCaptionDialog,
45785
46108
  contextMenu,
45786
46109
  setContextMenu,
45787
46110
  fontDialog,
@@ -46081,7 +46404,12 @@ function OasisEditorApp(props = {}) {
46081
46404
  openImageAltDialog: (initialAlt) => setImageAltDialog({
46082
46405
  isOpen: true,
46083
46406
  initialAlt
46084
- })
46407
+ }),
46408
+ openImageCaptionDialog: (initialCaption) => setImageCaptionDialog({
46409
+ isOpen: true,
46410
+ initialCaption
46411
+ }),
46412
+ imageCaptionLabel: () => (ui().locale ?? "pt-BR").startsWith("en") ? "Figure" : "Figura"
46085
46413
  });
46086
46414
  const keyboardCommandsController = {
46087
46415
  ...commandsController,
@@ -46409,6 +46737,8 @@ function OasisEditorApp(props = {}) {
46409
46737
  setLinkDialog,
46410
46738
  imageAltDialog,
46411
46739
  setImageAltDialog,
46740
+ imageCaptionDialog,
46741
+ setImageCaptionDialog,
46412
46742
  contextMenu,
46413
46743
  setContextMenu,
46414
46744
  fontDialog,
@@ -46429,6 +46759,9 @@ function OasisEditorApp(props = {}) {
46429
46759
  get applyImageAltCommand() {
46430
46760
  return commandsController.applyImageAltCommand;
46431
46761
  },
46762
+ get applyImageCaptionCommand() {
46763
+ return commandsController.applyImageCaptionCommand;
46764
+ },
46432
46765
  applyFontDialogValues,
46433
46766
  applyParagraphDialogValues,
46434
46767
  applyTablePropertiesDialogValues,
@@ -21,6 +21,8 @@ export interface EditorCommandsControllerDeps {
21
21
  selectedImageRun: () => SelectedImageRun | null;
22
22
  openLinkDialog: (initialHref: string) => void;
23
23
  openImageAltDialog: (initialAlt: string) => void;
24
+ openImageCaptionDialog: (initialCaption: string) => void;
25
+ imageCaptionLabel: () => string;
24
26
  }
25
27
  export declare function createEditorCommandsController(deps: EditorCommandsControllerDeps): {
26
28
  applyBooleanStyleCommand: (key: BooleanStyleKey) => void;
@@ -48,6 +50,8 @@ export declare function createEditorCommandsController(deps: EditorCommandsContr
48
50
  removeLinkCommand: () => void;
49
51
  applyImageAltCommand: (alt: string) => void;
50
52
  promptForImageAlt: () => void;
53
+ applyImageCaptionCommand: (caption: string) => void;
54
+ promptForImageCaption: () => void;
51
55
  handleListTab: (direction: "indent" | "outdent") => boolean;
52
56
  handleListEnter: () => boolean;
53
57
  handleListBoundaryBackspace: (event: KeyboardEvent & {