Pdf.js: bind javascript events

Created on 5 Mar 2018  路  10Comments  路  Source: mozilla/pdf.js

How can I bind javascript events on this:

https://mozilla.github.io/pdf.js/web/viewer.html

I want to bind events on when it's done rendering and when there is something else being rendered.
Because I want to create pdfjs annotations on top of the rendered pdf file.

Most helpful comment

set "eventBusDispatchToDOM": true in viewer.js why isn't anyone telling this!

All 10 comments

@timvandermeij I am talking about the prebuild version, not from sources.

document.addEventListener("resize",function(){console.log("resize pdfjs!");});
document.addEventListener("pagechanging",function(){console.log("pagechanging pdfjs!");});

this doesn't work

also i see a dom_events.js file which generates the events, how can i use this?

edit:

got it fixed, the events where named 'scalechange' and 'pagechange'!

Thank you & bedankt :D

set "eventBusDispatchToDOM": true in viewer.js why isn't anyone telling this!

@diwakar1911 Thanks!
how do you set this setting?

@issy123 how did you finally solve this? I need to do the same thing (catch events using the prebuild version)

thanks!

I think I changed the event listener names like so:

document.addEventListener("scalechange",function(){console.log("resize pdfjs!");});
document.addEventListener("pagechange",function(){console.log("pagechanging");});

"The eventBusDispatchToDOM option/preference is deprecated, add event listeners to the EventBus instance rather than the DOM."

How do I know when the eventBus will exist? I'm trying to log each event by adding at viewer.js:200 (after the PDFViewerApplication.run() call, which awaits initialize() which awaits _initializeViewerComponents which sets this.eventBus):

  app.PDFViewerApplication.eventBus.addEventListener(
    "documentload",
    function() {
      console.log("documentload fired");
    }
  );

This raises:

viewer.js:200 Uncaught (in promise) TypeError: Cannot read property 'addEventListener' of null at viewer.js:200

I.e., eventBus is (still) null. Am I right thinking the eventBus is in the process of being started up? How do I time attaching my event handlers?

Edit: Following 10718 I tried adding the above to the webviewerloaded event, at viewer.js:200:

      app.PDFViewerApplication.run(config);
      document.addEventListener("webviewerloaded", function() {
        console.log("webviewerloaded event handler called");  // never happens
        window.PDFViewerApplicationOptions.set("disablePreferences", true);
        window.PDFViewerApplicationOptions.set("eventBusDispatchToDOM", true);
        attachEventListeners(window.PDFViewerApplication); // contains viewerApp.eventBus.on("<everyevent>", function() {console.log("<everyevent> fired")});
      });

Following the deprecation MR I tried .on or ._on instead of .addEventListener but if I don't put it in the webviewerloaded event, I get Cannot read property 'addEventListener' of null, which I think means eventBus is null, even though initialize should have assigned it. If I create a webviewerloaded event handler, it is never called, including if I put the above code before app.PDFViewerApplication.run(config);.

I have the deprecated method working.

I added above the run call at viewer.js 199:

      window.PDFViewerApplicationOptions.set("disablePreferences", true);
      window.PDFViewerApplicationOptions.set("eventBusDispatchToDOM", true);
      attachEventListeners();
      app.PDFViewerApplication.run(config);  // original code https://github.com/mozilla/pdf.js/blob/master/web/viewer.js#L199

Then attachEventListeners just attaches to the global events:

function attachEventListeners() {
  console.log("attachEventListeners called");
  document.addEventListener("documentload", function() {
    console.log("documentload fired");
  });
  document.addEventListener("pagerendered", function() {
    console.log("pagerendered fired");
  });
  document.addEventListener("textlayerrendered", function() {
    console.log("textlayerrendered fired");
  });
  document.addEventListener("pagechange", function() {
    console.log("pagechange fired");
  });
  document.addEventListener("pagesinit", function() {
    console.log("pagesinit fired");
  });
  document.addEventListener("pagesloaded", function() {
    console.log("pagesloaded fired");
  });
  document.addEventListener("scalechange", function() {
    console.log("scalechange fired");
  });
  document.addEventListener("updateviewarea", function() {
    console.log("updateviewarea fired");
  });
  document.addEventListener("find", function() {
    console.log("find fired");
  });
  document.addEventListener("attachmentsloaded", function() {
    console.log("attachmentsloaded fired");
  });
  document.addEventListener("sidebarviewchanged", function() {
    console.log("sidebarviewchanged fired");
  });
  document.addEventListener("pagemode", function() {
    console.log("pagemode fired");
  });
  document.addEventListener("namedaction", function() {
    console.log("namedaction fired");
  });
  document.addEventListener("presentationmodechanged", function() {
    console.log("presentationmodechanged fired");
  });
  document.addEventListener("outlineloaded", function() {
    console.log("outlineloaded fired");
  });
}

I would still love to do this properly using the eventBus, if anyone has any ideas, as I'll be building this out substantially.

Regarding https://github.com/mozilla/pdf.js/issues/9527#issuecomment-604157830, please see the first section of https://github.com/mozilla/pdf.js/wiki/Third-party-viewer-usage for the correct way of waiting for the viewer to load/initialize; hence waiting for e.g. the "documentloaded" event is done like so:

document.addEventListener("webviewerloaded", function() {
  PDFViewerApplication.initializedPromise.then(function() {
    PDFViewerApplication.eventBus.on("documentloaded", function(event) {
      console.log("The document has now been loaded");
    });
  });
});

Enormous thanks @Snuffleupagus and sorry I have corrected a typo in my comment.

If I add your code above (or below) the app.PDFViewerApplication.run(config) call the webviewerloaded event handler is never called.

My theory is that if I search across the repo for webviewerloaded the only match is viewer.js#L214, so it seems to be raised if and only if PDFJSDev.test("PRODUCTION") && PDFJSDev.test("GENERIC") and on my development machine I am running the !PDFJSDev.test("PRODUCTION") branch of that if statement. Should the webviewerloaded event be raised in !PRODUCTION && GENERIC environments too?

I can now attach events via the eventBus with the code:

function webViewerLoad() {
  const config = getViewerConfiguration();
  if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("PRODUCTION")) {
    Promise.all([
      SystemJS.import("pdfjs-web/app.js"),
      SystemJS.import("pdfjs-web/app_options.js"),
      SystemJS.import("pdfjs-web/genericcom.js"),
      SystemJS.import("pdfjs-web/pdf_print_service.js"),
    ]).then(function([app, appOptions, ...otherModules]) {
      window.PDFViewerApplication = app.PDFViewerApplication;
      window.PDFViewerApplicationOptions = appOptions.AppOptions;
      // *** From here ***
      window.PDFViewerApplication.initializedPromise.then(function() {
        console.log("initializedPromise.then called");
        attachEventListeners(window.PDFViewerApplication);
        window.PDFViewerApplication.eventBus.on("documenloaded", function(event) {
          console.log("The document has now been loaded", event);
        });
      });
      // *** To here ***
      app.PDFViewerApplication.run(config);
    });
  } else {
  ...

My attachEventListeners method is now:

function attachEventListeners(viewerApp) {
  viewerApp.eventBus.on("documentload", function(evt) {
    console.log("documentload fired", evt); // deleted `evt` from the trace below
  });
  ...

However the documentloaded event is never called. The list of events I see of those in the attachEventListeners method above (all events in 'dom_events.js'), is as follows:

initializedPromise.then called
viewer.js:189 attachEventListeners called, app: [object Object]
app.js:1465 {initialBookmark: "", _initializedCapability: {鈥, fellback: false, appConfig: {鈥, pdfDocument: null,聽鈥
viewer.js:203 pagesinit fired
viewer.js:221 sidebarviewchanged fired
viewer.js:212 updateviewarea fired
app.js:2327 PDF 110dd61fd57444010b1ab5ff38782f0f [1.4 pdfeTeX-1.21a / TeX] (PDF.js: -)
viewer.js:212 updateviewarea fired
viewer.js:194 pagerendered fired
viewer.js:233 outlineloaded fired
viewer.js:218 attachmentsloaded fired
viewer.js:206 pagesloaded fired
viewer.js:212 updateviewarea fired
viewer.js:197 textlayerrendered fired
viewer.js:194 pagerendered fired
viewer.js:197 textlayerrendered fired
viewer.js:194 pagerendered fired
viewer.js:197 textlayerrendered fired

I will mainly be using the textlayerrendered event, so this is not an issue for me, but keen to contribute, e.g., let me know if a PR raising the custom webviewerloaded in the non-PROD GENERIC branch, above the run call would be useful. Either way, huge thanks for taking the time to help me @Snuffleupagus.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

BadFriend picture BadFriend  路  38Comments

syssgx picture syssgx  路  29Comments

kaymes picture kaymes  路  62Comments

Rob--W picture Rob--W  路  43Comments

AliND picture AliND  路  29Comments