Skip to content

Commit 3727acc

Browse files
committed
prepare publishing version 28: fixed a CSS error; updated the README.md
1 parent cbf3051 commit 3727acc

6 files changed

Lines changed: 50 additions & 17 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,4 @@ sbom.json
5858
/ftp/.env
5959
.htaccess
6060
.claude
61+
/test-results/.last-run.json

projects/ngx-extended-pdf-viewer/README.md

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,23 @@ Built on Mozilla’s pdf.js and extended with dozens of enhancements, it's ideal
1717

1818
### Prerequisites
1919

20-
⚠️ **Versions 26 and 27 require Angular 19, 20, or 21.** If you're using Angular 17 or 18, please continue using version 25.6.4.
20+
⚠️ **Versions 26 through 28 require Angular 19, 20, 21, or 22.** If you're using Angular 17 or 18, please continue using version 25.6.4.
2121

2222
**Why this breaking change?** There are many reasons: Version 26 supports zone-less Angular and migrates to signals. And Angular 18 exited its Long-Term Support (LTS) phase, and security vulnerability CVE-2025-66035 will not be fixed in Angular 17 or 18. Updating to Angular 19 ensures your application continues to receive critical security patches.
2323

2424
In general, I aim to support the last four Angular versions (roughly two years of updates), but sometimes security requirements force me to raise the minimum version sooner.
2525

2626
**Is there a migration schematic?** No - because migrating to ngx-extended-pdf-viewer shouldn't be a big deal. The library uses signals internally, but that hardly ever shows in your application, unless you're using `@ViewChild` to access properties of ngx-extended-pdf-viewer. Even then, solving the error messages should be easy. Adopting zone-less Angular was also surprisingly easy, at least in my showcase. I hope you'll experience a similarly smooth transition!
2727

28-
**Angular 21+ Zoneless Support**
28+
**Zoneless Angular Support (21 and 22)**
2929

30-
**ngx-extended-pdf-viewer 26 now fully supports Angular 21+ zoneless change detection!** The library works seamlessly in both zone.js and zoneless applications with zero configuration required.
30+
**ngx-extended-pdf-viewer fully supports zoneless change detection in Angular 21 and 22.** The library works seamlessly in both zone.js and zoneless applications with zero configuration required.
3131

32-
**Using Zoneless (Default in Angular 21+):**
32+
**Using Zoneless (the default in Angular 21 and 22):**
3333
Simply use the library as normal - it will automatically detect zoneless mode and trigger change detection appropriately. You'll have to use `cdr.markForCheck()` every once in a while, but I assume you're already familiar with that pattern.
3434

3535
**Using Zone.js (Optional):**
36-
If you prefer to use zone.js in your Angular 21+ application, add this to your `app.config.ts`:
36+
If you prefer to use zone.js in your Angular 21 or 22 application, add this to your `app.config.ts`:
3737

3838
```typescript
3939
import { provideZoneChangeDetection } from '@angular/core';
@@ -60,8 +60,8 @@ npm add ngx-extended-pdf-viewer
6060

6161
| Package | Version |
6262
| ----------------- | ------------------ |
63-
| `@angular/core` | `>=19.0.0 <22.0.0` |
64-
| `@angular/common` | `>=19.0.0 <22.0.0` |
63+
| `@angular/core` | `>=19.0.0 <23.0.0` |
64+
| `@angular/common` | `>=19.0.0 <23.0.0` |
6565

6666
### 2. Usage in Your Angular Component
6767

@@ -153,6 +153,32 @@ Regarding security: I'm not perfect - it's always a best-effort approach without
153153

154154
## 📦 Version Highlights
155155

156+
### Version 28
157+
158+
Version 28 updates to pdf.js 6.0 and adds Angular 22 support.
159+
160+
**New for end users:**
161+
162+
- **Merge PDFs and images**: A new "Add file" button in the sidebar lets users append another PDF or an image to the current document. Enable with `[enableMerge]="true"`.
163+
- **Auto-detected links**: URLs and email addresses in the text layer are turned into clickable links automatically.
164+
- **Highlight shortcut** (opt-in): A small "Highlight" button appears next to selected text. Enable with `pdfDefaultOptions.enableHighlightFloatingButton = true`.
165+
- **Improved accessibility**: Toolbar buttons now expose their localized name to screen readers.
166+
- **Works in hidden tabs and lazy-loaded routes**: Mounting the viewer inside an inactive Material tab or a lazy route used to behave erratically. It now starts up correctly once it becomes visible, and the navigation inputs you set up front are applied at that moment.
167+
168+
**New for developers:**
169+
170+
- **Angular 22 support**: ngx-extended-pdf-viewer 28 supports Angular 19, 20, 21, and 22.
171+
- **`ng add` works with Angular 22**: The schematic recognizes Angular 17+'s `@angular/build:application` builder (the default in the Angular 22 scaffold) and raises the production bundle budget so your first `ng build` doesn't fail because of the viewer's size.
172+
- **`[theme]` plays nicely with the host app's theming**: Setting `[theme]` no longer conflicts with Angular Material's automatic light/dark detection.
173+
- **Hidden tabs & lazy routes**: `[page]`, `[nameddest]`, and `scrollPageIntoView()` are queued and replayed once the viewer becomes visible. A new "Hidden tabs & lazy routes" showcase page demonstrates the setup.
174+
- **CSP-friendly image decoding**: Set `pdfDefaultOptions.useWasm = false` if your CSP forbids `'wasm-unsafe-eval'`, and the viewer falls back to JavaScript image decoders.
175+
- **New `pdfDefaultOptions` flags**: `useWasm`, `enableAltText`, `enableAutoLinking`, `enableHighlightFloatingButton`.
176+
177+
**Bug fixes:**
178+
179+
- Fixed a crash when dragging thumbnails to reorder pages.
180+
- Fixed `[(zoom)]` showing wrong percentages after SPA navigation.
181+
156182
### Version 27
157183

158184
Version 27 updates to pdf.js 5.6.205 and introduces page management features.

projects/ngx-extended-pdf-viewer/changelog.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -745,4 +745,4 @@
745745
- 28.0.0-alpha.0 updated to pdf.js 6.0 on both the stable and bleeding-edge branches. #3141 new `[enableMerge]` input adds an "Add file" button to the sidebar that merges another PDF or image into the current document. #3115 `[theme]` no longer fights with the host application's theming (e.g. Angular Material auto/dark mode). #1321 the viewer now works inside hidden tabs and lazy routes — `[page]`, `[nameddest]` and `scrollPageIntoView()` are replayed when the viewer becomes visible; fixed several startup crashes. Added a "Hidden tabs & lazy routes" showcase page. #3140 fixed the selected thumbnail's blue border being clipped on the right, and fixed PDF form JavaScript (calculations, validation) failing on sub-routes. #3142 fixed a crash when dragging thumbnails to reorder pages. Removed the obsolete `isEvalSupported` option.
746746
- 28.0.0-rc.1 #3209 added `pdfDefaultOptions.useWasm` — set it to `false` if your CSP forbids `'wasm-unsafe-eval'` and the viewer will decode images via the bundled JavaScript fallbacks instead of WebAssembly. Also exposed three pdf.js 6 options that were not surfaced before: `enableAltText` (alt-text editor for user-inserted images, default `false`), `enableAutoLinking` (auto-detect URLs/emails in the text layer, default `true`), and `enableHighlightFloatingButton` (small "Highlight" shortcut next to selected text, default `false`).
747747
- 28.0.0-rc.2 #3209 expose the pdf.js options `pdfDefaultOptions.useWasm`, 'pdfDefaultOptions.enableAltText', 'pdfDefaultOptions.enableAutoLinking', `pdfDefaultOptions.enableHighlightFloatingButton`
748-
- 28.0.0-rc.3 `ng add` now recognizes Angular 17+'s `@angular/build:application` builder and reads the `builder` field in `angular.json` (it previously looked only at `executor` and missed the default Angular 22 scaffold). The schematic also raises the production `initial` bundle budget to 2 MB warning / 3 MB error so the first `ng build` after `ng add` doesn't fail — the library's JS wrapper alone is ~1.2 MB. (Asset files like `viewer-*.mjs` and `pdf.worker-*.mjs` are NOT included in the budget; only the bundled code is.) Finally, `ng add` now prints a deployment-time hint about serving `.mjs` as `application/javascript` — some web servers default `.mjs` to `application/octet-stream`, and browsers refuse to execute it.
748+
- 28.0.0-rc.3 `ng add` now recognizes Angular 17+'s `@angular/build:application` builder and reads the `builder` field in `angular.json` (it previously looked only at `executor` and missed the default Angular 22 scaffold). The schematic also raises the production `initial` bundle budget to 2 MB warning / 3 MB error so the first `ng build` after `ng add` doesn't fail — the library's JS wrapper alone is ~1.2 MB. (Asset files like `viewer-*.mjs` and `pdf.worker-*.mjs` are NOT included in the budget; only the bundled code is.) `ng add` also now prints a deployment-time hint about serving `.mjs` as `application/javascript` — some web servers default `.mjs` to `application/octet-stream`, and browsers refuse to execute it. pdf-shy-button (the primary-toolbar button) now renders an inner `<span [data-l10n-id]="l10nLabel"></span>` so Fluent can fill the screen-reader label — matching pdf.js's canonical markup and the secondary toolbar template; the `l10nLabel` input was tracked but never reached the DOM, so primary toolbar buttons were missing the localised label entirely. Fixed a latent bug in `updateButtonImage()` that iterated a live `NodeList` while removing children (skipped every other child). Fixed toolbar icons (rotate, highlight, freetext, stamp, ink, hand tool, select tool, page-flip) being pushed below the baseline of the other primary-toolbar buttons at wide viewports: removed a long-standing `#outerContainer .hiddenXLView, .hiddenXXLView { display: unset }` rule in `DynamicCssComponent` that was clobbering the `display: inline-flex` set by `button.toolbarButton`; the override was harmless while the button was empty, but the new label `<span>` introduced text content whose line-height baseline-aligned the inline `<svg>` icon below the button's vertical centre. **Potentially breaking for custom toolbars:** if you put the responsive-visibility classes `.hiddenXLView` or `.hiddenXXLView` on your own elements (via the `responsiveCSSClass` pipe or by hand), they no longer get `display: unset` at wide viewports. They now keep their natural display (`inline-flex` for `.toolbarButton`, `block` for `<div>`, etc.). The previous `unset` resolved to `inline-block` for `<button>` and to `inline` for any other element — values that were almost certainly never what anyone intended. If your custom toolbar overrode `display` somewhere downstream, you're unaffected; if you implicitly depended on the `unset` value, set the desired display explicitly on your element.

projects/ngx-extended-pdf-viewer/src/lib/dynamic-css/dynamic-css.component.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,11 +135,6 @@ export class DynamicCssComponent implements OnDestroy {
135135
display: none;
136136
}
137137
138-
#outerContainer .hiddenXLView,
139-
#outerContainer .hiddenXXLView {
140-
display: unset;
141-
}
142-
143138
@media all and (max-width: ${this.xl()}px) {
144139
#outerContainer .hiddenXLView {
145140
display: none;

projects/ngx-extended-pdf-viewer/src/lib/toolbar/pdf-shy-button/pdf-shy-button.component.html

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
<button type="button" [id]="primaryToolbarId()" [class]="'toolbarButton ' + cssClass()" [title]="title()"
99
[attr.data-l10n-id]="l10nId() || null" [class.toggled]="toggled()" [disabled]="disabled()" (click)="onClick($event)"
1010
[attr.aria-label]="title()" [attr.role]="role()" [attr.aria-expanded]="toggled() ? 'true' : (ariaHasPopup() ? 'false' : null)"
11-
[attr.aria-haspopup]="ariaHasPopup()" [attr.aria-controls]="ariaControls()" #buttonRef></button>
11+
[attr.aria-haspopup]="ariaHasPopup()" [attr.aria-controls]="ariaControls()" #buttonRef>
12+
<span [attr.data-l10n-id]="l10nLabel() || null"></span>
13+
</button>
1214
}
1315
}

projects/ngx-extended-pdf-viewer/src/lib/toolbar/pdf-shy-button/pdf-shy-button.component.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,9 +221,18 @@ export class PdfShyButtonComponent implements OnInit, AfterViewInit, AfterConten
221221
this.renderer.appendChild(el, image);
222222
}
223223
} else {
224-
const childNodes = el.childNodes;
225-
for (let child of childNodes) {
226-
this.renderer.removeChild(el, child);
224+
// Only clear the SVG image previously injected by this method;
225+
// leave the Angular-managed label span (rendered in the template
226+
// for Fluent's screen-reader translation) alone. Snapshot first —
227+
// iterating a live NodeList while removing skips every other child.
228+
const children: ChildNode[] = Array.from(el.childNodes);
229+
for (const child of children) {
230+
if (
231+
child.nodeType === Node.ELEMENT_NODE &&
232+
(child as Element).tagName.toLowerCase() === 'svg'
233+
) {
234+
this.renderer.removeChild(el, child);
235+
}
227236
}
228237
}
229238
}

0 commit comments

Comments
 (0)