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

Convert the overlay manager to ES6 syntax #8450

Merged
merged 1 commit into from
May 28, 2017

Conversation

timvandermeij
Copy link
Contributor

@timvandermeij timvandermeij commented May 26, 2017

This pull request is a redo of #8119.

You can test that the web/chromecom.js change works using the steps from #6233. The other overlays (document properties, password prompt and print) can be tested using the viewer itself. For convenience, you can use http://async5.org/moz/passwordOU.pdf (password: 123456) to test the password prompt.

Copy link
Collaborator

@Snuffleupagus Snuffleupagus left a comment

Choose a reason for hiding this comment

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

Note that I've not actually tested this yet, but generally it looks good!
However, I'm adding a couple of smaller comments based on a quick look at the code.

web/app.js Outdated
this.pdfDocumentProperties =
new PDFDocumentProperties(appConfig.documentProperties);
new PDFDocumentProperties(documentPropertiesConfig);
Copy link
Collaborator

Choose a reason for hiding this comment

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

What you could perhaps do instead (here and elsewhere in the patch), to avoid adding even more of these hacks, is something similar to what PR #8394 does; see https://github.com/mozilla/pdf.js/pull/8394/files#diff-529d1853ee1bba753a0fcb40ea778723R372.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea! Done in the new commit.

web/app.js Outdated
@@ -119,6 +119,9 @@ var PDFViewerApplication = {
store: null,
/** @type {DownloadManager} */
downloadManager: null,
/** @type {OverlayManager} */
// TODO: move initialization to `_initializeViewerComponents` if possible
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: missing a period at the end.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in the new commit.

web/chromecom.js Outdated
*/
ChromeCom.resolvePDFFile = function ChromeCom_resolvePDFFile(file, callback) {
ChromeCom.resolvePDFFile =
function ChromeCom_resolvePDFFile(file, overlayManager, callback) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This fits on one line if you just use:
ChromeCom.resolvePDFFile = function(file, overlayManager, callback) {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in the new commit.

web/chromecom.js Outdated
var appConfig = PDFViewerApplication.appConfig;
ChromeCom.resolvePDFFile(appConfig.defaultUrl,
let appConfig = PDFViewerApplication.appConfig;
let overlayManager = PDFViewerApplication.overlayManager;
Copy link
Collaborator

Choose a reason for hiding this comment

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

This can be let { appConfig, overlayManager, } = PDFViewerApplication; instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in the new commit.

var OverlayManager = {
overlays: {},
active: null,
const ESC_KEYCODE = 27;
Copy link
Collaborator

@Snuffleupagus Snuffleupagus May 26, 2017

Choose a reason for hiding this comment

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

I'm not sure that adding this as a constant really brings much value; it's not like the keycode of Esc is ever going to change!?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think that's exactly the reason why it should be a constant, both for readability and because it does not change. However, I can see that that is a personal choice, so I reverted the change in the new commit.

@timvandermeij
Copy link
Contributor Author

/botio-linux preview

@Snuffleupagus
Copy link
Collaborator

Snuffleupagus commented May 27, 2017

I left a TODO for the initialization of the overlay manager. We cannot move that (yet) because the viewer is usually not yet initialized when e.g., web/chromecom.js needs it.

Looking at the code, I'm cannot help wondering if this problem wasn't limited to the prior PR, but actually isn't an issue any more in this PR!?
In this patch, you're now accessing PDFViewerApplication.overlayManager from inside of the externalServices.initPassiveLoading function. So tracing through the code pertaining to the CHROME build target, this is what I see:

  1. externalServices.initPassiveLoading is called from https://github.com/mozilla/pdf.js/blob/master/web/app.js#L484, within the PDFViewerApplication.initPassiveLoading method (see https://github.com/mozilla/pdf.js/blob/master/web/app.js#L481).
  2. PDFViewerApplication.initPassiveLoading is called from https://github.com/mozilla/pdf.js/blob/master/web/app.js#L1523, which is inside of the webViewerOpenFileViaURL function (see https://github.com/mozilla/pdf.js/blob/master/web/app.js#L1493).
  3. webViewerOpenFileViaURL is called from https://github.com/mozilla/pdf.js/blob/master/web/app.js#L1486, which is the last thing that webViewerInitialized does (see https://github.com/mozilla/pdf.js/blob/master/web/app.js#L1344).
  4. webViewerInitialized is called from https://github.com/mozilla/pdf.js/blob/master/web/app.js#L392, once the PDFViewerApplication.initialize method has resolved.
  5. PDFViewerApplication.initialize (see https://github.com/mozilla/pdf.js/blob/master/web/app.js#L149), will resolve only once PDFViewerApplication._initializeViewerComponents has successfully been run, see https://github.com/mozilla/pdf.js/blob/master/web/app.js#L156.
  6. Finally, note how ChromeExternalServices.initPassiveLoading accesses PDFViewerApplication.appConfig in https://github.com/mozilla/pdf.js/blob/master/web/chromecom.js#L341. Unless the current code is broken, we can thus at the very least be sure that regardless of all of the above, we've reached line https://github.com/mozilla/pdf.js/blob/master/web/app.js#L153 when initPassiveLoading is called.

Unless I've made some sort of fundamental error in the analysis above, it should be possible to place the this.overlayManager = new OverlayManager(); call after line

this.appConfig = appConfig;
instead.
Edit: It could probably be placed in _initializeViewerComponents too, but let's be a bit defensive here!

Edit2: D'oh, but the actual issue would now probably be in pdf_print_service.js rather than in chromecom.js; I completely missed this :-(
However, we might be able to get around that by just defining let overlayManager = null; at https://github.com/mozilla/pdf.js/pull/8450/files#diff-8d1ea0bdf9b33774c7895b5fb752f6a8R21, and then adding overlayManager = PDFViewerApplication.overlayManager; before line https://github.com/mozilla/pdf.js/pull/8450/files#diff-8d1ea0bdf9b33774c7895b5fb752f6a8R313.

This obviously assumes that the PDFPrintService isn't initialized before the viewer itself somehow, but looking through the logic in PDFViewerApplication.beforePrint (see https://github.com/mozilla/pdf.js/blob/master/web/app.js#L1138) I think it should be fine!

@timvandermeij
Copy link
Contributor Author

You're absolutely right! Everything works as expected with the changes you described. Here is the interdiff of the change:

diff --git a/web/app.js b/web/app.js
index 58653bfe..0b99c732 100644
--- a/web/app.js
+++ b/web/app.js
@@ -120,8 +120,7 @@ var PDFViewerApplication = {
   /** @type {DownloadManager} */
   downloadManager: null,
   /** @type {OverlayManager} */
-  // TODO: Move initialization to `_initializeViewerComponents` when possible.
-  overlayManager: new OverlayManager(),
+  overlayManager: null,
   /** @type {Preferences} */
   preferences: null,
   /** @type {Toolbar} */
@@ -264,6 +263,8 @@ var PDFViewerApplication = {
     let appConfig = this.appConfig;
 
     return new Promise((resolve, reject) => {
+      this.overlayManager = new OverlayManager();
+
       let eventBus = appConfig.eventBus || getGlobalEventBus();
       this.eventBus = eventBus;
 
diff --git a/web/pdf_print_service.js b/web/pdf_print_service.js
index 3b44da12..dde9d447 100644
--- a/web/pdf_print_service.js
+++ b/web/pdf_print_service.js
@@ -18,7 +18,7 @@ import { PDFPrintServiceFactory, PDFViewerApplication } from './app';
 import { PDFJS } from './pdfjs';
 
 let activeService = null;
-let overlayManager = PDFViewerApplication.overlayManager;
+let overlayManager = null;
 
 // Renders the page to the canvas of the given print service, and returns
 // the suggested dimensions of the output page.
@@ -310,6 +310,7 @@ if ('onbeforeprint' in window) {
 var overlayPromise;
 function ensureOverlay() {
   if (!overlayPromise) {
+    overlayManager = PDFViewerApplication.overlayManager;
     overlayPromise = overlayManager.register('printServiceOverlay',
       document.getElementById('printServiceOverlay'), abort, true);
     document.getElementById('printCancel').onclick = abort;

@timvandermeij
Copy link
Contributor Author

/botio-linux preview

Copy link
Collaborator

@Snuffleupagus Snuffleupagus left a comment

Choose a reason for hiding this comment

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

I've tested all the current overlays (document properties, password prompt, printing, Chrome local file access), and everything still works as it should :-)

However, looking through pdf_print_service.js one last time, there's a couple of cases where we may want to pro-actively avoid possible, but very unlikely, errors.

Aside from that, this looks great; thank you for persisting with the class conversion of the OverlayManager!

@@ -310,7 +310,8 @@ if ('onbeforeprint' in window) {
var overlayPromise;
function ensureOverlay() {
if (!overlayPromise) {
overlayPromise = OverlayManager.register('printServiceOverlay',
overlayManager = PDFViewerApplication.overlayManager;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Given that this file binds itself to window.print, I'm wondering if there's any way that a user might be able to trigger printing before PDFViewerApplication is completely initialized?

I've not been successful in triggering this myself; but we might want to add an additional check here just for good measure, to avoid an uncaught Error if the overlayManager isn't defined yet!? Something like this, perhaps:

if (!overlayManager) {
  throw new Error('OverlayManager not initialized.'); // Might need a better error message...
}  

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have not been able to trigger that as well, but for safety I added this check in the new commit.

@@ -217,8 +217,8 @@ window.print = function print() {
} finally {
if (!activeService) {
console.error('Expected print service to be initialized.');
if (OverlayManager.active === 'printServiceOverlay') {
OverlayManager.close('printServiceOverlay');
if (overlayManager.active === 'printServiceOverlay') {
Copy link
Collaborator

@Snuffleupagus Snuffleupagus May 27, 2017

Choose a reason for hiding this comment

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

In line with the comment below, and the existing code in PDFPrintService.destroy, we might want change this to the follow instead (to avoid an unlikely uncaught Error):

ensureOverlay().then(function () {
  if (overlayManager.active !== 'printServiceOverlay') {
    return; // overlay was already closed
  }
  overlayManager.close('printServiceOverlay');
});

Note: I'd actually consider this a pre-existing issue with the code!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Indeed, ensureOverlay should have been there. I added it in the new commit.

@timvandermeij
Copy link
Contributor Author

/botio-linux preview

@timvandermeij
Copy link
Contributor Author

/botio-linux preview

@pdfjsbot
Copy link

From: Bot.io (Linux m4)


Received

Command cmd_preview from @timvandermeij received. Current queue size: 0

Live output at: http://54.67.70.0:8877/ee74696060bee42/output.txt

@pdfjsbot
Copy link

From: Bot.io (Linux m4)


Success

Full output at http://54.67.70.0:8877/ee74696060bee42/output.txt

Total script time: 2.02 mins

Published

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants