Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make logic for waiting for PDFs to load work in PDF.js >= 2.5.207 #2641

Merged
merged 1 commit into from
Oct 16, 2020

Conversation

robertknight
Copy link
Member

@robertknight robertknight commented Oct 14, 2020

f96af43 added support for PDF.js >= v2.5.207 by changing an event
listener to use PDF.js's internal event bus rather than DOM events.
However there was another DOM event listener for the pagesloaded event
in src/annotator/anchoring/pdf.js that should also have been updated but was
overlooked. This didn't cause a problem in testing with the dev server because
the test documents load quickly enough that they are already loaded by the time
the client's anchoring logic ran.

This commit updates the way that the client listens for events from
PDF.js to use the event bus where available and only fall back to the
DOM in versions of PDF.js that don't support it.

  • Use PDF.js's event bus to listen for documentload/documentloaded
    and pagesloaded events

  • Add a fallback method to wait for event bus to become available in
    versions of PDF.js which support the eventBus but don't have the
    initializedPromise API

  • Improve the documentation around which versions of PDF.js support
    different event types and event dispatch methods

  • Add tests to cover the behavior from different releases of PDF.js

For an overview of the different versions of PDF.js that the client
needs to support, see #2643.


TODO

  • Re-test manually in 1) the version of Hypothesis that ships with the dev server, 2) the version that ships with Via and 3) the v1.1.114 release that shipped with https://github.com/hypothesis/pdf.js-hypothes.is until November 2019
  • Add tests to cover fallback paths that wait for PDF viewer to be initialized

@codecov
Copy link

codecov bot commented Oct 14, 2020

Codecov Report

Merging #2641 into master will increase coverage by 0.00%.
The diff coverage is 100.00%.

Impacted file tree graph

@@           Coverage Diff           @@
##           master    #2641   +/-   ##
=======================================
  Coverage   97.39%   97.40%           
=======================================
  Files         200      200           
  Lines        7487     7503   +16     
  Branches     1646     1653    +7     
=======================================
+ Hits         7292     7308   +16     
  Misses        195      195           
Impacted Files Coverage Δ
src/annotator/anchoring/pdf.js 99.41% <100.00%> (+0.01%) ⬆️
src/annotator/plugin/pdf-metadata.js 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update da788da...5da3feb. Read the comment docs.

@robertknight robertknight force-pushed the fix-pagesloaded-event-handler branch 2 times, most recently from d01872f to 20c5d97 Compare October 15, 2020 10:32
Copy link
Contributor

@lyzadanger lyzadanger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not going to pretend this is straightforward :), but your commenting will go a long ways toward making this feasible to maintain for future devs!

app.eventBus?.off('documentloaded', finish);
this._loaded = pdfViewerInitialized(app).then(() => {
// Check if document has already loaded.
if (app.downloadComplete) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any version difference here? Or is downloadComplete relevant to all of our supported versions of PDFjs?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not aware of any version differences with downloadComplete, but I also haven't looked closely. This code was just taken from the previous version of this file.


// `documentloaded` is the preferred event in PDF.js >= v2.0.943.
// See https://github.com/mozilla/pdf.js/commit/7bc4bfcc8b7f52b14107f0a551becdf01643c5c2
app.eventBus.on('documentloaded', finish);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two event names make me cringe...

window.addEventListener('documentload', finish);
}
if (app.eventBus) {
// PDF.js >= v1.6.210 dispatch events via an internal event bus.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent commenting, thank you.

// See https://github.com/mozilla/pdf.js/commit/7bc4bfcc8b7f52b14107f0a551becdf01643c5c2
app.eventBus.on('documentloaded', finish);

// `documentload` is dispatched by PDF.js < v2.1.266.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is its meaning different from documentloaded? Or was it literally just Very Slightly Renamed (arghghgh)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is just renamed AFAIK. I haven't checked what the payloads of the events are, but we don't use them anyway.

@@ -42,23 +42,42 @@ class FakePDFViewerApplication {
/**
* Initialize the "PDF viewer" as it would be when loading a document or
* when a document fails to load.
*
* @param {string} url - Fake PDF URL
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much for adding these thorough comments. This could be crazymaking in the future without them.

@@ -110,22 +129,32 @@ function delay(ms) {
describe('annotator/plugin/pdf-metadata', function () {
[
{
// Oldest PDF.js versions (pre-2.x)
// PDF.js < 1.6.210: `documentload` event dispatched via DOM.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, we'd be at sea later on without these comments, so thank you!

@@ -75,10 +75,20 @@ async function getPageView(pageIndex) {
// a "pdfPage" property.
pageView = await new Promise(resolve => {
const onPagesLoaded = () => {
document.removeEventListener('pagesloaded', onPagesLoaded);
if (pdfViewer.eventBus) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps drop some of those snazzy comments about versions in here for later reference?

f96af43 added support for PDF.js >= v2.5.207 by changing an event
listener to use PDF.js's internal event bus rather than DOM events.
However there was another DOM event listener for the `pagesloaded` event
in `src/annotator/anchoring/pdf.js` that should also have been updated but was
overlooked. This didn't cause a problem in testing with the dev server because
the test documents load quickly enough that they are already loaded by the time
the client's anchoring logic ran.

This commit updates the way that the client listens for events from
PDF.js to use the event bus where available and only fall back to the
DOM in versions of PDF.js that don't support it.

 - Use PDF.js's event bus to listen for `documentload`/`documentloaded`
   and `pagesloaded` events

 - Add a fallback method to wait for event bus to become available in
   versions of PDF.js which support the eventBus but don't have the
   `initializedPromise` API

 - Improve the documentation around which versions of PDF.js support
   different event types and event dispatch methods

 - Add tests to cover the behavior from different releases of PDF.js

For an overview of the different versions of PDF.js that the client
needs to support, see #2643.
@robertknight robertknight marked this pull request as ready for review October 16, 2020 13:21
@robertknight
Copy link
Member Author

I agreed with Lyza yesterday that this was good to merge once the missing tests were added.

@robertknight robertknight merged commit 77d3023 into master Oct 16, 2020
@robertknight robertknight deleted the fix-pagesloaded-event-handler branch October 16, 2020 13:23
robertknight added a commit to hypothesis/browser-extension that referenced this pull request Sep 17, 2021
 - Remove the `eventBusDispatchToDOM` option, as the client now watches
   for these events on the event bus. See [1].
 - Use `PDFViewerApplication.initializedPromise` to simplify waiting for
   app to load. This was added in PDF.js v2.10.377. See [2].

[1] hypothesis/client#2641
[2] mozilla/pdf.js#11607
robertknight added a commit to hypothesis/browser-extension that referenced this pull request Sep 20, 2021
 - Remove the `eventBusDispatchToDOM` option, as the client now watches
   for these events on the event bus. See [1].
 - Use `PDFViewerApplication.initializedPromise` to simplify waiting for
   app to load. This was added in PDF.js v2.10.377. See [2].

[1] hypothesis/client#2641
[2] mozilla/pdf.js#11607
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants