Skip to content

Commit 47fde67

Browse files
authored
Merge pull request #42 from alekswebnet/3.1.0
Release new 3.1.0 version
2 parents 43fc056 + 8d0c351 commit 47fde67

File tree

337 files changed

+1401
-161253
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

337 files changed

+1401
-161253
lines changed

README.md

Lines changed: 81 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -14,28 +14,23 @@ Supported in all [major browsers](https://caniuse.com/custom-elementsv1), and wo
1414

1515
## Features
1616

17-
✅ Standalone web component with no runtime dependencies
18-
19-
✅ Drop-in, iframe-based PDF.js default viewer for any web app
20-
21-
✅ Works with same-origin and cross-origin PDF documents
22-
23-
✅ Configure via attributes and URL parameters (page, zoom, search, pagemode, locale)
24-
25-
✅ Programmatic access to `PDFViewerApplication` and `PDFViewerApplicationOptions` via the `initialized` event
26-
27-
✅ Theme control (automatic/light/dark) plus custom CSS injection or external stylesheets
28-
29-
✅ Locale override support using PDF.js viewer locales
30-
31-
✅ Supports all modern browsers and most JS frameworks
17+
- Standalone web component with no runtime dependencies
18+
- Drop-in, iframe-based PDF.js default viewer for any web app
19+
- Works with same-origin and cross-origin PDF documents
20+
- Configure via attributes and URL parameters (page, zoom, search, pagemode, locale)
21+
- Programmatic access to `PDFViewerApplication` and `PDFViewerApplicationOptions` via the `initialized` event
22+
- Theme control (automatic/light/dark) plus custom CSS injection
23+
- Locale override support using PDF.js viewer locales
24+
- Supports all modern browsers and most JS frameworks
3225

3326
## Docs
3427

3528
[Getting started](https://alekswebnet.github.io/pdfjs-viewer-element/)
3629

3730
[API playground](https://alekswebnet.github.io/pdfjs-viewer-element/#api)
3831

32+
[CodePen demo](https://codepen.io/redrobot753/pen/bNwVVvp)
33+
3934
[Various use cases](https://github.com/alekswebnet/pdfjs-viewer-element/tree/master/demo)
4035

4136
## Install
@@ -62,34 +57,40 @@ import 'pdfjs-viewer-element'
6257
## Usage
6358

6459
```html
65-
<pdfjs-viewer-element src="path-to/file.pdf"></pdfjs-viewer-element>
60+
<pdfjs-viewer-element
61+
src="/sample.pdf"
62+
style="height: 100dvh">
63+
</pdfjs-viewer-element>
6664
```
6765

68-
## Attributes
69-
70-
`src` - PDF file URL
71-
72-
`iframe-title` - The title of the `iframe` element, required for better accessibility
73-
74-
`page` - Page number.
75-
76-
`search` - Search text.
77-
78-
`phrase` - Search by phrase, `true` to enable.
66+
The element is block-level and needs an explicit height.
7967

80-
`zoom` - Zoom level.
68+
## Attributes
8169

82-
`pagemode` - Page mode, `thumbs | bookmarks | attachments | layers | none`.
70+
| Attribute | Description | Default |
71+
| --- | --- | --- |
72+
| `src` | PDF file URL. | `''` |
73+
| `iframe-title` | Title for the internal `iframe` (recommended for accessibility). | `PDF viewer window` |
74+
| `page` | Page number. | `''` |
75+
| `search` | Search query text. | `''` |
76+
| `phrase` | Phrase search mode, set to `true` to enable phrase matching. | `''` |
77+
| `zoom` | Zoom level (for example `auto`, `page-width`, `200%`). | `''` |
78+
| `pagemode` | Sidebar mode: `thumbs`, `bookmarks`, `attachments`, `layers`, `none`. | `none` |
79+
| `locale` | Viewer UI locale (for example `en-US`, `de`, `uk`). [Available locales](https://github.com/mozilla/pdf.js/tree/master/l10n) | `''` |
80+
| `viewer-css-theme` | Viewer theme: `AUTOMATIC`, `LIGHT`, `DARK`. | `AUTOMATIC` |
81+
| `worker-src` | PDF.js worker URL override. | `https://cdn.jsdelivr.net/npm/pdfjs-dist@5.4.624/build/pdf.worker.min.mjs` |
8382

84-
`locale` - Specifies which language to use in the viewer UI, `en-US | ...`. [Available locales](https://github.com/mozilla/pdf.js/tree/master/l10n)
83+
Play with attributes on [API docs page](https://alekswebnet.github.io/pdfjs-viewer-element/#api).
8584

86-
`viewer-css-theme` - Apply automatic, light, or dark theme, `AUTOMATIC | LIGHT | DARK`
85+
## Runtime updates
8786

88-
`viewer-extra-styles` - Add your CSS rules to the viewer application, pass a string with styles.
87+
Most attributes can be updated dynamically:
8988

90-
`viewer-extra-styles-urls` - Add external CSS files to the viewer application, pass an array with URLs.
91-
92-
Play with attributes on [API docs page](https://alekswebnet.github.io/pdfjs-viewer-element/#api).
89+
- `src` updates by calling PDF.js `open({ url })` without rebuilding the viewer.
90+
- `page`, `search`, `phrase`, `zoom`, `pagemode` update via hash parameters.
91+
- `viewer-css-theme` updates the viewer theme at runtime.
92+
- `worker-src` updates viewer options for subsequent document loads.
93+
- `locale` rebuilds the viewer so localization resources can be applied.
9394

9495
## Viewer CSS theme
9596

@@ -102,18 +103,33 @@ Use `viewer-css-theme` attribute to set light or dark theme manually:
102103
</pdfjs-viewer-element>
103104
```
104105

105-
## Viewer custom styles
106+
Runtime example:
107+
108+
```javascript
109+
const viewer = document.querySelector('pdfjs-viewer-element')
110+
viewer.setAttribute('viewer-css-theme', 'DARK')
111+
viewer.setAttribute('viewer-css-theme', 'AUTOMATIC')
112+
```
113+
114+
## Viewer custom styles
106115

107-
You can add your own CSS rules to the viewer application using `viewer-extra-styles` or `viewer-extra-styles-urls` attribute:
116+
You can add your own CSS rules to the viewer application using `injectViewerStyles(styles: string)`:
108117

109118
```html
110-
<pdfjs-viewer-element
111-
src="/file.pdf"
112-
viewer-extra-styles="#toolbarViewerMiddle { display: none; }"
113-
viewer-extra-styles-urls="['/demo/viewer-custom-theme.css']">
119+
<pdfjs-viewer-element id="viewer" src="/file.pdf">
114120
</pdfjs-viewer-element>
115121
```
116-
Build your own theme with viewer's custom variables and `viewer-extra-styles-urls` attribute:
122+
123+
```javascript
124+
const viewer = document.querySelector('#viewer')
125+
viewer.injectViewerStyles(`
126+
#toolbarViewerMiddle, #toolbarViewerRight { display: none; }
127+
`)
128+
```
129+
130+
`injectViewerStyles(...)` applies styles immediately when the viewer document is ready, and keeps them for future rebuilds.
131+
132+
Build your own theme with viewer custom variables and inject it via `injectViewerStyles(...)`:
117133

118134
```css
119135
:root {
@@ -136,7 +152,11 @@ Build your own theme with viewer's custom variables and `viewer-extra-styles-url
136152
}
137153
```
138154

139-
## PDF.js Viewer Application and Options
155+
## Methods
156+
157+
`injectViewerStyles(styles: string)` - Adds custom CSS to the viewer now (when ready) and for future rebuilds.
158+
159+
## Programmatic access to PDF.js
140160

141161
```html
142162
<pdfjs-viewer-element></pdfjs-viewer-element>
@@ -152,13 +172,31 @@ document.addEventListener('DOMContentLoaded', async () => {
152172
})
153173
```
154174

175+
You can also react to source changes dynamically:
176+
177+
```javascript
178+
const viewer = document.querySelector('pdfjs-viewer-element')
179+
viewer.setAttribute('src', '/another-file.pdf')
180+
```
181+
155182
## Events
156183

157184
`initialized` - Fired after the PDF.js viewer is ready (after `PDFViewerApplication.initializedPromise` resolves). The event `detail` contains:
158185

159186
- `viewerApp` (`PDFViewerApplication`)
160187
- `viewerOptions` (`PDFViewerApplicationOptions`)
161188

189+
The event is emitted each time the internal viewer is rebuilt (for example after changing `locale`).
190+
191+
## Migration notes
192+
193+
If you are upgrading from an older version:
194+
195+
- `viewer-extra-styles` and `viewer-extra-styles-urls` attributes are removed.
196+
- Use `injectViewerStyles(styles)` instead of style attributes.
197+
- Use the `initialized` event for `viewerApp` / `viewerOptions` access.
198+
- Runtime `src` updates are supported with `setAttribute('src', ...)`.
199+
162200
## Accessibility
163201

164202
Use `iframe-title` to add a title to the `iframe` element and improve accessibility.

demo/basic.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<meta charset="UTF-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
66
<title>pdfjs-viewer-element | Basic demo</title>
7-
<script type="module" src="https://cdn.jsdelivr.net/npm/pdfjs-viewer-element/dist/pdfjs-viewer-element.js"></script>
7+
<script type="module" src="../dist/pdfjs-viewer-element.js"></script>
88
<style>
99
body {
1010
margin: 0;

demo/dark-theme.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<meta charset="UTF-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
66
<title>pdfjs-viewer-element | Dark theme demo</title>
7-
<script type="module" src="https://cdn.jsdelivr.net/npm/pdfjs-viewer-element/dist/pdfjs-viewer-element.js"></script>
7+
<script type="module" src="../dist/pdfjs-viewer-element.js"></script>
88
<style>
99
body {
1010
margin: 0;

demo/extra-styles-urls.html

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<meta charset="UTF-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
66
<title>pdfjs-viewer-element | Extra styles demo</title>
7-
<script type="module" src="https://cdn.jsdelivr.net/npm/pdfjs-viewer-element/dist/pdfjs-viewer-element.js"></script>
7+
<script type="module" src="../dist/pdfjs-viewer-element.js"></script>
88
<style>
99
body {
1010
margin: 0;
@@ -16,8 +16,34 @@
1616
<body>
1717
<pdfjs-viewer-element
1818
src="/public/sample-pdf-with-images.pdf"
19-
viewer-extra-styles-urls="['/demo/viewer-custom-theme.css']"
20-
style="height: 100dvh">
19+
style="height: 100dvh"
20+
>
2121
</pdfjs-viewer-element>
22+
23+
<script>
24+
document.addEventListener('DOMContentLoaded', async () => {
25+
// Create a very simple toolbar by hiding the middle and right toolbar parts.
26+
document.querySelector('pdfjs-viewer-element').injectViewerStyles(`
27+
:root {
28+
--main-color: #5755FE;
29+
--toolbar-icon-bg-color: #0200a8;
30+
--field-color: #5755FE;
31+
--separator-color: #5755FE;
32+
--toolbar-border-color: #5755FE;
33+
--field-border-color: #5755FE;
34+
--toolbar-bg-color: rgba(139, 147, 255, .1);
35+
--body-bg-color: rgba(255, 247, 252, .7);
36+
--button-hover-color: rgba(139, 147, 255, .1);
37+
--toolbar-icon-hover-bg-color: #0200a8;
38+
--toggled-btn-color: #0200a8;
39+
--toggled-btn-bg-color: rgba(139, 147, 255, .1);
40+
--toggled-hover-active-btn-color: #5755FE;
41+
--doorhanger-hover-bg-color: rgba(139, 147, 255, .1);
42+
--doorhanger-hover-color: #0200a8;
43+
--dropdown-btn-bg-color: rgba(139, 147, 255, .1);
44+
}
45+
`)
46+
})
47+
</script>
2248
</body>
2349
</html>

demo/extra-styles.html

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<meta charset="UTF-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
66
<title>pdfjs-viewer-element | Extra styles demo</title>
7-
<script type="module" src="https://cdn.jsdelivr.net/npm/pdfjs-viewer-element/dist/pdfjs-viewer-element.js"></script>
7+
<script type="module" src="../dist/pdfjs-viewer-element.js"></script>
88
<style>
99
body {
1010
margin: 0;
@@ -16,8 +16,16 @@
1616
<body>
1717
<pdfjs-viewer-element
1818
src="/public/sample-pdf-with-images.pdf"
19-
viewer-extra-styles="#toolbarViewerMiddle { display: none; }"
2019
style="height: 100dvh">
2120
</pdfjs-viewer-element>
2221
</body>
22+
23+
<script>
24+
document.addEventListener('DOMContentLoaded', async () => {
25+
// Create a very simple toolbar by hiding the middle and right toolbar parts.
26+
document.querySelector('pdfjs-viewer-element').injectViewerStyles(`
27+
#toolbarViewerMiddle, #toolbarViewerRight { display: none; }
28+
`)
29+
})
30+
</script>
2331
</html>

demo/multiple.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<meta charset="UTF-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
66
<title>pdfjs-viewer-element | Multiple demo</title>
7-
<script type="module" src="https://cdn.jsdelivr.net/npm/pdfjs-viewer-element/dist/pdfjs-viewer-element.js"></script>
7+
<script type="module" src="../dist/pdfjs-viewer-element.js"></script>
88
<style>
99
body {
1010
margin: 0;

demo/opened-findbar.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<meta charset="UTF-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
66
<title>pdfjs-viewer-element | Opened find bar demo</title>
7-
<script type="module" src="https://cdn.jsdelivr.net/npm/pdfjs-viewer-element/dist/pdfjs-viewer-element.js"></script>
7+
<script type="module" src="../dist/pdfjs-viewer-element.js"></script>
88
<style>
99
body {
1010
margin: 0;
@@ -26,7 +26,7 @@
2626
const { viewerApp } = event.detail
2727
viewerApp.eventBus.on('pagesloaded', () => {
2828
viewerApp.findBar.open()
29-
viewerApp.findBar.findField.value = 'na'
29+
viewerApp.findBar.findField.value = 'and'
3030
viewerApp.findBar.highlightAll.checked = true
3131
viewerApp.findBar.findNextButton.click()
3232
})

demo/pdf-data-load.html

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<meta charset="UTF-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
66
<title>pdfjs-viewer-element | Basic demo</title>
7-
<script type="module" src="https://cdn.jsdelivr.net/npm/pdfjs-viewer-element/dist/pdfjs-viewer-element.js"></script>
7+
<script type="module" src="../dist/pdfjs-viewer-element.js"></script>
88
<style>
99
body {
1010
margin: 0;
@@ -15,7 +15,6 @@
1515

1616
<body>
1717
<pdfjs-viewer-element
18-
id="viewer"
1918
style="height: 100dvh">
2019
</pdfjs-viewer-element>
2120

@@ -37,7 +36,7 @@
3736

3837

3938
document.addEventListener('DOMContentLoaded', async () => {
40-
document.querySelector('#viewer').addEventListener('initialized', (event) => {
39+
document.querySelector('pdfjs-viewer-element').addEventListener('initialized', (event) => {
4140
const { viewerApp } = event.detail
4241
viewerApp.open({ data: pdfData })
4342
})

index.html

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
<title>pdfjs-viewer-element</title>
77
<meta name="description" content="A web component for viewing pdf files in the browser, based on PDF.js">
88
<script type="module" src="./src/pdfjs-viewer-element.ts"></script>
9+
<script type="module" src="./index.js"></script>
910
</head>
1011
<body style="margin: 0">
1112
<pdfjs-viewer-element
@@ -20,11 +21,12 @@
2021
page="2"
2122
style="height: 600px">
2223
</pdfjs-viewer-element>
23-
<button onclick="document.querySelector('#hideOpenFileViewer').setAttribute('viewer-extra-styles', '#downloadButton { display: none }')">Hide download button</button>
24-
<button onclick="document.querySelector('#hideOpenFileViewer').setAttribute('viewer-extra-styles', '')">Show download button</button>
24+
<button onclick="toggleDownloadButton(document.querySelector('#hideOpenFileViewer'))">Toggle download button</button>
2525

2626
<pdfjs-viewer-element
2727
id="themedViewer"
28+
page="3"
29+
locale="uk"
2830
src="/sample-pdf-10MB.pdf"
2931
style="height: 600px">
3032
</pdfjs-viewer-element>
@@ -44,6 +46,8 @@
4446
<button onclick="document.querySelector('#themedViewer').setAttribute('zoom', 'auto')">Reset zoom</button>
4547
<button onclick="document.querySelector('#themedViewer').setAttribute('pagemode', 'thumbs')">Change page mode</button>
4648
<button onclick="document.querySelector('#themedViewer').setAttribute('pagemode', 'none')">Reset page mode</button>
49+
<button onclick="document.querySelector('#themedViewer').setAttribute('src', '/sample-pdf-with-images.pdf')">Load images PDF</button>
50+
<button onclick="document.querySelector('#themedViewer').setAttribute('src', '/sample-pdf-10MB.pdf')">Load 10MB PDF</button>
4751
<hr>
4852

4953
<pdfjs-viewer-element
@@ -52,29 +56,4 @@
5256
style="height: clamp(400px, 80dvh, 600px)">
5357
</pdfjs-viewer-element>
5458
</body>
55-
56-
<script>
57-
const pdfData = Uint8Array.from(atob(
58-
'JVBERi0xLjcKCjEgMCBvYmogICUgZW50cnkgcG9pbnQKPDwKICAvVHlwZSAvQ2F0YWxvZwog' +
59-
'IC9QYWdlcyAyIDAgUgo+PgplbmRvYmoKCjIgMCBvYmoKPDwKICAvVHlwZSAvUGFnZXMKICAv' +
60-
'TWVkaWFCb3ggWyAwIDAgMjAwIDIwMCBdCiAgL0NvdW50IDEKICAvS2lkcyBbIDMgMCBSIF0K' +
61-
'Pj4KZW5kb2JqCgozIDAgb2JqCjw8CiAgL1R5cGUgL1BhZ2UKICAvUGFyZW50IDIgMCBSCiAg' +
62-
'L1Jlc291cmNlcyA8PAogICAgL0ZvbnQgPDwKICAgICAgL0YxIDQgMCBSIAogICAgPj4KICA+' +
63-
'PgogIC9Db250ZW50cyA1IDAgUgo+PgplbmRvYmoKCjQgMCBvYmoKPDwKICAvVHlwZSAvRm9u' +
64-
'dAogIC9TdWJ0eXBlIC9UeXBlMQogIC9CYXNlRm9udCAvVGltZXMtUm9tYW4KPj4KZW5kb2Jq' +
65-
'Cgo1IDAgb2JqICAlIHBhZ2UgY29udGVudAo8PAogIC9MZW5ndGggNDQKPj4Kc3RyZWFtCkJU' +
66-
'CjcwIDUwIFRECi9GMSAxMiBUZgooSGVsbG8sIHdvcmxkISkgVGoKRVQKZW5kc3RyZWFtCmVu' +
67-
'ZG9iagoKeHJlZgowIDYKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDEwIDAwMDAwIG4g' +
68-
'CjAwMDAwMDAwNzkgMDAwMDAgbiAKMDAwMDAwMDE3MyAwMDAwMCBuIAowMDAwMDAwMzAxIDAw' +
69-
'MDAwIG4gCjAwMDAwMDAzODAgMDAwMDAgbiAKdHJhaWxlcgo8PAogIC9TaXplIDYKICAvUm9v' +
70-
'dCAxIDAgUgo+PgpzdGFydHhyZWYKNDkyCiUlRU9G'), (m) => m.codePointAt(0));
71-
72-
73-
document.addEventListener('DOMContentLoaded', async () => {
74-
document.querySelector('#base-viewer').addEventListener('initialized', (event) => {
75-
const { viewerApp } = event.detail
76-
viewerApp.open({ data: pdfData })
77-
})
78-
})
79-
</script>
8059
</html>

0 commit comments

Comments
 (0)