@docmentis/udoc-viewer 0.4.2 → 0.4.4
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 +102 -26
- package/dist/package.json +1 -1
- package/dist/src/wasm/udoc_bg.wasm +0 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
# @docmentis/udoc-viewer
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Universal Document Viewer built on top of a WebAssembly engine.
|
|
4
4
|
|
|
5
5
|
**Free. Unlimited. Forever.** Provided by [docMentis.com](https://docmentis.com).
|
|
6
6
|
|
|
7
7
|
## Supported Formats
|
|
8
8
|
|
|
9
|
-
| Format | Extensions |
|
|
10
|
-
|
|
11
|
-
| PDF | .pdf |
|
|
12
|
-
| PPTX | .pptx |
|
|
13
|
-
| Images | .jpg, .jpeg, .png, .gif, .bmp, .tif, .tiff, .webp, .ico, .tga, .ppm, .pgm, .pbm, .hdr, .exr, .qoi |
|
|
9
|
+
| Format | Extensions |
|
|
10
|
+
|--------|------------|
|
|
11
|
+
| PDF | .pdf |
|
|
12
|
+
| PPTX | .pptx |
|
|
13
|
+
| Images | .jpg, .jpeg, .png, .gif, .bmp, .tif, .tiff, .webp, .ico, .tga, .ppm, .pgm, .pbm, .hdr, .exr, .qoi |
|
|
14
14
|
|
|
15
15
|
## Installation
|
|
16
16
|
|
|
@@ -28,7 +28,7 @@ const client = await UDocClient.create();
|
|
|
28
28
|
|
|
29
29
|
// Create a viewer attached to a container element
|
|
30
30
|
const viewer = await client.createViewer({
|
|
31
|
-
container: '#viewer'
|
|
31
|
+
container: '#viewer',
|
|
32
32
|
});
|
|
33
33
|
|
|
34
34
|
// Load a document
|
|
@@ -57,11 +57,27 @@ await viewer.load(new Uint8Array(buffer));
|
|
|
57
57
|
viewer.close();
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
+
## Password-Protected Documents
|
|
61
|
+
|
|
62
|
+
When a password-protected document is loaded in UI mode, the viewer automatically prompts the user to enter the password. For headless mode, you can handle it programmatically:
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
await viewer.load(source);
|
|
66
|
+
|
|
67
|
+
if (await viewer.needsPassword()) {
|
|
68
|
+
const success = await viewer.authenticate('my-password');
|
|
69
|
+
if (!success) {
|
|
70
|
+
console.error('Incorrect password');
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
60
75
|
## Client Options
|
|
61
76
|
|
|
62
77
|
```typescript
|
|
63
78
|
const client = await UDocClient.create({
|
|
64
79
|
// Custom base URL for worker and WASM files (optional)
|
|
80
|
+
// Expected files: {baseUrl}/worker.js and {baseUrl}/udoc_bg.wasm
|
|
65
81
|
baseUrl: 'https://cdn.example.com/udoc/',
|
|
66
82
|
});
|
|
67
83
|
```
|
|
@@ -70,32 +86,46 @@ const client = await UDocClient.create({
|
|
|
70
86
|
|
|
71
87
|
```typescript
|
|
72
88
|
const viewer = await client.createViewer({
|
|
73
|
-
// Container element or CSS selector (required for UI mode)
|
|
89
|
+
// Container element or CSS selector (required for UI mode, omit for headless)
|
|
74
90
|
container: '#viewer',
|
|
75
91
|
|
|
76
|
-
// Scroll mode: 'continuous' or '
|
|
77
|
-
scrollMode:
|
|
92
|
+
// Scroll mode: 'continuous' or 'spread' (default: 'continuous')
|
|
93
|
+
scrollMode: 'continuous',
|
|
78
94
|
|
|
79
|
-
// Layout mode: 'single-page', '
|
|
80
|
-
|
|
95
|
+
// Layout mode: 'single-page', 'double-page', 'double-page-odd-right', 'double-page-odd-left'
|
|
96
|
+
// (default: 'single-page')
|
|
97
|
+
layoutMode: 'single-page',
|
|
81
98
|
|
|
82
|
-
// Zoom mode: 'fit-width', 'fit-
|
|
83
|
-
|
|
99
|
+
// Zoom mode: 'fit-spread-width', 'fit-spread-height', 'fit-spread', 'custom'
|
|
100
|
+
// (default: 'fit-spread-width')
|
|
101
|
+
zoomMode: 'fit-spread-width',
|
|
84
102
|
|
|
85
|
-
// Initial zoom level (when zoomMode is 'custom')
|
|
103
|
+
// Initial zoom level (when zoomMode is 'custom', default: 1)
|
|
86
104
|
zoom: 1,
|
|
87
105
|
|
|
88
106
|
// Custom zoom steps for zoom in/out
|
|
89
|
-
|
|
107
|
+
// (default: [0.1, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 2, 3, 4, 5])
|
|
108
|
+
zoomSteps: [0.1, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 2, 3, 4, 5],
|
|
90
109
|
|
|
91
|
-
// Spacing between pages in pixels
|
|
110
|
+
// Spacing between pages in pixels (default: 10)
|
|
92
111
|
pageSpacing: 10,
|
|
93
112
|
|
|
94
|
-
//
|
|
113
|
+
// Spacing between spreads in pixels (default: 20)
|
|
114
|
+
spreadSpacing: 20,
|
|
115
|
+
|
|
116
|
+
// Initially active panel, or null for no panel (default: null)
|
|
117
|
+
// Left panels: 'thumbnail', 'outline', 'bookmarks', 'layers', 'attachments'
|
|
118
|
+
// Right panels: 'search', 'comments'
|
|
95
119
|
activePanel: null,
|
|
96
120
|
|
|
97
121
|
// Target display DPI (default: 96)
|
|
98
122
|
dpi: 96,
|
|
123
|
+
|
|
124
|
+
// Enable Google Fonts for automatic font fetching (default: true)
|
|
125
|
+
googleFonts: true,
|
|
126
|
+
|
|
127
|
+
// Enable performance tracking (default: false)
|
|
128
|
+
enablePerformanceCounter: false,
|
|
99
129
|
});
|
|
100
130
|
```
|
|
101
131
|
|
|
@@ -105,7 +135,7 @@ const viewer = await client.createViewer({
|
|
|
105
135
|
// Get current page (1-based)
|
|
106
136
|
const page = viewer.currentPage;
|
|
107
137
|
|
|
108
|
-
// Go to a specific page
|
|
138
|
+
// Go to a specific page (1-based)
|
|
109
139
|
viewer.goToPage(5);
|
|
110
140
|
|
|
111
141
|
// Navigate to a destination (from outline)
|
|
@@ -120,6 +150,10 @@ if (viewer.isLoaded) {
|
|
|
120
150
|
// Get page count
|
|
121
151
|
const total = viewer.pageCount;
|
|
122
152
|
|
|
153
|
+
// Get document metadata
|
|
154
|
+
const meta = viewer.metadata;
|
|
155
|
+
console.log(meta?.title, meta?.author);
|
|
156
|
+
|
|
123
157
|
// Get page dimensions (0-based index)
|
|
124
158
|
const info = await viewer.getPageInfo(0);
|
|
125
159
|
console.log(`Page 1: ${info.width} x ${info.height} points`);
|
|
@@ -127,7 +161,7 @@ if (viewer.isLoaded) {
|
|
|
127
161
|
// Get document outline (table of contents)
|
|
128
162
|
const outline = await viewer.getOutline();
|
|
129
163
|
|
|
130
|
-
// Get annotations on a page
|
|
164
|
+
// Get annotations on a page (0-based index)
|
|
131
165
|
const annotations = await viewer.getPageAnnotations(0);
|
|
132
166
|
}
|
|
133
167
|
```
|
|
@@ -141,21 +175,34 @@ Render pages to images without UI:
|
|
|
141
175
|
const viewer = await client.createViewer();
|
|
142
176
|
await viewer.load(pdfBytes);
|
|
143
177
|
|
|
144
|
-
// Render page to ImageData
|
|
178
|
+
// Render page to ImageData (0-based page index)
|
|
145
179
|
const imageData = await viewer.renderPage(0, { scale: 2 });
|
|
146
180
|
|
|
147
181
|
// Render to Blob
|
|
148
182
|
const blob = await viewer.renderPage(0, {
|
|
149
183
|
format: 'blob',
|
|
150
|
-
imageType: 'image/png'
|
|
184
|
+
imageType: 'image/png',
|
|
151
185
|
});
|
|
152
186
|
|
|
153
187
|
// Render to data URL
|
|
154
188
|
const dataUrl = await viewer.renderPage(0, {
|
|
155
189
|
format: 'data-url',
|
|
156
190
|
imageType: 'image/jpeg',
|
|
157
|
-
quality: 0.9
|
|
191
|
+
quality: 0.9,
|
|
158
192
|
});
|
|
193
|
+
|
|
194
|
+
// Render thumbnail
|
|
195
|
+
const thumb = await viewer.renderThumbnail(0, { scale: 1 });
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Document Export
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
// Export document as raw bytes
|
|
202
|
+
const bytes = await viewer.toBytes();
|
|
203
|
+
|
|
204
|
+
// Download document as a file
|
|
205
|
+
await viewer.download('document.pdf');
|
|
159
206
|
```
|
|
160
207
|
|
|
161
208
|
## Document Composition
|
|
@@ -166,9 +213,9 @@ Compose new documents by cherry-picking and rotating pages:
|
|
|
166
213
|
// Create a new document from pages of existing documents
|
|
167
214
|
const [newDoc] = await client.compose([
|
|
168
215
|
[
|
|
169
|
-
{ doc: viewerA, pages:
|
|
170
|
-
{ doc: viewerB, pages:
|
|
171
|
-
]
|
|
216
|
+
{ doc: viewerA, pages: '1-3' },
|
|
217
|
+
{ doc: viewerB, pages: '5', rotation: 90 },
|
|
218
|
+
],
|
|
172
219
|
]);
|
|
173
220
|
|
|
174
221
|
// Export the composed document
|
|
@@ -176,6 +223,30 @@ const bytes = await newDoc.toBytes();
|
|
|
176
223
|
await newDoc.download('composed.pdf');
|
|
177
224
|
```
|
|
178
225
|
|
|
226
|
+
## Document Utilities
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
// Split a document by its outline (table of contents)
|
|
230
|
+
const { viewers, sections } = await client.splitByOutline(source, {
|
|
231
|
+
maxLevel: 2,
|
|
232
|
+
splitMidPage: false,
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
// Extract images from a document
|
|
236
|
+
const images = await client.extractImages(source, {
|
|
237
|
+
convertRawToPng: true,
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
// Extract fonts from a document
|
|
241
|
+
const fonts = await client.extractFonts(source);
|
|
242
|
+
|
|
243
|
+
// Compress a document
|
|
244
|
+
const compressed = await client.compress(source);
|
|
245
|
+
|
|
246
|
+
// Decompress a document
|
|
247
|
+
const decompressed = await client.decompress(source);
|
|
248
|
+
```
|
|
249
|
+
|
|
179
250
|
## Events
|
|
180
251
|
|
|
181
252
|
```typescript
|
|
@@ -189,6 +260,11 @@ viewer.on('document:close', () => {
|
|
|
189
260
|
console.log('Document closed');
|
|
190
261
|
});
|
|
191
262
|
|
|
263
|
+
// Download progress
|
|
264
|
+
viewer.on('download:progress', ({ loaded, total, percent }) => {
|
|
265
|
+
console.log(`Downloaded ${loaded}/${total} bytes (${percent}%)`);
|
|
266
|
+
});
|
|
267
|
+
|
|
192
268
|
// Error occurred
|
|
193
269
|
viewer.on('error', ({ error, phase }) => {
|
|
194
270
|
console.error(`Error during ${phase}:`, error);
|
package/dist/package.json
CHANGED
|
Binary file
|