@forevka/wordcanvas 0.7.0 → 0.7.1

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 (47) hide show
  1. package/README.md +48 -1
  2. package/dist-lib/assets/{worker-BsOsK39A.js → worker-D8rUOKfg.js} +9603 -9451
  3. package/dist-lib/assets/worker-wXuuyshQ.js +2258 -0
  4. package/dist-lib/{blockFactory-Bcy0U40y.js → blockFactory-CUI4Rqiq.js} +50 -42
  5. package/dist-lib/{browser-5Sv4CuNy.js → browser-DkKxreJM.js} +404 -383
  6. package/dist-lib/builder.js +364 -109
  7. package/dist-lib/editorApp-DLXMmtu5.js +8023 -0
  8. package/dist-lib/export.js +3820 -3768
  9. package/dist-lib/generate-toc.js +4 -4
  10. package/dist-lib/import.js +4 -1538
  11. package/dist-lib/{lists-BegzmTmD.js → lists-Sc5I40JO.js} +2 -2
  12. package/dist-lib/pipeline-CbxmCE84.js +1705 -0
  13. package/dist-lib/recalc-docx.js +2 -2
  14. package/dist-lib/recalcToc-g1hFKSNs.js +3935 -0
  15. package/dist-lib/toc-B6VpkJge.js +213 -0
  16. package/dist-lib/{webmcp-B7Gvd58E.js → webmcp-6WxRNKCc.js} +2 -2
  17. package/dist-lib/{wordcanvas-BAxBeErX.js → wordcanvas-CFqpDK0k.js} +1 -1
  18. package/dist-lib/wordcanvas.js +1 -1
  19. package/dist-node/{chunk-GXFDF7UY.js → chunk-22JHAERT.js} +95 -23
  20. package/dist-node/chunk-22JHAERT.js.map +7 -0
  21. package/dist-node/{chunk-2RCPB7UZ.js → chunk-6AJJMHKY.js} +1 -1
  22. package/dist-node/chunk-6AJJMHKY.js.map +7 -0
  23. package/dist-node/{chunk-XDUDPPJW.js → chunk-CDN6WU2P.js} +89 -26
  24. package/dist-node/chunk-CDN6WU2P.js.map +7 -0
  25. package/dist-node/{chunk-TBSXA2I4.js → chunk-EGSAVPCC.js} +1 -1
  26. package/dist-node/chunk-EGSAVPCC.js.map +7 -0
  27. package/dist-node/{chunk-IJLL6IFJ.js → chunk-RNB336F3.js} +116 -5
  28. package/dist-node/{chunk-IJLL6IFJ.js.map → chunk-RNB336F3.js.map} +2 -2
  29. package/dist-node/{engine-FRCX7PXF.js → engine-5FGDJD2H.js} +3 -3
  30. package/dist-node/export.js +92 -31
  31. package/dist-node/export.js.map +2 -2
  32. package/dist-node/generate-toc.js +5 -5
  33. package/dist-node/import.js +3 -3
  34. package/dist-node/recalc-docx.js +4 -4
  35. package/dist-node/recalc-docx.js.map +1 -1
  36. package/package.json +1 -1
  37. package/types/model.d.ts +231 -225
  38. package/types/recalc-docx.d.ts +27 -27
  39. package/dist-lib/assets/worker-BbFAIxdy.js +0 -2163
  40. package/dist-lib/editorApp-DvjFPHiy.js +0 -7582
  41. package/dist-lib/recalcToc-uaLWt59L.js +0 -3835
  42. package/dist-lib/toc-CZel_Kk3.js +0 -127
  43. package/dist-node/chunk-2RCPB7UZ.js.map +0 -7
  44. package/dist-node/chunk-GXFDF7UY.js.map +0 -7
  45. package/dist-node/chunk-TBSXA2I4.js.map +0 -7
  46. package/dist-node/chunk-XDUDPPJW.js.map +0 -7
  47. /package/dist-node/{engine-FRCX7PXF.js.map → engine-5FGDJD2H.js.map} +0 -0
@@ -9,7 +9,7 @@ import {
9
9
  formatListNumber,
10
10
  isHiddenParagraph,
11
11
  markerText
12
- } from "./chunk-XDUDPPJW.js";
12
+ } from "./chunk-CDN6WU2P.js";
13
13
  import {
14
14
  charStyleToFont,
15
15
  fontMetrics,
@@ -3868,6 +3868,12 @@ var PrepareCache = class {
3868
3868
  evict(blockId) {
3869
3869
  this.map.delete(blockId);
3870
3870
  }
3871
+ /** Drop every entry — used when the whole document is replaced (the importer
3872
+ * re-mints block ids from i0, so a stale entry at the same id+revision would
3873
+ * otherwise leak the previous document's prepared text into the new one). */
3874
+ clear() {
3875
+ this.map.clear();
3876
+ }
3871
3877
  /** Drop every entry whose id is NOT in `keep` (paragraphs no longer in the
3872
3878
  * document). Called after a full layout to bound the cache to live blocks. */
3873
3879
  retainOnly(keep) {
@@ -3910,6 +3916,10 @@ function createLayoutEngine() {
3910
3916
  evict(blockId) {
3911
3917
  prepCache.evict(blockId);
3912
3918
  linesCache.delete(blockId);
3919
+ },
3920
+ reset() {
3921
+ prepCache.clear();
3922
+ linesCache.clear();
3913
3923
  }
3914
3924
  };
3915
3925
  }
@@ -4379,7 +4389,7 @@ function layoutDocument(doc, getLines, getPrepared, rawBand) {
4379
4389
  lines: getLines(block, colWidth - indentOf(block) - rightIndentOf(block) - gutter)
4380
4390
  });
4381
4391
  } else if (block.kind === "image") {
4382
- measured.push({ kind: "image", block, height: block.heightPx });
4392
+ measured.push({ kind: "image", block, height: block.anchor ? 0 : block.heightPx });
4383
4393
  } else {
4384
4394
  const t = measureTable(block, colWidth, getLines, cellListCtx);
4385
4395
  measured.push({ kind: "table", block, ...t });
@@ -4610,7 +4620,59 @@ function layoutDocument(doc, getLines, getPrepared, rawBand) {
4610
4620
  return { x0, width: Math.max(40, x1 - x0) };
4611
4621
  };
4612
4622
  const floatsActiveAt = (yy) => floats.some((f) => f.bottom > yy);
4623
+ const placeAnchoredImage = (img) => {
4624
+ const a = img.anchor;
4625
+ let ox;
4626
+ switch (a.relFromH) {
4627
+ case "page":
4628
+ case "leftMargin":
4629
+ ox = 0;
4630
+ break;
4631
+ case "rightMargin":
4632
+ ox = sec.pageWidthPx - sec.marginPx.right;
4633
+ break;
4634
+ case "column":
4635
+ ox = colX();
4636
+ break;
4637
+ default:
4638
+ ox = sec.marginPx.left;
4639
+ break;
4640
+ }
4641
+ let oy;
4642
+ switch (a.relFromV) {
4643
+ case "page":
4644
+ case "topMargin":
4645
+ oy = 0;
4646
+ break;
4647
+ case "bottomMargin":
4648
+ oy = sec.pageHeightPx - sec.marginPx.bottom;
4649
+ break;
4650
+ case "paragraph":
4651
+ case "line":
4652
+ oy = y;
4653
+ break;
4654
+ // current flow position
4655
+ default:
4656
+ oy = sec.marginPx.top;
4657
+ break;
4658
+ }
4659
+ const placedImage = { src: img.src, width: img.widthPx, height: img.heightPx, z: a.z ?? 0 };
4660
+ if (a.behind) placedImage.behind = true;
4661
+ else placedImage.front = true;
4662
+ page.blocks.push({
4663
+ blockId: img.id,
4664
+ x: ox + a.offsetXPx,
4665
+ y: oy + a.offsetYPx,
4666
+ firstLineIndex: 0,
4667
+ lines: [],
4668
+ image: placedImage
4669
+ });
4670
+ };
4613
4671
  const placeImage = (img) => {
4672
+ if (img.anchor) {
4673
+ placeAnchoredImage(img);
4674
+ return;
4675
+ }
4614
4676
  if (y + img.heightPx > bottomY() && colHasContent()) newPage();
4615
4677
  const floating = img.wrap === "square" && img.align !== "center";
4616
4678
  const slack = colWidth - img.widthPx;
@@ -4638,7 +4700,10 @@ function layoutDocument(doc, getLines, getPrepared, rawBand) {
4638
4700
  if (placed === null) {
4639
4701
  placed = { blockId: p.id, x: colX() + indentOf(p), y, firstLineIndex: lineIdx, lines: [] };
4640
4702
  const marker = lineIdx === 0 ? markers.get(p.id) : void 0;
4641
- if (marker) placed.marker = { text: marker.text, style: marker.style, x: placed.x - marker.hangingPx };
4703
+ if (marker) {
4704
+ const firstX = frags[0]?.frag.x ?? 0;
4705
+ placed.marker = { text: marker.text, style: marker.style, x: placed.x + firstX - marker.hangingPx };
4706
+ }
4642
4707
  page.blocks.push(placed);
4643
4708
  }
4644
4709
  const box = { y: y - placed.y, height, ascent, fragments: frags.map((rf) => rf.frag) };
@@ -4752,10 +4817,14 @@ function layoutDocument(doc, getLines, getPrepared, rawBand) {
4752
4817
  startSectionPage();
4753
4818
  }
4754
4819
  const m = measured[bi];
4755
- const atomicKind = (x) => x?.kind === "table" || x?.kind === "image";
4820
+ const atomicKind = (x) => x?.kind === "table" || x?.kind === "image" && x.block.anchor === void 0;
4756
4821
  const prevAtomic = atomicKind(measured[bi - 1]);
4757
4822
  const nextAtomic = atomicKind(measured[bi + 1]);
4758
4823
  if (m.kind === "image") {
4824
+ if (m.block.anchor) {
4825
+ placeImage(m.block);
4826
+ continue;
4827
+ }
4759
4828
  if (!prevAtomic) y += ATOMIC_GAP;
4760
4829
  placeImage(m.block);
4761
4830
  if (!nextAtomic && (m.block.wrap !== "square" || m.block.align === "center")) y += ATOMIC_GAP;
@@ -4860,6 +4929,19 @@ function layoutDocument(doc, getLines, getPrepared, rawBand) {
4860
4929
  }
4861
4930
  }
4862
4931
  }
4932
+ for (const pg of pages) {
4933
+ if (!pg.blocks.some((b) => b.image?.behind || b.image?.front)) continue;
4934
+ const layer = (b) => b.image?.behind ? 0 : b.image?.front ? 2 : 1;
4935
+ pg.blocks = pg.blocks.map((b, i) => ({ b, i })).sort((p, q) => {
4936
+ const dl = layer(p.b) - layer(q.b);
4937
+ if (dl !== 0) return dl;
4938
+ if (layer(p.b) !== 1) {
4939
+ const dz = (p.b.image.z ?? 0) - (q.b.image.z ?? 0);
4940
+ if (dz !== 0) return dz;
4941
+ }
4942
+ return p.i - q.i;
4943
+ }).map((x) => x.b);
4944
+ }
4863
4945
  const pageNumbers = [];
4864
4946
  {
4865
4947
  let n = 0;
@@ -4872,6 +4954,35 @@ function layoutDocument(doc, getLines, getPrepared, rawBand) {
4872
4954
  pages[i].number = n;
4873
4955
  }
4874
4956
  }
4957
+ const fieldDefs = doc.fields;
4958
+ if (fieldDefs) {
4959
+ const isPageNumField = (fid) => {
4960
+ if (fid === void 0) return false;
4961
+ const def = fieldDefs[fid];
4962
+ const t = def && def.kind === "builtin" ? def.spec?.type : void 0;
4963
+ return t === "PAGE" || t === "NUMPAGES";
4964
+ };
4965
+ const resolveLineTokens = (line, pageNum) => {
4966
+ let dx = 0;
4967
+ for (const frag of line.fragments) {
4968
+ if (dx !== 0) frag.x += dx;
4969
+ if (!isPageNumField(frag.style.fieldId)) continue;
4970
+ const sub = substituteTokens(frag.text, pageNum, pages.length);
4971
+ if (sub === frag.text) continue;
4972
+ const modelLen = frag.endOffset - frag.startOffset;
4973
+ const oldWidth = frag.width;
4974
+ frag.text = sub;
4975
+ frag.width = measureTextWidth(sub, charStyleToFont(frag.style));
4976
+ frag.offsetMap = Array.from({ length: sub.length + 1 }, (_v, i) => i === sub.length ? modelLen : 0);
4977
+ dx += frag.width - oldWidth;
4978
+ }
4979
+ };
4980
+ const resolveBlockTokens = (b, pageNum) => {
4981
+ for (const line of b.lines) resolveLineTokens(line, pageNum);
4982
+ if (b.table) for (const row of b.table.rows) for (const cell of row.cells) for (const cb of cell.blocks) resolveBlockTokens(cb, pageNum);
4983
+ };
4984
+ for (const pg of pages) for (const b of pg.blocks) resolveBlockTokens(b, pageNumbers[pg.index]);
4985
+ }
4875
4986
  if (tocPlacements.size > 0) {
4876
4987
  const firstPageOf = /* @__PURE__ */ new Map();
4877
4988
  const mapPage = (blocks, num) => {
@@ -5200,4 +5311,4 @@ export {
5200
5311
  effectiveSection,
5201
5312
  resolveSections
5202
5313
  };
5203
- //# sourceMappingURL=chunk-IJLL6IFJ.js.map
5314
+ //# sourceMappingURL=chunk-RNB336F3.js.map