From 20d6286cceb936dfcb334ac1c963cf93c0da3637 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Wed, 19 Jul 2017 16:26:17 +0200 Subject: [PATCH] Add support for, the API property, PageMode in the viewer (issue 8657) Note that the PageMode, as specified in the API, will only be honoured when either: the user hasn't set the `sidebarViewOnLoad` preference to a non-default value, or a non-default `sidebarView` entry doesn't exist in the view history, or the "pagemode" hash parameter is included in the URL. Since this is new functionality, the patch also includes a preference (`disablePageMode`), to make it easy to opt-out of this functionality if the user/implementor so wishes. --- extensions/chromium/preferences_schema.json | 4 ++ web/app.js | 42 ++++++++++++++++++++- web/default_preferences.json | 1 + 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/extensions/chromium/preferences_schema.json b/extensions/chromium/preferences_schema.json index 0371a9cf9..16cf475eb 100644 --- a/extensions/chromium/preferences_schema.json +++ b/extensions/chromium/preferences_schema.json @@ -102,6 +102,10 @@ "type": "boolean", "default": false }, + "disablePageMode": { + "type": "boolean", + "default": false + }, "disableTelemetry": { "title": "Disable telemetry", "type": "boolean", diff --git a/web/app.js b/web/app.js index 7b8cfc64a..7c7ee1fdf 100644 --- a/web/app.js +++ b/web/app.js @@ -141,6 +141,7 @@ let PDFViewerApplication = { pdfBugEnabled: false, showPreviousViewOnLoad: true, defaultZoomValue: '', + disablePageMode: false, disablePageLabels: false, renderer: 'canvas', enhanceTextSelection: false, @@ -255,6 +256,9 @@ let PDFViewerApplication = { preferences.get('renderInteractiveForms').then(function resolved(value) { viewerPrefs['renderInteractiveForms'] = value; }), + preferences.get('disablePageMode').then(function resolved(value) { + viewerPrefs['disablePageMode'] = value; + }), preferences.get('disablePageLabels').then(function resolved(value) { viewerPrefs['disablePageLabels'] = value; }), @@ -883,6 +887,11 @@ let PDFViewerApplication = { }); }); + // Since the `setInitialView` call below depends on this being resolved, + // fetch it early to avoid delaying initial rendering of the PDF document. + let pageModePromise = pdfDocument.getPageMode().catch( + function() { /* Avoid breaking initial rendering; ignoring errors. */ }); + this.toolbar.setPagesCount(pdfDocument.numPages, false); this.secondaryToolbar.setPagesCount(pdfDocument.numPages); @@ -939,9 +948,10 @@ let PDFViewerApplication = { scrollLeft: '0', scrollTop: '0', sidebarView: SidebarView.NONE, - }).catch(() => { /* Unable to read from storage -- ignoring errors. */ }); + }).catch(() => { /* Unable to read from storage; ignoring errors. */ }); - storePromise.then((values = {}) => { + Promise.all([storePromise, pageModePromise]).then( + ([values = {}, pageMode]) => { // Initialize the default values, from user preferences. let hash = this.viewerPrefs['defaultZoomValue'] ? ('zoom=' + this.viewerPrefs['defaultZoomValue']) : null; @@ -953,6 +963,10 @@ let PDFViewerApplication = { ',' + values.scrollLeft + ',' + values.scrollTop; sidebarView = sidebarView || (values.sidebarView | 0); } + if (pageMode && !this.viewerPrefs['disablePageMode']) { + // Always let the user preference/history take precedence. + sidebarView = sidebarView || apiPageModeToSidebarView(pageMode); + } return { hash, sidebarView, @@ -2290,6 +2304,30 @@ function webViewerKeyDown(evt) { } } +/** + * Converts API PageMode values to the format used by `PDFSidebar`. + * NOTE: There's also a "FullScreen" parameter which is not possible to support, + * since the Fullscreen API used in browsers requires that entering + * fullscreen mode only occurs as a result of a user-initiated event. + * @param {string} mode - The API PageMode value. + * @returns {number} A value from {SidebarView}. + */ +function apiPageModeToSidebarView(mode) { + switch (mode) { + case 'UseNone': + return SidebarView.NONE; + case 'UseThumbs': + return SidebarView.THUMBS; + case 'UseOutlines': + return SidebarView.OUTLINE; + case 'UseAttachments': + return SidebarView.ATTACHMENTS; + case 'UseOC': + // Not implemented, since we don't support Optional Content Groups yet. + } + return SidebarView.NONE; // Default value. +} + /* Abstract factory for the print service. */ let PDFPrintServiceFactory = { instance: { diff --git a/web/default_preferences.json b/web/default_preferences.json index 73b315bff..425de07c3 100644 --- a/web/default_preferences.json +++ b/web/default_preferences.json @@ -17,5 +17,6 @@ "renderer": "canvas", "renderInteractiveForms": false, "enablePrintAutoRotate": false, + "disablePageMode": false, "disablePageLabels": false }