pdfjs-viewer-element 2.7.2 → 2.7.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 CHANGED
@@ -46,9 +46,7 @@ If you find `pdfjs-viewer-element` useful and want to support its development, c
46
46
 
47
47
  The prebuilt comes with each PDF.js release. [PDF.JS releases](https://github.com/mozilla/pdf.js/releases)
48
48
 
49
- ✅ All v4 and v3 releases are fully supported.
50
-
51
- 🚧 For v5 releases - there are some breaking changes that affects styles injecting, and theme changing not work anymore.
49
+ ✅ All v3, v4 and v5 releases are fully supported.
52
50
 
53
51
  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)).
54
52
 
@@ -78,7 +76,7 @@ import 'pdfjs-viewer-element'
78
76
  ## Usage
79
77
 
80
78
  ```html
81
- <pdfjs-viewer-element src="/file.pdf" viewer-path="/pdfjs-4.10.38-dist"></pdfjs-viewer-element>
79
+ <pdfjs-viewer-element src="/file.pdf" viewer-path="/pdfjs-5.3.93-dist"></pdfjs-viewer-element>
82
80
  ```
83
81
 
84
82
  ## Attributes
@@ -87,6 +85,8 @@ import 'pdfjs-viewer-element'
87
85
 
88
86
  `viewer-path` - Path to PDF.js [prebuilt](http://mozilla.github.io/pdf.js/getting_started/)
89
87
 
88
+ `iframe-title` - The title of the `iframe` element, required for better accessibility
89
+
90
90
  `page` - Page number.
91
91
 
92
92
  `nameddest` - Go to a named destination.
@@ -130,7 +130,7 @@ Use `viewer-css-theme` attribute to set light or dark theme manually:
130
130
  ```html
131
131
  <pdfjs-viewer-element
132
132
  src="/file.pdf"
133
- viewer-path="/pdfjs-4.10.38-dist"
133
+ viewer-path="/pdfjs-5.3.93-dist"
134
134
  viewer-css-theme="DARK">
135
135
  </pdfjs-viewer-element>
136
136
  ```
@@ -142,7 +142,7 @@ You can add your own CSS rules to the viewer application using `viewer-extra-sty
142
142
  ```html
143
143
  <pdfjs-viewer-element
144
144
  src="/file.pdf"
145
- viewer-path="/pdfjs-4.10.38-dist"
145
+ viewer-path="/pdfjs-5.3.93-dist"
146
146
  viewer-extra-styles="#toolbarViewerMiddle { display: none; }"
147
147
  viewer-extra-styles-urls="['/demo/viewer-custom-theme.css']">
148
148
  </pdfjs-viewer-element>
@@ -175,7 +175,7 @@ Build your own theme with viewer's custom variables and `viewer-extra-styles-url
175
175
  `initialize` - using this method you can access PDFViewerApplication and use methods and events of PDF.js default viewer
176
176
 
177
177
  ```html
178
- <pdfjs-viewer-element viewer-path="/pdfjs-4.10.38-dist"></pdfjs-viewer-element>
178
+ <pdfjs-viewer-element viewer-path="/pdfjs-5.3.93-dist"></pdfjs-viewer-element>
179
179
  ```
180
180
 
181
181
  ```javascript
@@ -186,6 +186,10 @@ const viewerApp = await viewer.initialize()
186
186
  viewerApp.open({ data: pdfData })
187
187
  ```
188
188
 
189
+ ## Accessablity
190
+
191
+ Use `iframe-title` to add a title to the `iframe` element and improve accessibility.
192
+
189
193
  ## Known issues
190
194
 
191
195
  ### The `.mjs` files support
@@ -1,124 +1,127 @@
1
1
  const y = (p, t) => new Promise((o) => {
2
- let s = t.querySelector(p);
3
- s ? o(s) : new MutationObserver((r, i) => {
4
- Array.from(t.querySelectorAll(p)).forEach((e) => {
5
- o(e), i.disconnect();
2
+ let e = t.querySelector(p);
3
+ e ? o(e) : new MutationObserver((s, i) => {
4
+ Array.from(t.querySelectorAll(p)).forEach((r) => {
5
+ o(r), i.disconnect();
6
6
  });
7
7
  }).observe(t, { childList: !0, subtree: !0 });
8
- }), E = { trailing: !0 }, T = "/pdfjs", D = "/web/viewer.html", A = "", C = "", P = "", k = "", R = "", V = "none", F = "", O = "", L = "", I = "", j = "", q = "", M = "", W = "", 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
- class x extends HTMLElement {
8
+ }), E = { trailing: !0 }, D = "/pdfjs", P = "/web/viewer.html", A = "", v = "PDF viewer window", C = "", k = "", F = "", V = "", R = "none", O = "", L = "", I = "", j = "", W = "", q = "", M = "", z = "", $ = "AUTOMATIC", x = "", H = "", N = "", b = { AUTOMATIC: 0, LIGHT: 1, DARK: 2 }, U = ["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
+ class T extends HTMLElement {
10
10
  constructor() {
11
- super(), this.onIframeReady = function(s, r = 25, i = {}) {
12
- if (i = { ...E, ...i }, !Number.isFinite(r)) throw new TypeError("Expected `wait` to be a finite number");
13
- let e, n, a, l, h = [];
14
- const f = (c, m) => (a = async function(d, u, w) {
15
- return await d.apply(u, w);
16
- }(s, c, m), a.finally(() => {
11
+ super(), this.onIframeReady = (function(e, s = 25, i = {}) {
12
+ if (i = { ...E, ...i }, !Number.isFinite(s)) throw new TypeError("Expected `wait` to be a finite number");
13
+ let r, n, a, l, c = [];
14
+ const m = (h, u) => (a = (async function(d, f, w) {
15
+ return await d.apply(f, w);
16
+ })(e, h, u), a.finally(() => {
17
17
  if (a = null, i.trailing && l && !n) {
18
- const d = f(c, l);
18
+ const d = m(h, l);
19
19
  return l = null, d;
20
20
  }
21
21
  }), a);
22
- return function(...c) {
23
- return a ? (i.trailing && (l = c), a) : new Promise((m) => {
22
+ return function(...h) {
23
+ return a ? (i.trailing && (l = h), a) : new Promise((u) => {
24
24
  const d = !n && i.leading;
25
25
  clearTimeout(n), n = setTimeout(() => {
26
26
  n = null;
27
- const u = i.leading ? e : f(this, c);
28
- for (const w of h) w(u);
29
- h = [];
30
- }, r), d ? (e = f(this, c), m(e)) : h.push(m);
27
+ const f = i.leading ? r : m(this, h);
28
+ for (const w of c) w(f);
29
+ c = [];
30
+ }, s), d ? (r = m(this, h), u(r)) : c.push(u);
31
31
  });
32
32
  };
33
- }(async (s) => {
34
- await y("iframe", this.shadowRoot), s();
35
- }, 0, { leading: !0 }), this.setViewerExtraStyles = (s, r = "extra") => {
36
- var e, n, a, l, h;
37
- if (!s) return void ((n = (e = this.iframe.contentDocument) == null ? void 0 : e.head.querySelector(`style[${r}]`)) == null ? void 0 : n.remove());
38
- if (((l = (a = this.iframe.contentDocument) == null ? void 0 : a.head.querySelector(`style[${r}]`)) == null ? void 0 : l.innerHTML) === s) return;
33
+ })(async (e) => {
34
+ await y("iframe", this.shadowRoot), e();
35
+ }, 0, { leading: !0 }), this.setViewerExtraStyles = (e, s = "extra") => {
36
+ var r, n, a, l, c;
37
+ if (!e) return void ((n = (r = this.iframe.contentDocument) == null ? void 0 : r.head.querySelector(`style[${s}]`)) == null ? void 0 : n.remove());
38
+ if (((l = (a = this.iframe.contentDocument) == null ? void 0 : a.head.querySelector(`style[${s}]`)) == null ? void 0 : l.innerHTML) === e) return;
39
39
  const i = document.createElement("style");
40
- i.innerHTML = s, i.setAttribute(r, ""), (h = this.iframe.contentDocument) == null || h.head.appendChild(i);
41
- }, this.injectExtraStylesLinks = (s) => {
42
- s && s.replace(/'|]|\[/g, "").split(",").map((r) => r.trim()).forEach((r) => {
40
+ i.innerHTML = e, i.setAttribute(s, ""), (c = this.iframe.contentDocument) == null || c.head.appendChild(i);
41
+ }, this.injectExtraStylesLinks = (e) => {
42
+ e && e.replace(/'|]|\[/g, "").split(",").map((s) => s.trim()).forEach((s) => {
43
43
  var n, a;
44
- if ((n = this.iframe.contentDocument) == null ? void 0 : n.head.querySelector(`link[href="${r}"]`)) return;
45
- const e = document.createElement("link");
46
- e.rel = "stylesheet", e.href = r, (a = this.iframe.contentDocument) == null || a.head.appendChild(e);
44
+ if ((n = this.iframe.contentDocument) == null ? void 0 : n.head.querySelector(`link[href="${s}"]`)) return;
45
+ const r = document.createElement("link");
46
+ r.rel = "stylesheet", r.href = s, (a = this.iframe.contentDocument) == null || a.head.appendChild(r);
47
47
  });
48
- }, this.initialize = () => new Promise(async (s) => {
49
- var r;
50
- await y("iframe", this.shadowRoot), (r = this.iframe) == null || r.addEventListener("load", async () => {
51
- var i, e, n;
52
- await ((e = (i = this.iframe.contentWindow) == null ? void 0 : i.PDFViewerApplication) == null ? void 0 : e.initializedPromise), s((n = this.iframe.contentWindow) == null ? void 0 : n.PDFViewerApplication);
48
+ }, this.initialize = () => new Promise(async (e) => {
49
+ var s;
50
+ await y("iframe", this.shadowRoot), (s = this.iframe) == null || s.addEventListener("load", async () => {
51
+ var i, r, n;
52
+ await ((r = (i = this.iframe.contentWindow) == null ? void 0 : i.PDFViewerApplication) == null ? void 0 : r.initializedPromise), e((n = this.iframe.contentWindow) == null ? void 0 : n.PDFViewerApplication);
53
53
  }, { once: !0 });
54
54
  });
55
55
  const t = 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
- <iframe frameborder="0" width="100%" loading="lazy"></iframe>
58
+ <iframe frameborder="0" width="100%" loading="lazy" title="${this.getAttribute("iframe-title") || v}"></iframe>
59
59
  `, t.appendChild(o.content.cloneNode(!0));
60
60
  }
61
61
  static get observedAttributes() {
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"];
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", "iframe-title"];
63
63
  }
64
64
  connectedCallback() {
65
- this.iframe = this.shadowRoot.querySelector("iframe"), document.addEventListener("webviewerloaded", async () => {
66
- var t, o, s, r, i, e, n, 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 = (t = this.iframe.contentWindow) == null ? void 0 : t.PDFViewerApplicationOptions) == null || o.set("defaultUrl", "")), (r = (s = this.iframe.contentWindow) == null ? void 0 : s.PDFViewerApplicationOptions) == null || r.set("disablePreferences", !0), (e = (i = this.iframe.contentWindow) == null ? void 0 : i.PDFViewerApplicationOptions) == null || e.set("pdfBugEnabled", !0), (a = (n = this.iframe.contentWindow) == null ? void 0 : n.PDFViewerApplicationOptions) == null || a.set("eventBusDispatchToDOM", !0);
65
+ var t;
66
+ this.iframe = (t = this.shadowRoot) == null ? void 0 : t.querySelector("iframe"), document.addEventListener("webviewerloaded", async () => {
67
+ var o, e, s, i, r, n, a, l;
68
+ this.setCssTheme(this.getCssThemeOption()), this.injectExtraStylesLinks(this.getAttribute("viewer-extra-styles-urls") ?? H), this.setViewerExtraStyles(this.getAttribute("viewer-extra-styles") ?? x), this.getAttribute("src") !== A && ((e = (o = this.iframe.contentWindow) == null ? void 0 : o.PDFViewerApplicationOptions) == null || e.set("defaultUrl", "")), (i = (s = this.iframe.contentWindow) == null ? void 0 : s.PDFViewerApplicationOptions) == null || i.set("disablePreferences", !0), (n = (r = this.iframe.contentWindow) == null ? void 0 : r.PDFViewerApplicationOptions) == null || n.set("pdfBugEnabled", !0), (l = (a = this.iframe.contentWindow) == null ? void 0 : a.PDFViewerApplicationOptions) == null || l.set("eventBusDispatchToDOM", !0);
68
69
  });
69
70
  }
70
71
  attributeChangedCallback(t) {
71
- N.includes(t) ? this.onIframeReady(() => this.mountViewer(this.getIframeSrc())) : this.onIframeReady(() => {
72
+ U.includes(t) ? this.onIframeReady(() => this.mountViewer(this.getIframeSrc())) : this.onIframeReady(() => {
72
73
  this.iframe.src = this.getIframeSrc();
73
74
  });
74
75
  }
75
76
  getIframeSrc() {
76
- const t = this.getFullPath(this.getAttribute("src") || A), o = this.getFullPath(this.getAttribute("viewer-path") || T), s = this.getAttribute("page") || C, r = this.getAttribute("search") || P, i = this.getAttribute("phrase") || k, e = this.getAttribute("zoom") || R, n = this.getAttribute("pagemode") || V, a = this.getAttribute("disable-worker") || O, l = this.getAttribute("text-layer") || L, h = this.getAttribute("disable-font-face") || I, f = this.getAttribute("disable-range") || j, c = this.getAttribute("disable-stream") || q, m = this.getAttribute("disable-auto-fetch") || M, d = this.getAttribute("verbosity") || W, u = this.getAttribute("locale") || F, w = this.getAttribute("viewer-css-theme") || v, S = !!(this.getAttribute("viewer-extra-styles") || $), g = this.getAttribute("nameddest") || H;
77
+ const t = this.getFullPath(this.getAttribute("src") || A), o = this.getFullPath(this.getAttribute("viewer-path") || D), e = this.getAttribute("page") || C, s = this.getAttribute("search") || k, i = this.getAttribute("phrase") || F, r = this.getAttribute("zoom") || V, n = this.getAttribute("pagemode") || R, a = this.getAttribute("disable-worker") || L, l = this.getAttribute("text-layer") || I, c = this.getAttribute("disable-font-face") || j, m = this.getAttribute("disable-range") || W, h = this.getAttribute("disable-stream") || q, u = this.getAttribute("disable-auto-fetch") || M, d = this.getAttribute("verbosity") || z, f = this.getAttribute("locale") || O, w = this.getAttribute("viewer-css-theme") || $, S = !!(this.getAttribute("viewer-extra-styles") || x), g = this.getAttribute("nameddest") || N;
77
78
  return `
78
- ${o}${D}?file=
79
- ${encodeURIComponent(t)}#page=${s}&zoom=${e}&pagemode=${n}&search=${r}&phrase=${i}&textLayer=
79
+ ${o}${P}?file=
80
+ ${encodeURIComponent(t)}#page=${e}&zoom=${r}&pagemode=${n}&search=${s}&phrase=${i}&textLayer=
80
81
  ${l}&disableWorker=
81
82
  ${a}&disableFontFace=
82
- ${h}&disableRange=
83
- ${f}&disableStream=
84
- ${c}&disableAutoFetch=
85
- ${m}&verbosity=
83
+ ${c}&disableRange=
84
+ ${m}&disableStream=
85
+ ${h}&disableAutoFetch=
86
+ ${u}&verbosity=
86
87
  ${d}
87
- ${u ? "&locale=" + u : ""}&viewerCssTheme=
88
+ ${f ? "&locale=" + f : ""}&viewerCssTheme=
88
89
  ${w}&viewerExtraStyles=
89
90
  ${S}
90
91
  ${g ? "&nameddest=" + g : ""}`;
91
92
  }
92
93
  mountViewer(t) {
93
- t && this.iframe && (this.shadowRoot.replaceChild(this.iframe.cloneNode(), this.iframe), this.iframe = this.shadowRoot.querySelector("iframe"), this.iframe.src = t);
94
+ var o, e;
95
+ t && this.iframe && ((o = this.shadowRoot) == null || o.replaceChild(this.iframe.cloneNode(), this.iframe), this.iframe = (e = this.shadowRoot) == null ? void 0 : e.querySelector("iframe"), this.iframe.src = t, this.iframe.setAttribute("title", this.getAttribute("iframe-title") || v));
94
96
  }
95
97
  getFullPath(t) {
96
98
  return t.startsWith("/") ? `${window.location.origin}${t}` : t;
97
99
  }
98
100
  getCssThemeOption() {
99
101
  const t = this.getAttribute("viewer-css-theme");
100
- return Object.keys(b).includes(t) ? b[t] : b[v];
102
+ return Object.keys(b).includes(t) ? b[t] : b[$];
101
103
  }
102
104
  setCssTheme(t) {
103
- var o, s, r, i;
105
+ var o, e, s, i, r, n;
104
106
  if (t === b.DARK) {
105
107
  if (!((o = this.iframe.contentDocument) != null && o.styleSheets.length)) return;
106
- for (const e of Array.from(this.iframe.contentDocument.styleSheets)) if ((s = e.href) != null && s.includes("/web/viewer.css")) {
107
- const n = (e == null ? void 0 : e.cssRules) || [], a = Object.keys(n).filter((l) => {
108
+ for (const a of Array.from(this.iframe.contentDocument.styleSheets)) if ((e = a.href) != null && e.includes("/web/viewer.css")) {
109
+ const l = (a == null ? void 0 : a.cssRules) || [], c = Object.keys(l).filter((m) => {
108
110
  var h;
109
- return ((h = n[Number(l)]) == null ? void 0 : h.conditionText) === "(prefers-color-scheme: dark)";
110
- }).map((l) => n[Number(l)].cssText.split(`@media (prefers-color-scheme: dark) {
111
+ return ((h = l[Number(m)]) == null ? void 0 : h.conditionText) === "(prefers-color-scheme: dark)";
112
+ }).map((m) => l[Number(m)].cssText.split(`@media (prefers-color-scheme: dark) {
111
113
  `)[1].split(`
112
114
  }`)[0]);
113
- this.setViewerExtraStyles(a.join(""), "theme");
115
+ this.setViewerExtraStyles(c.join(""), "theme");
114
116
  }
115
- } else (i = (r = this.iframe.contentDocument) == null ? void 0 : r.head.querySelector("style[theme]")) == null || i.remove();
117
+ } else (i = (s = this.iframe.contentDocument) == null ? void 0 : s.head.querySelector("style[theme]")) == null || i.remove();
118
+ (n = (r = this.iframe.contentWindow) == null ? void 0 : r.PDFViewerApplicationOptions) == null || n.set("viewerCssTheme", t);
116
119
  }
117
120
  }
118
- window.customElements.get("pdfjs-viewer-element") || (window.PdfjsViewerElement = x, window.customElements.define("pdfjs-viewer-element", x));
121
+ window.customElements.get("pdfjs-viewer-element") || (window.PdfjsViewerElement = T, window.customElements.define("pdfjs-viewer-element", T));
119
122
  export {
120
- x as PdfjsViewerElement,
123
+ T as PdfjsViewerElement,
121
124
  b as ViewerCssTheme,
122
- x as default,
123
- N as hardRefreshAttributes
125
+ T as default,
126
+ U as hardRefreshAttributes
124
127
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pdfjs-viewer-element",
3
- "version": "2.7.2",
3
+ "version": "2.7.4",
4
4
  "license": "MIT",
5
5
  "author": {
6
6
  "name": "Oleksandr Shevchuk",
@@ -34,13 +34,13 @@
34
34
  "devDependencies": {
35
35
  "@awlsn/pdfjs-full": "^4.3.1",
36
36
  "@rollup/plugin-terser": "^0.4.4",
37
- "@types/node": "^22.16.5",
37
+ "@types/node": "^22.18.8",
38
38
  "@vitest/browser": "^3.2.4",
39
39
  "jsdom": "^26.1.0",
40
- "typescript": "^5.8.3",
41
- "vite": "^6.3.5",
40
+ "typescript": "^5.9.3",
41
+ "vite": "^6.3.6",
42
42
  "vitest": "^3.2.4",
43
- "webdriverio": "^9.18.1"
43
+ "webdriverio": "^9.20.0"
44
44
  },
45
45
  "dependencies": {
46
46
  "perfect-debounce": "^1.0.0"