UNPKG

84.1 kBMarkdownView Raw
1# ngx-extended-pdf-viewer
2<p>
3 <a href="https://www.npmjs.com/package/ngx-extended-pdf-viewer">
4 <img src="https://img.shields.io/npm/dm/ngx-extended-pdf-viewer.svg?style=flat" alt="downloads">
5 </a>
6 <a href="https://badge.fury.io/js/ngx-extended-pdf-viewer">
7 <img src="https://badge.fury.io/js/ngx-extended-pdf-viewer.svg" alt="npm version">
8 </a>
9 <a href="https://opensource.org/licenses/Apache-2.0"><img src="https://img.shields.io/badge/License-Apache%202.0-brightgreen.svg"></a>
10 <a href="https://openbase.io/js/ngx-extended-pdf-viewer?utm_source=embedded&utm_medium=badge&utm_campaign=rate-badge"><img src="https://badges.openbase.io/js/rating/ngx-extended-pdf-viewer.svg"></a>
11 </p>
12 <p>
13 CDN: <a href="https://unpkg.com/browse/ngx-extended-pdf-viewer/">unpkg.com</a>
14 </p>
15
16## Showcase and manual
17
18There's a showcase at <a href="https://pdfviewer.net">https://pdfviewer.net</a>. Check this page for live demos, source code examples, and a handbook.
19
20There's also a detailed <a href="https://github.com/stephanrauh/ngx-extended-pdf-viewer/tree/main/projects/ngx-extended-pdf-viewer/changelog.md">changelog<a/>. If you're interested in breaking changes when updating to the latest version, scroll to the end of this page.
21
22## Contributors welcome!
23
24Would you like to participate in a popular open source project? It's easy: just open a ticket so we can discuss the change, create a fork, and send me a pull request. Contributions to the showcase are as welcome as contributions to the core library itself.
25
26## Bringing PDF to the Angular world
27
28This library provides an embeddable PDF viewer component. It's different from other approaches like [ng2-pdf-viewer](https://vadimdez.github.io/ng2-pdf-viewer/) in that it shows the full suite of UI widgets. In other words, it strongly resembles the PDF viewer of your browser:
29
30<img src="https://beyondjava.net/blog/images/ngx-extended-pdf-viewer/example-screenshot.png">
31
32## Features
33
34- Searching (including a programmatic API)
35- Printing
36- Support for forms, including two-way binding
37- (Limited) support for signatures (lacking verification of the signature, so use on your own risk!)
38- Sidebar with thumbnails, outlines, and attachments (and each of them both optional and customizable)
39- Rotating
40- Download (including form data) and upload
41- Zoom (with optional two-way binding to an attribute)
42- Full-screen mode
43- Various selection tools
44- Standard display or even / odd spreads (like a book)
45- Multiple event listeners
46- Several approaches to scrolling (vertical, horizontal, "wrapped" scrolling)
47- Internationalization (providing translations to several dozen languages)
48- Direct access to the core API of pdf.js (including TypeScript definition files)
49- The ability to deactivate (i.e. hide) every button, menu item, and the context menu
50- Color theming
51- And to customize the toolbars and menus according to your needs.
52
53Not to mention the ability to display PDF files, running on a customized version of Mozilla's pdf.js 2.10, released in July 2021. If you're the daring one, you can also use the developer version 2.11. It's bleeding edge, so use it at own risk. Basically, the preview version helps me because I can add Mozilla's latest improvements in frequent, small increments. But every once in a while, it contains a feature you may need, so feel free to use it. I don't encourage using the "bleeding edge" branch in production, but most of the time, the quality is production-ready.
54
55## Alternatives
56<details>
57 <summary><b>Expand to learn more about the other options to display PDF files in Angular</b></summary>
58 If you only need the base functionality, I'll happily pass you to <a href="https://github.com/vadimdez/ng2-pdf-viewer/" target="#">the project of Vadym Yatsyuk</a>. Vadym does a great job delivering a no-nonsense PDF viewer. However, if you need something that can easily pass as the native viewer on a gloomy day, ngx-extended-pdf-viewer is your friend.
59
60There's also a direct counterpart to my library: <a href="https://www.npmjs.com/package/ng2-pdfjs-viewer" target="#">ng2-pdfjs-viewer</a>. As far as I can see, it's also a good library. As of May 2021, it's running on PDF.js 2.2.171. It wraps the PDF viewer in an iFrame. That's a more reliable approach, but it also offers fewer options. The list of attributes is shorter, and the PDF viewer can't emit events to your application. If you're not happy with my library, check out ng2-pdfjs-viewer. It's a good library, too. Its unique selling point is displaying multiple PDF files simultaneously on the same page.
61
62You might also try to use the native PDF viewer of your browser. That's a valid approach. It's even the preferred approach. However, `ngx-extended-pdf-viewer` gives you a wide range of options that aren't available using the native API.
63</details>
64
65## How to use the library
66As a rule of thumb, I recommend cloning the [showcase project from GitHub](https://github.com/stephanrauh/extended-pdf-viewer-showcase) before doing anything else. It's a standard Angular CLI application, so you'll get it up and running in less than ten minutes. It's a good starting point to do your own experiments. Maybe even more important: you'll learn if the library works on your machine. (Of course, it does, but it's always good to double-check!)
67
68Currently, the minimum required version is Angular 9. The idea is to support the four most current versions of Angular, which gives you roughly two years to update.
69
701. Install the library with `npm i ngx-extended-pdf-viewer --save`
71
722. Open the file `angular.json` (or `.angular-cli.json` if you're using an older version of Angular) and configure Angular to copy the `assets` folder of the library into the `assets` folder of your application:
73 ```json
74 "assets": [
75 "src/favicon.ico",
76 "src/assets",
77 {
78 "glob": "**/*",
79 "input": "node_modules/ngx-extended-pdf-viewer/assets/",
80 "output": "/assets/"
81 }
82 ],
83 "scripts": []
84 ```
85 This simply copies the entire assets folder. If you're concerned about disk memory, you can omit the subfolders `inline-locale-files` and `additional-locale`. If you need only one language, you can reduce the list to `locale.properties` and your language folder.
86
87 If you want to use the developer preview of pdf.js 2.10, also import the "bleeding edge" files:
88
89 ```json
90 "assets": [
91 "src/favicon.ico",
92 "src/assets",
93 {
94 "glob": "**/*",
95 "input": "node_modules/ngx-extended-pdf-viewer/assets/",
96 "output": "/assets/"
97 },
98 {
99 "glob": "**/*",
100 "input": "node_modules/ngx-extended-pdf-viewer/bleeding-edge/",
101 "output": "/bleeding-edge/"
102 }
103 ],
104 "scripts": []
105 ```
106
107 You will also need to add those lines to your component :
108 - An import statement
109 ```ts
110 import { pdfDefaultOptions } from 'ngx-extended-pdf-viewer';
111 ```
112 - A line in your constructor
113 ```ts
114 pdfDefaultOptions.assetsFolder = 'bleeding-edge';
115 ```
116
117 _Hint:_ There are two ways to define the language files needed for the labels of the buttons and screen elements. The second method is described below in the "internationalization" section.
118
1193. Now you can display the PDF file like so:
120 ```html
121 <ngx-extended-pdf-viewer [src]="'assets/example.pdf'" useBrowserLocale="true" height="80vh"></ngx-extended-pdf-viewer>
122 ```
123
1244. If you want to display a PDF file you have downloaded from a server, you probably have a `Blob` or a Base64 encoded string. `Blobs` can be passed directly to the attribute `[src]`. Base64 string must be passed to the attribute `[base64Src]` instead.
125
126## Configuration, options, and events
127Do you miss a configuration option? File an issue on the [project bug tracker](https://github.com/stephanrauh/ExploringAngular/tree/main/embedding-pdf). If the base library [pdf.js](https://mozilla.github.io/pdf.js/) supports the requested option, I'll probably add it. BTW, you can speed up the process by providing a code snippet telling me how to implement the feature or by submitting a pull request.
128
129_Legend:_
130
131- [(attribute)] describes an attribute with two-way-binding
132- [attribute] means that PDF-viewer reacts when the attribute changes
133- (attribute) means an event is raised when the user changes a setting
134- attribute (without special characters) means the attribute is used at load time only. Subsequent changes are ignored.
135
136Also see [the attribute list on the showcase](https://pdfviewer.net/attributes). It's the same list, just a little more useful because the showcase doesn't truncate the table on the right-hand side.
137
138| _Attribute_ | _default value_ | _description_ |
139| :--------------------------- | :-------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
140| [(src)] | | If `[src]` is a string: defines the URL of the PDF file to display. `src` may also be a `Blob`, a `Uint8Array`, an `URL` or an `ArrayBuffer`. To a limited extend, `[(src)]` is also a two-way binding attribute. If the user opens another PDF file, the event (srcChange) is fired. There's a catch: for security reasons, most browsers don't display the correct filename. Most often than not, the path is `C:\fakepath\`. The (srcChange) event removes the fakepath bit of the path. The $event attribute is simply the filename. But don't rely on it: it's up to the browser to implement that feature. |
141| [base64Src] | | accepts a PDF file as base64 encoded string |
142| (afterPrint) | | This event is fired after the print jov has either been sent to the printer, or after the user has cancelled the print job. Note there's no way to tell printing from aborting the print. |
143| [authorization] | undefined | This attribute is designed to activate server-side authorization. If this attribute has a value, the attribute `withCredentials` is set to true. If you're using Keycloak, you can pass the bearer token with this attribute. Note that you have to add the prefix "Bearer: " (with a capital B and a trailing space). To support other authorization servers, you can also set additional headers using the attribute `[httpHeaders]`. |
144| (beforePrint) | | This event is fired when the print is initiated. Note that this simply means the print preview window is opened. There's no way to predict if the user is actually going to print. |
145| [backgroundColor] | ? | background color |
146| [contextMenuAllowed] | true | should the context menu show when the right-hand side button is clicked? |
147| (currentZoomFactor) | n/a | fires each time the viewer changes the zoom level. The parameter is the numeric scale factor. Note that it's not a percentage; instead, `[zoom]="'100%'"` results in `(currentZoomFactor)` sending a value of `1.0`. This event seems to fire often enough to make it reliable for detecting the current zoom factor all the time. |
148| [customFindbarInputArea] | (none) | Allows you to customize the pop-up dialog that opens when you click the "find" button. See [https://pdfviewer.net/custom-toolbar](https://pdfviewer.net/custom-toolbar). |
149| [customFindbarButtons] | (none) | Allows you to customize the pop-up dialog that opens when you click the "find" button. See [https://pdfviewer.net/custom-toolbar](https://pdfviewer.net/custom-toolbar). |
150| [customSecondaryToolbar] | (none) | Allows you to replace the kebab menu on the right-hand side with your custom menu. |
151| [customSidebar] | (none) | Allows you to replace the entire toolbar with your own custom toolbar. See [https://pdfviewer.net/custom-sidebar](https://pdfviewer.net/custom-sidebar). |
152| [customThumbnail] | (none) | Allows you to implement custom thumbnails in the sidebar. See [https://pdfviewer.net/custom-thumbnails](https://pdfviewer.net/custom-thumbnails). |
153| [customToolbar] | (none) | Allows you to replace the entire toolbar with your own custom toolbar. See [https://pdfviewer.net/custom-toolbar](https://pdfviewer.net/custom-toolbar). |
154| [customFreeFloatingBar] | (none) | Allows you to add a toolbar you can place anywhere on the PDF viewer. The original use case was to let the zoom controls hover as a separate window at the bottom of the PDF file. See [https://pdfviewer.net/custom-toolbar](https://pdfviewer.net/custom-toolbar). |
155| delayFirstView | 0 | Number of milliseconds to wait between initializing the PDF viewer and loading the PDF file. Most users can let this parameter safely at it's default value of zero. Set this to 1000 or higher if you run into timing problems (typically caused by loading the locale files after the PDF files, so they are not available when the PDF viewer is initialized). |
156| [enableDragAndDrop] | true | Setting this attribute to false disables dragging and dropping a PDF file to the PDF viewer. |
157| [enablePinchOnMobile] | false | By default, the pinch gesture zooms the entire window on mobile devices. If you prefer to zoom the PDF viewer only, you can activate `enablePinchOnMobile="true"`. |
158| [enablePrint] | true | Setting this flag to false disables printing the PDF file. |
159| [filenameForDownload] | document.pdf | Allows the user to define the name of the file after clicking "download" |
160| [(handTool)] | true | setting this flag to true, activates the "hand tool" to scroll the PDF file by dragging. Setting this to false activates the "text selection" tool. You can also use this flag as a two-way binding attribute. If you're only interested in the event, the event name is `(handToolChange)`. Deactivating this flag also activates the "text layer". This, in turn, enables marking text and highlighting search result. |
161| [height] | (see text) | define the height of the PDF window. By default, it's 100%. On most web pages, this results in a height of 0 pixels. In this case, the height is set to fill all the available space. More precisely, the all the space to the bottom of the window. If that's less then 100 pixel, the height is set to 100 pixel. Note that this is just an initial setting. It doesn't change when the window is resized. |
162| [httpHeaders] | (none) | If you pass a JSON object to `httpHeaders`, the content of the JSON object is sent to the server as an array of additional httpHeaders. |
163| [ignoreKeyboard] | false | if this flag is set to true, the PDF viewer ignores every keyboard event. |
164| [ignoreKeys] | (none) | Accepts a comma-separated list of keys. For example, a legal value is `"['P', 'N']"`. Every key in the list is ignored. In the example, the key "k" navigates to the next page but "n" does not. |
165| [acceptKeys] | (none) | Accepts a comma-separated list of keys. For example, a legal value is `"['P', 'N']"`. Every key in the list is accepted, and every other key is ignored. In the example, the key "n" navigates to the next page but "k" does not. |
166| ~~[ignoreResponsiveCSS]~~ | n/a | This property has been removed in version 3.0.0-beta.6. |
167| imageResourcesPath | ./assets/images | allows you to put the viewer's SVG files into an arbitrary folder. |
168| localeFolderPath | ./assets/locale | allows you to put the locale folder into an arbitrary folder. |
169| language | undefined | Language of the UI. Must the the complete locale name, such as "es-ES" or "es-AR". It may be all lowercase. |
170| listenToURL | false | deactivates the URL listener of the PDF viewer. You can set it to "true" to allow for anchor tags like "#page=23" or "#nameddest=chapter_3". Only activate this flag if you don't use the anchor to encode the URLs for the router. |
171| [logLevel] | 1 | Log level. Legal values: VerbosityLevel.ERRORS (=0),VerbosityLevel.WARNINGS (=1), and VerbosityLevel.INFOS (=5). The higher the log level, the more is logged. Please note that the log level is only updated when a new PDF document is loaded programmatically (i.e. when `[src]`changes). |
172| [nameddest] | undefined | allows you to jump to a "named destination" inside the document. Typical examples of names destinations are "chapter_7" oder "image_3". The named destination are defined within the PDF document; you can only jump to destinations defined by the author of the PDF file. |
173| [showSidebarButton] | true | Show or hide the button to toggle the sidebar |
174| minifiedJSLibraries | true | Since version 4.0.0, ngx-extended-pdf-viewer loads the minified pdf.js libraries by default. You can set this flag to load the human-readable files. However, in most cases this shouldn't be necessary due to the source map files. Using the human-readable files give you a performance penalty. |
175| minZoom | 0.1 | Minimum zoom factor you can achieve by pinching or by hitting the "-" button or the "+" key. |
176| maxZoom | 10 | Maximum zoom factor you can achieve by pinching or by hitting the "+" button or the "+" key. |
177| [mobileFriendlyZoom] | 100% | Increases the size of the UI elements so you can use them on small mobile devices. Must be a percentage (`'150%'`) or a floating-point number (`'1.5'`). Alternatively you can set this attribute to `'true'` (= `'150%'`) or `'false'` (= `'100%'`). |
178| [password] | undefined | Allows you to pass a password programatically. If you pass the wrong password, a red error message claiming "corrupt pdf file" is show in below the toolbar. Caveat: the password must be a string. During my test I accidentially used a numerical value. This fails even if the password consists only of digits. Please note that the password is stored in the main memory without encryption. If you're really serious about protecting your user's data from hackers, this might be a security issue. Please note that the log level is only updated when a new PDF document is loaded programmatically (i.e. when `[src]`changes). |
179| [(page)] | undefined | two-way binding attribute to determine the page to display; more precisely: `[page]="25"` makes the PDF viewer show page 25 (at any time - even after load time); `[(page)]="attribute"` updates the attribute each time the user scrolls to another page. If you're only interested in the event, that's `(pageChange)`. |
180| [(pageLabel)] | undefined | two-way binding attribute to determine the page to display; more precisely: `[pageLabel]="25"` makes the PDF viewer show the page the author called page "25". This may or may not be a numeric value. For instance, many books use roman numbers for the preface and arab numbers for the rest of the document. In this case, `[pageLabe]="iv"` usually refers to the same page as `[page]="4"`. `[(pageLabel)]="attribute"` updates the attribute each time the user scrolls to another page. If you're only interested in the event, that's `(pageLabelChange)`. | |
181| (pagesLoaded) | undefined | emits the number of pages when a document is loaded; more precisely: emits an instance of `PagesLoadedEvent`. The attribute `pagesCount` tells how many pages the document has. The source attribute contains a reference to the PDF viewer. You can also use this event to detect when a document has been loaded. |
182| (pageRender) | undefined | fires each time a page is about to be rendered. Emits an instance of `PageRenderEvent`. |
183| (pageRendered) | undefined | fires each time a page has finished rendering. Emits an instance of `PageRenderedEvent`. The `pageNumber` attribute tells you which page has been rendered. When you receive this event, you can safely manipulate the page image or the text layer. |
184| pageViewMode | multiple | `pageViewMode="multiple"` is the default PDF viewer. It shows the entire PDF files as a long roll of pages, just as Acrobat reader does. `pageViewMode="single"` only displays one page at a time. You can't scroll to the next page. The only way to navigate to another page is to click on the "next page/previous page" button, enter a page number, jump to the next result of a search, and to click on an entry of the table of contents. |
185| (pdfDownloaded) | undefined | fires when a user downloads a document. Strictly speaking, it fires when they click the "download" button. Caveat: Even if the user cancels the download, the event is fired. |
186| (pdfLoaded) | undefined | emits when the PDF file has been load successfully. The paramter `$event` is an `PdfLoadedEvent`, containing the number of pages of the PDF file. |
187| (pdfLoadingFailed) | undefined | emits when trying to load and open a PDF file has failed. The parameter `$event` is an `Error`, which may or may not contain the stacktrace and additional info about the root cause of the error. |
188| [printResolution] | 150 | set the print resolution in DPI. Sensible values are 300, 600, and maybe even 900. Note that higher values result in more memory consumption, more CPU uses, and may even cause browser crashes. During my tests setting the resolution to 1100 dpi worked, but 1150 failed. In my case, the browser seemed to ignore the print request without displaying any error message. |
189| (progress) | undefined | emits while the PDF file is loading (`type="load"`) or printing (`type="print"`). The parameter `$event` is an object containing the number of bytes loaded, the total number of bytes of the PDF file as well as the percentage of completion. It also contains the type mention before and a reference to the object emitting the event (`source`). Note that the events objects are slightly different between printing and loading. To avoid confusion, check the `type` field of the `ProgressBarEvent` or rely on the field `percent`, which is populated in both cases. . |
190| [showBorders] | true | By default, the PDF file is displayed with page borders. You hide them by setting `[showBorders]="false"`. Note that the page borders can be switched off and on even after the PDF file is diplayed, but if you're using one of the zoom presets (`auto`, `page-width` etc.), the page isn't resized correctly. |
191| [(rotation)] | 0 | [rotation] allows you to rotate every page. Note that this attribute is not responsible to rotate individual pages - it always rotates the entire document. (rotationChange) notifies you when the user rotates the document. This attribute can be used as a two-way binding attribute, i.e. [(rotation)]="angle". Legal values are 0, 90, 180, and 270. Every other value is ignored. |
192| [showBookmarkButton] | true | Show or hide the "bookmark" button |
193| [showDownloadButton] | true | Show or hide the "download" button (aka "save" button) |
194| [showFindButton] | true | Show or hide the "find" button |
195| [showHandToolButton] | false | Show or hide the "hand tool" menu item in the secondary toolbar. (The hand tool allows you to move the page by clicking and dragging). This activates also the opposite menu item: "text selection tool". As a side effect, the hand tool also activates the "text layer". This, in turn, enables marking text and highlighting search result. |
196| [showOpenFileButton] | true | Show or hide the "open file" button |
197| [showPagingButtons] | true | Show or hide the buttons to navigate between pages and the input field to navigate to a particular input field |
198| [showPresentationModeButton] | true | Show or hide the "full screen" button |
199| [showPrintButton] | true | Show or hide the "print" button |
200| [showPropertiesButton] | true | Show or hide the "show document properties" menu item in the secondary toolbar |
201| [showRotateButton] | true | Show or hide the "rotate" menu items in the secondary toolbar |
202| [showScrollingButton] | true | show or hide the button switching between horizontal and vertical scrolling |
203| [showToolbar] | true | Show or hide the toolbar |
204| [showSecondaryToolbarButton] | true | Show or hide the secondary toolbar (the menu hiding behind the arrows at the right-hand side) |
205| [showSelectToolButton] | n/a | This attribute has been removed with version 0.9.47. Use [showHandToolButton] instead. |
206| [showSpreadButton] | true | Show or hide the "spread" menu items in the secondary toolbar. Also see the attribute `[(spread)]` below. |
207| [showUnverifiedSignatures] | false | The base library, pdf.js, does not show signatures for a good reason. Signatures can't be verified (yet), so there's always the danger so show faked signatures, leading the readers to wrong conclusion. So proceed with care. If you insist, ngx-extended-pdf-viewer allows you to display signatures by setting `[showUnverifiedSignatures]="true"`. Note that you also have to disable form support. Also note that ngx-extended-pdf-viewer adds a hint making the reader aware of the potentially falsy signature. |
208| [showZoomButtons] | true | Show or hide the "zoom" area (containing of the buttons "+" and "-" and the dropdown menu) |
209| [(sidebarVisible)] | undefined | Two-way-binding attribute determining whether the sidebar is visible. If you're only interested in the event, the event name is `(sidebarVisibleChange)`. |
210| [(spread)] | off | determines if you're seeing one page or two pages at once (like a paper book). `'off'` means there's only one page. `'odd'` is the traditional book-like view, with two pages side-by-side. `'even'` is similar, only the first page is displayed alone. |
211| [startTabindex] | undefined | By default, the PDF viewer leaves it to the browser to determine the correct tab index. You can set the tab indexes explicitly by setting `[startTabindex]="100"`. Note that there are roughly 40, 50 buttons and menu items. It's a good idea to reserve a range of - say - 100 indexes for the PDF viewer. |
212| textLayer | undefined | allows you to activate or deactivate the text layer. If this flag is set to false, both the "find" button and the "select tool" are hidden. If you don't set this flag explicitely, it's automatically set by `[handTool]` and `[showHandToolButton]`. The text layer is shown by default if and only if `[handTool]="false"` or `[showHandToolButton]="true"`. As a rule of thumb, you always want to activate the text layer unless you run into performance problems. |
213| (textLayerRendered) | undefined | This callback is called when the text layer is rendered. |
214| (updateFindMatchesCount) | undefined | This event is call during a find operation. Note that it can be called hundreds or even thousands of time, due to the asynchronous implementation of the find algorithm. It sends a `FindFindResultMatchesCount`. |
215| (updateFindState) | undefined | This event is called during the find operations. It sends a `FindState`(i.e. `FindState.FOUND`, `FindState.NOT_FOUND`, `FindState.PENDING` or `FindState.WRAPPED`). |
216| useBrowserLocale | false | if true, the PDF viewer assumes the locale files are in the assets folder. If false, you are responsible for providing the translated texts. |
217| [(zoom)] | undefined | `[zoom]="undefined"` (default value): use the zoom level `"auto"`. If not `undefined`: Set the zoom level of the page, no matter which zoom level was previously configured. Legal values are `[zoom]="'auto'"`, `'page-actual'"`, `"'page-fit'"`, `"'page-width'"`, `"50%"`, or `50` (or any other numeric value). Numbers are always considered percentages; the trailing "%" character is optional. This attribute supports two-way binding. `[(zoom)]="zoomAttribute"` updates the variable `zoomAttribute` each time the user changes the zoom setting. This is useful to use the same zoom across multiple PDF viewer instances or PDF document. If you're only interested in the event, that's `(zoomChange)`, described in some more detail below. |
218| [zoomLevels] | undefined | This attribute allows you to use custom zoom levels. It's an array of strings and numbers. The default value is `['auto', 'page-actual', 'page-fit', 'page-width', 0.5, 1, 1.25, 1.5, 2, 3, 4]` |
219| (zoomChange) | undefined | `(zoomChange)` is intended to fire when the user changes the zoom setting. If the zoom setting because of a different reason, such as resizing the window, the event should not fire. That's the difference to `(currentZoomFactor)`, which fires on every zoom event. In practice, it's a bit difficult to distinguish the two types of events, so chances are `(zoomChange)` fires too often or too seldom. However, when it fires, it fires a numeric value, basically the percentage without the percent character. It never fires when the zoom dropdown is set to `[zoom]="'auto'"`, `'page-actual'"`, `"'page-fit'"` or `"'page-width'"`. That also applies if it was the user who changed the dropdown. Putting it in simpler words: the event is not fired if the zoom is a string value. |
220
221## Searching programmatically
222
223The service `NgxExtendedPdfViewerService` allows you to search programmatically. If the PDF viewer hasn't been initialized, or if it has already been destroyed, calling the service results in an error message on the console.
224
225| _method_ | action |
226| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
227| `find(text: string):boolean` | finds a certain text. If the PDF viewer is not initialized, the method returns `false` and prints an error message on the console. |
228| `findNext(): boolean` | finds the next search result. Only call it after calling `find()` first. If the PDF viewer is not initialized, the method returns `false` and prints an error message on the console. |
229| `findPrevious(): boolean` | finds the previous search result. Only call it after calling `find()` first. If the PDF viewer is not initialized, the method returns `false` and prints an error message on the console. |
230
231## Internationalization
232<details>
233 <summary><b>Expand to learn how to translate ngx-extended-pdf-viewer to 120+ languages</b></summary>
234
235
236### Slow default way
237
238If you add the translation files to your project as described above in step 3, the PDF viewer uses the browser language setting to determine which language to load. First, it loads the `locale.properties`, scans it for the desired language files, and loads the language file from the corresponding folder. That's two additional HTTP calls. That's slow, and it may even lead to errors if the network is already congested loading other resource files.
239
240Don't forget to set the attribute `useBrowserLocale="true"` if you follow this approach.
241
242### Slow way with custom translation files
243
244If you want to use the slow way, but prefer to load the language files from a different URL, add a link to your application like so:
245
246```html
247<link rel="resource" type="application/l10n" href="https://www.example.com/locale/locale.properties" />
248```
249
250In this case, don't set `useBrowserLocale` (or set it explicitly to false).
251
252### Inlining (aka embedding) the language files
253
254Alternatively, you can provide the translations as a Json file. This Json file has to be part of an HTML page. That's especially useful if you need only one or two languages, because the are loaded a lot faster. To get familiar with this approach, embed the Json file in the `index.html` like so:
255
256```html
257<script type="application/l10n">
258 {"default_locale":"de","locales":{"de": ... }}
259</script>
260```
261
262The folder `node_modules/ngx-extended-pdf-viewer/assets/inline-locale-files` contains snippet files you can simply copy into your HTML page.
263
264_Hint_: You can also add the language definition in another HTML file. The bottom line is that the HTML snippet is already part of the DOM when the PDF viewer is initialized. Cluttering the root index file with the translations is an ugly and inflexible hack, but it works.
265
266If you're using the "inline" approach, don't set `useBrowserLocale` (or set it explicitly to `false`).
267</details>
268
269## Troubleshooting
270See https://github.com/stephanrauh/ngx-extended-pdf-viewer/tree/main/projects/ngx-extended-pdf-viewer/troubleshooting.md
271
272
273## Feedback, pull requests and bug reports
274
275Pull requests and bug reports are welcome. Please send them to the bug tracker of
276the project page: https://github.com/stephanrauh/ngx-extended-pdf-viewer/issues
277
278## Building the library from scratch (and updating to the latest version of Mozilla's pdf.js)
279
280Have a look at [this walkthrough](https://github.com/stephanrauh/ngx-extended-pdf-viewer/blob/main/projects/ngx-extended-pdf-viewer/how-to-build.md).
281
282## License and Kudos
283The license of the `ngx-extended-pdf-viewer` is the Apache V2 license.
284
285The library is based on https://github.com/mozilla/pdf.js, which has been published under an Apache V2 license.
286
287Some of the default icons have been published under a <a href="http://scripts.sil.org/cms/scripts/page.php?item_id=OFL_web" target="#">SIL Open Font License 1.1</a> license at <a href="https://materialdesignicons.com/" target="#">Material Design Icons</a>. The other icons have either been published under an <a href="https://github.com/google/material-design-icons/blob/main/LICENSE" target="#">Apache V2 license</a> by Google or by the pdf.js team at Mozilla.
288
289Thanks to the awesome pdf.js team and all the users who've reported bugs and even sent me pull requests!
290
291## Internet Explorer 11 is no longer supported
292
293Reluctantly, I have to drop support for Internet Explorer 11. The base library, Mozilla's pdf.js, now generates binaries that are no longer compatible to Internet Explorer 11, and it seems there's no easy fix. That's a pity because IE11 support was the original use-case of the library and because I frequently get messages from developers who need IE11 support. The last version known to be compatible is 5.3. Version 7.3.2 should be compatible, too, but a user reported crashes.
294
295## Breaking changes in version 10.0
296- Version 10.0.0-alpha.11 fixes a bug that made relative URLs almost unpredictable when using the router. Now the `[src]` attribute uses the BASE_HREF of the application as base path. The downside is that probably many projects simply worked around the bug, so their relative URL are broken.
297
298## Breaking changes in version 9.0
299- Version 9.0 updates pdf.js to version 2.9 (default branch) and 2.10 ("bleeding edge" branch). That shouldn't break your application. However, the pdf.js team has been very diligent during the versions 2.8 and 2.9, so it's possible one of the new features break your application.
300
301- I've re-implemented form support. However, it was already broken in version 8, so it's hard to call this a breaking change. The good news: form support with two-way binding works again.
302
303- Version 9.0 drops compatibility to Angular 8 and below. The minimum required version is 9.0. Maybe it also works with Angular 8, but there's no guarantee.
304
305- The library should work with and without Ivy (the new compiler of Angular), but I frequently see a warning concerning Ivy, so I'm not sure yet. If you run into trouble (usually error messages with a greek letter theta), please open an issue.
306
307- I went over the print CSS rules. Now you should be able to print without additional CSS rules. In particular, *remove* this rule because it breaks printing:
308```css
309@media print {
310 #printContainer>div {
311 display: inline; /* must be flex since version 9.0.0 */
312 }
313}
314```
315- The z-indexes in the CSS rules of the PDF viewer have been drastically increased. If you use a z-index to display custom widgets above the PDF viewer, this may be a breaking change.
316- If you omit `[zoom]` or assign `undefined` to it, the user's last choice of the scale factor is used. Before 9.0.0, it was always set to `auto`. Note that this feature only work when the document is initially loaded. If the user loads a document using the upload button of the PDF viewer, the zoom setting isn't changed, even if there's a zoom setting store in `localStorage`.
317- If you omit `[zoom]`, the PDF file is shown roughly half a second later, depending on the PDF file and the network connection. However, at least one user reports the PDF file shows only after a long wait, and sometimes it doesn't show at all. If you run into the same problem, please add your insight at https://github.com/stephanrauh/ngx-extended-pdf-viewer/issues/748. Possible workaround: set `[zoom]` or set `[listenToURL]="true"`.
318- The event `(updateFindMatchesCount)` is now also fired when there's not find result. Before 9.0.0, it only fired when there was at least on find result, so you didn't notice when the user enters a word that's not there.
319## Other potentially breaking changes
320Version 8.0 introduces a few minor CSS changes. If your layout is broken, check the version history of the *.scss files.
321
322Version 7.1. is a pure bug-fix release. It's extremely unlikely, but it might cause difficulties if the PDF viewer is destroyed and immediately re-created. Should you run into this, adding a delay of a single millisecond fixes this (or even a `setTimeout()` without the delay parameter).
323
324Version 7.0 fixes several bugs concerning `[(zoom)]`. Now `(zoom)` also emits the text values ("page-fit", "auto", "page-width", "page-actual"). When you open
325a new PDF document, the old value of `[zoom]` is used for the new document. This was always the intended behavior, but it's possible it breaks applications relying
326on the bugs.
327
328The JavaScript files have been renamed. Now the version number is part of the file name.
329
330Version 7.0 also removes several attributes and methods that have been deprecated a long time ago.
331
332## Changelog
333See https://github.com/stephanrauh/ngx-extended-pdf-viewer/tree/main/projects/ngx-extended-pdf-viewer/changelog.md