@docx4j/core-ts 0.4.0 → 0.5.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.
- package/README.md +5 -2
- package/dist/html/convert.mjs +38 -14
- package/dist/model/content/Body.d.mts +13 -1
- package/dist/model/content/Body.mjs +90 -19
- package/dist/model/content/Comment.mjs +7 -0
- package/dist/model/content/InlinePicture.d.mts +71 -7
- package/dist/model/content/InlinePicture.mjs +201 -28
- package/dist/model/content/List.mjs +10 -1
- package/dist/model/content/Paragraph.d.mts +28 -5
- package/dist/model/content/Paragraph.mjs +77 -37
- package/dist/model/content/Range.d.mts +18 -2
- package/dist/model/content/Range.mjs +194 -64
- package/dist/model/content/TrackedChange.d.mts +129 -3
- package/dist/model/content/TrackedChange.mjs +577 -12
- package/dist/model/content/binder.d.mts +2 -1
- package/dist/model/content/binder.mjs +48 -1
- package/dist/model/content/index.d.mts +2 -2
- package/dist/model/content/index.mjs +1 -1
- package/dist/model/content/relationships.d.mts +30 -0
- package/dist/model/content/relationships.mjs +133 -0
- package/dist/model/content/tree.d.mts +52 -2
- package/dist/model/content/tree.mjs +48 -3
- package/dist/model/customxml/pictures.d.mts +5 -2
- package/dist/model/customxml/pictures.mjs +13 -7
- package/dist/model/fonts/families.generated.mjs +2 -2
- package/dist/model/fonts/registry.mjs +7 -1
- package/dist/model/fonts/substitutions.generated.mjs +2 -2
- package/dist/model/fonts/themes.generated.mjs +1 -1
- package/dist/model/listnumbering/definitions.mjs +18 -0
- package/dist/model/properties/PropertyResolver.d.mts +27 -6
- package/dist/model/properties/PropertyResolver.mjs +83 -16
- package/dist/model/properties/catalogue.d.mts +15 -1
- package/dist/model/properties/catalogue.mjs +80 -27
- package/dist/model/properties/table.d.mts +16 -2
- package/dist/model/properties/table.mjs +13 -3
- package/dist/opc/Load.d.mts +9 -2
- package/dist/opc/index.d.mts +2 -2
- package/dist/opc/index.mjs +2 -2
- package/dist/opc/mce/preprocessor.d.mts +62 -6
- package/dist/opc/mce/preprocessor.mjs +142 -35
- package/dist/opc/mce/understood.d.mts +10 -0
- package/dist/opc/mce/understood.mjs +25 -3
- package/dist/packages/OpcPackage.d.mts +7 -0
- package/dist/packages/OpcPackage.mjs +15 -3
- package/dist/packages/WordprocessingMLPackage.d.mts +35 -2
- package/dist/packages/WordprocessingMLPackage.mjs +98 -2
- package/dist/parts/XmlPart.d.mts +26 -5
- package/dist/parts/XmlPart.mjs +67 -18
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -43,8 +43,11 @@ const ooxml = await pkg.saveFlatOpc(); // pkg:package, for insertOo
|
|
|
43
43
|
```
|
|
44
44
|
|
|
45
45
|
A part that is never touched is written back byte for byte; `getContents()` (or a view over
|
|
46
|
-
it) marks a part for re-marshalling. `mc:AlternateContent` is
|
|
47
|
-
|
|
46
|
+
it) marks a part for re-marshalling. `mc:AlternateContent` is kept with every branch, as docx4j
|
|
47
|
+
keeps it: the content API reads the branch Word would (the first `mc:Choice` whose namespaces are
|
|
48
|
+
understood, else the `mc:Fallback`), an edit lands in every branch, and a save writes them all
|
|
49
|
+
(`{ mcePreprocess: true }` resolves the element when a part is unmarshalled instead, as Word does on
|
|
50
|
+
open). Subpaths
|
|
48
51
|
`@docx4j/core-ts/opc`, `/parts`, `/packages` and `/model` give the layers separately,
|
|
49
52
|
`/office-js` the `Word` shim (below), `/html` HTML to WordprocessingML (a converter to an
|
|
50
53
|
intermediate form and a builder from it, CR-005 section 8; the HTML parser is yours, a browser's
|
package/dist/html/convert.mjs
CHANGED
|
@@ -454,19 +454,37 @@ function tableFrom(el, w) {
|
|
|
454
454
|
w.report.tables++;
|
|
455
455
|
return { kind: 'table', rows, style: w.tableStyle };
|
|
456
456
|
}
|
|
457
|
-
/**
|
|
457
|
+
/** Elements a line holds: gathered with the text beside them into one paragraph when they stand under a container. */
|
|
458
|
+
const INLINE_TAGS = new Set(['span', 'a', 'b', 'strong', 'i', 'em', 'u', 's', 'strike', 'del', 'ins', 'sub', 'sup', 'code', 'font', 'small', 'big', 'mark', 'abbr', 'cite', 'q', 'kbd', 'var', 'samp', 'tt', 'time', 'label', 'wbr', 'br']);
|
|
459
|
+
/** What makes an inline element a container after all: a block inside it (`<span><p>` in Word's HTML, `<a><div>`). */
|
|
460
|
+
const BLOCK_INSIDE = 'p,h1,h2,h3,h4,h5,h6,li,pre,blockquote,ul,ol,dl,table,div,section,article,header,footer,nav,aside,main,figure,figcaption,hr,img';
|
|
461
|
+
/**
|
|
462
|
+
* Block-level content in document order: paragraphs, headings, list items, tables; containers descended into.
|
|
463
|
+
* Text and inline elements met under a container (a cell without a paragraph; ChatGPT's note after a table, a
|
|
464
|
+
* `span` holding a `span` per word) are one paragraph together, up to the next block or the container's end,
|
|
465
|
+
* as a browser lays them out: a paragraph per text node had made a paragraph of every word.
|
|
466
|
+
*/
|
|
458
467
|
function walkBlocks(parent, out, w) {
|
|
459
468
|
var _a;
|
|
460
|
-
|
|
461
|
-
|
|
469
|
+
let pending = null;
|
|
470
|
+
const flush = () => {
|
|
471
|
+
if (pending === null)
|
|
472
|
+
return;
|
|
473
|
+
while (pending.length > 0 && 'br' in pending[pending.length - 1])
|
|
474
|
+
pending.pop();
|
|
475
|
+
trimEdges(pending);
|
|
476
|
+
if (pending.length > 0) {
|
|
477
|
+
out.push({ kind: 'paragraph', style: null, inlines: pending });
|
|
478
|
+
w.report.paragraphs++;
|
|
479
|
+
}
|
|
480
|
+
pending = null;
|
|
481
|
+
};
|
|
462
482
|
for (const node of Array.from(parent.childNodes)) {
|
|
463
483
|
if (node.nodeType === 3) {
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
w.report.paragraphs++;
|
|
469
|
-
}
|
|
484
|
+
if (pending === null && ((_a = node.textContent) !== null && _a !== void 0 ? _a : '').trim() === '')
|
|
485
|
+
continue; // the markup's own line ends between blocks
|
|
486
|
+
pending !== null && pending !== void 0 ? pending : (pending = []);
|
|
487
|
+
walkInline(node, pending, {}, w, false);
|
|
470
488
|
continue;
|
|
471
489
|
}
|
|
472
490
|
if (node.nodeType !== 1)
|
|
@@ -475,6 +493,14 @@ function walkBlocks(parent, out, w) {
|
|
|
475
493
|
const tag = el.tagName.toLowerCase();
|
|
476
494
|
if (tag === 'script' || tag === 'style' || tag === 'head' || tag === 'meta' || tag === 'link' || tag === 'title' || tag === 'o:p')
|
|
477
495
|
continue;
|
|
496
|
+
if (INLINE_TAGS.has(tag) && el.querySelector(BLOCK_INSIDE) === null) {
|
|
497
|
+
if (tag === 'br' && pending === null)
|
|
498
|
+
continue; // a break between blocks starts no paragraph
|
|
499
|
+
pending !== null && pending !== void 0 ? pending : (pending = []);
|
|
500
|
+
walkInline(el, pending, {}, w, false);
|
|
501
|
+
continue;
|
|
502
|
+
}
|
|
503
|
+
flush();
|
|
478
504
|
if (tag === 'p' || HEADING.test(tag) || tag === 'li' || tag === 'pre' || tag === 'blockquote' && el.querySelector('p') === null) {
|
|
479
505
|
out.push(paragraphFrom(el, w));
|
|
480
506
|
continue;
|
|
@@ -486,19 +512,17 @@ function walkBlocks(parent, out, w) {
|
|
|
486
512
|
continue;
|
|
487
513
|
}
|
|
488
514
|
if (tag === 'table') {
|
|
489
|
-
|
|
490
|
-
out.push(tableFrom(el, w));
|
|
515
|
+
out.push(tableFrom(el, w));
|
|
491
516
|
continue;
|
|
492
517
|
}
|
|
493
518
|
if (tag === 'img') {
|
|
494
519
|
w.drop('images');
|
|
495
520
|
continue;
|
|
496
521
|
}
|
|
497
|
-
|
|
498
|
-
continue;
|
|
499
|
-
// A container (div, body, html, span at block level, blockquote with paragraphs, td outside a table): its blocks.
|
|
522
|
+
// A container (div, body, html, a span holding blocks, blockquote with paragraphs, td outside a table): its blocks.
|
|
500
523
|
walkBlocks(el, out, w);
|
|
501
524
|
}
|
|
525
|
+
flush();
|
|
502
526
|
}
|
|
503
527
|
/**
|
|
504
528
|
* Where a parsed fragment's elements are: a browser's `DOMParser` wraps a bare fragment (the text
|
|
@@ -192,7 +192,8 @@ export declare class Body {
|
|
|
192
192
|
replaceText(find: string, replace: string, options?: SearchOptions): number;
|
|
193
193
|
/**
|
|
194
194
|
* Removes everything (section properties stay). While the package tracks changes, every
|
|
195
|
-
* paragraph is marked deleted and every row's `w:trPr` takes a `w:del` instead.
|
|
195
|
+
* paragraph is marked deleted and every row's `w:trPr` takes a `w:del` instead. Removed outright,
|
|
196
|
+
* the relationships the content held (its pictures' images) are settled on save (CR-002 section 47).
|
|
196
197
|
*/
|
|
197
198
|
clear(): void;
|
|
198
199
|
/**
|
|
@@ -256,3 +257,14 @@ export declare class Body {
|
|
|
256
257
|
*/
|
|
257
258
|
insertContentControl(kind?: ContentControlType): ContentControl;
|
|
258
259
|
}
|
|
260
|
+
/**
|
|
261
|
+
* A story's tracked changes resolved (`Body.acceptAll` or `rejectAll`), then those of each text box in
|
|
262
|
+
* it - a `w:txbxContent`, in a DrawingML shape or a VML one - which Word counts as a story of its own
|
|
263
|
+
* (CR-002 section 49). A text box inside a text box is reached through its own story. Returns how many
|
|
264
|
+
* changes were listed.
|
|
265
|
+
*
|
|
266
|
+
* In a kept `mc:AlternateContent` the text box of every branch is resolved, so that each says the same
|
|
267
|
+
* afterwards (docx4j's `McMode.ALL`), and the changes are counted in the selected branch alone, so a
|
|
268
|
+
* text box held in both counts once, as a resolved load's does (CR-010 phase 3).
|
|
269
|
+
*/
|
|
270
|
+
export declare function resolveStory(body: Body, what: 'accept' | 'reject'): number;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Docx4JException, PropertyResolverNotCreatedException } from '../../opc/exceptions.mjs';
|
|
2
|
-
import { typeNameOf, childrenOf, linkParents, BLOCK_LEVEL_TYPES, textOf, textOfView, rowsOf, cellsOf } from './tree.mjs';
|
|
2
|
+
import { typeNameOf, childrenOf, linkParents, BLOCK_LEVEL_TYPES, textOf, textOfView, rowsOf, cellsOf, selectedBranchOf, ALTERNATE_CONTENT } from './tree.mjs';
|
|
3
3
|
import { r as textRun, br as breakItem, tbl as tableOf } from '@docx4j/generated-objects-ts/builders/wml';
|
|
4
4
|
import { runOf, paragraphOf, runsOf } from './tree.mjs';
|
|
5
5
|
import { Paragraph } from './Paragraph.mjs';
|
|
@@ -9,10 +9,11 @@ import { sdt as sdtOf, nextSdtId } from '@docx4j/generated-objects-ts/builders/w
|
|
|
9
9
|
import { controlIdScope, sdtKindFor, declareSdtExtensions } from '../customxml/insert.mjs';
|
|
10
10
|
import { InlinePicture, addImage, writableWidthEmu } from './InlinePicture.mjs';
|
|
11
11
|
import { contentOf } from './ooxml.mjs';
|
|
12
|
+
import { relationshipIdsIn, queueRelationshipRemovals } from './relationships.mjs';
|
|
12
13
|
import { expandReplacement } from './search.mjs';
|
|
13
14
|
import { commentApi } from './comments.mjs';
|
|
14
15
|
import { trackerOf, trackInsertedBlock, markHolderInserted } from './tracking.mjs';
|
|
15
|
-
import { trackedChangesOfRow, trackedChangeTokensOfParagraph, groupTouching, BREAK, tablePropertiesChangeOf, cellChangeOf, bodySectionChangeOf, resolveUnlisted, holderInsertionAt } from './TrackedChange.mjs';
|
|
16
|
+
import { trackedChangesOfRow, trackedChangeTokensOfParagraph, groupTouching, BREAK, tablePropertiesChangeOf, cellChangeOf, bodySectionChangeOf, resolveUnlisted, holderInsertionAt, resolving } from './TrackedChange.mjs';
|
|
16
17
|
import { listsOf, listLabelsOf } from './List.mjs';
|
|
17
18
|
/**
|
|
18
19
|
* A subset of Office JS `Word.Body` over any container with block-level content: the main
|
|
@@ -264,8 +265,11 @@ export class Body {
|
|
|
264
265
|
throw new Docx4JException('This body has no part, so an image cannot be related to it');
|
|
265
266
|
const { run, drawing } = addImage(this.part, base64, this.container, writableWidthEmu(this.container), options);
|
|
266
267
|
const paragraph = this.insertParagraph('', location);
|
|
267
|
-
paragraph
|
|
268
|
-
|
|
268
|
+
// under tracking the picture is an insertion, as its paragraph's mark is (insertBreak's form)
|
|
269
|
+
const tracker = paragraph.changeTracker;
|
|
270
|
+
const item = tracker ? tracker.ins([run]) : run;
|
|
271
|
+
paragraph.p.content.push(item);
|
|
272
|
+
linkParents(item, paragraph.p);
|
|
269
273
|
return new InlinePicture(drawing, run, paragraph);
|
|
270
274
|
}
|
|
271
275
|
insertBreak(type, location) {
|
|
@@ -370,11 +374,16 @@ export class Body {
|
|
|
370
374
|
}
|
|
371
375
|
/**
|
|
372
376
|
* Removes everything (section properties stay). While the package tracks changes, every
|
|
373
|
-
* paragraph is marked deleted and every row's `w:trPr` takes a `w:del` instead.
|
|
377
|
+
* paragraph is marked deleted and every row's `w:trPr` takes a `w:del` instead. Removed outright,
|
|
378
|
+
* the relationships the content held (its pictures' images) are settled on save (CR-002 section 47).
|
|
374
379
|
*/
|
|
375
380
|
clear() {
|
|
381
|
+
var _a;
|
|
376
382
|
const tracker = this.changeTracker;
|
|
377
383
|
if (!tracker) {
|
|
384
|
+
const ids = new Set();
|
|
385
|
+
relationshipIdsIn(this.content, ids);
|
|
386
|
+
queueRelationshipRemovals((_a = this.package_) === null || _a === void 0 ? void 0 : _a.pendingRelationshipRemovals, this.part, ids);
|
|
378
387
|
this.content.length = 0;
|
|
379
388
|
return;
|
|
380
389
|
}
|
|
@@ -427,14 +436,14 @@ export class Body {
|
|
|
427
436
|
// belongs to that change, which accepts or rejects it along with the row.
|
|
428
437
|
const tokens = [];
|
|
429
438
|
for (const cell of cellsOf(row.element.value)) {
|
|
430
|
-
const cellChange = cellChangeOf(cell.element, cell.container, row.element.value);
|
|
439
|
+
const cellChange = cellChangeOf(cell.element, cell.container, row.element.value, this);
|
|
431
440
|
if (cellChange)
|
|
432
441
|
tokens.push(cellChange, BREAK);
|
|
433
442
|
visit((_b = childrenOf(cell.element.value)) !== null && _b !== void 0 ? _b : [], tokens);
|
|
434
443
|
tokens.push(BREAK);
|
|
435
444
|
}
|
|
436
445
|
const inner = groupTouching(tokens);
|
|
437
|
-
const rowChanges = trackedChangesOfRow(row.element, row.container, inner, { element: el, container: items });
|
|
446
|
+
const rowChanges = trackedChangesOfRow(row.element, row.container, inner, { element: el, container: items }, this);
|
|
438
447
|
if (rowChanges.length > 0)
|
|
439
448
|
into.push(...rowChanges);
|
|
440
449
|
else {
|
|
@@ -481,18 +490,22 @@ export class Body {
|
|
|
481
490
|
* pass that resolves nothing ends it.
|
|
482
491
|
*/
|
|
483
492
|
resolveAll(what) {
|
|
484
|
-
let
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
493
|
+
let count = 0;
|
|
494
|
+
// one resolution for the lot, so the bookmarks are read before the first and after the last
|
|
495
|
+
resolving(this.package_, this, () => {
|
|
496
|
+
let changes = this.getTrackedChanges();
|
|
497
|
+
count = changes.length;
|
|
498
|
+
while (changes.length > 0) {
|
|
499
|
+
for (let i = changes.length - 1; i >= 0; i--)
|
|
500
|
+
changes[i][what]();
|
|
501
|
+
const left = this.getTrackedChanges();
|
|
502
|
+
if (left.length >= changes.length)
|
|
503
|
+
break;
|
|
504
|
+
changes = left;
|
|
505
|
+
}
|
|
506
|
+
// and what is never listed: a cell merge, a numbering change, records that change nothing
|
|
507
|
+
resolveUnlisted(this.content, what);
|
|
508
|
+
});
|
|
496
509
|
return count;
|
|
497
510
|
}
|
|
498
511
|
/** Every `w:tr` in this body's tables, in document order (rows of nested tables included). */
|
|
@@ -777,3 +790,61 @@ function describe(el) {
|
|
|
777
790
|
const tn = typeNameOf(el);
|
|
778
791
|
return `${(_b = (_a = el.name) === null || _a === void 0 ? void 0 : _a.localPart) !== null && _b !== void 0 ? _b : '?'} (${tn !== null && tn !== void 0 ? tn : 'no TYPE_NAME'})`;
|
|
779
792
|
}
|
|
793
|
+
/**
|
|
794
|
+
* A story's tracked changes resolved (`Body.acceptAll` or `rejectAll`), then those of each text box in
|
|
795
|
+
* it - a `w:txbxContent`, in a DrawingML shape or a VML one - which Word counts as a story of its own
|
|
796
|
+
* (CR-002 section 49). A text box inside a text box is reached through its own story. Returns how many
|
|
797
|
+
* changes were listed.
|
|
798
|
+
*
|
|
799
|
+
* In a kept `mc:AlternateContent` the text box of every branch is resolved, so that each says the same
|
|
800
|
+
* afterwards (docx4j's `McMode.ALL`), and the changes are counted in the selected branch alone, so a
|
|
801
|
+
* text box held in both counts once, as a resolved load's does (CR-010 phase 3).
|
|
802
|
+
*/
|
|
803
|
+
export function resolveStory(body, what) {
|
|
804
|
+
let count = what === 'accept' ? body.acceptAll() : body.rejectAll();
|
|
805
|
+
for (const { box, selected } of textBoxesIn(body.container)) {
|
|
806
|
+
const resolved = resolveStory(body.sub(box), what);
|
|
807
|
+
if (selected)
|
|
808
|
+
count += resolved;
|
|
809
|
+
}
|
|
810
|
+
return count;
|
|
811
|
+
}
|
|
812
|
+
/**
|
|
813
|
+
* The `w:txbxContent` of every text box in a story's content, not descending into one found, each with
|
|
814
|
+
* whether it is in a branch a reader takes: false inside a branch of a kept `mc:AlternateContent` other
|
|
815
|
+
* than its selected one (`selectedBranchOf`).
|
|
816
|
+
*/
|
|
817
|
+
function textBoxesIn(container) {
|
|
818
|
+
const out = [];
|
|
819
|
+
const seen = new Set();
|
|
820
|
+
const visit = (o, selected) => {
|
|
821
|
+
var _a;
|
|
822
|
+
if (typeof o !== 'object' || o === null || seen.has(o))
|
|
823
|
+
return;
|
|
824
|
+
if (typeof o.nodeType === 'number')
|
|
825
|
+
return; // DOM the model does not type
|
|
826
|
+
seen.add(o);
|
|
827
|
+
if (Array.isArray(o)) {
|
|
828
|
+
for (const item of o)
|
|
829
|
+
visit(item, selected);
|
|
830
|
+
return;
|
|
831
|
+
}
|
|
832
|
+
const typeName = o.TYPE_NAME;
|
|
833
|
+
if (typeName === 'org_docx4j_wml.CTTxbxContent') {
|
|
834
|
+
out.push({ box: o, selected });
|
|
835
|
+
return;
|
|
836
|
+
}
|
|
837
|
+
if (typeName === ALTERNATE_CONTENT) {
|
|
838
|
+
const ac = o;
|
|
839
|
+
const read = selectedBranchOf(ac);
|
|
840
|
+
for (const branch of [...((_a = ac.choice) !== null && _a !== void 0 ? _a : []), ...(ac.fallback ? [ac.fallback] : [])])
|
|
841
|
+
visit(branch.any, selected && branch.any === read);
|
|
842
|
+
return;
|
|
843
|
+
}
|
|
844
|
+
for (const key in o)
|
|
845
|
+
if (key !== 'PARENT')
|
|
846
|
+
visit(o[key], selected);
|
|
847
|
+
};
|
|
848
|
+
visit(container.content, true);
|
|
849
|
+
return out;
|
|
850
|
+
}
|
|
@@ -9,6 +9,7 @@ import { Paragraph } from './Paragraph.mjs';
|
|
|
9
9
|
import { Range } from './Range.mjs';
|
|
10
10
|
import { runOf, paragraphOf, typeNameOf } from './tree.mjs';
|
|
11
11
|
import { revisionDateOf, wordCalendarOf, copyRPr } from './tracking.mjs';
|
|
12
|
+
import { relationshipIdsIn, queueRelationshipRemovals } from './relationships.mjs';
|
|
12
13
|
import { COMMENT_REFERENCE_STYLE, COMMENT_TEXT_STYLE, commentExOf, commentIdsOf, commentPartsAccess, commentParaId, initialsOf, isDone, markersOf, markersOfParagraph, nextCommentId, paraIdTaken, randomHexId, removeMarkers, setCommentApi, } from './comments.mjs';
|
|
13
14
|
/**
|
|
14
15
|
* A subset of Office JS `Word.Comment` over a `w:comment` and the markers that anchor it. A view:
|
|
@@ -191,6 +192,12 @@ export class Comment {
|
|
|
191
192
|
if (i >= 0)
|
|
192
193
|
comments.splice(i, 1);
|
|
193
194
|
}
|
|
195
|
+
// what the comment's own content related to - a picture's image - goes on save when nothing else
|
|
196
|
+
// uses it, as for a picture deleted outright (CR-002 section 50; docx4j's Removals)
|
|
197
|
+
const released = new Set();
|
|
198
|
+
relationshipIdsIn(this.element.content, released);
|
|
199
|
+
const pkg = this.body.package_;
|
|
200
|
+
queueRelationshipRemovals(pkg === null || pkg === void 0 ? void 0 : pkg.pendingRelationshipRemovals, this.parts.commentsPart, released);
|
|
194
201
|
const paraId = this.paraId;
|
|
195
202
|
if (paraId === undefined)
|
|
196
203
|
return;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type * as wml from '@docx4j/generated-objects-ts/modules/org_docx4j_wml';
|
|
2
|
+
import type * as dml from '@docx4j/generated-objects-ts/modules/org_docx4j_dml';
|
|
2
3
|
import type * as wp from '@docx4j/generated-objects-ts/modules/org_docx4j_dml_wordprocessingDrawing';
|
|
3
4
|
import { IMAGE_CONTENT_TYPES_BY_EXTENSION } from '../../opc/ContentTypes.mjs';
|
|
4
5
|
import { ImagePart } from '../../parts/BinaryPart.mjs';
|
|
@@ -72,9 +73,35 @@ export declare function addImagePart(source: Part, base64: string): NewImagePart
|
|
|
72
73
|
export declare function addImage(source: Part, base64: string, scope: object, maxCx: number | undefined, options?: InlinePictureOptions): NewPicture;
|
|
73
74
|
/** The writable width of a section in EMU (page width less the margins), for scaling. */
|
|
74
75
|
export declare function writableWidthEmu(container: object): number | undefined;
|
|
76
|
+
/** The `asvg:svgBlip` in a blip's `a:extLst`, if any: an SVG picture's SVG (CR-002 section 52). */
|
|
77
|
+
export declare function svgBlipOf(blip: dml.CTBlip | undefined): {
|
|
78
|
+
embed?: string;
|
|
79
|
+
} | undefined;
|
|
75
80
|
/**
|
|
76
|
-
*
|
|
77
|
-
*
|
|
81
|
+
* Points a blip at a new image the way Word's own picture binding does (test/README.md checks 46 and
|
|
82
|
+
* 47; CR-002 section 52). The blip's effects and other extensions stay.
|
|
83
|
+
* - A raster image goes in `r:embed`, and an `asvg:svgBlip` is taken away. Left in place, Word would go
|
|
84
|
+
* on drawing its old SVG, and would replace the new image with a PNG of that SVG when it saves.
|
|
85
|
+
* - An SVG goes under the `asvg:svgBlip`, and `r:embed` is taken away. Word puts a PNG of the SVG it
|
|
86
|
+
* makes itself in `r:embed`, which this package cannot make, and Word 365 draws the SVG without one.
|
|
87
|
+
* `r:link` is left as it was.
|
|
88
|
+
*/
|
|
89
|
+
export declare function setBlipImage(blip: dml.CTBlip, relId: string, svg: boolean): void;
|
|
90
|
+
/**
|
|
91
|
+
* The inline pictures a run's item holds: the item itself when it is a `w:drawing` whose `wp:inline`
|
|
92
|
+
* holds a `pic:pic`, and those in a kept `mc:AlternateContent`'s selected branch (`selectedBranchOf`,
|
|
93
|
+
* CR-010 phase 3). A drawing of anything else, such as a chart, a text box, a group or SmartArt, is no
|
|
94
|
+
* inline picture: Office JS lists none for an inline text box (CR-010 section 12.6, test/README.md
|
|
95
|
+
* check 42).
|
|
96
|
+
*/
|
|
97
|
+
export declare function picturesIn(item: Element): Element<wml.Drawing>[];
|
|
98
|
+
/**
|
|
99
|
+
* A subset of Office JS `Word.InlinePicture` over a `w:drawing` holding a `wp:inline` with a `pic:pic`.
|
|
100
|
+
* A view: the drawing, the run it is in and the paragraph. Sizes are points, as Office JS reports them.
|
|
101
|
+
*
|
|
102
|
+
* A picture in a kept `mc:AlternateContent`'s selected branch has the element as its `holder`. Reads and
|
|
103
|
+
* the setters are the selected branch's drawing; `delete` removes the element whole, every branch with
|
|
104
|
+
* it (CR-010 phase 3).
|
|
78
105
|
*/
|
|
79
106
|
export declare class InlinePicture {
|
|
80
107
|
/** The `w:drawing` element pair. */
|
|
@@ -82,11 +109,15 @@ export declare class InlinePicture {
|
|
|
82
109
|
/** The run holding the drawing, and the array holding the run. */
|
|
83
110
|
readonly run: Element<wml.R>;
|
|
84
111
|
readonly paragraph: Paragraph;
|
|
112
|
+
/** The run's item the drawing stands in, where that is not the drawing: a kept `mc:AlternateContent`. */
|
|
113
|
+
readonly holder?: Element | undefined;
|
|
85
114
|
constructor(
|
|
86
115
|
/** The `w:drawing` element pair. */
|
|
87
116
|
element: Element<wml.Drawing>,
|
|
88
117
|
/** The run holding the drawing, and the array holding the run. */
|
|
89
|
-
run: Element<wml.R>, paragraph: Paragraph
|
|
118
|
+
run: Element<wml.R>, paragraph: Paragraph,
|
|
119
|
+
/** The run's item the drawing stands in, where that is not the drawing: a kept `mc:AlternateContent`. */
|
|
120
|
+
holder?: Element | undefined);
|
|
90
121
|
/** The wp:inline; a floating picture (wp:anchor) is not an InlinePicture, and throws. */
|
|
91
122
|
get inline(): wp.Inline;
|
|
92
123
|
/** Width in points, as Office JS. */
|
|
@@ -100,18 +131,51 @@ export declare class InlinePicture {
|
|
|
100
131
|
/** wp:docPr/@title (typed since objects 0.1.3; before that the attribute was not marshalled, CR-002 section 8). */
|
|
101
132
|
get altTextTitle(): string;
|
|
102
133
|
set altTextTitle(text: string);
|
|
103
|
-
/**
|
|
134
|
+
/**
|
|
135
|
+
* The kind of image, from the content type of the part `getBase64` reads: `Svg` for an SVG picture
|
|
136
|
+
* (`svgImagePart`), else the `a:blip`'s part's. Office JS gives `null` for an SVG picture, though its
|
|
137
|
+
* typings declare the property non-null and `Word.ImageFormat` has `Svg` (test/README.md check 45);
|
|
138
|
+
* this package gives `Svg`, a departure (CR-002 section 52).
|
|
139
|
+
*/
|
|
104
140
|
get imageFormat(): ImageFormat;
|
|
105
141
|
/** The relationship id of the embedded image (r:embed), if any (extension). */
|
|
106
142
|
get relId(): string | undefined;
|
|
107
|
-
/**
|
|
143
|
+
/**
|
|
144
|
+
* The relationship id of the SVG the picture embeds beside its image, if any (extension): the
|
|
145
|
+
* `r:embed` of an `asvg:svgBlip` in the `a:blip`'s `a:extLst`, as Office 2016 and later write an SVG
|
|
146
|
+
* picture, with the `a:blip`'s own image a PNG of it for readers that don't understand SVG.
|
|
147
|
+
*/
|
|
148
|
+
get svgRelId(): string | undefined;
|
|
149
|
+
/**
|
|
150
|
+
* The image's bytes as base64 (Office JS getBase64ImageSrc). For an SVG picture, the SVG
|
|
151
|
+
* (`svgImagePart`), as Office JS gives it (test/README.md check 43); else the `a:blip`'s image.
|
|
152
|
+
*/
|
|
108
153
|
getBase64(): Promise<string>;
|
|
109
154
|
/** Office JS's name for `getBase64()`. */
|
|
110
155
|
getBase64ImageSrc(): Promise<string>;
|
|
111
|
-
/** The image part this picture embeds (extension). */
|
|
156
|
+
/** The image part this picture embeds: the `a:blip`'s, which is an SVG picture's PNG (extension). */
|
|
112
157
|
imagePart(): ImagePart | undefined;
|
|
113
|
-
/**
|
|
158
|
+
/** The SVG part an SVG picture embeds beside its image (`svgRelId`), if any (extension). */
|
|
159
|
+
svgImagePart(): ImagePart | undefined;
|
|
160
|
+
private partFor;
|
|
161
|
+
/**
|
|
162
|
+
* Removes the picture; the run goes too when the picture was all it held. A picture in a kept
|
|
163
|
+
* `mc:AlternateContent` takes the element with it, every branch (`holder`).
|
|
164
|
+
*
|
|
165
|
+
* While the package tracks changes it is marked deleted instead: its run goes into a `w:del`, and
|
|
166
|
+
* when the run held more than the picture, the picture is first given a run of its own with the
|
|
167
|
+
* same properties, so the deletion holds it alone. Accepting the deletion then takes it, and its
|
|
168
|
+
* image part with it (CR-002 section 46). A picture its author inserted under tracking is taken
|
|
169
|
+
* back, as `Paragraph.delete` takes back its own text, and one inside a deletion is refused.
|
|
170
|
+
*
|
|
171
|
+
* A picture removed outright (tracking off, or taken back) queues its image relationship on the
|
|
172
|
+
* package. On save the relationship goes if nothing then references it, and the image part with it
|
|
173
|
+
* when nothing else targets it. Waiting for the save lets a picture cut and pasted back keep its
|
|
174
|
+
* image.
|
|
175
|
+
*/
|
|
114
176
|
delete(): void;
|
|
177
|
+
/** The picture's run in a `w:del`, the picture split into a run of its own when the run held more. */
|
|
178
|
+
private markDeleted;
|
|
115
179
|
private pic;
|
|
116
180
|
private resize;
|
|
117
181
|
}
|