pdfjs-viewer-element 2.7.1 → 2.7.3
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 +38 -31
- package/dist/pdfjs-viewer-element.js +72 -68
- package/package.json +9 -9
package/README.md
CHANGED
|
@@ -1,53 +1,60 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
<h1 align="center">pdfjs-viewer-element</h1>
|
|
1
|
+
# pdfjs-viewer-element
|
|
2
|
+
|
|
3
|
+
Custom element that embeds [PDF.js default viewer](https://mozilla.github.io/pdf.js/web/viewer.html) using the `iframe`.
|
|
5
4
|
|
|
6
|
-
The simplest integration of [PDF.js default viewer](https://mozilla.github.io/pdf.js/web/viewer.html) using the `iframe` element and web component.
|
|
7
5
|
The package provides a custom element, based on PDF.js [viewer options](https://github.com/mozilla/pdf.js/wiki/Viewer-options) and [URL parameters](https://github.com/mozilla/pdf.js/wiki/Debugging-PDF.js#url-parameters) API.
|
|
6
|
+
|
|
8
7
|
Supported in all [major browsers](https://caniuse.com/custom-elementsv1), and works with most [JS frameworks](https://custom-elements-everywhere.com/).
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
[](https://www.npmjs.com/package/pdfjs-viewer-element)
|
|
10
|
+
[](https://packagequality.com/#?package=pdfjs-viewer-element)
|
|
11
|
+
[](https://www.webcomponents.org/element/pdfjs-viewer-element)
|
|
12
|
+
|
|
13
|
+

|
|
12
14
|
|
|
13
15
|
## Features
|
|
14
16
|
|
|
15
17
|
- Simple PDF.js viewer integration to any web application
|
|
16
|
-
- PDF.js viewer options and parameters support, access
|
|
17
|
-
-
|
|
18
|
+
- PDF.js viewer options and parameters support, access the viewer application instance
|
|
19
|
+
- Customize viewer styles and themes
|
|
18
20
|
|
|
19
|
-
##
|
|
21
|
+
## Docs
|
|
20
22
|
|
|
21
|
-
|
|
23
|
+
[Getting started](https://alekswebnet.github.io/pdfjs-viewer-element/)
|
|
22
24
|
|
|
23
|
-
|
|
25
|
+
[API playground](https://alekswebnet.github.io/pdfjs-viewer-element/#api)
|
|
24
26
|
|
|
25
|
-
|
|
27
|
+
[Usage with frameworks](https://alekswebnet.github.io/pdfjs-viewer-element/#demo)
|
|
26
28
|
|
|
27
|
-
|
|
28
|
-
All v4 and v3 [releases](https://github.com/mozilla/pdf.js/releases) are supported.
|
|
29
|
+
[Various usecases](https://github.com/alekswebnet/pdfjs-viewer-element/tree/master/demo)
|
|
29
30
|
|
|
30
|
-
|
|
31
|
+
## Support via Ko-fi
|
|
31
32
|
|
|
32
|
-
|
|
33
|
+
If you find `pdfjs-viewer-element` useful and want to support its development, consider making a donation via Ko-fi:
|
|
33
34
|
|
|
34
|
-
[](https://packagequality.com/#?package=pdfjs-viewer-element)
|
|
36
|
-
[](https://www.webcomponents.org/element/pdfjs-viewer-element)
|
|
35
|
+
[](https://ko-fi.com/oleksandrshevchuk)
|
|
37
36
|
|
|
38
|
-
|
|
37
|
+
> ❤️ Your support helps with maintenance, bug fixes, and long-term improvements.
|
|
39
38
|
|
|
40
|
-
|
|
39
|
+
## How it works
|
|
41
40
|
|
|
42
|
-
|
|
41
|
+
**⚠️ This is an important part, please read this FIRST !!!**
|
|
42
|
+
|
|
43
|
+
**You should download and place the PDF.js prebuilt files in the project.**
|
|
44
|
+
|
|
45
|
+
`pdfjs-viewer-element` requires [PDF.js prebuilt](http://mozilla.github.io/pdf.js/getting_started/), that includes the generic build of PDF.js and the viewer.
|
|
46
|
+
|
|
47
|
+
The prebuilt comes with each PDF.js release. [PDF.JS releases](https://github.com/mozilla/pdf.js/releases)
|
|
48
|
+
|
|
49
|
+
✅ All v4 and v3 releases are fully supported.
|
|
43
50
|
|
|
44
|
-
|
|
51
|
+
🚧 For v5 releases - there are some breaking changes that affects styles injecting, and theme changing not work anymore.
|
|
45
52
|
|
|
46
|
-
[
|
|
53
|
+
After placing the prebuild specify the path to the directory with the `viewer-path` property (`/pdfjs` by default) and PDF file URL with `src` property (should refer to the [same origin](https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions#can-i-load-a-pdf-from-another-server-cross-domain-request)).
|
|
47
54
|
|
|
48
55
|
## Install
|
|
49
56
|
|
|
50
|
-
Using module bundlers:
|
|
57
|
+
### Using module bundlers:
|
|
51
58
|
|
|
52
59
|
```bash
|
|
53
60
|
# With npm
|
|
@@ -62,7 +69,7 @@ pnpm add pdfjs-viewer-element
|
|
|
62
69
|
import 'pdfjs-viewer-element'
|
|
63
70
|
```
|
|
64
71
|
|
|
65
|
-
Using browser:
|
|
72
|
+
### Using browser and CDN:
|
|
66
73
|
|
|
67
74
|
```html
|
|
68
75
|
<script type="module" src="https://cdn.skypack.dev/pdfjs-viewer-element"></script>
|
|
@@ -71,7 +78,7 @@ Using browser:
|
|
|
71
78
|
## Usage
|
|
72
79
|
|
|
73
80
|
```html
|
|
74
|
-
<pdfjs-viewer-element src="/file.pdf" viewer-path="/pdfjs-
|
|
81
|
+
<pdfjs-viewer-element src="/file.pdf" viewer-path="/pdfjs-5.3.93-dist"></pdfjs-viewer-element>
|
|
75
82
|
```
|
|
76
83
|
|
|
77
84
|
## Attributes
|
|
@@ -123,7 +130,7 @@ Use `viewer-css-theme` attribute to set light or dark theme manually:
|
|
|
123
130
|
```html
|
|
124
131
|
<pdfjs-viewer-element
|
|
125
132
|
src="/file.pdf"
|
|
126
|
-
viewer-path="/pdfjs-
|
|
133
|
+
viewer-path="/pdfjs-5.3.93-dist"
|
|
127
134
|
viewer-css-theme="DARK">
|
|
128
135
|
</pdfjs-viewer-element>
|
|
129
136
|
```
|
|
@@ -135,7 +142,7 @@ You can add your own CSS rules to the viewer application using `viewer-extra-sty
|
|
|
135
142
|
```html
|
|
136
143
|
<pdfjs-viewer-element
|
|
137
144
|
src="/file.pdf"
|
|
138
|
-
viewer-path="/pdfjs-
|
|
145
|
+
viewer-path="/pdfjs-5.3.93-dist"
|
|
139
146
|
viewer-extra-styles="#toolbarViewerMiddle { display: none; }"
|
|
140
147
|
viewer-extra-styles-urls="['/demo/viewer-custom-theme.css']">
|
|
141
148
|
</pdfjs-viewer-element>
|
|
@@ -168,7 +175,7 @@ Build your own theme with viewer's custom variables and `viewer-extra-styles-url
|
|
|
168
175
|
`initialize` - using this method you can access PDFViewerApplication and use methods and events of PDF.js default viewer
|
|
169
176
|
|
|
170
177
|
```html
|
|
171
|
-
<pdfjs-viewer-element viewer-path="/pdfjs-
|
|
178
|
+
<pdfjs-viewer-element viewer-path="/pdfjs-5.3.93-dist"></pdfjs-viewer-element>
|
|
172
179
|
```
|
|
173
180
|
|
|
174
181
|
```javascript
|
|
@@ -1,115 +1,119 @@
|
|
|
1
|
-
const y = (p,
|
|
2
|
-
let s =
|
|
3
|
-
s ? o(s) : new MutationObserver((r,
|
|
4
|
-
Array.from(
|
|
5
|
-
o(
|
|
1
|
+
const y = (p, e) => new Promise((o) => {
|
|
2
|
+
let s = e.querySelector(p);
|
|
3
|
+
s ? o(s) : new MutationObserver((r, t) => {
|
|
4
|
+
Array.from(e.querySelectorAll(p)).forEach((n) => {
|
|
5
|
+
o(n), t.disconnect();
|
|
6
6
|
});
|
|
7
|
-
}).observe(
|
|
8
|
-
}), T = { trailing: !0 },
|
|
7
|
+
}).observe(e, { childList: !0, subtree: !0 });
|
|
8
|
+
}), T = { trailing: !0 }, E = "/pdfjs", D = "/web/viewer.html", A = "", C = "", P = "", k = "", V = "", F = "none", R = "", O = "", L = "", I = "", j = "", W = "", q = "", M = "", v = "AUTOMATIC", $ = "", z = "", H = "", b = { AUTOMATIC: 0, LIGHT: 1, DARK: 2 }, N = ["src", "viewer-path", "disable-worker", "text-layer", "disable-font-face", "disable-range", "disable-stream", "disable-auto-fetch", "verbosity", "locale", "viewer-css-theme", "viewer-extra-styles", "viewer-extra-styles-urls"];
|
|
9
9
|
class x extends HTMLElement {
|
|
10
10
|
constructor() {
|
|
11
|
-
super(), this.onIframeReady = function(s, r = 25,
|
|
12
|
-
if (
|
|
13
|
-
let
|
|
14
|
-
const
|
|
15
|
-
return await
|
|
16
|
-
}(s,
|
|
17
|
-
if (a = null,
|
|
18
|
-
const
|
|
19
|
-
return
|
|
11
|
+
super(), this.onIframeReady = (function(s, r = 25, t = {}) {
|
|
12
|
+
if (t = { ...T, ...t }, !Number.isFinite(r)) throw new TypeError("Expected `wait` to be a finite number");
|
|
13
|
+
let n, i, a, h, l = [];
|
|
14
|
+
const c = (d, u) => (a = (async function(m, f, w) {
|
|
15
|
+
return await m.apply(f, w);
|
|
16
|
+
})(s, d, u), a.finally(() => {
|
|
17
|
+
if (a = null, t.trailing && h && !i) {
|
|
18
|
+
const m = c(d, h);
|
|
19
|
+
return h = null, m;
|
|
20
20
|
}
|
|
21
21
|
}), a);
|
|
22
|
-
return function(...
|
|
23
|
-
return a ? (
|
|
24
|
-
const
|
|
25
|
-
clearTimeout(
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
for (const w of
|
|
29
|
-
|
|
30
|
-
}, r),
|
|
22
|
+
return function(...d) {
|
|
23
|
+
return a ? (t.trailing && (h = d), a) : new Promise((u) => {
|
|
24
|
+
const m = !i && t.leading;
|
|
25
|
+
clearTimeout(i), i = setTimeout(() => {
|
|
26
|
+
i = null;
|
|
27
|
+
const f = t.leading ? n : c(this, d);
|
|
28
|
+
for (const w of l) w(f);
|
|
29
|
+
l = [];
|
|
30
|
+
}, r), m ? (n = c(this, d), u(n)) : l.push(u);
|
|
31
31
|
});
|
|
32
32
|
};
|
|
33
|
-
}(async (s) => {
|
|
33
|
+
})(async (s) => {
|
|
34
34
|
await y("iframe", this.shadowRoot), s();
|
|
35
35
|
}, 0, { leading: !0 }), this.setViewerExtraStyles = (s, r = "extra") => {
|
|
36
|
-
var
|
|
37
|
-
if (!s) return void ((
|
|
38
|
-
if (((
|
|
39
|
-
const
|
|
40
|
-
|
|
36
|
+
var n, i, a, h, l;
|
|
37
|
+
if (!s) return void ((i = (n = this.iframe.contentDocument) == null ? void 0 : n.head.querySelector(`style[${r}]`)) == null ? void 0 : i.remove());
|
|
38
|
+
if (((h = (a = this.iframe.contentDocument) == null ? void 0 : a.head.querySelector(`style[${r}]`)) == null ? void 0 : h.innerHTML) === s) return;
|
|
39
|
+
const t = document.createElement("style");
|
|
40
|
+
t.innerHTML = s, t.setAttribute(r, ""), (l = this.iframe.contentDocument) == null || l.head.appendChild(t);
|
|
41
41
|
}, this.injectExtraStylesLinks = (s) => {
|
|
42
42
|
s && s.replace(/'|]|\[/g, "").split(",").map((r) => r.trim()).forEach((r) => {
|
|
43
|
-
var
|
|
44
|
-
if ((
|
|
45
|
-
const
|
|
46
|
-
|
|
43
|
+
var i, a;
|
|
44
|
+
if ((i = this.iframe.contentDocument) == null ? void 0 : i.head.querySelector(`link[href="${r}"]`)) return;
|
|
45
|
+
const n = document.createElement("link");
|
|
46
|
+
n.rel = "stylesheet", n.href = r, (a = this.iframe.contentDocument) == null || a.head.appendChild(n);
|
|
47
47
|
});
|
|
48
48
|
}, this.initialize = () => new Promise(async (s) => {
|
|
49
49
|
var r;
|
|
50
50
|
await y("iframe", this.shadowRoot), (r = this.iframe) == null || r.addEventListener("load", async () => {
|
|
51
|
-
var
|
|
52
|
-
await ((
|
|
51
|
+
var t, n, i;
|
|
52
|
+
await ((n = (t = this.iframe.contentWindow) == null ? void 0 : t.PDFViewerApplication) == null ? void 0 : n.initializedPromise), s((i = this.iframe.contentWindow) == null ? void 0 : i.PDFViewerApplication);
|
|
53
53
|
}, { once: !0 });
|
|
54
54
|
});
|
|
55
|
-
const
|
|
55
|
+
const e = this.attachShadow({ mode: "open" }), o = document.createElement("template");
|
|
56
56
|
o.innerHTML = `
|
|
57
57
|
<style>:host{width:100%;display:block;overflow:hidden}:host iframe{height:100%}</style>
|
|
58
58
|
<iframe frameborder="0" width="100%" loading="lazy"></iframe>
|
|
59
|
-
`,
|
|
59
|
+
`, e.appendChild(o.content.cloneNode(!0));
|
|
60
60
|
}
|
|
61
61
|
static get observedAttributes() {
|
|
62
62
|
return ["src", "viewer-path", "page", "search", "phrase", "zoom", "pagemode", "disable-worker", "text-layer", "disable-font-face", "disable-range", "disable-stream", "disable-auto-fetch", "verbosity", "locale", "viewer-css-theme", "viewer-extra-styles", "viewer-extra-styles-urls", "nameddest"];
|
|
63
63
|
}
|
|
64
64
|
connectedCallback() {
|
|
65
65
|
this.iframe = this.shadowRoot.querySelector("iframe"), document.addEventListener("webviewerloaded", async () => {
|
|
66
|
-
var
|
|
67
|
-
this.setCssTheme(this.getCssThemeOption()), this.injectExtraStylesLinks(this.getAttribute("viewer-extra-styles-urls") ?? z), this.setViewerExtraStyles(this.getAttribute("viewer-extra-styles") ?? $), this.getAttribute("src") !== A && ((o = (
|
|
66
|
+
var e, o, s, r, t, n, i, a;
|
|
67
|
+
this.setCssTheme(this.getCssThemeOption()), this.injectExtraStylesLinks(this.getAttribute("viewer-extra-styles-urls") ?? z), this.setViewerExtraStyles(this.getAttribute("viewer-extra-styles") ?? $), this.getAttribute("src") !== A && ((o = (e = this.iframe.contentWindow) == null ? void 0 : e.PDFViewerApplicationOptions) == null || o.set("defaultUrl", "")), (r = (s = this.iframe.contentWindow) == null ? void 0 : s.PDFViewerApplicationOptions) == null || r.set("disablePreferences", !0), (n = (t = this.iframe.contentWindow) == null ? void 0 : t.PDFViewerApplicationOptions) == null || n.set("pdfBugEnabled", !0), (a = (i = this.iframe.contentWindow) == null ? void 0 : i.PDFViewerApplicationOptions) == null || a.set("eventBusDispatchToDOM", !0);
|
|
68
68
|
});
|
|
69
69
|
}
|
|
70
|
-
attributeChangedCallback(
|
|
71
|
-
N.includes(
|
|
70
|
+
attributeChangedCallback(e) {
|
|
71
|
+
N.includes(e) ? this.onIframeReady(() => this.mountViewer(this.getIframeSrc())) : this.onIframeReady(() => {
|
|
72
72
|
this.iframe.src = this.getIframeSrc();
|
|
73
73
|
});
|
|
74
74
|
}
|
|
75
75
|
getIframeSrc() {
|
|
76
|
-
const
|
|
76
|
+
const e = this.getFullPath(this.getAttribute("src") || A), o = this.getFullPath(this.getAttribute("viewer-path") || E), s = this.getAttribute("page") || C, r = this.getAttribute("search") || P, t = this.getAttribute("phrase") || k, n = this.getAttribute("zoom") || V, i = this.getAttribute("pagemode") || F, a = this.getAttribute("disable-worker") || O, h = this.getAttribute("text-layer") || L, l = this.getAttribute("disable-font-face") || I, c = this.getAttribute("disable-range") || j, d = this.getAttribute("disable-stream") || W, u = this.getAttribute("disable-auto-fetch") || q, m = this.getAttribute("verbosity") || M, f = this.getAttribute("locale") || R, w = this.getAttribute("viewer-css-theme") || v, S = !!(this.getAttribute("viewer-extra-styles") || $), g = this.getAttribute("nameddest") || H;
|
|
77
77
|
return `
|
|
78
78
|
${o}${D}?file=
|
|
79
|
-
${encodeURIComponent(
|
|
80
|
-
${
|
|
79
|
+
${encodeURIComponent(e)}#page=${s}&zoom=${n}&pagemode=${i}&search=${r}&phrase=${t}&textLayer=
|
|
80
|
+
${h}&disableWorker=
|
|
81
81
|
${a}&disableFontFace=
|
|
82
|
-
${
|
|
83
|
-
${
|
|
84
|
-
${
|
|
85
|
-
${
|
|
86
|
-
${
|
|
87
|
-
${
|
|
82
|
+
${l}&disableRange=
|
|
83
|
+
${c}&disableStream=
|
|
84
|
+
${d}&disableAutoFetch=
|
|
85
|
+
${u}&verbosity=
|
|
86
|
+
${m}
|
|
87
|
+
${f ? "&locale=" + f : ""}&viewerCssTheme=
|
|
88
88
|
${w}&viewerExtraStyles=
|
|
89
|
-
${
|
|
89
|
+
${S}
|
|
90
90
|
${g ? "&nameddest=" + g : ""}`;
|
|
91
91
|
}
|
|
92
|
-
mountViewer(
|
|
93
|
-
|
|
92
|
+
mountViewer(e) {
|
|
93
|
+
e && this.iframe && (this.shadowRoot.replaceChild(this.iframe.cloneNode(), this.iframe), this.iframe = this.shadowRoot.querySelector("iframe"), this.iframe.src = e);
|
|
94
94
|
}
|
|
95
|
-
getFullPath(
|
|
96
|
-
return
|
|
95
|
+
getFullPath(e) {
|
|
96
|
+
return e.startsWith("/") ? `${window.location.origin}${e}` : e;
|
|
97
97
|
}
|
|
98
98
|
getCssThemeOption() {
|
|
99
|
-
const
|
|
100
|
-
return Object.keys(b).includes(
|
|
99
|
+
const e = this.getAttribute("viewer-css-theme");
|
|
100
|
+
return Object.keys(b).includes(e) ? b[e] : b[v];
|
|
101
101
|
}
|
|
102
|
-
setCssTheme(
|
|
103
|
-
var o, s, r;
|
|
104
|
-
if (
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
102
|
+
setCssTheme(e) {
|
|
103
|
+
var o, s, r, t, n;
|
|
104
|
+
if (e === b.DARK) {
|
|
105
|
+
if (!((o = this.iframe.contentDocument) != null && o.styleSheets.length)) return;
|
|
106
|
+
for (const i of Array.from(this.iframe.contentDocument.styleSheets)) if ((s = i.href) != null && s.includes("/web/viewer.css")) {
|
|
107
|
+
const a = (i == null ? void 0 : i.cssRules) || [], h = Object.keys(a).filter((l) => {
|
|
108
|
+
var c;
|
|
109
|
+
return ((c = a[Number(l)]) == null ? void 0 : c.conditionText) === "(prefers-color-scheme: dark)";
|
|
110
|
+
}).map((l) => a[Number(l)].cssText.split(`@media (prefers-color-scheme: dark) {
|
|
109
111
|
`)[1].split(`
|
|
110
112
|
}`)[0]);
|
|
111
|
-
|
|
112
|
-
|
|
113
|
+
this.setViewerExtraStyles(h.join(""), "theme");
|
|
114
|
+
}
|
|
115
|
+
} else (t = (r = this.iframe.contentDocument) == null ? void 0 : r.head.querySelector("style[theme]")) == null || t.remove();
|
|
116
|
+
(n = this.iframe.contentWindow) == null || n.PDFViewerApplicationOptions.set("viewerCssTheme", e);
|
|
113
117
|
}
|
|
114
118
|
}
|
|
115
119
|
window.customElements.get("pdfjs-viewer-element") || (window.PdfjsViewerElement = x, window.customElements.define("pdfjs-viewer-element", x));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pdfjs-viewer-element",
|
|
3
|
-
"version": "2.7.
|
|
3
|
+
"version": "2.7.3",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Oleksandr Shevchuk",
|
|
@@ -32,15 +32,15 @@
|
|
|
32
32
|
"types"
|
|
33
33
|
],
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@awlsn/pdfjs-full": "^4.
|
|
35
|
+
"@awlsn/pdfjs-full": "^4.3.1",
|
|
36
36
|
"@rollup/plugin-terser": "^0.4.4",
|
|
37
|
-
"@types/node": "^22.
|
|
38
|
-
"@vitest/browser": "^3.
|
|
39
|
-
"jsdom": "^26.
|
|
40
|
-
"typescript": "^5.
|
|
41
|
-
"vite": "^6.
|
|
42
|
-
"vitest": "^3.
|
|
43
|
-
"webdriverio": "^9.
|
|
37
|
+
"@types/node": "^22.18.8",
|
|
38
|
+
"@vitest/browser": "^3.2.4",
|
|
39
|
+
"jsdom": "^26.1.0",
|
|
40
|
+
"typescript": "^5.9.3",
|
|
41
|
+
"vite": "^6.3.6",
|
|
42
|
+
"vitest": "^3.2.4",
|
|
43
|
+
"webdriverio": "^9.20.0"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"perfect-debounce": "^1.0.0"
|