pdfjs-viewer-element 2.6.1 → 2.6.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 +34 -5
- package/dist/pdfjs-viewer-element.js +72 -60
- package/package.json +1 -1
- package/types/pdfjs-viewer-element.d.ts +1 -5
package/README.md
CHANGED
|
@@ -7,7 +7,8 @@ The simplest integration of [PDF.js default viewer](https://mozilla.github.io/pd
|
|
|
7
7
|
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.
|
|
8
8
|
Supported in all [major browsers](https://caniuse.com/custom-elementsv1), and works with most [JS frameworks](https://custom-elements-everywhere.com/).
|
|
9
9
|
|
|
10
|
-
See [
|
|
10
|
+
See [demo pages](https://github.com/alekswebnet/pdfjs-viewer-element/tree/master/demo) for various usecases.
|
|
11
|
+
See [live examples](https://alekswebnet.github.io/pdfjs-viewer-element/#demo) of usage with frameworks.
|
|
11
12
|
|
|
12
13
|
⚠️ `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.
|
|
13
14
|
|
|
@@ -34,10 +35,12 @@ Then specify the path to the directory with the `viewer-path` property (`/pdfjs`
|
|
|
34
35
|
|
|
35
36
|
[Getting started](https://alekswebnet.github.io/pdfjs-viewer-element/)
|
|
36
37
|
|
|
37
|
-
[API](https://alekswebnet.github.io/pdfjs-viewer-element/#api)
|
|
38
|
+
[API playground](https://alekswebnet.github.io/pdfjs-viewer-element/#api)
|
|
38
39
|
|
|
39
40
|
[Live examples](https://alekswebnet.github.io/pdfjs-viewer-element/#demo)
|
|
40
41
|
|
|
42
|
+
[Demo pages](https://github.com/alekswebnet/pdfjs-viewer-element/tree/master/demo)
|
|
43
|
+
|
|
41
44
|
## Install
|
|
42
45
|
|
|
43
46
|
Using module bundlers:
|
|
@@ -79,6 +82,8 @@ Using browser:
|
|
|
79
82
|
|
|
80
83
|
`page` - Page number
|
|
81
84
|
|
|
85
|
+
`nameddest` - Go to a named destination
|
|
86
|
+
|
|
82
87
|
`search` - Search text
|
|
83
88
|
|
|
84
89
|
`phrase` - Search by phrase
|
|
@@ -91,6 +96,8 @@ Using browser:
|
|
|
91
96
|
|
|
92
97
|
`viewer-extra-styles` - Add your CSS rules to the viewer application
|
|
93
98
|
|
|
99
|
+
`viewer-extra-styles-urls` - Add external CSS files to the viewer application
|
|
100
|
+
|
|
94
101
|
Play with attributes on [Api docs page](https://alekswebnet.github.io/pdfjs-viewer-element/#api).
|
|
95
102
|
|
|
96
103
|
## Viewer CSS theme
|
|
@@ -107,16 +114,38 @@ Use `viewer-css-theme` attribute to set light or dark theme manually:
|
|
|
107
114
|
|
|
108
115
|
## Viewer extra styles
|
|
109
116
|
|
|
110
|
-
You can add your own CSS rules to the viewer application using `viewer-extra-styles` attribute:
|
|
117
|
+
You can add your own CSS rules to the viewer application using `viewer-extra-styles` or `viewer-extra-styles-urls` attribute:
|
|
111
118
|
|
|
112
119
|
```html
|
|
113
|
-
<!-- Remove download button from viewer toolbar -->
|
|
114
120
|
<pdfjs-viewer-element
|
|
115
121
|
src="/file.pdf"
|
|
116
122
|
viewer-path="/pdfjs-4.0.379-dist"
|
|
117
|
-
viewer-extra-styles="#
|
|
123
|
+
viewer-extra-styles="#toolbarViewerMiddle { display: none; }"
|
|
124
|
+
viewer-extra-styles-urls="['/demo/viewer-custom-theme.css']">
|
|
118
125
|
</pdfjs-viewer-element>
|
|
119
126
|
```
|
|
127
|
+
Build your own theme with viewer's custom variables and `viewer-extra-styles-urls` attribute:
|
|
128
|
+
|
|
129
|
+
```css
|
|
130
|
+
:root {
|
|
131
|
+
--main-color: #5755FE;
|
|
132
|
+
--toolbar-icon-bg-color: #0200a8;
|
|
133
|
+
--field-color: #5755FE;
|
|
134
|
+
--separator-color: #5755FE;
|
|
135
|
+
--toolbar-border-color: #5755FE;
|
|
136
|
+
--field-border-color: #5755FE;
|
|
137
|
+
--toolbar-bg-color: rgba(139, 147, 255, .1);
|
|
138
|
+
--body-bg-color: rgba(255, 247, 252, .7);
|
|
139
|
+
--button-hover-color: rgba(139, 147, 255, .1);
|
|
140
|
+
--toolbar-icon-hover-bg-color: #0200a8;
|
|
141
|
+
--toggled-btn-color: #0200a8;
|
|
142
|
+
--toggled-btn-bg-color: rgba(139, 147, 255, .1);
|
|
143
|
+
--toggled-hover-active-btn-color: #5755FE;
|
|
144
|
+
--doorhanger-hover-bg-color: rgba(139, 147, 255, .1);
|
|
145
|
+
--doorhanger-hover-color: #0200a8;
|
|
146
|
+
--dropdown-btn-bg-color: rgba(139, 147, 255, .1);
|
|
147
|
+
}
|
|
148
|
+
```
|
|
120
149
|
|
|
121
150
|
## PDF.js Viewer Application
|
|
122
151
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
const
|
|
2
|
-
let
|
|
3
|
-
if (
|
|
4
|
-
r
|
|
1
|
+
const f = (m, e) => new Promise((s) => {
|
|
2
|
+
let r = e.querySelector(m);
|
|
3
|
+
if (r) {
|
|
4
|
+
s(r);
|
|
5
5
|
return;
|
|
6
6
|
}
|
|
7
|
-
new MutationObserver((
|
|
8
|
-
Array.from(e.querySelectorAll(m)).forEach((
|
|
9
|
-
|
|
7
|
+
new MutationObserver((n, t) => {
|
|
8
|
+
Array.from(e.querySelectorAll(m)).forEach((i) => {
|
|
9
|
+
s(i), t.disconnect();
|
|
10
10
|
});
|
|
11
11
|
}).observe(e, {
|
|
12
12
|
childList: !0,
|
|
@@ -15,31 +15,31 @@ const w = (m, e) => new Promise((r) => {
|
|
|
15
15
|
}), g = {
|
|
16
16
|
trailing: !0
|
|
17
17
|
};
|
|
18
|
-
function
|
|
19
|
-
if (
|
|
18
|
+
function v(m, e = 25, s = {}) {
|
|
19
|
+
if (s = { ...g, ...s }, !Number.isFinite(e))
|
|
20
20
|
throw new TypeError("Expected `wait` to be a finite number");
|
|
21
|
-
let
|
|
22
|
-
const
|
|
23
|
-
if (
|
|
24
|
-
const u =
|
|
25
|
-
return
|
|
21
|
+
let r, n, t = [], i, a;
|
|
22
|
+
const o = (l, h) => (i = b(m, l, h), i.finally(() => {
|
|
23
|
+
if (i = null, s.trailing && a && !n) {
|
|
24
|
+
const u = o(l, a);
|
|
25
|
+
return a = null, u;
|
|
26
26
|
}
|
|
27
|
-
}),
|
|
27
|
+
}), i);
|
|
28
28
|
return function(...l) {
|
|
29
|
-
return
|
|
30
|
-
const u = !
|
|
31
|
-
clearTimeout(
|
|
32
|
-
|
|
33
|
-
const
|
|
34
|
-
for (const y of
|
|
35
|
-
y(
|
|
36
|
-
|
|
37
|
-
}, e), u ? (
|
|
29
|
+
return i ? (s.trailing && (a = l), i) : new Promise((h) => {
|
|
30
|
+
const u = !n && s.leading;
|
|
31
|
+
clearTimeout(n), n = setTimeout(() => {
|
|
32
|
+
n = null;
|
|
33
|
+
const w = s.leading ? r : o(this, l);
|
|
34
|
+
for (const y of t)
|
|
35
|
+
y(w);
|
|
36
|
+
t = [];
|
|
37
|
+
}, e), u ? (r = o(this, l), h(r)) : t.push(h);
|
|
38
38
|
});
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
|
-
async function
|
|
42
|
-
return await m.apply(e,
|
|
41
|
+
async function b(m, e, s) {
|
|
42
|
+
return await m.apply(e, s);
|
|
43
43
|
}
|
|
44
44
|
const c = {
|
|
45
45
|
viewerPath: "/pdfjs",
|
|
@@ -53,47 +53,59 @@ const c = {
|
|
|
53
53
|
locale: "",
|
|
54
54
|
textLayer: "",
|
|
55
55
|
viewerCssTheme: "AUTOMATIC",
|
|
56
|
-
viewerExtraStyles: ""
|
|
56
|
+
viewerExtraStyles: "",
|
|
57
|
+
viewerExtraStylesUrls: "",
|
|
58
|
+
nameddest: ""
|
|
57
59
|
}, d = {
|
|
58
60
|
AUTOMATIC: 0,
|
|
59
61
|
// Default value.
|
|
60
62
|
LIGHT: 1,
|
|
61
63
|
DARK: 2
|
|
62
|
-
}, A = ["src", "viewer-path", "locale", "text-layer", "viewer-css-theme", "viewer-extra-styles"];
|
|
63
|
-
class
|
|
64
|
+
}, A = ["src", "viewer-path", "locale", "text-layer", "viewer-css-theme", "viewer-extra-styles", "viewer-extra-styles-urls"];
|
|
65
|
+
class p extends HTMLElement {
|
|
64
66
|
constructor() {
|
|
65
|
-
super(), this.onIframeReady =
|
|
66
|
-
await
|
|
67
|
-
}, 0, { leading: !0 }), this.setViewerExtraStyles = (
|
|
68
|
-
var
|
|
69
|
-
if (!
|
|
70
|
-
(
|
|
67
|
+
super(), this.onIframeReady = v(async (r) => {
|
|
68
|
+
await f("iframe", this.shadowRoot), r();
|
|
69
|
+
}, 0, { leading: !0 }), this.setViewerExtraStyles = (r, n = "extra") => {
|
|
70
|
+
var i, a, o, l, h;
|
|
71
|
+
if (!r) {
|
|
72
|
+
(a = (i = this.iframe.contentDocument) == null ? void 0 : i.head.querySelector(`style[${n}]`)) == null || a.remove();
|
|
71
73
|
return;
|
|
72
74
|
}
|
|
73
|
-
if (((l = (
|
|
75
|
+
if (((l = (o = this.iframe.contentDocument) == null ? void 0 : o.head.querySelector(`style[${n}]`)) == null ? void 0 : l.innerHTML) === r)
|
|
74
76
|
return;
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
}, this.
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
77
|
+
const t = document.createElement("style");
|
|
78
|
+
t.innerHTML = r, t.setAttribute(n, ""), (h = this.iframe.contentDocument) == null || h.head.appendChild(t);
|
|
79
|
+
}, this.injectExtraStylesLinks = (r) => {
|
|
80
|
+
if (!r)
|
|
81
|
+
return;
|
|
82
|
+
r.replace(/'|]|\[/g, "").split(",").map((t) => t.trim()).forEach((t) => {
|
|
83
|
+
var o, l;
|
|
84
|
+
if ((o = this.iframe.contentDocument) == null ? void 0 : o.head.querySelector(`link[href="${t}"]`))
|
|
85
|
+
return;
|
|
86
|
+
const a = document.createElement("link");
|
|
87
|
+
a.rel = "stylesheet", a.href = t, (l = this.iframe.contentDocument) == null || l.head.appendChild(a);
|
|
88
|
+
});
|
|
89
|
+
}, this.initialize = () => new Promise(async (r) => {
|
|
90
|
+
var n;
|
|
91
|
+
await f("iframe", this.shadowRoot), (n = this.iframe) == null || n.addEventListener("load", async () => {
|
|
92
|
+
var t, i, a;
|
|
93
|
+
await ((i = (t = this.iframe.contentWindow) == null ? void 0 : t.PDFViewerApplication) == null ? void 0 : i.initializedPromise), r((a = this.iframe.contentWindow) == null ? void 0 : a.PDFViewerApplication);
|
|
82
94
|
}, { once: !0 });
|
|
83
95
|
});
|
|
84
|
-
const e = this.attachShadow({ mode: "open" }),
|
|
85
|
-
|
|
96
|
+
const e = this.attachShadow({ mode: "open" }), s = document.createElement("template");
|
|
97
|
+
s.innerHTML = `
|
|
86
98
|
<style>:host{width:100%;display:block;overflow:hidden}:host iframe{height:100%}</style>
|
|
87
99
|
<iframe frameborder="0" width="100%" loading="lazy"></iframe>
|
|
88
|
-
`, e.appendChild(
|
|
100
|
+
`, e.appendChild(s.content.cloneNode(!0));
|
|
89
101
|
}
|
|
90
102
|
static get observedAttributes() {
|
|
91
|
-
return ["src", "viewer-path", "locale", "page", "search", "phrase", "zoom", "pagemode", "text-layer", "viewer-css-theme", "viewer-extra-styles"];
|
|
103
|
+
return ["src", "viewer-path", "locale", "page", "search", "phrase", "zoom", "pagemode", "text-layer", "viewer-css-theme", "viewer-extra-styles", "viewer-extra-styles-urls", "nameddest"];
|
|
92
104
|
}
|
|
93
105
|
connectedCallback() {
|
|
94
106
|
this.iframe = this.shadowRoot.querySelector("iframe"), document.addEventListener("webviewerloaded", async () => {
|
|
95
|
-
var e,
|
|
96
|
-
this.setCssTheme(this.getCssThemeOption()), this.setViewerExtraStyles(this.getAttribute("viewer-extra-styles")), this.getAttribute("src") !== c.src && ((
|
|
107
|
+
var e, s, r, n, t, i, a, o;
|
|
108
|
+
this.setCssTheme(this.getCssThemeOption()), this.injectExtraStylesLinks(this.getAttribute("viewer-extra-styles-urls") ?? c.viewerExtraStylesUrls), this.setViewerExtraStyles(this.getAttribute("viewer-extra-styles") ?? c.viewerExtraStyles), this.getAttribute("src") !== c.src && ((s = (e = this.iframe.contentWindow) == null ? void 0 : e.PDFViewerApplicationOptions) == null || s.set("defaultUrl", "")), (n = (r = this.iframe.contentWindow) == null ? void 0 : r.PDFViewerApplicationOptions) == null || n.set("disablePreferences", !0), (i = (t = this.iframe.contentWindow) == null ? void 0 : t.PDFViewerApplicationOptions) == null || i.set("pdfBugEnabled", !0), (o = (a = this.iframe.contentWindow) == null ? void 0 : a.PDFViewerApplicationOptions) == null || o.set("eventBusDispatchToDOM", !0);
|
|
97
109
|
});
|
|
98
110
|
}
|
|
99
111
|
attributeChangedCallback(e) {
|
|
@@ -106,8 +118,8 @@ class f extends HTMLElement {
|
|
|
106
118
|
this.onIframeReady(() => this.mountViewer(this.getIframeSrc()));
|
|
107
119
|
}
|
|
108
120
|
getIframeSrc() {
|
|
109
|
-
const e = this.getFullPath(this.getAttribute("src") || c.src),
|
|
110
|
-
return `${
|
|
121
|
+
const e = this.getFullPath(this.getAttribute("src") || c.src), s = this.getFullPath(this.getAttribute("viewer-path") || c.viewerPath), r = this.getAttribute("page") || c.page, n = this.getAttribute("search") || c.search, t = this.getAttribute("phrase") || c.phrase, i = this.getAttribute("zoom") || c.zoom, a = this.getAttribute("pagemode") || c.pagemode, o = this.getAttribute("locale") || c.locale, l = this.getAttribute("text-layer") || c.textLayer, h = this.getAttribute("viewer-css-theme") || c.viewerCssTheme, u = !!(this.getAttribute("viewer-extra-styles") || c.viewerExtraStyles), w = this.getAttribute("nameddest") || c.nameddest;
|
|
122
|
+
return `${s}${c.viewerEntry}?file=${encodeURIComponent(e)}#page=${r}&zoom=${i}&pagemode=${a}&search=${n}&phrase=${t}&textLayer=${l}${o ? "&locale=" + o : ""}&viewerCssTheme=${h}&viewerExtraStyles=${u}&nameddest=${w}`;
|
|
111
123
|
}
|
|
112
124
|
mountViewer(e) {
|
|
113
125
|
!e || !this.iframe || (this.shadowRoot.replaceChild(this.iframe.cloneNode(), this.iframe), this.iframe = this.shadowRoot.querySelector("iframe"), this.iframe.src = e);
|
|
@@ -120,23 +132,23 @@ class f extends HTMLElement {
|
|
|
120
132
|
return Object.keys(d).includes(e) ? d[e] : d[c.viewerCssTheme];
|
|
121
133
|
}
|
|
122
134
|
setCssTheme(e) {
|
|
123
|
-
var
|
|
135
|
+
var s, r, n;
|
|
124
136
|
if (e === d.DARK) {
|
|
125
|
-
const
|
|
137
|
+
const t = (s = this.iframe.contentDocument) == null ? void 0 : s.styleSheets[0], i = (t == null ? void 0 : t.cssRules) || [], a = Object.keys(i).filter((o) => {
|
|
126
138
|
var l;
|
|
127
|
-
return ((l =
|
|
128
|
-
}).map((
|
|
139
|
+
return ((l = i[Number(o)]) == null ? void 0 : l.conditionText) === "(prefers-color-scheme: dark)";
|
|
140
|
+
}).map((o) => i[Number(o)].cssText.split(`@media (prefers-color-scheme: dark) {
|
|
129
141
|
`)[1].split(`
|
|
130
142
|
}`)[0]);
|
|
131
|
-
this.setViewerExtraStyles(
|
|
143
|
+
this.setViewerExtraStyles(a.join(""), "theme");
|
|
132
144
|
} else
|
|
133
|
-
(
|
|
145
|
+
(n = (r = this.iframe.contentDocument) == null ? void 0 : r.head.querySelector("style[theme]")) == null || n.remove();
|
|
134
146
|
}
|
|
135
147
|
}
|
|
136
|
-
window.customElements.get("pdfjs-viewer-element") || (window.PdfjsViewerElement =
|
|
148
|
+
window.customElements.get("pdfjs-viewer-element") || (window.PdfjsViewerElement = p, window.customElements.define("pdfjs-viewer-element", p));
|
|
137
149
|
export {
|
|
138
|
-
|
|
150
|
+
p as PdfjsViewerElement,
|
|
139
151
|
d as ViewerCssTheme,
|
|
140
|
-
|
|
152
|
+
p as default,
|
|
141
153
|
A as hardRefreshAttributes
|
|
142
154
|
};
|
package/package.json
CHANGED
|
@@ -17,6 +17,7 @@ export declare class PdfjsViewerElement extends HTMLElement {
|
|
|
17
17
|
private getCssThemeOption;
|
|
18
18
|
private setCssTheme;
|
|
19
19
|
private setViewerExtraStyles;
|
|
20
|
+
private injectExtraStylesLinks;
|
|
20
21
|
initialize: () => Promise<PdfjsViewerElementIframeWindow['PDFViewerApplication']>;
|
|
21
22
|
}
|
|
22
23
|
declare global {
|
|
@@ -42,9 +43,4 @@ export interface PdfjsViewerElementIframeWindow extends Window {
|
|
|
42
43
|
export interface PdfjsViewerElementIframe extends HTMLIFrameElement {
|
|
43
44
|
contentWindow: PdfjsViewerElementIframeWindow;
|
|
44
45
|
}
|
|
45
|
-
export interface PdfjsViewerLoadedEvent extends Event {
|
|
46
|
-
detail: {
|
|
47
|
-
source: PdfjsViewerElementIframeWindow;
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
46
|
export default PdfjsViewerElement;
|