docx-diff-editor 1.0.35 → 1.0.38

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.
package/README.md CHANGED
@@ -132,6 +132,18 @@ interface DocxDiffEditorRef {
132
132
 
133
133
  // Check if ready
134
134
  isReady(): boolean;
135
+
136
+ // Get current page count
137
+ getPages(): number;
138
+
139
+ // Get document metadata and statistics
140
+ getDocumentInfo(): DocumentInfo | null;
141
+
142
+ // Get document core properties
143
+ getProperties(): Promise<DocumentProperties | null>;
144
+
145
+ // Set document core properties (partial update)
146
+ setProperties(properties: Partial<DocumentProperties>): Promise<boolean>;
135
147
  }
136
148
  ```
137
149
 
@@ -148,6 +160,39 @@ interface ComparisonResult {
148
160
  }
149
161
  ```
150
162
 
163
+ ### DocumentInfo
164
+
165
+ ```tsx
166
+ interface DocumentInfo {
167
+ // Metadata
168
+ documentGuid: string | null;
169
+ isModified: boolean;
170
+ version: number | null;
171
+ // Statistics
172
+ words: number;
173
+ characters: number;
174
+ paragraphs: number;
175
+ pages: number;
176
+ }
177
+ ```
178
+
179
+ ### DocumentProperties
180
+
181
+ ```tsx
182
+ interface DocumentProperties {
183
+ title?: string;
184
+ author?: string;
185
+ subject?: string;
186
+ description?: string;
187
+ keywords?: string;
188
+ category?: string;
189
+ lastModifiedBy?: string;
190
+ revision?: string;
191
+ created?: Date;
192
+ modified?: Date;
193
+ }
194
+ ```
195
+
151
196
  ## Getting LLM Context
152
197
 
153
198
  Extract enriched changes with semantic context for AI/LLM processing:
@@ -175,6 +220,30 @@ await fetch('/api/summarize', {
175
220
  // }
176
221
  ```
177
222
 
223
+ ## Document Properties
224
+
225
+ Read and update document metadata (stored in `docProps/core.xml`):
226
+
227
+ ```tsx
228
+ // Get current properties
229
+ const props = await editorRef.current?.getProperties();
230
+ if (props) {
231
+ console.log(`Title: ${props.title}`);
232
+ console.log(`Author: ${props.author}`);
233
+ console.log(`Created: ${props.created?.toLocaleDateString()}`);
234
+ console.log(`Modified: ${props.modified?.toLocaleDateString()}`);
235
+ }
236
+
237
+ // Update properties (partial update - only specified fields are changed)
238
+ await editorRef.current?.setProperties({
239
+ title: 'Quarterly Report Q4 2026',
240
+ author: 'Jane Smith',
241
+ subject: 'Financial Summary',
242
+ keywords: 'report, quarterly, finance, 2026',
243
+ modified: new Date(),
244
+ });
245
+ ```
246
+
178
247
  ## Customization
179
248
 
180
249
  ### CSS Variables
package/dist/index.d.mts CHANGED
@@ -109,6 +109,50 @@ interface TrackChangeAuthor {
109
109
  name: string;
110
110
  email: string;
111
111
  }
112
+ /**
113
+ * Document core properties (stored in docProps/core.xml)
114
+ */
115
+ interface DocumentProperties {
116
+ /** Document title (dc:title) */
117
+ title?: string;
118
+ /** Original author (dc:creator) */
119
+ author?: string;
120
+ /** Subject/topic (dc:subject) */
121
+ subject?: string;
122
+ /** Comments/description (dc:description) */
123
+ description?: string;
124
+ /** Keywords/tags (cp:keywords) */
125
+ keywords?: string;
126
+ /** Category (cp:category) */
127
+ category?: string;
128
+ /** Last modified by (cp:lastModifiedBy) */
129
+ lastModifiedBy?: string;
130
+ /** Revision number (cp:revision) */
131
+ revision?: string;
132
+ /** Creation date (dcterms:created) */
133
+ created?: Date;
134
+ /** Last modified date (dcterms:modified) */
135
+ modified?: Date;
136
+ }
137
+ /**
138
+ * Combined document metadata and statistics
139
+ */
140
+ interface DocumentInfo {
141
+ /** Document unique identifier */
142
+ documentGuid: string | null;
143
+ /** Whether the document has unsaved changes */
144
+ isModified: boolean;
145
+ /** Document version number */
146
+ version: number | null;
147
+ /** Word count */
148
+ words: number;
149
+ /** Character count */
150
+ characters: number;
151
+ /** Paragraph count */
152
+ paragraphs: number;
153
+ /** Page count */
154
+ pages: number;
155
+ }
112
156
  /**
113
157
  * Props for DocxDiffEditor component
114
158
  */
@@ -164,6 +208,14 @@ interface DocxDiffEditorRef {
164
208
  acceptAllChanges(): Promise<ProseMirrorJSON>;
165
209
  /** Check if editor is ready */
166
210
  isReady(): boolean;
211
+ /** Get the current page count from the presentation editor */
212
+ getPages(): number;
213
+ /** Get combined document metadata and statistics */
214
+ getDocumentInfo(): DocumentInfo | null;
215
+ /** Get document core properties (from docProps/core.xml) */
216
+ getProperties(): Promise<DocumentProperties | null>;
217
+ /** Set document core properties (partial update) */
218
+ setProperties(properties: Partial<DocumentProperties>): Promise<boolean>;
167
219
  }
168
220
 
169
221
  /**
@@ -311,4 +363,4 @@ declare function getBlankTemplateBlob(): Blob;
311
363
  */
312
364
  declare function isValidDocxFile(file: File): boolean;
313
365
 
314
- export { CSS_PREFIX, type ChangeLocation, type ComparisonResult, DEFAULT_AUTHOR, DEFAULT_SUPERDOC_USER, type DiffResult, type DiffSegment, type DocxContent, DocxDiffEditor, type DocxDiffEditorProps, type DocxDiffEditorRef, type EnrichedChange, type FormatChange, type FormatDetails, type ProseMirrorJSON, type ProseMirrorMark, type ProseMirrorNode, type TrackChangeAuthor, createTrackDeleteMark, createTrackFormatMark, createTrackInsertMark, DocxDiffEditor as default, detectContentType, diffDocuments, extractEnrichedChanges, getBlankTemplateBlob, getBlankTemplateFile, isProseMirrorJSON, isValidDocxFile, mergeDocuments, parseDocxFile };
366
+ export { CSS_PREFIX, type ChangeLocation, type ComparisonResult, DEFAULT_AUTHOR, DEFAULT_SUPERDOC_USER, type DiffResult, type DiffSegment, type DocumentInfo, type DocumentProperties, type DocxContent, DocxDiffEditor, type DocxDiffEditorProps, type DocxDiffEditorRef, type EnrichedChange, type FormatChange, type FormatDetails, type ProseMirrorJSON, type ProseMirrorMark, type ProseMirrorNode, type TrackChangeAuthor, createTrackDeleteMark, createTrackFormatMark, createTrackInsertMark, DocxDiffEditor as default, detectContentType, diffDocuments, extractEnrichedChanges, getBlankTemplateBlob, getBlankTemplateFile, isProseMirrorJSON, isValidDocxFile, mergeDocuments, parseDocxFile };
package/dist/index.d.ts CHANGED
@@ -109,6 +109,50 @@ interface TrackChangeAuthor {
109
109
  name: string;
110
110
  email: string;
111
111
  }
112
+ /**
113
+ * Document core properties (stored in docProps/core.xml)
114
+ */
115
+ interface DocumentProperties {
116
+ /** Document title (dc:title) */
117
+ title?: string;
118
+ /** Original author (dc:creator) */
119
+ author?: string;
120
+ /** Subject/topic (dc:subject) */
121
+ subject?: string;
122
+ /** Comments/description (dc:description) */
123
+ description?: string;
124
+ /** Keywords/tags (cp:keywords) */
125
+ keywords?: string;
126
+ /** Category (cp:category) */
127
+ category?: string;
128
+ /** Last modified by (cp:lastModifiedBy) */
129
+ lastModifiedBy?: string;
130
+ /** Revision number (cp:revision) */
131
+ revision?: string;
132
+ /** Creation date (dcterms:created) */
133
+ created?: Date;
134
+ /** Last modified date (dcterms:modified) */
135
+ modified?: Date;
136
+ }
137
+ /**
138
+ * Combined document metadata and statistics
139
+ */
140
+ interface DocumentInfo {
141
+ /** Document unique identifier */
142
+ documentGuid: string | null;
143
+ /** Whether the document has unsaved changes */
144
+ isModified: boolean;
145
+ /** Document version number */
146
+ version: number | null;
147
+ /** Word count */
148
+ words: number;
149
+ /** Character count */
150
+ characters: number;
151
+ /** Paragraph count */
152
+ paragraphs: number;
153
+ /** Page count */
154
+ pages: number;
155
+ }
112
156
  /**
113
157
  * Props for DocxDiffEditor component
114
158
  */
@@ -164,6 +208,14 @@ interface DocxDiffEditorRef {
164
208
  acceptAllChanges(): Promise<ProseMirrorJSON>;
165
209
  /** Check if editor is ready */
166
210
  isReady(): boolean;
211
+ /** Get the current page count from the presentation editor */
212
+ getPages(): number;
213
+ /** Get combined document metadata and statistics */
214
+ getDocumentInfo(): DocumentInfo | null;
215
+ /** Get document core properties (from docProps/core.xml) */
216
+ getProperties(): Promise<DocumentProperties | null>;
217
+ /** Set document core properties (partial update) */
218
+ setProperties(properties: Partial<DocumentProperties>): Promise<boolean>;
167
219
  }
168
220
 
169
221
  /**
@@ -311,4 +363,4 @@ declare function getBlankTemplateBlob(): Blob;
311
363
  */
312
364
  declare function isValidDocxFile(file: File): boolean;
313
365
 
314
- export { CSS_PREFIX, type ChangeLocation, type ComparisonResult, DEFAULT_AUTHOR, DEFAULT_SUPERDOC_USER, type DiffResult, type DiffSegment, type DocxContent, DocxDiffEditor, type DocxDiffEditorProps, type DocxDiffEditorRef, type EnrichedChange, type FormatChange, type FormatDetails, type ProseMirrorJSON, type ProseMirrorMark, type ProseMirrorNode, type TrackChangeAuthor, createTrackDeleteMark, createTrackFormatMark, createTrackInsertMark, DocxDiffEditor as default, detectContentType, diffDocuments, extractEnrichedChanges, getBlankTemplateBlob, getBlankTemplateFile, isProseMirrorJSON, isValidDocxFile, mergeDocuments, parseDocxFile };
366
+ export { CSS_PREFIX, type ChangeLocation, type ComparisonResult, DEFAULT_AUTHOR, DEFAULT_SUPERDOC_USER, type DiffResult, type DiffSegment, type DocumentInfo, type DocumentProperties, type DocxContent, DocxDiffEditor, type DocxDiffEditorProps, type DocxDiffEditorRef, type EnrichedChange, type FormatChange, type FormatDetails, type ProseMirrorJSON, type ProseMirrorMark, type ProseMirrorNode, type TrackChangeAuthor, createTrackDeleteMark, createTrackFormatMark, createTrackInsertMark, DocxDiffEditor as default, detectContentType, diffDocuments, extractEnrichedChanges, getBlankTemplateBlob, getBlankTemplateFile, isProseMirrorJSON, isValidDocxFile, mergeDocuments, parseDocxFile };
package/dist/index.js CHANGED
@@ -1177,6 +1177,182 @@ var DocxDiffEditor = react.forwardRef(
1177
1177
  */
1178
1178
  isReady() {
1179
1179
  return readyRef.current;
1180
+ },
1181
+ /**
1182
+ * Get the current page count from the presentation editor.
1183
+ * Returns 0 if editor is not ready or pages are unavailable.
1184
+ */
1185
+ getPages() {
1186
+ if (!readyRef.current || !superdocRef.current) {
1187
+ return 0;
1188
+ }
1189
+ try {
1190
+ const sd = superdocRef.current;
1191
+ const doc = sd.superdocStore?.documents?.[0];
1192
+ if (!doc) {
1193
+ return 0;
1194
+ }
1195
+ const presentationEditor = doc.getPresentationEditor?.();
1196
+ const pages = presentationEditor?.getPages?.();
1197
+ return pages?.length ?? 0;
1198
+ } catch (err) {
1199
+ console.warn("[DocxDiffEditor] Failed to get page count:", err);
1200
+ return 0;
1201
+ }
1202
+ },
1203
+ /**
1204
+ * Get combined document metadata and statistics.
1205
+ * Returns null if editor is not ready.
1206
+ */
1207
+ getDocumentInfo() {
1208
+ if (!readyRef.current || !superdocRef.current) {
1209
+ return null;
1210
+ }
1211
+ try {
1212
+ const sd = superdocRef.current;
1213
+ const doc = sd.superdocStore?.documents?.[0];
1214
+ if (!doc) {
1215
+ return null;
1216
+ }
1217
+ const editor = doc.getEditor?.();
1218
+ const metadata = editor?.getMetadata?.() ?? {};
1219
+ const stats = editor?.commands?.getDocumentStats?.() ?? {};
1220
+ const presentationEditor = doc.getPresentationEditor?.();
1221
+ const pages = presentationEditor?.getPages?.();
1222
+ const pageCount = pages?.length ?? 0;
1223
+ return {
1224
+ // Metadata
1225
+ documentGuid: metadata.documentGuid ?? null,
1226
+ isModified: metadata.isModified ?? false,
1227
+ version: metadata.version ?? null,
1228
+ // Stats
1229
+ words: stats.words ?? 0,
1230
+ characters: stats.characters ?? 0,
1231
+ paragraphs: stats.paragraphs ?? 0,
1232
+ // Pages
1233
+ pages: pageCount
1234
+ };
1235
+ } catch (err) {
1236
+ console.warn("[DocxDiffEditor] Failed to get document info:", err);
1237
+ return null;
1238
+ }
1239
+ },
1240
+ /**
1241
+ * Get document core properties from docProps/core.xml.
1242
+ * Returns null if editor is not ready or properties unavailable.
1243
+ */
1244
+ async getProperties() {
1245
+ if (!readyRef.current || !superdocRef.current) {
1246
+ return null;
1247
+ }
1248
+ try {
1249
+ const sd = superdocRef.current;
1250
+ const doc = sd.superdocStore?.documents?.[0];
1251
+ if (!doc) {
1252
+ return null;
1253
+ }
1254
+ const editor = doc.getEditor?.();
1255
+ if (!editor) {
1256
+ return null;
1257
+ }
1258
+ const coreProps = editor.getInternalXmlFile?.("docProps/core.xml", "json");
1259
+ if (!coreProps?.elements) {
1260
+ return null;
1261
+ }
1262
+ const xmlToKey = {
1263
+ "dc:title": "title",
1264
+ "dc:creator": "author",
1265
+ "dc:subject": "subject",
1266
+ "dc:description": "description",
1267
+ "cp:keywords": "keywords",
1268
+ "cp:category": "category",
1269
+ "cp:lastModifiedBy": "lastModifiedBy",
1270
+ "cp:revision": "revision",
1271
+ "dcterms:created": "created",
1272
+ "dcterms:modified": "modified"
1273
+ };
1274
+ const props = {};
1275
+ for (const el of coreProps.elements) {
1276
+ const key = xmlToKey[el.name];
1277
+ if (key) {
1278
+ const textValue = el.elements?.[0]?.text;
1279
+ if (textValue !== void 0 && textValue !== null) {
1280
+ if (key === "created" || key === "modified") {
1281
+ props[key] = new Date(textValue);
1282
+ } else {
1283
+ props[key] = textValue;
1284
+ }
1285
+ }
1286
+ }
1287
+ }
1288
+ return props;
1289
+ } catch (err) {
1290
+ console.warn("[DocxDiffEditor] Failed to get properties:", err);
1291
+ return null;
1292
+ }
1293
+ },
1294
+ /**
1295
+ * Set document core properties (partial update).
1296
+ * Only provided properties will be updated; others are preserved.
1297
+ * Returns true on success, false on failure.
1298
+ */
1299
+ async setProperties(properties) {
1300
+ if (!readyRef.current || !superdocRef.current) {
1301
+ return false;
1302
+ }
1303
+ try {
1304
+ const sd = superdocRef.current;
1305
+ const doc = sd.superdocStore?.documents?.[0];
1306
+ if (!doc) {
1307
+ return false;
1308
+ }
1309
+ const editor = doc.getEditor?.();
1310
+ if (!editor) {
1311
+ return false;
1312
+ }
1313
+ const coreProps = editor.getInternalXmlFile?.("docProps/core.xml", "json");
1314
+ if (!coreProps?.elements) {
1315
+ return false;
1316
+ }
1317
+ const keyToXml = {
1318
+ title: "dc:title",
1319
+ author: "dc:creator",
1320
+ subject: "dc:subject",
1321
+ description: "dc:description",
1322
+ keywords: "cp:keywords",
1323
+ category: "cp:category",
1324
+ lastModifiedBy: "cp:lastModifiedBy",
1325
+ revision: "cp:revision",
1326
+ created: "dcterms:created",
1327
+ modified: "dcterms:modified"
1328
+ };
1329
+ for (const [key, value] of Object.entries(properties)) {
1330
+ if (value === void 0) continue;
1331
+ const xmlName = keyToXml[key];
1332
+ if (!xmlName) continue;
1333
+ const textValue = value instanceof Date ? value.toISOString() : String(value);
1334
+ let found = false;
1335
+ for (const el of coreProps.elements) {
1336
+ if (el.name === xmlName) {
1337
+ el.elements = [{ type: "text", text: textValue }];
1338
+ found = true;
1339
+ break;
1340
+ }
1341
+ }
1342
+ if (!found) {
1343
+ coreProps.elements.push({
1344
+ type: "element",
1345
+ name: xmlName,
1346
+ elements: [{ type: "text", text: textValue }]
1347
+ });
1348
+ }
1349
+ }
1350
+ editor.updateInternalXmlFile?.("docProps/core.xml", { elements: [coreProps] });
1351
+ return true;
1352
+ } catch (err) {
1353
+ console.warn("[DocxDiffEditor] Failed to set properties:", err);
1354
+ return false;
1355
+ }
1180
1356
  }
1181
1357
  }),
1182
1358
  [