web-doc 0.9.0 → 0.11.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.
Files changed (48) hide show
  1. package/THIRD_PARTY_NOTICES.md +14 -0
  2. package/dist/adapters/office.js +6 -3
  3. package/dist/contracts.d.ts +9 -0
  4. package/dist/edit/docx/engine.d.ts +9 -1
  5. package/dist/edit/docx/engine.js +22 -0
  6. package/dist/edit/docx/provider.d.ts +3 -1
  7. package/dist/edit/docx/provider.js +3 -0
  8. package/dist/edit/docx/session.d.ts +6 -2
  9. package/dist/edit/docx/session.js +7 -1
  10. package/dist/edit/docx/style.d.ts +1 -1
  11. package/dist/edit/docx/style.js +3 -2
  12. package/dist/edit/docx/types.d.ts +11 -1
  13. package/dist/edit/pdf/engine/cff.d.ts +28 -0
  14. package/dist/edit/pdf/engine/cff.js +416 -0
  15. package/dist/edit/pdf/engine/document.d.ts +3 -1
  16. package/dist/edit/pdf/engine/document.js +21 -1
  17. package/dist/edit/pdf/engine/elements.d.ts +7 -0
  18. package/dist/edit/pdf/engine/elements.js +12 -1
  19. package/dist/edit/pdf/engine/existing-text.js +6 -4
  20. package/dist/edit/pdf/engine/glyph-names.d.ts +2 -0
  21. package/dist/edit/pdf/engine/glyph-names.js +163 -0
  22. package/dist/edit/pdf/engine/handler.js +2 -0
  23. package/dist/edit/pdf/engine/opentype.d.ts +14 -0
  24. package/dist/edit/pdf/engine/opentype.js +317 -0
  25. package/dist/edit/pdf/engine/text-font.d.ts +4 -0
  26. package/dist/edit/pdf/engine/text-font.js +81 -0
  27. package/dist/edit/pdf/provider.d.ts +3 -1
  28. package/dist/edit/pdf/provider.js +3 -0
  29. package/dist/edit/pdf/session.d.ts +2 -1
  30. package/dist/edit/pdf/session.js +3 -0
  31. package/dist/edit/pdf/types.d.ts +40 -0
  32. package/dist/edit/pptx/elements.d.ts +4 -1
  33. package/dist/edit/pptx/elements.js +35 -0
  34. package/dist/edit/pptx/engine.d.ts +5 -1
  35. package/dist/edit/pptx/engine.js +11 -0
  36. package/dist/edit/pptx/handler.js +8 -0
  37. package/dist/edit/pptx/provider.d.ts +3 -1
  38. package/dist/edit/pptx/provider.js +3 -0
  39. package/dist/edit/pptx/session.d.ts +13 -4
  40. package/dist/edit/pptx/session.js +48 -4
  41. package/dist/edit/pptx/types.d.ts +11 -1
  42. package/dist/edit/range-style.d.ts +24 -0
  43. package/dist/edit/range-style.js +46 -0
  44. package/dist/viewport.js +83 -20
  45. package/dist/worker-protocol.d.ts +1 -1
  46. package/dist/workers/ooxml-edit-worker.js +90 -2
  47. package/dist/workers/pdf-edit-worker.js +1118 -184
  48. package/package.json +1 -1
@@ -2166,11 +2166,12 @@ var DocxStyles = class _DocxStyles {
2166
2166
  node.children.find((child) => child.local === "basedOn") ?? node,
2167
2167
  "w:val"
2168
2168
  );
2169
+ const defaultAttribute = part.attribute(node, "w:default");
2169
2170
  const record = {
2170
2171
  id,
2171
2172
  type: part.attribute(node, "w:type") ?? "paragraph",
2172
2173
  ...basedOn && basedOn !== id ? { basedOn } : {},
2173
- isDefault: isOn(part.attribute(node, "w:default")),
2174
+ isDefault: defaultAttribute !== void 0 && isOn(defaultAttribute),
2174
2175
  ...pick(node, "rPr", "pPr")
2175
2176
  };
2176
2177
  styles.set(id, record);
@@ -5329,6 +5330,31 @@ function issueCollector(operationIndex, issues) {
5329
5330
  return (path, code, message) => issues.push({ operationIndex, path, code, message });
5330
5331
  }
5331
5332
 
5333
+ // src/edit/range-style.ts
5334
+ function runsCovering(runs, span) {
5335
+ if (span.start < span.end)
5336
+ return runs.filter((run2) => run2.start < span.end && run2.end > span.start);
5337
+ const before = runs.filter((run2) => run2.start < span.start && run2.end >= span.start).at(-1);
5338
+ const at = before ?? runs.find((run2) => run2.start >= span.start);
5339
+ return at ? [at] : [];
5340
+ }
5341
+ function sharedStyle(styles) {
5342
+ const [first, ...rest] = styles;
5343
+ if (!first) return void 0;
5344
+ const shared = {};
5345
+ for (const key of Object.keys(first)) {
5346
+ const value = JSON.stringify(first[key]);
5347
+ if (rest.every(
5348
+ (style) => key in style && JSON.stringify(style[key]) === value
5349
+ ))
5350
+ shared[key] = first[key];
5351
+ }
5352
+ return shared;
5353
+ }
5354
+ function spanFits(span, length) {
5355
+ return span.start >= 0 && span.start <= span.end && span.end <= length;
5356
+ }
5357
+
5332
5358
  // src/edit/docx/engine.ts
5333
5359
  var UNAUTHORED_PART = "/webdoc/unauthored.xml";
5334
5360
  var UNAUTHORED_NS = "urn:web-doc:docx-edit";
@@ -5602,6 +5628,26 @@ var DocxEditEngine = class _DocxEditEngine {
5602
5628
  if (!record || record.kind !== "paragraph") return [];
5603
5629
  return revisionsOf(model.document, record.node);
5604
5630
  }
5631
+ /**
5632
+ * The style a span of a paragraph shows: what every run it covers shares;
5633
+ * the paragraph mark's for an empty paragraph. None for another element,
5634
+ * an unknown id or a span past the text.
5635
+ */
5636
+ async textStyle(id, span, signal) {
5637
+ const model = await this.model(signal);
5638
+ const record = model.byId.get(id);
5639
+ if (!record || record.kind !== "paragraph") return void 0;
5640
+ const { text, items } = record.text;
5641
+ const range = span ?? { start: 0, end: text.length };
5642
+ if (!spanFits(range, text.length)) return void 0;
5643
+ const covered = runsCovering(items, range);
5644
+ const mark = record.pPr?.children.find((child) => child.local === "rPr");
5645
+ return sharedStyle(
5646
+ covered.length > 0 ? covered.map(
5647
+ (item) => resolveTextStyle(model.styles, record.pPr, item.rPr)
5648
+ ) : [resolveTextStyle(model.styles, record.pPr, mark)]
5649
+ );
5650
+ }
5605
5651
  async materialize(purposeOrSignal = "show", options = {}, signal = new AbortController().signal) {
5606
5652
  return (await this.materializeDocument(purposeOrSignal, options, signal)).bytes;
5607
5653
  }
@@ -6469,7 +6515,10 @@ function readRecord(context, node, parents, parent, readOnly, walk) {
6469
6515
  ...spPr ? { spPr } : {},
6470
6516
  ...text ? { text } : {},
6471
6517
  readOnly,
6472
- ...parent ? { parent } : {}
6518
+ ...parent ? { parent } : {},
6519
+ ...text && txBody ? {
6520
+ styleOf: (span) => rangeStyleOf(context, placeholder, txBody, text, span)
6521
+ } : {}
6473
6522
  };
6474
6523
  }
6475
6524
  function operationsFor(kind, hasText) {
@@ -6513,6 +6562,29 @@ function listStylesOf(context, txBody, placeholder) {
6513
6562
  if (defaults) lists.push(defaults);
6514
6563
  return lists;
6515
6564
  }
6565
+ function rangeStyleOf(context, placeholder, txBody, text, span) {
6566
+ const lists = listStylesOf(context, txBody, placeholder);
6567
+ const styleOf = (paragraph2, rPr) => resolveTextStyle2({
6568
+ ...rPr ? { rPr: { part: context.part, node: rPr } } : {},
6569
+ ...paragraph2.pPr ? { pPr: { part: context.part, node: paragraph2.pPr } } : {},
6570
+ level: paragraph2.level,
6571
+ lists,
6572
+ fonts: context.fonts
6573
+ });
6574
+ const runs = text.paragraphs.flatMap(
6575
+ (paragraph2) => paragraph2.runs.map((run2) => ({
6576
+ start: run2.start,
6577
+ end: run2.end,
6578
+ style: () => styleOf(paragraph2, run2.rPr)
6579
+ }))
6580
+ );
6581
+ const covered = runsCovering(runs, span);
6582
+ if (covered.length > 0) return sharedStyle(covered.map((run2) => run2.style()));
6583
+ const paragraph = text.paragraphs.find(
6584
+ (candidate) => candidate.start <= span.start && span.start <= candidate.end
6585
+ ) ?? text.paragraphs[0];
6586
+ return paragraph ? sharedStyle([styleOf(paragraph, paragraph.endParaRPr)]) : void 0;
6587
+ }
6516
6588
  function textStyleOf(context, placeholder, txBody, text) {
6517
6589
  const first = firstTextRun(text);
6518
6590
  const paragraph = first?.paragraph ?? text.paragraphs[0];
@@ -8918,6 +8990,14 @@ var PptxEditEngine = class _PptxEditEngine {
8918
8990
  });
8919
8991
  return out;
8920
8992
  }
8993
+ /** The style a span of a shape's text shows; none for an element without text or a span past it. */
8994
+ async textStyle(id, span, signal) {
8995
+ const record = await this.#locate(id, signal);
8996
+ if (!record?.styleOf || !record.text) return void 0;
8997
+ const range = span ?? { start: 0, end: record.text.text.length };
8998
+ if (!spanFits(range, record.text.text.length)) return void 0;
8999
+ return record.styleOf(range);
9000
+ }
8921
9001
  async layouts(signal) {
8922
9002
  const model = await this.model(signal);
8923
9003
  return model.layouts.map((layout) => ({
@@ -9136,6 +9216,14 @@ function createOoxmlEditHandler() {
9136
9216
  payload.id,
9137
9217
  signal
9138
9218
  );
9219
+ case "edit-docx-text-style": {
9220
+ const { id, span } = payload;
9221
+ return docx().textStyle(id, span, signal);
9222
+ }
9223
+ case "edit-pptx-text-style": {
9224
+ const { id, span } = payload;
9225
+ return pptx().textStyle(id, span, signal);
9226
+ }
9139
9227
  case "edit-dispose":
9140
9228
  await state?.dispose();
9141
9229
  state = void 0;