From 88cfab4e4b39a1367680c0c896c6e12492affa0e Mon Sep 17 00:00:00 2001 From: Aleksandr Shevchuk Date: Fri, 6 Mar 2026 15:13:14 +0200 Subject: [PATCH 1/2] #43, #44 (feat) Add localeSrcTemplate, include PDF.js worker to build --- README.md | 40 +++++++++++++++++++++++++++++++-- demo/custom-worker-src.html | 23 +++++++++++++++++++ package.json | 5 +++-- pnpm-lock.yaml | 3 +++ scripts/copy-worker.mjs | 26 +++++++++++++++++++++ src/pdfjs-viewer-element.ts | 20 ++++++++++++++--- types/pdfjs-viewer-element.d.ts | 1 + vite.config.ts | 1 - 8 files changed, 111 insertions(+), 8 deletions(-) create mode 100644 demo/custom-worker-src.html create mode 100644 scripts/copy-worker.mjs diff --git a/README.md b/README.md index b39479e..8109f2d 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Supported in all [major browsers](https://caniuse.com/custom-elementsv1), and wo ## Features -- Standalone web component with no runtime dependencies +- Standalone isolated web component with no runtime dependencies - Drop-in, iframe-based PDF.js default viewer for any web app - Works with same-origin and cross-origin PDF documents - Configure via attributes and URL parameters (page, zoom, search, pagemode, locale) @@ -86,8 +86,9 @@ The element is block-level and needs an explicit height. | `zoom` | Zoom level (for example `auto`, `page-width`, `200%`). | `''` | | `pagemode` | Sidebar mode: `thumbs`, `bookmarks`, `attachments`, `layers`, `none`. | `none` | | `locale` | Viewer UI locale (for example `en-US`, `de`, `uk`). [Available locales](https://github.com/mozilla/pdf.js/tree/master/l10n) | `''` | +| `locale-src-template` | Locale file URL template. Must contain `{locale}` placeholder. Used together with `locale`. | `https://cdn.jsdelivr.net/gh/mozilla-l10n/firefox-l10n@main/{locale}/toolkit/toolkit/pdfviewer/viewer.ftl` | | `viewer-css-theme` | Viewer theme: `AUTOMATIC`, `LIGHT`, `DARK`. | `AUTOMATIC` | -| `worker-src` | PDF.js worker URL override. | `https://cdn.jsdelivr.net/npm/pdfjs-dist@5.4.624/build/pdf.worker.min.mjs` | +| `worker-src` | PDF.js worker URL override. | `/pdf.worker.min.mjs` | Play with attributes on [API docs page](https://alekswebnet.github.io/pdfjs-viewer-element/#api). @@ -101,6 +102,41 @@ Most attributes can be updated dynamically: - `worker-src` updates viewer options for subsequent document loads. - `locale` rebuilds the viewer so localization resources can be applied. +## Worker source + +By default, the component resolves `worker-src` to the worker shipped with this package (`pdf.worker.min.mjs` in `dist`). + +Set `worker-src` only if you want to serve the worker from a custom location (for example your own CDN or static assets path). + +- The URL must point to a valid PDF.js module worker file. +- The worker version should match the bundled PDF.js version. + +```html + + +``` + +## Locale source template + +Use `locale-src-template` when you need to load localization files from a custom host. + +- The template must include `{locale}`. +- `{locale}` is replaced by the `locale` attribute value (for example `de`, `uk`, `en-US`). +- If `locale` is not set, no locale file is loaded. +- Changes to `locale-src-template` are applied when the viewer is (re)initialized, for example after setting/changing `locale`. + +Example: + +```html + + +``` + ## Viewer CSS theme Use `viewer-css-theme` attribute to set light or dark theme manually: diff --git a/demo/custom-worker-src.html b/demo/custom-worker-src.html new file mode 100644 index 0000000..6ed6140 --- /dev/null +++ b/demo/custom-worker-src.html @@ -0,0 +1,23 @@ + + + + + + pdfjs-viewer-element | Custom Worker Src Demo + + + + + + + + + diff --git a/package.json b/package.json index 9429d25..fbe8137 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pdfjs-viewer-element", - "version": "3.1.1", + "version": "3.1.2", "license": "MIT", "author": { "name": "Oleksandr Shevchuk", @@ -37,7 +37,7 @@ ], "scripts": { "dev": "vite", - "build": "tsc && vite build", + "build": "tsc && vite build && node scripts/copy-worker.mjs", "test": "vitest", "coverage": "vitest run --coverage" }, @@ -47,6 +47,7 @@ "@vitest/browser": "^4.0.18", "@vitest/browser-webdriverio": "^4.0.18", "jsdom": "^28.1.0", + "terser": "^5.39.0", "typescript": "^5.9.3", "vite": "^7.3.1", "vitest": "^4.0.18", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9aead25..451173f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,6 +23,9 @@ importers: jsdom: specifier: ^28.1.0 version: 28.1.0 + terser: + specifier: ^5.39.0 + version: 5.46.0 typescript: specifier: ^5.9.3 version: 5.9.3 diff --git a/scripts/copy-worker.mjs b/scripts/copy-worker.mjs new file mode 100644 index 0000000..0526efc --- /dev/null +++ b/scripts/copy-worker.mjs @@ -0,0 +1,26 @@ +import { mkdir, readFile, writeFile } from 'node:fs/promises' +import { resolve } from 'node:path' +import { minify } from 'terser' + +const rootDir = resolve(import.meta.dirname, '..') +const sourceFile = resolve(rootDir, 'src', 'build', 'pdf.worker.mjs') +const distDir = resolve(rootDir, 'dist') +const targetFile = resolve(distDir, 'pdf.worker.min.mjs') + +await mkdir(distDir, { recursive: true }) + +const workerCode = await readFile(sourceFile, 'utf8') +const result = await minify(workerCode, { + module: true, + compress: true, + mangle: true, + format: { + comments: false + } +}) + +if (!result.code) { + throw new Error('Worker minification failed: empty output') +} + +await writeFile(targetFile, result.code, 'utf8') diff --git a/src/pdfjs-viewer-element.ts b/src/pdfjs-viewer-element.ts index f08b867..1b65dfa 100644 --- a/src/pdfjs-viewer-element.ts +++ b/src/pdfjs-viewer-element.ts @@ -1,4 +1,6 @@ -const PDFJS_VERSION = '5.5.207' +const DEFAULT_WORKER_SRC = import.meta.env.DEV + ? new URL('./build/pdf.worker.mjs', import.meta.url).href + : new URL('./pdf.worker.min.mjs', import.meta.url).href const DEFAULTS = { src: '', @@ -10,7 +12,8 @@ const DEFAULTS = { pagemode: 'none', locale: '', viewerCssTheme: 'AUTOMATIC', - workerSrc: `https://cdn.jsdelivr.net/npm/pdfjs-dist@${PDFJS_VERSION}/build/pdf.worker.min.mjs` + workerSrc: DEFAULT_WORKER_SRC, + localeSrcTemplate: 'https://cdn.jsdelivr.net/gh/mozilla-l10n/firefox-l10n@main/{locale}/toolkit/toolkit/pdfviewer/viewer.ftl' } as const export const ViewerCssTheme = { AUTOMATIC: 0, LIGHT: 1, DARK: 2 } as const @@ -38,6 +41,13 @@ export class PdfjsViewerElement extends HTMLElement { ] } + private formatTemplate(template: string, params: Record) { + return template.replace(/\{(\w+)\}/g, (_, key) => { + if (!(key in params)) throw new Error(`Missing param: ${key}`); + return String(params[key]); + }); + } + private getFullPath(path: string) { return path.startsWith('/') ? `${window.location.origin}${path}` : path } @@ -120,8 +130,12 @@ export class PdfjsViewerElement extends HTMLElement { this.cleanupLocaleResource() return } + const localeUrl = this.formatTemplate( + this.getAttribute('locale-src-template') || DEFAULTS.localeSrcTemplate, + { locale } + ) const localeObject = { - [String(locale)]: `https://raw.githubusercontent.com/mozilla-l10n/firefox-l10n/main/${locale}/toolkit/toolkit/pdfviewer/viewer.ftl` + [String(locale)]: localeUrl } const localeLink = doc.createElement('link') localeLink.rel = 'resource' diff --git a/types/pdfjs-viewer-element.d.ts b/types/pdfjs-viewer-element.d.ts index 507d5c8..39967f9 100644 --- a/types/pdfjs-viewer-element.d.ts +++ b/types/pdfjs-viewer-element.d.ts @@ -11,6 +11,7 @@ export declare class PdfjsViewerElement extends HTMLElement { private localeResourceLink?; private viewerStyles; static get observedAttributes(): string[]; + private formatTemplate; private getFullPath; private getCssThemeOption; private applyIframeHash; diff --git a/vite.config.ts b/vite.config.ts index 69c549c..579edfc 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -11,7 +11,6 @@ export default defineConfig({ output: { plugins: [ terser({ - 'sourceMap': false, compress: true, mangle: false, format: { comments: false } From ba16de22d4465f65a3cef6b4361ffcd0992155c6 Mon Sep 17 00:00:00 2001 From: Aleksandr Shevchuk Date: Fri, 6 Mar 2026 15:28:02 +0200 Subject: [PATCH 2/2] Fix readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8109f2d..ae7fb96 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ Set `worker-src` only if you want to serve the worker from a custom location (fo ```html + worker-src="https://cdn.jsdelivr.net/npm/pdfjs-dist@5.5.207/build/pdf.worker.min.mjs"> ``` @@ -249,7 +249,7 @@ You can also react to source changes dynamically: ```javascript const viewerElement = document.querySelector('pdfjs-viewer-element') -viewer.setAttribute('src', '/another-file.pdf') +viewerElement.setAttribute('src', '/another-file.pdf') ``` ## Accessibility