@file-viewer/docx 0.3.27 → 0.3.28

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
@@ -38,6 +38,7 @@ const options = {
38
38
  updatePageReferences: false,
39
39
  hideWebHiddenContent: false,
40
40
  externalLinkPolicy: "allow",
41
+ externalResourcePolicy: "block",
41
42
  progress: ev => console.log(ev.phase, ev.current, ev.total, ev.message)
42
43
  };
43
44
 
@@ -59,6 +60,80 @@ await renderAsync(fileOrArrayBuffer, container, null, {
59
60
  });
60
61
  ```
61
62
 
63
+ Under a CSP with `require-trusted-types-for 'script'`, create the Worker at the
64
+ application boundary and pass it through `workerFactory`:
65
+
66
+ ```ts
67
+ const workerPolicy = trustedTypes.createPolicy("app-docx-worker", {
68
+ createScriptURL(value) {
69
+ const url = new URL(value, location.href);
70
+ if (url.origin !== location.origin)
71
+ throw new TypeError("DOCX Worker must be same-origin");
72
+ return url.href;
73
+ }
74
+ });
75
+
76
+ await renderAsync(fileOrArrayBuffer, container, null, {
77
+ useWorker: true,
78
+ workerFactory: () => new Worker(
79
+ workerPolicy.createScriptURL("/assets/docx-preview.worker.js")
80
+ )
81
+ });
82
+ ```
83
+
84
+ Copy `dist/docx-preview.worker.js` to that same-origin application asset path as
85
+ part of your build or deployment.
86
+
87
+ Allow the application-owned Worker policy and the renderer's three narrow HTML
88
+ policies in the `trusted-types` CSP directive:
89
+
90
+ ```text
91
+ trusted-types app-docx-worker file-viewer-docx-xml-parser file-viewer-docx-altchunk-parser file-viewer-docx-altchunk-srcdoc;
92
+ require-trusted-types-for 'script';
93
+ ```
94
+
95
+ The renderer policies brand only the exact value being sent to an inert XML/HTML
96
+ parser or the sanitized altChunk `srcdoc`; no default policy is installed.
97
+
98
+ ### Read-only review preview
99
+
100
+ Tracked changes remain disabled by default. Pass `reviewMode` to keep Word revision
101
+ markup in the DOM, show comments by default, and enable the four read-only views:
102
+
103
+ ```ts
104
+ import {
105
+ collectDocxReviewChanges,
106
+ renderAsync,
107
+ setDocxReviewMode
108
+ } from "@file-viewer/docx";
109
+
110
+ const document = await renderAsync(file, container, null, {
111
+ reviewMode: "all" // "final" | "original" | "simple" | "all"
112
+ });
113
+
114
+ const changes = collectDocxReviewChanges(document);
115
+ setDocxReviewMode(container, "original"); // no reparse required
116
+ ```
117
+
118
+ `renderChanges: true` is retained as a compatibility alias for `reviewMode: "all"`.
119
+ Set `renderComments: false` explicitly when tracked changes are required without
120
+ the comments surface.
121
+
122
+ The mode values follow Word's **Display for Review** semantics: `simple` keeps
123
+ the current text with compact change indicators, `all` exposes every supported
124
+ revision and comment anchor, `final` is the current document with markup hidden,
125
+ and `original` restores the pre-revision text with markup hidden. A host that
126
+ wants Word-style margin balloons can use `collectDocxReviewChanges()` together
127
+ with the stable `data-docx-change-*` anchors; the renderer does not force that
128
+ optional review UI on normal document previews.
129
+
130
+ `collectDocxReviewChanges()` returns logical Word review items rather than raw
131
+ OOXML wrappers. Adjacent/nested revision fragments from the same paragraph,
132
+ author, and edit session are coalesced; `ids` lists every source revision id.
133
+ The `presentation` field is `inline` for insert/move-to items and `balloon` for
134
+ delete/move-from/format/comment items. Formatting items include structured
135
+ `formatChanges` and a semantic description such as `无下划线`.
136
+
62
137
  ## API
63
138
 
64
139
  ```ts
@@ -139,6 +214,7 @@ collectLayoutSnapshot(
139
214
  renderEndnotes: true,
140
215
  renderComments: false,
141
216
  renderAltChunks: true,
217
+ reviewMode: undefined, // opt-in: "final" | "original" | "simple" | "all"
142
218
  renderChanges: false,
143
219
  experimental: false,
144
220
  trimXmlDeclaration: true,
@@ -176,7 +252,18 @@ For Word-authored documents, keep `ignoreLastRenderedPageBreak: false`. Those ma
176
252
 
177
253
  `w:webHidden` is not hidden by default in this renderer because it only applies to Word's Web Layout view. In Print Layout, Word still displays the TOC tab before the page number and the cached `PAGEREF` result even when those runs are marked `w:webHidden`. Set `hideWebHiddenContent: true` only for an explicit Web Layout style preview.
178
254
 
179
- External hyperlinks remain active by default. Set `externalLinkPolicy: "block"` to omit their `href` while preserving their text and target metadata. Document-internal bookmark links remain active in either mode.
255
+ External hyperlinks remain active by default, but only HTTP(S), `mailto:`, `tel:`
256
+ and safe relative targets receive an `href`. Script-capable, local-file, blob,
257
+ protocol-relative and unknown schemes are rejected in every mode. Set
258
+ `externalLinkPolicy: "block"` to omit safe external `href` values while preserving
259
+ their text and sanitized target metadata. Document-internal bookmark links remain
260
+ active in either mode.
261
+
262
+ External image relationships are blocked by default. Set `externalResourcePolicy: "allow"` only when the document is trusted to load HTTP(S) image resources. Package-embedded images and local `data:image/...` or `blob:` image URLs remain available without enabling network access; unknown and script-capable protocols are rejected in either mode.
263
+
264
+ `renderAltChunks` remains compatible with existing integrations. Embedded HTML is
265
+ parsed inertly and stripped of scripts, active elements, event handlers, CSS and
266
+ URL-bearing attributes before it reaches a maximally restricted sandboxed iframe.
180
267
 
181
268
  Set `darkMode: true` to reproduce Word Online's "Switch Modes" dark appearance. Every color the renderer emits — text, backgrounds/highlights, borders, underlines, theme colors and DrawingML/VML shape fills and strokes — is converted with the same lightness-inversion algorithm Microsoft uses for this exact purpose (see `roosterjs`'s `getDarkColor`): the color is converted to CIE Lab, only the lightness (`L`) channel is inverted around a fixed base value (the `L` of `#333333`), and hue/chroma (`a`/`b`) are left untouched. That guarantees every color stays legible on a dark page — pure black becomes pure white, pure white becomes `#333333`, and an arbitrary color such as `rgb(99, 36, 35)` keeps its reddish hue while becoming light enough to read — without the hue-flipping side effects of a naive per-channel RGB invert. The toggle is purely a rendering-time CSS transform — it does not change the parsed document model — and every transformed color is wrapped in a CSS variable so that `@media print` can restore the exact original light-mode value; print output always renders with Word's normal light appearance regardless of `darkMode`.
182
269
 
@@ -3,6 +3,7 @@ export interface Options {
3
3
  hideWrapperOnPrint: boolean;
4
4
  ignoreWidth: boolean;
5
5
  ignoreHeight: boolean;
6
+ fixedPageHeight: boolean;
6
7
  ignoreFonts: boolean;
7
8
  breakPages: boolean;
8
9
  strictWordCompatibility: boolean;
@@ -11,16 +12,19 @@ export interface Options {
11
12
  awaitLayout: boolean;
12
13
  useWorker: boolean;
13
14
  workerUrl?: string;
15
+ workerFactory?: () => Worker;
14
16
  workerJsZipUrl?: string;
15
17
  workerFallback: boolean;
16
18
  workerTimeout: number;
17
19
  renderPageBatchSize: number;
18
20
  renderYieldEveryMs: number;
19
21
  progress?: (event: DocxProgressEvent) => void;
22
+ licenseToken?: unknown;
20
23
  preserveComplexFieldResults: boolean;
21
24
  updatePageReferences: boolean;
22
25
  hideWebHiddenContent: boolean;
23
26
  externalLinkPolicy: "allow" | "block";
27
+ externalResourcePolicy: "allow" | "block";
24
28
  darkMode: boolean;
25
29
  debug: boolean;
26
30
  experimental: boolean;
@@ -33,10 +37,20 @@ export interface Options {
33
37
  ignoreLastRenderedPageBreak: boolean;
34
38
  useBase64URL: boolean;
35
39
  renderChanges: boolean;
40
+ reviewMode?: ReviewMode;
36
41
  renderComments: boolean;
37
42
  renderAltChunks: boolean;
38
43
  h: (elem: any) => Node;
39
44
  }
45
+ export type ReviewMode = "final" | "original" | "simple" | "all";
46
+ export type ReviewChangeKind = "insert" | "delete" | "move-from" | "move-to" | "format";
47
+ export interface ReviewChange {
48
+ id?: string;
49
+ kind: ReviewChangeKind;
50
+ author?: string;
51
+ date?: string;
52
+ text: string;
53
+ }
40
54
  export interface DocxProgressEvent {
41
55
  phase: "worker" | "parse" | "render" | "layout" | "done" | string;
42
56
  current?: number;
@@ -76,3 +90,5 @@ export declare function parseAsyncInWorker(data: Blob | any, userOptions?: Parti
76
90
  export declare function awaitRenderedLayout(container: HTMLElement, userOptions?: Partial<Options>): Promise<LayoutSnapshot>;
77
91
  export declare function collectLayoutSnapshot(container: HTMLElement, userOptions?: Partial<Options>): LayoutSnapshot;
78
92
  export declare function yieldToBrowser(): Promise<void>;
93
+ export declare function collectDocxReviewChanges(documentOrRoot: any): ReviewChange[];
94
+ export declare function setDocxReviewMode(container: HTMLElement, mode: ReviewMode): boolean;