stephanrauh / ngx-extended-pdf-viewer

A full-blown PDF viewer for Angular 16, 17, and beyond
https://pdfviewer.net
Apache License 2.0
491 stars 184 forks source link

Problem using ngx-extended-pdf-viewer with a AMD Loader #1427

Closed gmaggiodev closed 2 years ago

gmaggiodev commented 2 years ago

The ngx-extended-pdf-viewer fail to load the pdf.js viewer when the browser has previously loaded a AMD Loader (for example the loader.js of visual studio code - monaco editor).

Infact, the loadViewer code bases its functioning on this condition:

loadViewer() {
        window['ngxZone'] = this.ngZone;
        this.ngZone.runOutsideAngular(() => {
            if (!window['pdfjs-dist/build/pdf']) {     // <----- THIS condition is always true when using AMD Loader so loop infinitly
                setTimeout(() => this.loadViewer(), 25);
            }
            else {
                this.needsES5().then((needsES5) => {
                    const viewerPath = this.getPdfJsPath('viewer', needsES5);
                    const script = this.createScriptElement(viewerPath);
                    // script.onload = async () => await this.addFeatures(); // DEBUG CODE!!!
                    document.getElementsByTagName('head')[0].appendChild(script);
                });
            }
        });
    }

But the code in pdf-2.15.350.js define the module is several ways depending on browser capabilities:

(function webpackUniversalModuleDefinition(root, factory) {
    if(typeof exports === 'object' && typeof module === 'object')
        module.exports = factory();
    else if(typeof define === 'function' && define.amd)
        define("pdfjs-dist/build/pdf", [], factory);
    else if(typeof exports === 'object')
        exports["pdfjs-dist/build/pdf"] = factory();    // <---- ONLY THIS CASE is covered by ngx-extended-pdf-viewer
    else
        root["pdfjs-dist/build/pdf"] = root.pdfjsLib = factory();
})(globalThis, () => {

This is exactly the same reason why is not possible to use your component into stackblitz (because stackblitz use amd loader).

IMHO I think you should base the loadviewer logic on a more generic check.

Version info

Desktop (please complete the following information):

To Reproduce You can use this repo to reproduce the problem https://github.com/gmaggiodev/ngx-extended-pdf-viewer-bug-amdloader.git

In the index.html there is a line to load the loader.js (from microsoft). Comment this line to see the viewer working (without amd loader).

stephanrauh commented 2 years ago

I've implemented a solution. Please run a test and confirm it solves your issue.

BTW: I'm not 100% AMD modules play well with the new sandboxed JavaScript engine.