js.documents 7.20.32 → 7.20.33

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.
@@ -5,20 +5,19 @@ const require_metadata_core_patch = require("../../metadata/core-patch.cjs");
5
5
  const require_model_metadata = require("../../model/metadata.cjs");
6
6
  const require_ports_clock = require("../../ports/clock.cjs");
7
7
  const require_edit_docx_paragraph = require("./paragraph.cjs");
8
+ const require_edit_docx_parts = require("./parts.cjs");
8
9
  const require_edit_docx_scaffold = require("./scaffold.cjs");
9
10
  const require_edit_docx_table = require("./table.cjs");
10
11
  let ooxml_js = require("ooxml.js");
11
12
  //#region src/edit/docx/editor.ts
12
- const DOCUMENT_PART_PATH = "word/document.xml";
13
- const MEDIA_DIR = "word/media";
14
- function findDocumentRoot(pkg) {
15
- const root = (0, ooxml_js.rootElement)(pkg.parts[DOCUMENT_PART_PATH]);
16
- if (root === void 0) throw new Error(`package has no root element at ${DOCUMENT_PART_PATH}`);
13
+ function findDocumentRoot(pkg, documentPartPath) {
14
+ const root = (0, ooxml_js.rootElement)(pkg.parts[documentPartPath]);
15
+ if (root === void 0) throw new Error(`package has no root element at ${documentPartPath}`);
17
16
  return root;
18
17
  }
19
- function findBody(documentRoot) {
18
+ function findBody(documentRoot, documentPartPath) {
20
19
  for (const child of documentRoot.children) if (child.type === "element" && child.tag === "w:body") return child;
21
- throw new Error(`${DOCUMENT_PART_PATH} has no w:body element`);
20
+ throw new Error(`${documentPartPath} has no w:body element`);
22
21
  }
23
22
  function bodyInsertionPoint(body) {
24
23
  const sectPrIndex = body.children.findIndex((c) => c.type === "element" && c.tag === "w:sectPr");
@@ -170,17 +169,21 @@ function spellDeletedText(element) {
170
169
  var DocxEditor = class {
171
170
  body;
172
171
  pkg;
172
+ documentPartPath;
173
+ mediaDir;
173
174
  constructor(pkg) {
174
175
  this.pkg = pkg;
175
- const documentRoot = findDocumentRoot(pkg);
176
- const body = findBody(documentRoot);
176
+ this.documentPartPath = require_edit_docx_parts.docxMainPartPath(pkg);
177
+ this.mediaDir = require_edit_docx_parts.docxMediaDir(this.documentPartPath);
178
+ const documentRoot = findDocumentRoot(pkg, this.documentPartPath);
179
+ const body = findBody(documentRoot, this.documentPartPath);
177
180
  const imageContext = {
178
181
  pkg,
179
182
  documentRoot,
180
183
  media: {
181
184
  pkg,
182
- partPath: DOCUMENT_PART_PATH,
183
- mediaDir: MEDIA_DIR
185
+ partPath: this.documentPartPath,
186
+ mediaDir: this.mediaDir
184
187
  }
185
188
  };
186
189
  this.body = new DocxBodyImpl(body, imageContext, this.pkg);
@@ -192,15 +195,15 @@ var DocxEditor = class {
192
195
  require_metadata_core_patch.patchOoxmlCorePropertiesOnPackage(this.pkg, value);
193
196
  }
194
197
  paragraphs() {
195
- const documentRoot = findDocumentRoot(this.pkg);
196
- const body = findBody(documentRoot);
198
+ const documentRoot = findDocumentRoot(this.pkg, this.documentPartPath);
199
+ const body = findBody(documentRoot, this.documentPartPath);
197
200
  const imageContext = {
198
201
  pkg: this.pkg,
199
202
  documentRoot,
200
203
  media: {
201
204
  pkg: this.pkg,
202
- partPath: DOCUMENT_PART_PATH,
203
- mediaDir: MEDIA_DIR
205
+ partPath: this.documentPartPath,
206
+ mediaDir: this.mediaDir
204
207
  }
205
208
  };
206
209
  const out = [];
@@ -208,7 +211,7 @@ var DocxEditor = class {
208
211
  return out;
209
212
  }
210
213
  tables() {
211
- const body = findBody(findDocumentRoot(this.pkg));
214
+ const body = findBody(findDocumentRoot(this.pkg, this.documentPartPath), this.documentPartPath);
212
215
  const out = [];
213
216
  for (const child of body.children) if (child.type === "element" && child.tag === "w:tbl") out.push(new require_edit_docx_table.DocxTable(body.children, child));
214
217
  return out;
@@ -18,6 +18,8 @@ interface DocxBody {
18
18
  declare class DocxEditor {
19
19
  readonly body: DocxBody;
20
20
  private readonly pkg;
21
+ private readonly documentPartPath;
22
+ private readonly mediaDir;
21
23
  constructor(pkg: Package);
22
24
  get metadata(): LayoutMetadata;
23
25
  set metadata(value: LayoutMetadata);
@@ -18,6 +18,8 @@ interface DocxBody {
18
18
  declare class DocxEditor {
19
19
  readonly body: DocxBody;
20
20
  private readonly pkg;
21
+ private readonly documentPartPath;
22
+ private readonly mediaDir;
21
23
  constructor(pkg: Package);
22
24
  get metadata(): LayoutMetadata;
23
25
  set metadata(value: LayoutMetadata);
@@ -4,20 +4,19 @@ import { patchOoxmlCorePropertiesOnPackage } from "../../metadata/core-patch.js"
4
4
  import { resolveMetadataTimestamps } from "../../model/metadata.js";
5
5
  import { systemClock } from "../../ports/clock.js";
6
6
  import { DocxParagraph, buildParagraph } from "./paragraph.js";
7
+ import { docxMainPartPath, docxMediaDir } from "./parts.js";
7
8
  import { createEmptyDocxPackage } from "./scaffold.js";
8
9
  import { DocxTable, buildTable } from "./table.js";
9
10
  import { decodePackage, encodePackage, readCoreProperties, rootElement } from "ooxml.js";
10
11
  //#region src/edit/docx/editor.ts
11
- const DOCUMENT_PART_PATH = "word/document.xml";
12
- const MEDIA_DIR = "word/media";
13
- function findDocumentRoot(pkg) {
14
- const root = rootElement(pkg.parts[DOCUMENT_PART_PATH]);
15
- if (root === void 0) throw new Error(`package has no root element at ${DOCUMENT_PART_PATH}`);
12
+ function findDocumentRoot(pkg, documentPartPath) {
13
+ const root = rootElement(pkg.parts[documentPartPath]);
14
+ if (root === void 0) throw new Error(`package has no root element at ${documentPartPath}`);
16
15
  return root;
17
16
  }
18
- function findBody(documentRoot) {
17
+ function findBody(documentRoot, documentPartPath) {
19
18
  for (const child of documentRoot.children) if (child.type === "element" && child.tag === "w:body") return child;
20
- throw new Error(`${DOCUMENT_PART_PATH} has no w:body element`);
19
+ throw new Error(`${documentPartPath} has no w:body element`);
21
20
  }
22
21
  function bodyInsertionPoint(body) {
23
22
  const sectPrIndex = body.children.findIndex((c) => c.type === "element" && c.tag === "w:sectPr");
@@ -169,17 +168,21 @@ function spellDeletedText(element) {
169
168
  var DocxEditor = class {
170
169
  body;
171
170
  pkg;
171
+ documentPartPath;
172
+ mediaDir;
172
173
  constructor(pkg) {
173
174
  this.pkg = pkg;
174
- const documentRoot = findDocumentRoot(pkg);
175
- const body = findBody(documentRoot);
175
+ this.documentPartPath = docxMainPartPath(pkg);
176
+ this.mediaDir = docxMediaDir(this.documentPartPath);
177
+ const documentRoot = findDocumentRoot(pkg, this.documentPartPath);
178
+ const body = findBody(documentRoot, this.documentPartPath);
176
179
  const imageContext = {
177
180
  pkg,
178
181
  documentRoot,
179
182
  media: {
180
183
  pkg,
181
- partPath: DOCUMENT_PART_PATH,
182
- mediaDir: MEDIA_DIR
184
+ partPath: this.documentPartPath,
185
+ mediaDir: this.mediaDir
183
186
  }
184
187
  };
185
188
  this.body = new DocxBodyImpl(body, imageContext, this.pkg);
@@ -191,15 +194,15 @@ var DocxEditor = class {
191
194
  patchOoxmlCorePropertiesOnPackage(this.pkg, value);
192
195
  }
193
196
  paragraphs() {
194
- const documentRoot = findDocumentRoot(this.pkg);
195
- const body = findBody(documentRoot);
197
+ const documentRoot = findDocumentRoot(this.pkg, this.documentPartPath);
198
+ const body = findBody(documentRoot, this.documentPartPath);
196
199
  const imageContext = {
197
200
  pkg: this.pkg,
198
201
  documentRoot,
199
202
  media: {
200
203
  pkg: this.pkg,
201
- partPath: DOCUMENT_PART_PATH,
202
- mediaDir: MEDIA_DIR
204
+ partPath: this.documentPartPath,
205
+ mediaDir: this.mediaDir
203
206
  }
204
207
  };
205
208
  const out = [];
@@ -207,7 +210,7 @@ var DocxEditor = class {
207
210
  return out;
208
211
  }
209
212
  tables() {
210
- const body = findBody(findDocumentRoot(this.pkg));
213
+ const body = findBody(findDocumentRoot(this.pkg, this.documentPartPath), this.documentPartPath);
211
214
  const out = [];
212
215
  for (const child of body.children) if (child.type === "element" && child.tag === "w:tbl") out.push(new DocxTable(body.children, child));
213
216
  return out;
@@ -0,0 +1,15 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_opc_paths = require("../../opc/paths.cjs");
3
+ let ooxml_js = require("ooxml.js");
4
+ //#region src/edit/docx/parts.ts
5
+ const CONVENTIONAL_DOCUMENT_PART_PATH = "word/document.xml";
6
+ const MEDIA_DIR_NAME = "media";
7
+ function docxMainPartPath(pkg) {
8
+ return (0, ooxml_js.findMainPartPath)(pkg) ?? CONVENTIONAL_DOCUMENT_PART_PATH;
9
+ }
10
+ function docxMediaDir(documentPartPath) {
11
+ return require_opc_paths.siblingDirectory(documentPartPath, MEDIA_DIR_NAME);
12
+ }
13
+ //#endregion
14
+ exports.docxMainPartPath = docxMainPartPath;
15
+ exports.docxMediaDir = docxMediaDir;
@@ -0,0 +1,6 @@
1
+ import { Package } from "ooxml.js";
2
+ //#region src/edit/docx/parts.d.ts
3
+ declare function docxMainPartPath(pkg: Package): string;
4
+ declare function docxMediaDir(documentPartPath: string): string;
5
+ //#endregion
6
+ export { docxMainPartPath, docxMediaDir };
@@ -0,0 +1,6 @@
1
+ import { Package } from "ooxml.js";
2
+ //#region src/edit/docx/parts.d.ts
3
+ declare function docxMainPartPath(pkg: Package): string;
4
+ declare function docxMediaDir(documentPartPath: string): string;
5
+ //#endregion
6
+ export { docxMainPartPath, docxMediaDir };
@@ -0,0 +1,13 @@
1
+ import { siblingDirectory } from "../../opc/paths.js";
2
+ import { findMainPartPath } from "ooxml.js";
3
+ //#region src/edit/docx/parts.ts
4
+ const CONVENTIONAL_DOCUMENT_PART_PATH = "word/document.xml";
5
+ const MEDIA_DIR_NAME = "media";
6
+ function docxMainPartPath(pkg) {
7
+ return findMainPartPath(pkg) ?? CONVENTIONAL_DOCUMENT_PART_PATH;
8
+ }
9
+ function docxMediaDir(documentPartPath) {
10
+ return siblingDirectory(documentPartPath, MEDIA_DIR_NAME);
11
+ }
12
+ //#endregion
13
+ export { docxMainPartPath, docxMediaDir };
@@ -9,9 +9,9 @@ const require_ports_clock = require("../../ports/clock.cjs");
9
9
  const require_model_units = require("../../model/units.cjs");
10
10
  const require_edit_pptx_scaffold = require("./scaffold.cjs");
11
11
  const require_edit_pptx_slide = require("./slide.cjs");
12
+ const require_edit_pptx_parts = require("./parts.cjs");
12
13
  let ooxml_js = require("ooxml.js");
13
14
  //#region src/edit/pptx/editor.ts
14
- const MEDIA_DIR = "ppt/media";
15
15
  const SLIDE_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.presentationml.slide+xml";
16
16
  const SLIDE_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide";
17
17
  function directChild(parent, tag) {
@@ -20,19 +20,19 @@ function directChild(parent, tag) {
20
20
  function attrValue(element, name) {
21
21
  for (const a of element.attributes) if (a.name === name) return a.value;
22
22
  }
23
- function findPresentationRoot(pkg) {
24
- const root = (0, ooxml_js.rootElement)(pkg.parts[require_edit_pptx_scaffold.PRESENTATION_PART_PATH]);
25
- if (root === void 0) throw new Error(`package has no root element at ${require_edit_pptx_scaffold.PRESENTATION_PART_PATH}`);
23
+ function findPresentationRoot(pkg, presentationPartPath) {
24
+ const root = (0, ooxml_js.rootElement)(pkg.parts[presentationPartPath]);
25
+ if (root === void 0) throw new Error(`package has no root element at ${presentationPartPath}`);
26
26
  return root;
27
27
  }
28
- function findSldIdLst(presentationRoot) {
28
+ function findSldIdLst(presentationRoot, presentationPartPath) {
29
29
  const sldIdLst = directChild(presentationRoot, "p:sldIdLst");
30
- if (sldIdLst === void 0) throw new Error(`${require_edit_pptx_scaffold.PRESENTATION_PART_PATH} has no p:sldIdLst element`);
30
+ if (sldIdLst === void 0) throw new Error(`${presentationPartPath} has no p:sldIdLst element`);
31
31
  return sldIdLst;
32
32
  }
33
- function findSldSz(presentationRoot) {
33
+ function findSldSz(presentationRoot, presentationPartPath) {
34
34
  const sldSz = directChild(presentationRoot, "p:sldSz");
35
- if (sldSz === void 0) throw new Error(`${require_edit_pptx_scaffold.PRESENTATION_PART_PATH} has no p:sldSz element`);
35
+ if (sldSz === void 0) throw new Error(`${presentationPartPath} has no p:sldSz element`);
36
36
  return sldSz;
37
37
  }
38
38
  function nextSlideId(sldIdLst) {
@@ -46,8 +46,8 @@ function nextSlideId(sldIdLst) {
46
46
  }
47
47
  return max + 1;
48
48
  }
49
- function nextSlidePartIndex(pkg) {
50
- const pattern = /^ppt\/slides\/slide(\d+)\.xml$/;
49
+ function nextSlidePartIndex(pkg, slidesDir) {
50
+ const pattern = new RegExp(`^${require_opc_paths.escapeRegExp(slidesDir)}/slide(\\d+)\\.xml$`);
51
51
  let max = 0;
52
52
  for (const path of Object.keys(pkg.parts)) {
53
53
  const match = pattern.exec(path);
@@ -68,8 +68,14 @@ function buildEmptySlideRoot() {
68
68
  }
69
69
  var PptxEditor = class {
70
70
  pkg;
71
+ presentationPartPath;
72
+ mediaDir;
73
+ slidesDir;
71
74
  constructor(pkg) {
72
75
  this.pkg = pkg;
76
+ this.presentationPartPath = require_edit_pptx_parts.pptxMainPartPath(pkg);
77
+ this.mediaDir = require_edit_pptx_parts.pptxMediaDir(this.presentationPartPath);
78
+ this.slidesDir = require_edit_pptx_parts.pptxSlidesDir(this.presentationPartPath);
73
79
  }
74
80
  get metadata() {
75
81
  return (0, ooxml_js.readCoreProperties)(this.pkg);
@@ -78,8 +84,8 @@ var PptxEditor = class {
78
84
  require_metadata_core_patch.patchOoxmlCorePropertiesOnPackage(this.pkg, value);
79
85
  }
80
86
  slides() {
81
- const sldIdLst = findSldIdLst(findPresentationRoot(this.pkg));
82
- const presentationRels = (0, ooxml_js.resolveRelationships)(this.pkg, require_edit_pptx_scaffold.PRESENTATION_PART_PATH);
87
+ const sldIdLst = findSldIdLst(findPresentationRoot(this.pkg, this.presentationPartPath), this.presentationPartPath);
88
+ const presentationRels = (0, ooxml_js.resolveRelationships)(this.pkg, this.presentationPartPath);
83
89
  const out = [];
84
90
  for (const child of sldIdLst.children) {
85
91
  if (child.type !== "element" || child.tag !== "p:sldId") continue;
@@ -92,25 +98,26 @@ var PptxEditor = class {
92
98
  const context = {
93
99
  pkg: this.pkg,
94
100
  slidePartPath: rel.target,
95
- mediaDir: MEDIA_DIR
101
+ mediaDir: this.mediaDir,
102
+ presentationPartPath: this.presentationPartPath
96
103
  };
97
104
  out.push(new require_edit_pptx_slide.PptxSlide(sldIdLst.children, slideRoot, context));
98
105
  }
99
106
  return out;
100
107
  }
101
108
  addSlide() {
102
- const sldIdLst = findSldIdLst(findPresentationRoot(this.pkg));
103
- const partIndex = nextSlidePartIndex(this.pkg);
104
- const slidePartPath = `ppt/slides/slide${partIndex}.xml`;
109
+ const sldIdLst = findSldIdLst(findPresentationRoot(this.pkg, this.presentationPartPath), this.presentationPartPath);
110
+ const partIndex = nextSlidePartIndex(this.pkg, this.slidesDir);
111
+ const slidePartPath = `${this.slidesDir}/slide${partIndex}.xml`;
105
112
  const slideRoot = buildEmptySlideRoot();
106
113
  this.pkg.parts[slidePartPath] = {
107
114
  kind: "xml",
108
115
  nodes: [slideRoot]
109
116
  };
110
117
  require_opc_content_types.ensureContentTypeOverride(this.pkg, slidePartPath, SLIDE_CONTENT_TYPE);
111
- const relationshipId = require_opc_rels.addRelationship(this.pkg, require_edit_pptx_scaffold.PRESENTATION_PART_PATH, {
118
+ const relationshipId = require_opc_rels.addRelationship(this.pkg, this.presentationPartPath, {
112
119
  type: SLIDE_RELATIONSHIP_TYPE,
113
- target: `slides/slide${partIndex}.xml`
120
+ target: require_opc_paths.buildRelativeTarget(this.presentationPartPath, slidePartPath)
114
121
  });
115
122
  require_opc_rels.addRelationship(this.pkg, slidePartPath, {
116
123
  type: require_edit_pptx_scaffold.SLIDE_LAYOUT_REL_TYPE,
@@ -124,24 +131,25 @@ var PptxEditor = class {
124
131
  const context = {
125
132
  pkg: this.pkg,
126
133
  slidePartPath,
127
- mediaDir: MEDIA_DIR
134
+ mediaDir: this.mediaDir,
135
+ presentationPartPath: this.presentationPartPath
128
136
  };
129
137
  return new require_edit_pptx_slide.PptxSlide(sldIdLst.children, slideRoot, context);
130
138
  }
131
139
  removeSlideAt(index) {
132
- const sldIdLst = findSldIdLst(findPresentationRoot(this.pkg));
140
+ const sldIdLst = findSldIdLst(findPresentationRoot(this.pkg, this.presentationPartPath), this.presentationPartPath);
133
141
  const target = sldIdLst.children.filter((c) => c.type === "element" && c.tag === "p:sldId")[index];
134
142
  if (target?.type !== "element") throw new Error(`slide index ${index} does not exist`);
135
143
  const rId = attrValue(target, "r:id");
136
144
  const listIndex = sldIdLst.children.indexOf(target);
137
145
  sldIdLst.children.splice(listIndex, 1);
138
146
  if (rId !== void 0) {
139
- const rel = (0, ooxml_js.resolveRelationships)(this.pkg, require_edit_pptx_scaffold.PRESENTATION_PART_PATH).get(rId);
147
+ const rel = (0, ooxml_js.resolveRelationships)(this.pkg, this.presentationPartPath).get(rId);
140
148
  if (rel !== void 0) Reflect.deleteProperty(this.pkg.parts, rel.target);
141
149
  }
142
150
  }
143
151
  moveSlide(from, to) {
144
- const sldIdLst = findSldIdLst(findPresentationRoot(this.pkg));
152
+ const sldIdLst = findSldIdLst(findPresentationRoot(this.pkg, this.presentationPartPath), this.presentationPartPath);
145
153
  const sldIdIndices = [];
146
154
  sldIdLst.children.forEach((child, i) => {
147
155
  if (child.type === "element" && child.tag === "p:sldId") sldIdIndices.push(i);
@@ -158,7 +166,7 @@ var PptxEditor = class {
158
166
  sldIdLst.children.splice(insertAt, 0, moved);
159
167
  }
160
168
  get slideSize() {
161
- const sldSz = findSldSz(findPresentationRoot(this.pkg));
169
+ const sldSz = findSldSz(findPresentationRoot(this.pkg, this.presentationPartPath), this.presentationPartPath);
162
170
  const cx = attrValue(sldSz, "cx");
163
171
  const cy = attrValue(sldSz, "cy");
164
172
  return {
@@ -167,7 +175,7 @@ var PptxEditor = class {
167
175
  };
168
176
  }
169
177
  set slideSize(size) {
170
- const sldSz = findSldSz(findPresentationRoot(this.pkg));
178
+ const sldSz = findSldSz(findPresentationRoot(this.pkg, this.presentationPartPath), this.presentationPartPath);
171
179
  sldSz.attributes = [{
172
180
  name: "cx",
173
181
  value: String(require_model_units.ptToEmu(size.widthPt))
@@ -5,6 +5,9 @@ import { Package } from "ooxml.js";
5
5
  //#region src/edit/pptx/editor.d.ts
6
6
  declare class PptxEditor {
7
7
  private readonly pkg;
8
+ private readonly presentationPartPath;
9
+ private readonly mediaDir;
10
+ private readonly slidesDir;
8
11
  constructor(pkg: Package);
9
12
  get metadata(): LayoutMetadata;
10
13
  set metadata(value: LayoutMetadata);
@@ -5,6 +5,9 @@ import { LayoutMetadata, PageSize } from "document-schema.js";
5
5
  //#region src/edit/pptx/editor.d.ts
6
6
  declare class PptxEditor {
7
7
  private readonly pkg;
8
+ private readonly presentationPartPath;
9
+ private readonly mediaDir;
10
+ private readonly slidesDir;
8
11
  constructor(pkg: Package);
9
12
  get metadata(): LayoutMetadata;
10
13
  set metadata(value: LayoutMetadata);
@@ -1,16 +1,16 @@
1
1
  import { el } from "../../xml/fragment.js";
2
2
  import { ensureContentTypeOverride } from "../../opc/content-types.js";
3
- import { buildRelativeTarget } from "../../opc/paths.js";
3
+ import { buildRelativeTarget, escapeRegExp } from "../../opc/paths.js";
4
4
  import { addRelationship } from "../../opc/rels.js";
5
5
  import { patchOoxmlCorePropertiesOnPackage } from "../../metadata/core-patch.js";
6
6
  import { resolveMetadataTimestamps } from "../../model/metadata.js";
7
7
  import { systemClock } from "../../ports/clock.js";
8
8
  import { emuToPt, ptToEmu } from "../../model/units.js";
9
- import { DML_NS, PML_NS, PRESENTATION_PART_PATH, R_NS, SLIDE_LAYOUT_PART_PATH, SLIDE_LAYOUT_REL_TYPE, buildEmptyGroupSpTree, createEmptyPptxPackage } from "./scaffold.js";
9
+ import { DML_NS, PML_NS, R_NS, SLIDE_LAYOUT_PART_PATH, SLIDE_LAYOUT_REL_TYPE, buildEmptyGroupSpTree, createEmptyPptxPackage } from "./scaffold.js";
10
10
  import { PptxSlide } from "./slide.js";
11
+ import { pptxMainPartPath, pptxMediaDir, pptxSlidesDir } from "./parts.js";
11
12
  import { decodePackage, encodePackage, readCoreProperties, resolveRelationships, rootElement } from "ooxml.js";
12
13
  //#region src/edit/pptx/editor.ts
13
- const MEDIA_DIR = "ppt/media";
14
14
  const SLIDE_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.presentationml.slide+xml";
15
15
  const SLIDE_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide";
16
16
  function directChild(parent, tag) {
@@ -19,19 +19,19 @@ function directChild(parent, tag) {
19
19
  function attrValue(element, name) {
20
20
  for (const a of element.attributes) if (a.name === name) return a.value;
21
21
  }
22
- function findPresentationRoot(pkg) {
23
- const root = rootElement(pkg.parts[PRESENTATION_PART_PATH]);
24
- if (root === void 0) throw new Error(`package has no root element at ${PRESENTATION_PART_PATH}`);
22
+ function findPresentationRoot(pkg, presentationPartPath) {
23
+ const root = rootElement(pkg.parts[presentationPartPath]);
24
+ if (root === void 0) throw new Error(`package has no root element at ${presentationPartPath}`);
25
25
  return root;
26
26
  }
27
- function findSldIdLst(presentationRoot) {
27
+ function findSldIdLst(presentationRoot, presentationPartPath) {
28
28
  const sldIdLst = directChild(presentationRoot, "p:sldIdLst");
29
- if (sldIdLst === void 0) throw new Error(`${PRESENTATION_PART_PATH} has no p:sldIdLst element`);
29
+ if (sldIdLst === void 0) throw new Error(`${presentationPartPath} has no p:sldIdLst element`);
30
30
  return sldIdLst;
31
31
  }
32
- function findSldSz(presentationRoot) {
32
+ function findSldSz(presentationRoot, presentationPartPath) {
33
33
  const sldSz = directChild(presentationRoot, "p:sldSz");
34
- if (sldSz === void 0) throw new Error(`${PRESENTATION_PART_PATH} has no p:sldSz element`);
34
+ if (sldSz === void 0) throw new Error(`${presentationPartPath} has no p:sldSz element`);
35
35
  return sldSz;
36
36
  }
37
37
  function nextSlideId(sldIdLst) {
@@ -45,8 +45,8 @@ function nextSlideId(sldIdLst) {
45
45
  }
46
46
  return max + 1;
47
47
  }
48
- function nextSlidePartIndex(pkg) {
49
- const pattern = /^ppt\/slides\/slide(\d+)\.xml$/;
48
+ function nextSlidePartIndex(pkg, slidesDir) {
49
+ const pattern = new RegExp(`^${escapeRegExp(slidesDir)}/slide(\\d+)\\.xml$`);
50
50
  let max = 0;
51
51
  for (const path of Object.keys(pkg.parts)) {
52
52
  const match = pattern.exec(path);
@@ -67,8 +67,14 @@ function buildEmptySlideRoot() {
67
67
  }
68
68
  var PptxEditor = class {
69
69
  pkg;
70
+ presentationPartPath;
71
+ mediaDir;
72
+ slidesDir;
70
73
  constructor(pkg) {
71
74
  this.pkg = pkg;
75
+ this.presentationPartPath = pptxMainPartPath(pkg);
76
+ this.mediaDir = pptxMediaDir(this.presentationPartPath);
77
+ this.slidesDir = pptxSlidesDir(this.presentationPartPath);
72
78
  }
73
79
  get metadata() {
74
80
  return readCoreProperties(this.pkg);
@@ -77,8 +83,8 @@ var PptxEditor = class {
77
83
  patchOoxmlCorePropertiesOnPackage(this.pkg, value);
78
84
  }
79
85
  slides() {
80
- const sldIdLst = findSldIdLst(findPresentationRoot(this.pkg));
81
- const presentationRels = resolveRelationships(this.pkg, PRESENTATION_PART_PATH);
86
+ const sldIdLst = findSldIdLst(findPresentationRoot(this.pkg, this.presentationPartPath), this.presentationPartPath);
87
+ const presentationRels = resolveRelationships(this.pkg, this.presentationPartPath);
82
88
  const out = [];
83
89
  for (const child of sldIdLst.children) {
84
90
  if (child.type !== "element" || child.tag !== "p:sldId") continue;
@@ -91,25 +97,26 @@ var PptxEditor = class {
91
97
  const context = {
92
98
  pkg: this.pkg,
93
99
  slidePartPath: rel.target,
94
- mediaDir: MEDIA_DIR
100
+ mediaDir: this.mediaDir,
101
+ presentationPartPath: this.presentationPartPath
95
102
  };
96
103
  out.push(new PptxSlide(sldIdLst.children, slideRoot, context));
97
104
  }
98
105
  return out;
99
106
  }
100
107
  addSlide() {
101
- const sldIdLst = findSldIdLst(findPresentationRoot(this.pkg));
102
- const partIndex = nextSlidePartIndex(this.pkg);
103
- const slidePartPath = `ppt/slides/slide${partIndex}.xml`;
108
+ const sldIdLst = findSldIdLst(findPresentationRoot(this.pkg, this.presentationPartPath), this.presentationPartPath);
109
+ const partIndex = nextSlidePartIndex(this.pkg, this.slidesDir);
110
+ const slidePartPath = `${this.slidesDir}/slide${partIndex}.xml`;
104
111
  const slideRoot = buildEmptySlideRoot();
105
112
  this.pkg.parts[slidePartPath] = {
106
113
  kind: "xml",
107
114
  nodes: [slideRoot]
108
115
  };
109
116
  ensureContentTypeOverride(this.pkg, slidePartPath, SLIDE_CONTENT_TYPE);
110
- const relationshipId = addRelationship(this.pkg, PRESENTATION_PART_PATH, {
117
+ const relationshipId = addRelationship(this.pkg, this.presentationPartPath, {
111
118
  type: SLIDE_RELATIONSHIP_TYPE,
112
- target: `slides/slide${partIndex}.xml`
119
+ target: buildRelativeTarget(this.presentationPartPath, slidePartPath)
113
120
  });
114
121
  addRelationship(this.pkg, slidePartPath, {
115
122
  type: SLIDE_LAYOUT_REL_TYPE,
@@ -123,24 +130,25 @@ var PptxEditor = class {
123
130
  const context = {
124
131
  pkg: this.pkg,
125
132
  slidePartPath,
126
- mediaDir: MEDIA_DIR
133
+ mediaDir: this.mediaDir,
134
+ presentationPartPath: this.presentationPartPath
127
135
  };
128
136
  return new PptxSlide(sldIdLst.children, slideRoot, context);
129
137
  }
130
138
  removeSlideAt(index) {
131
- const sldIdLst = findSldIdLst(findPresentationRoot(this.pkg));
139
+ const sldIdLst = findSldIdLst(findPresentationRoot(this.pkg, this.presentationPartPath), this.presentationPartPath);
132
140
  const target = sldIdLst.children.filter((c) => c.type === "element" && c.tag === "p:sldId")[index];
133
141
  if (target?.type !== "element") throw new Error(`slide index ${index} does not exist`);
134
142
  const rId = attrValue(target, "r:id");
135
143
  const listIndex = sldIdLst.children.indexOf(target);
136
144
  sldIdLst.children.splice(listIndex, 1);
137
145
  if (rId !== void 0) {
138
- const rel = resolveRelationships(this.pkg, PRESENTATION_PART_PATH).get(rId);
146
+ const rel = resolveRelationships(this.pkg, this.presentationPartPath).get(rId);
139
147
  if (rel !== void 0) Reflect.deleteProperty(this.pkg.parts, rel.target);
140
148
  }
141
149
  }
142
150
  moveSlide(from, to) {
143
- const sldIdLst = findSldIdLst(findPresentationRoot(this.pkg));
151
+ const sldIdLst = findSldIdLst(findPresentationRoot(this.pkg, this.presentationPartPath), this.presentationPartPath);
144
152
  const sldIdIndices = [];
145
153
  sldIdLst.children.forEach((child, i) => {
146
154
  if (child.type === "element" && child.tag === "p:sldId") sldIdIndices.push(i);
@@ -157,7 +165,7 @@ var PptxEditor = class {
157
165
  sldIdLst.children.splice(insertAt, 0, moved);
158
166
  }
159
167
  get slideSize() {
160
- const sldSz = findSldSz(findPresentationRoot(this.pkg));
168
+ const sldSz = findSldSz(findPresentationRoot(this.pkg, this.presentationPartPath), this.presentationPartPath);
161
169
  const cx = attrValue(sldSz, "cx");
162
170
  const cy = attrValue(sldSz, "cy");
163
171
  return {
@@ -166,7 +174,7 @@ var PptxEditor = class {
166
174
  };
167
175
  }
168
176
  set slideSize(size) {
169
- const sldSz = findSldSz(findPresentationRoot(this.pkg));
177
+ const sldSz = findSldSz(findPresentationRoot(this.pkg, this.presentationPartPath), this.presentationPartPath);
170
178
  sldSz.attributes = [{
171
179
  name: "cx",
172
180
  value: String(ptToEmu(size.widthPt))
@@ -0,0 +1,20 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_opc_paths = require("../../opc/paths.cjs");
3
+ require("./scaffold.cjs");
4
+ let ooxml_js = require("ooxml.js");
5
+ //#region src/edit/pptx/parts.ts
6
+ const MEDIA_DIR_NAME = "media";
7
+ const SLIDES_DIR_NAME = "slides";
8
+ function pptxMainPartPath(pkg) {
9
+ return (0, ooxml_js.findMainPartPath)(pkg) ?? "ppt/presentation.xml";
10
+ }
11
+ function pptxMediaDir(presentationPartPath) {
12
+ return require_opc_paths.siblingDirectory(presentationPartPath, MEDIA_DIR_NAME);
13
+ }
14
+ function pptxSlidesDir(presentationPartPath) {
15
+ return require_opc_paths.siblingDirectory(presentationPartPath, SLIDES_DIR_NAME);
16
+ }
17
+ //#endregion
18
+ exports.pptxMainPartPath = pptxMainPartPath;
19
+ exports.pptxMediaDir = pptxMediaDir;
20
+ exports.pptxSlidesDir = pptxSlidesDir;
@@ -0,0 +1,7 @@
1
+ import { Package } from "ooxml.js";
2
+ //#region src/edit/pptx/parts.d.ts
3
+ declare function pptxMainPartPath(pkg: Package): string;
4
+ declare function pptxMediaDir(presentationPartPath: string): string;
5
+ declare function pptxSlidesDir(presentationPartPath: string): string;
6
+ //#endregion
7
+ export { pptxMainPartPath, pptxMediaDir, pptxSlidesDir };
@@ -0,0 +1,7 @@
1
+ import { Package } from "ooxml.js";
2
+ //#region src/edit/pptx/parts.d.ts
3
+ declare function pptxMainPartPath(pkg: Package): string;
4
+ declare function pptxMediaDir(presentationPartPath: string): string;
5
+ declare function pptxSlidesDir(presentationPartPath: string): string;
6
+ //#endregion
7
+ export { pptxMainPartPath, pptxMediaDir, pptxSlidesDir };
@@ -0,0 +1,17 @@
1
+ import { siblingDirectory } from "../../opc/paths.js";
2
+ import "./scaffold.js";
3
+ import { findMainPartPath } from "ooxml.js";
4
+ //#region src/edit/pptx/parts.ts
5
+ const MEDIA_DIR_NAME = "media";
6
+ const SLIDES_DIR_NAME = "slides";
7
+ function pptxMainPartPath(pkg) {
8
+ return findMainPartPath(pkg) ?? "ppt/presentation.xml";
9
+ }
10
+ function pptxMediaDir(presentationPartPath) {
11
+ return siblingDirectory(presentationPartPath, MEDIA_DIR_NAME);
12
+ }
13
+ function pptxSlidesDir(presentationPartPath) {
14
+ return siblingDirectory(presentationPartPath, SLIDES_DIR_NAME);
15
+ }
16
+ //#endregion
17
+ export { pptxMainPartPath, pptxMediaDir, pptxSlidesDir };
@@ -174,8 +174,8 @@ var PptxSlide = class {
174
174
  });
175
175
  }
176
176
  remove() {
177
- const { pkg, slidePartPath } = this.context;
178
- const presentationRels = (0, ooxml_js.resolveRelationships)(pkg, require_edit_pptx_scaffold.PRESENTATION_PART_PATH);
177
+ const { pkg, slidePartPath, presentationPartPath } = this.context;
178
+ const presentationRels = (0, ooxml_js.resolveRelationships)(pkg, presentationPartPath);
179
179
  for (const child of this.container) {
180
180
  if (child.type !== "element" || child.tag !== "p:sldId") continue;
181
181
  const rId = attrValue(child, "r:id");
@@ -20,6 +20,7 @@ interface SlideContext {
20
20
  readonly pkg: Package;
21
21
  readonly slidePartPath: string;
22
22
  readonly mediaDir: string;
23
+ readonly presentationPartPath: string;
23
24
  }
24
25
  declare class PptxSlide {
25
26
  private readonly container;
@@ -20,6 +20,7 @@ interface SlideContext {
20
20
  readonly pkg: Package;
21
21
  readonly slidePartPath: string;
22
22
  readonly mediaDir: string;
23
+ readonly presentationPartPath: string;
23
24
  }
24
25
  declare class PptxSlide {
25
26
  private readonly container;
@@ -4,7 +4,7 @@ import { ensureContentTypeOverride } from "../../opc/content-types.js";
4
4
  import { buildRelativeTarget } from "../../opc/paths.js";
5
5
  import { addRelationship } from "../../opc/rels.js";
6
6
  import { removeChild } from "../../xml/edit.js";
7
- import { DML_NS, NOTES_MASTER_REL_TYPE, PML_NS, PRESENTATION_PART_PATH, buildEmptyGroupSpTree, ensureNotesMaster } from "./scaffold.js";
7
+ import { DML_NS, NOTES_MASTER_REL_TYPE, PML_NS, buildEmptyGroupSpTree, ensureNotesMaster } from "./scaffold.js";
8
8
  import { PptxShape, buildTextBoxShape } from "./shape.js";
9
9
  import { insertPictureShapeMedia } from "./image.js";
10
10
  import { PptxTable, buildDrawingTable, buildTableGraphicFrame, findGraphicFrameTable } from "./table.js";
@@ -173,8 +173,8 @@ var PptxSlide = class {
173
173
  });
174
174
  }
175
175
  remove() {
176
- const { pkg, slidePartPath } = this.context;
177
- const presentationRels = resolveRelationships(pkg, PRESENTATION_PART_PATH);
176
+ const { pkg, slidePartPath, presentationPartPath } = this.context;
177
+ const presentationRels = resolveRelationships(pkg, presentationPartPath);
178
178
  for (const child of this.container) {
179
179
  if (child.type !== "element" || child.tag !== "p:sldId") continue;
180
180
  const rId = attrValue(child, "r:id");
@@ -5,11 +5,8 @@ const require_opc_rels = require("./rels.cjs");
5
5
  let ooxml_js = require("ooxml.js");
6
6
  //#region src/opc/media.ts
7
7
  const IMAGE_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
8
- function escapeRegExp(value) {
9
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
10
- }
11
8
  function nextMediaIndex(pkg, mediaDir, fileNamePrefix, extension) {
12
- const pattern = new RegExp(`^${escapeRegExp(fileNamePrefix)}(\\d+)\\.${escapeRegExp(extension)}$`);
9
+ const pattern = new RegExp(`^${require_opc_paths.escapeRegExp(fileNamePrefix)}(\\d+)\\.${require_opc_paths.escapeRegExp(extension)}$`);
13
10
  const prefix = `${mediaDir}/`;
14
11
  let max = 0;
15
12
  for (const path of Object.keys(pkg.parts)) {
package/dist/opc/media.js CHANGED
@@ -1,12 +1,9 @@
1
1
  import { defaultContentTypeForExtension, ensureDefaultContentType } from "./content-types.js";
2
- import { buildRelativeTarget } from "./paths.js";
2
+ import { buildRelativeTarget, escapeRegExp } from "./paths.js";
3
3
  import { addRelationship } from "./rels.js";
4
4
  import { bytesToBase64 } from "ooxml.js";
5
5
  //#region src/opc/media.ts
6
6
  const IMAGE_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
7
- function escapeRegExp(value) {
8
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
9
- }
10
7
  function nextMediaIndex(pkg, mediaDir, fileNamePrefix, extension) {
11
8
  const pattern = new RegExp(`^${escapeRegExp(fileNamePrefix)}(\\d+)\\.${escapeRegExp(extension)}$`);
12
9
  const prefix = `${mediaDir}/`;
@@ -23,6 +23,20 @@ function buildRelativeTarget(fromPartPath, toPartPath) {
23
23
  toFileName
24
24
  ].join("/");
25
25
  }
26
+ function partDirectory(partPath) {
27
+ const lastSlash = partPath.lastIndexOf("/");
28
+ return lastSlash === -1 ? "" : partPath.slice(0, lastSlash);
29
+ }
30
+ function siblingDirectory(partPath, name) {
31
+ const dir = partDirectory(partPath);
32
+ return dir === "" ? name : `${dir}/${name}`;
33
+ }
34
+ function escapeRegExp(value) {
35
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
36
+ }
26
37
  //#endregion
27
38
  exports.buildRelativeTarget = buildRelativeTarget;
39
+ exports.escapeRegExp = escapeRegExp;
40
+ exports.partDirectory = partDirectory;
28
41
  exports.relsPathFor = relsPathFor;
42
+ exports.siblingDirectory = siblingDirectory;
@@ -1,5 +1,8 @@
1
1
  //#region src/opc/paths.d.ts
2
2
  declare function relsPathFor(partPath: string): string;
3
3
  declare function buildRelativeTarget(fromPartPath: string, toPartPath: string): string;
4
+ declare function partDirectory(partPath: string): string;
5
+ declare function siblingDirectory(partPath: string, name: string): string;
6
+ declare function escapeRegExp(value: string): string;
4
7
  //#endregion
5
- export { buildRelativeTarget, relsPathFor };
8
+ export { buildRelativeTarget, escapeRegExp, partDirectory, relsPathFor, siblingDirectory };
@@ -1,5 +1,8 @@
1
1
  //#region src/opc/paths.d.ts
2
2
  declare function relsPathFor(partPath: string): string;
3
3
  declare function buildRelativeTarget(fromPartPath: string, toPartPath: string): string;
4
+ declare function partDirectory(partPath: string): string;
5
+ declare function siblingDirectory(partPath: string, name: string): string;
6
+ declare function escapeRegExp(value: string): string;
4
7
  //#endregion
5
- export { buildRelativeTarget, relsPathFor };
8
+ export { buildRelativeTarget, escapeRegExp, partDirectory, relsPathFor, siblingDirectory };
package/dist/opc/paths.js CHANGED
@@ -22,5 +22,16 @@ function buildRelativeTarget(fromPartPath, toPartPath) {
22
22
  toFileName
23
23
  ].join("/");
24
24
  }
25
+ function partDirectory(partPath) {
26
+ const lastSlash = partPath.lastIndexOf("/");
27
+ return lastSlash === -1 ? "" : partPath.slice(0, lastSlash);
28
+ }
29
+ function siblingDirectory(partPath, name) {
30
+ const dir = partDirectory(partPath);
31
+ return dir === "" ? name : `${dir}/${name}`;
32
+ }
33
+ function escapeRegExp(value) {
34
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
35
+ }
25
36
  //#endregion
26
- export { buildRelativeTarget, relsPathFor };
37
+ export { buildRelativeTarget, escapeRegExp, partDirectory, relsPathFor, siblingDirectory };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "js.documents",
3
- "version": "7.20.32",
3
+ "version": "7.20.33",
4
4
  "description": "Bidirectional docx/pptx <-> PDF conversion and a read+write editable OOXML document model, built on ooxml.js and Zod 4 codecs.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -85,7 +85,7 @@
85
85
  "fflate": "0.8.3",
86
86
  "markdown-codec": "7.0.0",
87
87
  "odf.js": "8.0.0",
88
- "ooxml.js": "9.1.0",
88
+ "ooxml.js": "9.1.1",
89
89
  "pdf-codec": "5.0.0",
90
90
  "ppt-codec": "2.0.0",
91
91
  "rtf-codec": "5.0.0",