From 313060aff55cd2c228a082d27a7d43911dc9c040 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Mon, 27 Mar 2017 23:37:14 +0200 Subject: [PATCH 1/3] Refactor the `DownloadManager` initialization in `GENERIC`/`CHROME` builds, to avoid issues when converting the code to ES6 modules --- web/app.js | 16 ++++++++-------- web/chromecom.js | 4 ++-- web/download_manager.js | 25 ++++++++++++++++++------- web/viewer.js | 4 +++- 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/web/app.js b/web/app.js index e33807222..a6d59b061 100644 --- a/web/app.js +++ b/web/app.js @@ -19,7 +19,7 @@ (function (root, factory) { if (typeof define === 'function' && define.amd) { define('pdfjs-web/app', ['exports', 'pdfjs-web/ui_utils', - 'pdfjs-web/download_manager', 'pdfjs-web/pdf_history', + 'pdfjs-web/pdf_history', 'pdfjs-web/preferences', 'pdfjs-web/pdf_sidebar', 'pdfjs-web/view_history', 'pdfjs-web/pdf_thumbnail_viewer', 'pdfjs-web/toolbar', 'pdfjs-web/secondary_toolbar', @@ -32,7 +32,7 @@ 'pdfjs-web/dom_events', 'pdfjs-web/pdfjs'], factory); } else if (typeof exports !== 'undefined') { - factory(exports, require('./ui_utils.js'), require('./download_manager.js'), + factory(exports, require('./ui_utils.js'), require('./pdf_history.js'), require('./preferences.js'), require('./pdf_sidebar.js'), require('./view_history.js'), require('./pdf_thumbnail_viewer.js'), require('./toolbar.js'), @@ -46,7 +46,7 @@ require('./dom_events.js'), require('./pdfjs.js')); } else { factory((root.pdfjsWebApp = {}), root.pdfjsWebUIUtils, - root.pdfjsWebDownloadManager, root.pdfjsWebPDFHistory, + root.pdfjsWebPDFHistory, root.pdfjsWebPreferences, root.pdfjsWebPDFSidebar, root.pdfjsWebViewHistory, root.pdfjsWebPDFThumbnailViewer, root.pdfjsWebToolbar, root.pdfjsWebSecondaryToolbar, @@ -58,7 +58,7 @@ root.pdfjsWebPDFFindController, root.pdfjsWebPDFFindBar, root.pdfjsWebDOMEvents, root.pdfjsWebPDFJS); } -}(this, function (exports, uiUtilsLib, downloadManagerLib, pdfHistoryLib, +}(this, function (exports, uiUtilsLib, pdfHistoryLib, preferencesLib, pdfSidebarLib, viewHistoryLib, pdfThumbnailViewerLib, toolbarLib, secondaryToolbarLib, passwordPromptLib, pdfPresentationModeLib, @@ -124,13 +124,13 @@ function configure(PDFJS) { } } -var DefaultExernalServices = { +var DefaultExternalServices = { updateFindControlState: function (data) {}, initPassiveLoading: function (callbacks) {}, fallback: function (data, callback) {}, reportTelemetry: function (data) {}, createDownloadManager: function () { - return new downloadManagerLib.DownloadManager(); + throw new Error('Not implemented: createDownloadManager'); }, supportsIntegratedFind: false, supportsDocumentFonts: true, @@ -196,7 +196,7 @@ var PDFViewerApplication = { isViewerEmbedded: (window.parent !== window), url: '', baseUrl: '', - externalServices: DefaultExernalServices, + externalServices: DefaultExternalServices, // called once when the document is loaded initialize: function pdfViewInitialize(appConfig) { @@ -2270,6 +2270,6 @@ var PDFPrintServiceFactory = { }; exports.PDFViewerApplication = PDFViewerApplication; -exports.DefaultExernalServices = DefaultExernalServices; +exports.DefaultExternalServices = DefaultExternalServices; exports.PDFPrintServiceFactory = PDFPrintServiceFactory; })); diff --git a/web/chromecom.js b/web/chromecom.js index 902052cb4..27c91dc18 100644 --- a/web/chromecom.js +++ b/web/chromecom.js @@ -36,7 +36,7 @@ } var PDFViewerApplication = app.PDFViewerApplication; - var DefaultExernalServices = app.DefaultExernalServices; + var DefaultExternalServices = app.DefaultExternalServices; var OverlayManager = overlayManager.OverlayManager; var Preferences = preferences.Preferences; @@ -349,7 +349,7 @@ }); }; - var ChromeExternalServices = Object.create(DefaultExernalServices); + var ChromeExternalServices = Object.create(DefaultExternalServices); ChromeExternalServices.initPassiveLoading = function (callbacks) { var appConfig = PDFViewerApplication.appConfig; ChromeCom.resolvePDFFile(appConfig.defaultUrl, diff --git a/web/download_manager.js b/web/download_manager.js index 87e29544d..a489899b4 100644 --- a/web/download_manager.js +++ b/web/download_manager.js @@ -17,18 +17,23 @@ (function (root, factory) { if (typeof define === 'function' && define.amd) { - define('pdfjs-web/download_manager', ['exports', 'pdfjs-web/pdfjs'], - factory); + define('pdfjs-web/download_manager', ['exports', 'pdfjs-web/app', + 'pdfjs-web/pdfjs'], factory); } else if (typeof exports !== 'undefined') { - factory(exports, require('./pdfjs.js')); + factory(exports, require('./app.js'), require('./pdfjs.js')); } else { - factory((root.pdfjsWebDownloadManager = {}), root.pdfjsWebPDFJS); + factory((root.pdfjsWebDownloadManager = {}), root.pdfjsWebApp, + root.pdfjsWebPDFJS); } -}(this, function (exports, pdfjsLib) { -if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('FIREFOX || MOZCENTRAL')) { - return; +}(this, function (exports, app, pdfjsLib) { +if (typeof PDFJSDev !== 'undefined' && !PDFJSDev.test('CHROME || GENERIC')) { + throw new Error('Module "pdfjs-web/download_manager" shall not be used ' + + 'outside CHROME and GENERIC builds.'); } +var PDFViewerApplication = app.PDFViewerApplication; +var DefaultExternalServices = app.DefaultExternalServices; + function download(blobUrl, filename) { var a = document.createElement('a'); if (a.click) { @@ -107,5 +112,11 @@ DownloadManager.prototype = { } }; +var GenericExternalServices = Object.create(DefaultExternalServices); +GenericExternalServices.createDownloadManager = function () { + return new DownloadManager(); +}; +PDFViewerApplication.externalServices = GenericExternalServices; + exports.DownloadManager = DownloadManager; })); diff --git a/web/viewer.js b/web/viewer.js index f9e3bbe41..3f9c67322 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -50,6 +50,7 @@ if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('CHROME')) { } if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('CHROME || GENERIC')) { require('./pdf_print_service.js'); + require('./download_manager.js'); } function getViewerConfiguration() { @@ -172,7 +173,8 @@ function webViewerLoad() { var config = getViewerConfiguration(); if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION')) { Promise.all([SystemJS.import('pdfjs-web/app'), - SystemJS.import('pdfjs-web/pdf_print_service')]) + SystemJS.import('pdfjs-web/pdf_print_service'), + SystemJS.import('pdfjs-web/download_manager')]) .then(function (modules) { var app = modules[0]; window.PDFViewerApplication = app.PDFViewerApplication; From 3b35c15d42384b6f72b1b39ff3b9d37aa1739684 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Tue, 28 Mar 2017 01:07:27 +0200 Subject: [PATCH 2/3] Convert the files in the `/web` folder to ES6 modules Note that as discussed on IRC, this makes the viewer slightly slower to load *only* in `gulp server` mode, however the difference seem slight enough that I think it will be fine. --- web/annotation_layer_builder.js | 28 +- web/app.js | 126 ++--- web/chromecom.js | 627 ++++++++++++------------- web/dom_events.js | 252 +++++----- web/download_manager.js | 22 +- web/firefox_print_service.js | 172 ++++--- web/firefoxcom.js | 26 +- web/grab_to_pan.js | 416 ++++++++--------- web/hand_tool.js | 26 +- web/overlay_manager.js | 17 +- web/password_prompt.js | 26 +- web/pdf_attachment_viewer.js | 18 +- web/pdf_document_properties.js | 24 +- web/pdf_find_bar.js | 24 +- web/pdf_find_controller.js | 22 +- web/pdf_history.js | 792 ++++++++++++++++---------------- web/pdf_link_service.js | 24 +- web/pdf_outline_viewer.js | 18 +- web/pdf_page_view.js | 37 +- web/pdf_presentation_mode.js | 19 +- web/pdf_print_service.js | 576 +++++++++++------------ web/pdf_rendering_queue.js | 19 +- web/pdf_sidebar.js | 26 +- web/pdf_thumbnail_view.js | 25 +- web/pdf_thumbnail_viewer.js | 28 +- web/pdf_viewer.js | 63 +-- web/preferences.js | 17 +- web/secondary_toolbar.js | 21 +- web/text_layer_builder.js | 22 +- web/toolbar.js | 31 +- web/ui_utils.js | 69 ++- web/view_history.js | 17 +- 32 files changed, 1585 insertions(+), 2045 deletions(-) diff --git a/web/annotation_layer_builder.js b/web/annotation_layer_builder.js index 493e58262..8ef9dbdb5 100644 --- a/web/annotation_layer_builder.js +++ b/web/annotation_layer_builder.js @@ -13,24 +13,9 @@ * limitations under the License. */ -'use strict'; - -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define('pdfjs-web/annotation_layer_builder', ['exports', - 'pdfjs-web/ui_utils', 'pdfjs-web/pdf_link_service', - 'pdfjs-web/pdfjs'], factory); - } else if (typeof exports !== 'undefined') { - factory(exports, require('./ui_utils.js'), - require('./pdf_link_service.js'), require('./pdfjs.js')); - } else { - factory((root.pdfjsWebAnnotationLayerBuilder = {}), root.pdfjsWebUIUtils, - root.pdfjsWebPDFLinkService, root.pdfjsWebPDFJS); - } -}(this, function (exports, uiUtils, pdfLinkService, pdfjsLib) { - -var mozL10n = uiUtils.mozL10n; -var SimpleLinkService = pdfLinkService.SimpleLinkService; +import * as pdfjsLib from 'pdfjs-web/pdfjs'; +import { mozL10n } from 'pdfjs-web/ui_utils'; +import { SimpleLinkService } from 'pdfjs-web/pdf_link_service'; /** * @typedef {Object} AnnotationLayerBuilderOptions @@ -142,6 +127,7 @@ DefaultAnnotationLayerFactory.prototype = { } }; -exports.AnnotationLayerBuilder = AnnotationLayerBuilder; -exports.DefaultAnnotationLayerFactory = DefaultAnnotationLayerFactory; -})); +export { + AnnotationLayerBuilder, + DefaultAnnotationLayerFactory, +}; diff --git a/web/app.js b/web/app.js index a6d59b061..e0cdc0df4 100644 --- a/web/app.js +++ b/web/app.js @@ -14,95 +14,34 @@ */ /* globals PDFBug, Stats */ -'use strict'; - -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define('pdfjs-web/app', ['exports', 'pdfjs-web/ui_utils', - 'pdfjs-web/pdf_history', - 'pdfjs-web/preferences', 'pdfjs-web/pdf_sidebar', - 'pdfjs-web/view_history', 'pdfjs-web/pdf_thumbnail_viewer', - 'pdfjs-web/toolbar', 'pdfjs-web/secondary_toolbar', - 'pdfjs-web/password_prompt', 'pdfjs-web/pdf_presentation_mode', - 'pdfjs-web/pdf_document_properties', 'pdfjs-web/hand_tool', - 'pdfjs-web/pdf_viewer', 'pdfjs-web/pdf_rendering_queue', - 'pdfjs-web/pdf_link_service', 'pdfjs-web/pdf_outline_viewer', - 'pdfjs-web/overlay_manager', 'pdfjs-web/pdf_attachment_viewer', - 'pdfjs-web/pdf_find_controller', 'pdfjs-web/pdf_find_bar', - 'pdfjs-web/dom_events', 'pdfjs-web/pdfjs'], - factory); - } else if (typeof exports !== 'undefined') { - factory(exports, require('./ui_utils.js'), - require('./pdf_history.js'), require('./preferences.js'), - require('./pdf_sidebar.js'), require('./view_history.js'), - require('./pdf_thumbnail_viewer.js'), require('./toolbar.js'), - require('./secondary_toolbar.js'), require('./password_prompt.js'), - require('./pdf_presentation_mode.js'), - require('./pdf_document_properties.js'), require('./hand_tool.js'), - require('./pdf_viewer.js'), require('./pdf_rendering_queue.js'), - require('./pdf_link_service.js'), require('./pdf_outline_viewer.js'), - require('./overlay_manager.js'), require('./pdf_attachment_viewer.js'), - require('./pdf_find_controller.js'), require('./pdf_find_bar.js'), - require('./dom_events.js'), require('./pdfjs.js')); - } else { - factory((root.pdfjsWebApp = {}), root.pdfjsWebUIUtils, - root.pdfjsWebPDFHistory, - root.pdfjsWebPreferences, root.pdfjsWebPDFSidebar, - root.pdfjsWebViewHistory, root.pdfjsWebPDFThumbnailViewer, - root.pdfjsWebToolbar, root.pdfjsWebSecondaryToolbar, - root.pdfjsWebPasswordPrompt, root.pdfjsWebPDFPresentationMode, - root.pdfjsWebPDFDocumentProperties, root.pdfjsWebHandTool, - root.pdfjsWebPDFViewer, root.pdfjsWebPDFRenderingQueue, - root.pdfjsWebPDFLinkService, root.pdfjsWebPDFOutlineViewer, - root.pdfjsWebOverlayManager, root.pdfjsWebPDFAttachmentViewer, - root.pdfjsWebPDFFindController, root.pdfjsWebPDFFindBar, - root.pdfjsWebDOMEvents, root.pdfjsWebPDFJS); - } -}(this, function (exports, uiUtilsLib, pdfHistoryLib, - preferencesLib, pdfSidebarLib, viewHistoryLib, - pdfThumbnailViewerLib, toolbarLib, secondaryToolbarLib, - passwordPromptLib, pdfPresentationModeLib, - pdfDocumentPropertiesLib, handToolLib, pdfViewerLib, - pdfRenderingQueueLib, pdfLinkServiceLib, pdfOutlineViewerLib, - overlayManagerLib, pdfAttachmentViewerLib, - pdfFindControllerLib, pdfFindBarLib, domEventsLib, pdfjsLib) { - -var UNKNOWN_SCALE = uiUtilsLib.UNKNOWN_SCALE; -var DEFAULT_SCALE_VALUE = uiUtilsLib.DEFAULT_SCALE_VALUE; -var MIN_SCALE = uiUtilsLib.MIN_SCALE; -var MAX_SCALE = uiUtilsLib.MAX_SCALE; -var ProgressBar = uiUtilsLib.ProgressBar; -var getPDFFileNameFromURL = uiUtilsLib.getPDFFileNameFromURL; -var noContextMenuHandler = uiUtilsLib.noContextMenuHandler; -var mozL10n = uiUtilsLib.mozL10n; -var parseQueryString = uiUtilsLib.parseQueryString; -var PDFHistory = pdfHistoryLib.PDFHistory; -var Preferences = preferencesLib.Preferences; -var SidebarView = pdfSidebarLib.SidebarView; -var PDFSidebar = pdfSidebarLib.PDFSidebar; -var ViewHistory = viewHistoryLib.ViewHistory; -var PDFThumbnailViewer = pdfThumbnailViewerLib.PDFThumbnailViewer; -var Toolbar = toolbarLib.Toolbar; -var SecondaryToolbar = secondaryToolbarLib.SecondaryToolbar; -var PasswordPrompt = passwordPromptLib.PasswordPrompt; -var PDFPresentationMode = pdfPresentationModeLib.PDFPresentationMode; -var PDFDocumentProperties = pdfDocumentPropertiesLib.PDFDocumentProperties; -var HandTool = handToolLib.HandTool; -var PresentationModeState = pdfViewerLib.PresentationModeState; -var PDFViewer = pdfViewerLib.PDFViewer; -var RenderingStates = pdfRenderingQueueLib.RenderingStates; -var PDFRenderingQueue = pdfRenderingQueueLib.PDFRenderingQueue; -var PDFLinkService = pdfLinkServiceLib.PDFLinkService; -var PDFOutlineViewer = pdfOutlineViewerLib.PDFOutlineViewer; -var OverlayManager = overlayManagerLib.OverlayManager; -var PDFAttachmentViewer = pdfAttachmentViewerLib.PDFAttachmentViewer; -var PDFFindController = pdfFindControllerLib.PDFFindController; -var PDFFindBar = pdfFindBarLib.PDFFindBar; -var getGlobalEventBus = domEventsLib.getGlobalEventBus; -var normalizeWheelEventDelta = uiUtilsLib.normalizeWheelEventDelta; -var animationStarted = uiUtilsLib.animationStarted; -var localized = uiUtilsLib.localized; -var RendererType = uiUtilsLib.RendererType; +import * as pdfjsLib from 'pdfjs-web/pdfjs'; +import { + animationStarted, DEFAULT_SCALE_VALUE, getPDFFileNameFromURL, localized, + MAX_SCALE, MIN_SCALE, mozL10n, noContextMenuHandler, normalizeWheelEventDelta, + parseQueryString, ProgressBar, RendererType, UNKNOWN_SCALE +} from 'pdfjs-web/ui_utils'; +import { + PDFRenderingQueue, RenderingStates +} from 'pdfjs-web/pdf_rendering_queue'; +import { PDFSidebar, SidebarView } from 'pdfjs-web/pdf_sidebar'; +import { PDFViewer, PresentationModeState } from 'pdfjs-web/pdf_viewer'; +import { getGlobalEventBus } from 'pdfjs-web/dom_events'; +import { HandTool } from 'pdfjs-web/hand_tool'; +import { OverlayManager } from 'pdfjs-web/overlay_manager'; +import { PasswordPrompt } from 'pdfjs-web/password_prompt'; +import { PDFAttachmentViewer } from 'pdfjs-web/pdf_attachment_viewer'; +import { PDFDocumentProperties } from 'pdfjs-web/pdf_document_properties'; +import { PDFFindBar } from 'pdfjs-web/pdf_find_bar'; +import { PDFFindController } from 'pdfjs-web/pdf_find_controller'; +import { PDFHistory } from 'pdfjs-web/pdf_history'; +import { PDFLinkService } from 'pdfjs-web/pdf_link_service'; +import { PDFOutlineViewer } from 'pdfjs-web/pdf_outline_viewer'; +import { PDFPresentationMode } from 'pdfjs-web/pdf_presentation_mode'; +import { PDFThumbnailViewer } from 'pdfjs-web/pdf_thumbnail_viewer'; +import { Preferences } from 'pdfjs-web/preferences'; +import { SecondaryToolbar } from 'pdfjs-web/secondary_toolbar'; +import { Toolbar } from 'pdfjs-web/toolbar'; +import { ViewHistory } from 'pdfjs-web/view_history'; var DEFAULT_SCALE_DELTA = 1.1; var DISABLE_AUTO_FETCH_LOADING_BAR_TIMEOUT = 5000; @@ -2269,7 +2208,8 @@ var PDFPrintServiceFactory = { } }; -exports.PDFViewerApplication = PDFViewerApplication; -exports.DefaultExternalServices = DefaultExternalServices; -exports.PDFPrintServiceFactory = PDFPrintServiceFactory; -})); +export { + PDFViewerApplication, + DefaultExternalServices, + PDFPrintServiceFactory, +}; diff --git a/web/chromecom.js b/web/chromecom.js index 27c91dc18..decff7590 100644 --- a/web/chromecom.js +++ b/web/chromecom.js @@ -14,350 +14,335 @@ */ /* globals chrome */ -'use strict'; +import * as pdfjsLib from 'pdfjs-web/pdfjs'; +import { DefaultExternalServices, PDFViewerApplication } from 'pdfjs-web/app'; +import { OverlayManager } from 'pdfjs-web/overlay_manager'; +import { Preferences } from 'pdfjs-web/preferences'; -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define('pdfjs-web/chromecom', ['exports', 'pdfjs-web/app', - 'pdfjs-web/overlay_manager', 'pdfjs-web/preferences', 'pdfjs-web/pdfjs'], - factory); - } else if (typeof exports !== 'undefined') { - factory(exports, require('./app.js'), require('./overlay_manager.js'), - require('./preferences.js'), require('./pdfjs.js')); +if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('CHROME')) { + throw new Error('Module "pdfjs-web/chromecom" shall not be used outside ' + + 'CHROME build.'); +} + +var ChromeCom = {}; +/** + * Creates an event that the extension is listening for and will + * asynchronously respond by calling the callback. + * + * @param {String} action The action to trigger. + * @param {String} data Optional data to send. + * @param {Function} callback Optional response callback that will be called + * with one data argument. When the request cannot be handled, the callback + * is immediately invoked with no arguments. + */ +ChromeCom.request = function ChromeCom_request(action, data, callback) { + var message = { + action: action, + data: data + }; + if (!chrome.runtime) { + console.error('chrome.runtime is undefined.'); + if (callback) { + callback(); + } + } else if (callback) { + chrome.runtime.sendMessage(message, callback); } else { - factory((root.pdfjsWebChromeCom = {}), root.pdfjsWebApp, - root.pdfjsWebOverlayManager, root.pdfjsWebPreferences, - root.pdfjsWebPDFJS); + chrome.runtime.sendMessage(message); } -}(this, function (exports, app, overlayManager, preferences, pdfjsLib) { - if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('CHROME')) { - throw new Error('Module "pdfjs-web/chromecom" shall not be used outside ' + - 'CHROME build.'); +}; + +/** + * Resolves a PDF file path and attempts to detects length. + * + * @param {String} file Absolute URL of PDF file. + * @param {Function} callback A callback with resolved URL and file length. + */ +ChromeCom.resolvePDFFile = function ChromeCom_resolvePDFFile(file, callback) { + // Expand drive:-URLs to filesystem URLs (Chrome OS) + file = file.replace(/^drive:/i, + 'filesystem:' + location.origin + '/external/'); + + if (/^filesystem:/.test(file) && !pdfjsLib.PDFJS.disableWorker) { + // The security origin of filesystem:-URLs are not preserved when the + // URL is passed to a Web worker, (http://crbug.com/362061), so we have + // to create an intermediate blob:-URL as a work-around. + var resolveLocalFileSystemURL = window.resolveLocalFileSystemURL || + window.webkitResolveLocalFileSystemURL; + resolveLocalFileSystemURL(file, function onResolvedFSURL(fileEntry) { + fileEntry.file(function(fileObject) { + var blobUrl = URL.createObjectURL(fileObject); + callback(blobUrl, fileObject.size); + }); + }, function onFileSystemError(error) { + // This should not happen. When it happens, just fall back to the + // usual way of getting the File's data (via the Web worker). + console.warn('Cannot resolve file ' + file + ', ' + error.name + ' ' + + error.message); + callback(file); + }); + return; } + if (/^https?:/.test(file)) { + // Assumption: The file being opened is the file that was requested. + // There is no UI to input a different URL, so this assumption will hold + // for now. + setReferer(file, function() { + callback(file); + }); + return; + } + if (/^file?:/.test(file)) { + getEmbedderOrigin(function(origin) { + // If the origin cannot be determined, let Chrome decide whether to + // allow embedding files. Otherwise, only allow local files to be + // embedded from local files or Chrome extensions. + // Even without this check, the file load in frames is still blocked, + // but this may change in the future (https://crbug.com/550151). + if (origin && !/^file:|^chrome-extension:/.test(origin)) { + PDFViewerApplication.error('Blocked ' + origin + ' from loading ' + + file + '. Refused to load a local file in a non-local page ' + + 'for security reasons.'); + return; + } + isAllowedFileSchemeAccess(function(isAllowedAccess) { + if (isAllowedAccess) { + callback(file); + } else { + requestAccessToLocalFile(file); + } + }); + }); + return; + } + callback(file); +}; - var PDFViewerApplication = app.PDFViewerApplication; - var DefaultExternalServices = app.DefaultExternalServices; - var OverlayManager = overlayManager.OverlayManager; - var Preferences = preferences.Preferences; +function getEmbedderOrigin(callback) { + var origin = window === top ? location.origin : location.ancestorOrigins[0]; + if (origin === 'null') { + // file:-URLs, data-URLs, sandboxed frames, etc. + getParentOrigin(callback); + } else { + callback(origin); + } +} - var ChromeCom = {}; - /** - * Creates an event that the extension is listening for and will - * asynchronously respond by calling the callback. - * - * @param {String} action The action to trigger. - * @param {String} data Optional data to send. - * @param {Function} callback Optional response callback that will be called - * with one data argument. When the request cannot be handled, the callback - * is immediately invoked with no arguments. - */ - ChromeCom.request = function ChromeCom_request(action, data, callback) { - var message = { - action: action, - data: data +function getParentOrigin(callback) { + ChromeCom.request('getParentOrigin', null, callback); +} + +function isAllowedFileSchemeAccess(callback) { + ChromeCom.request('isAllowedFileSchemeAccess', null, callback); +} + +function isRuntimeAvailable() { + try { + // When the extension is reloaded, the extension runtime is destroyed and + // the extension APIs become unavailable. + if (chrome.runtime && chrome.runtime.getManifest()) { + return true; + } + } catch (e) {} + return false; +} + +function reloadIfRuntimeIsUnavailable() { + if (!isRuntimeAvailable()) { + location.reload(); + } +} + +var chromeFileAccessOverlayPromise; +function requestAccessToLocalFile(fileUrl) { + var onCloseOverlay = null; + if (top !== window) { + // When the extension reloads after receiving new permissions, the pages + // have to be reloaded to restore the extension runtime. Auto-reload + // frames, because users should not have to reload the whole page just to + // update the viewer. + // Top-level frames are closed by Chrome upon reload, so there is no need + // for detecting unload of the top-level frame. Should this ever change + // (crbug.com/511670), then the user can just reload the tab. + window.addEventListener('focus', reloadIfRuntimeIsUnavailable); + onCloseOverlay = function() { + window.removeEventListener('focus', reloadIfRuntimeIsUnavailable); + reloadIfRuntimeIsUnavailable(); + OverlayManager.close('chromeFileAccessOverlay'); }; - if (!chrome.runtime) { - console.error('chrome.runtime is undefined.'); - if (callback) { - callback(); - } - } else if (callback) { - chrome.runtime.sendMessage(message, callback); - } else { - chrome.runtime.sendMessage(message); + } + if (!chromeFileAccessOverlayPromise) { + chromeFileAccessOverlayPromise = OverlayManager.register( + 'chromeFileAccessOverlay', + document.getElementById('chromeFileAccessOverlay'), + onCloseOverlay, true); + } + chromeFileAccessOverlayPromise.then(function() { + var iconPath = chrome.runtime.getManifest().icons[48]; + document.getElementById('chrome-pdfjs-logo-bg').style.backgroundImage = + 'url(' + chrome.runtime.getURL(iconPath) + ')'; + + // Use Chrome's definition of UI language instead of PDF.js's #lang=..., + // because the shown string should match the UI at chrome://extensions. + // These strings are from chrome/app/resources/generated_resources_*.xtb. + /* eslint-disable no-unexpected-multiline */ + var i18nFileAccessLabel = + PDFJSDev.json('$ROOT/web/chrome-i18n-allow-access-to-file-urls.json') + [chrome.i18n.getUILanguage && chrome.i18n.getUILanguage()]; + /* eslint-enable no-unexpected-multiline */ + + if (i18nFileAccessLabel) { + document.getElementById('chrome-file-access-label').textContent = + i18nFileAccessLabel; } - }; - /** - * Resolves a PDF file path and attempts to detects length. - * - * @param {String} file Absolute URL of PDF file. - * @param {Function} callback A callback with resolved URL and file length. - */ - ChromeCom.resolvePDFFile = function ChromeCom_resolvePDFFile(file, callback) { - // Expand drive:-URLs to filesystem URLs (Chrome OS) - file = file.replace(/^drive:/i, - 'filesystem:' + location.origin + '/external/'); - - if (/^filesystem:/.test(file) && !pdfjsLib.PDFJS.disableWorker) { - // The security origin of filesystem:-URLs are not preserved when the - // URL is passed to a Web worker, (http://crbug.com/362061), so we have - // to create an intermediate blob:-URL as a work-around. - var resolveLocalFileSystemURL = window.resolveLocalFileSystemURL || - window.webkitResolveLocalFileSystemURL; - resolveLocalFileSystemURL(file, function onResolvedFSURL(fileEntry) { - fileEntry.file(function(fileObject) { - var blobUrl = URL.createObjectURL(fileObject); - callback(blobUrl, fileObject.size); - }); - }, function onFileSystemError(error) { - // This should not happen. When it happens, just fall back to the - // usual way of getting the File's data (via the Web worker). - console.warn('Cannot resolve file ' + file + ', ' + error.name + ' ' + - error.message); - callback(file); + var link = document.getElementById('chrome-link-to-extensions-page'); + link.href = 'chrome://extensions/?id=' + chrome.runtime.id; + link.onclick = function(e) { + // Direct navigation to chrome:// URLs is blocked by Chrome, so we + // have to ask the background page to open chrome://extensions/?id=... + e.preventDefault(); + // Open in the current tab by default, because toggling the file access + // checkbox causes the extension to reload, and Chrome will close all + // tabs upon reload. + ChromeCom.request('openExtensionsPageForFileAccess', { + newTab: e.ctrlKey || e.metaKey || e.button === 1 || window !== top }); - return; - } - if (/^https?:/.test(file)) { - // Assumption: The file being opened is the file that was requested. - // There is no UI to input a different URL, so this assumption will hold - // for now. - setReferer(file, function() { - callback(file); - }); - return; - } - if (/^file?:/.test(file)) { - getEmbedderOrigin(function(origin) { - // If the origin cannot be determined, let Chrome decide whether to - // allow embedding files. Otherwise, only allow local files to be - // embedded from local files or Chrome extensions. - // Even without this check, the file load in frames is still blocked, - // but this may change in the future (https://crbug.com/550151). - if (origin && !/^file:|^chrome-extension:/.test(origin)) { - PDFViewerApplication.error('Blocked ' + origin + ' from loading ' + - file + '. Refused to load a local file in a non-local page ' + - 'for security reasons.'); - return; - } - isAllowedFileSchemeAccess(function(isAllowedAccess) { - if (isAllowedAccess) { - callback(file); - } else { - requestAccessToLocalFile(file); - } - }); - }); - return; - } - callback(file); - }; + }; - function getEmbedderOrigin(callback) { - var origin = window === top ? location.origin : location.ancestorOrigins[0]; - if (origin === 'null') { - // file:-URLs, data-URLs, sandboxed frames, etc. - getParentOrigin(callback); - } else { - callback(origin); - } - } + // Show which file is being opened to help the user with understanding + // why this permission request is shown. + document.getElementById('chrome-url-of-local-file').textContent = fileUrl; - function getParentOrigin(callback) { - ChromeCom.request('getParentOrigin', null, callback); - } + OverlayManager.open('chromeFileAccessOverlay'); + }); +} - function isAllowedFileSchemeAccess(callback) { - ChromeCom.request('isAllowedFileSchemeAccess', null, callback); - } - - function isRuntimeAvailable() { - try { - // When the extension is reloaded, the extension runtime is destroyed and - // the extension APIs become unavailable. - if (chrome.runtime && chrome.runtime.getManifest()) { - return true; - } - } catch (e) {} - return false; - } - - function reloadIfRuntimeIsUnavailable() { +if (window === top) { + // Chrome closes all extension tabs (crbug.com/511670) when the extension + // reloads. To counter this, the tab URL and history state is saved to + // localStorage and restored by extension-router.js. + // Unfortunately, the window and tab index are not restored. And if it was + // the only tab in an incognito window, then the tab is not restored either. + addEventListener('unload', function() { + // If the runtime is still available, the unload is most likely a normal + // tab closure. Otherwise it is most likely an extension reload. if (!isRuntimeAvailable()) { - location.reload(); + localStorage.setItem( + 'unload-' + Date.now() + '-' + document.hidden + '-' + location.href, + JSON.stringify(history.state)); } + }); +} + +// This port is used for several purposes: +// 1. When disconnected, the background page knows that the frame has unload. +// 2. When the referrer was saved in history.state.chromecomState, it is sent +// to the background page. +// 3. When the background page knows the referrer of the page, the referrer is +// saved in history.state.chromecomState. +var port; +// Set the referer for the given URL. +// 0. Background: If loaded via a http(s) URL: Save referer. +// 1. Page -> background: send URL and referer from history.state +// 2. Background: Bind referer to URL (via webRequest). +// 3. Background -> page: Send latest referer and save to history. +// 4. Page: Invoke callback. +function setReferer(url, callback) { + if (!port) { + // The background page will accept the port, and keep adding the Referer + // request header to requests to |url| until the port is disconnected. + port = chrome.runtime.connect({name: 'chromecom-referrer'}); } + port.onDisconnect.addListener(onDisconnect); + port.onMessage.addListener(onMessage); + // Initiate the information exchange. + port.postMessage({ + referer: window.history.state && window.history.state.chromecomState, + requestUrl: url + }); - var chromeFileAccessOverlayPromise; - function requestAccessToLocalFile(fileUrl) { - var onCloseOverlay = null; - if (top !== window) { - // When the extension reloads after receiving new permissions, the pages - // have to be reloaded to restore the extension runtime. Auto-reload - // frames, because users should not have to reload the whole page just to - // update the viewer. - // Top-level frames are closed by Chrome upon reload, so there is no need - // for detecting unload of the top-level frame. Should this ever change - // (crbug.com/511670), then the user can just reload the tab. - window.addEventListener('focus', reloadIfRuntimeIsUnavailable); - onCloseOverlay = function() { - window.removeEventListener('focus', reloadIfRuntimeIsUnavailable); - reloadIfRuntimeIsUnavailable(); - OverlayManager.close('chromeFileAccessOverlay'); - }; + function onMessage(referer) { + if (referer) { + // The background extracts the Referer from the initial HTTP request for + // the PDF file. When the viewer is reloaded or when the user navigates + // back and forward, the background page will not observe a HTTP request + // with Referer. To make sure that the Referer is preserved, store it in + // history.state, which is preserved across reloads/navigations. + var state = window.history.state || {}; + state.chromecomState = referer; + window.history.replaceState(state, ''); } - if (!chromeFileAccessOverlayPromise) { - chromeFileAccessOverlayPromise = OverlayManager.register( - 'chromeFileAccessOverlay', - document.getElementById('chromeFileAccessOverlay'), - onCloseOverlay, true); - } - chromeFileAccessOverlayPromise.then(function() { - var iconPath = chrome.runtime.getManifest().icons[48]; - document.getElementById('chrome-pdfjs-logo-bg').style.backgroundImage = - 'url(' + chrome.runtime.getURL(iconPath) + ')'; - - // Use Chrome's definition of UI language instead of PDF.js's #lang=..., - // because the shown string should match the UI at chrome://extensions. - // These strings are from chrome/app/resources/generated_resources_*.xtb. - /* eslint-disable no-unexpected-multiline */ - var i18nFileAccessLabel = - PDFJSDev.json('$ROOT/web/chrome-i18n-allow-access-to-file-urls.json') - [chrome.i18n.getUILanguage && chrome.i18n.getUILanguage()]; - /* eslint-enable no-unexpected-multiline */ - - if (i18nFileAccessLabel) { - document.getElementById('chrome-file-access-label').textContent = - i18nFileAccessLabel; - } - - var link = document.getElementById('chrome-link-to-extensions-page'); - link.href = 'chrome://extensions/?id=' + chrome.runtime.id; - link.onclick = function(e) { - // Direct navigation to chrome:// URLs is blocked by Chrome, so we - // have to ask the background page to open chrome://extensions/?id=... - e.preventDefault(); - // Open in the current tab by default, because toggling the file access - // checkbox causes the extension to reload, and Chrome will close all - // tabs upon reload. - ChromeCom.request('openExtensionsPageForFileAccess', { - newTab: e.ctrlKey || e.metaKey || e.button === 1 || window !== top - }); - }; - - // Show which file is being opened to help the user with understanding - // why this permission request is shown. - document.getElementById('chrome-url-of-local-file').textContent = fileUrl; - - OverlayManager.open('chromeFileAccessOverlay'); - }); + onCompleted(); } - - if (window === top) { - // Chrome closes all extension tabs (crbug.com/511670) when the extension - // reloads. To counter this, the tab URL and history state is saved to - // localStorage and restored by extension-router.js. - // Unfortunately, the window and tab index are not restored. And if it was - // the only tab in an incognito window, then the tab is not restored either. - addEventListener('unload', function() { - // If the runtime is still available, the unload is most likely a normal - // tab closure. Otherwise it is most likely an extension reload. - if (!isRuntimeAvailable()) { - localStorage.setItem( - 'unload-' + Date.now() + '-' + document.hidden + '-' + location.href, - JSON.stringify(history.state)); - } - }); + function onDisconnect() { + // When the connection fails, ignore the error and call the callback. + port = null; + callback(); } - - // This port is used for several purposes: - // 1. When disconnected, the background page knows that the frame has unload. - // 2. When the referrer was saved in history.state.chromecomState, it is sent - // to the background page. - // 3. When the background page knows the referrer of the page, the referrer is - // saved in history.state.chromecomState. - var port; - // Set the referer for the given URL. - // 0. Background: If loaded via a http(s) URL: Save referer. - // 1. Page -> background: send URL and referer from history.state - // 2. Background: Bind referer to URL (via webRequest). - // 3. Background -> page: Send latest referer and save to history. - // 4. Page: Invoke callback. - function setReferer(url, callback) { - if (!port) { - // The background page will accept the port, and keep adding the Referer - // request header to requests to |url| until the port is disconnected. - port = chrome.runtime.connect({name: 'chromecom-referrer'}); - } - port.onDisconnect.addListener(onDisconnect); - port.onMessage.addListener(onMessage); - // Initiate the information exchange. - port.postMessage({ - referer: window.history.state && window.history.state.chromecomState, - requestUrl: url - }); - - function onMessage(referer) { - if (referer) { - // The background extracts the Referer from the initial HTTP request for - // the PDF file. When the viewer is reloaded or when the user navigates - // back and forward, the background page will not observe a HTTP request - // with Referer. To make sure that the Referer is preserved, store it in - // history.state, which is preserved across reloads/navigations. - var state = window.history.state || {}; - state.chromecomState = referer; - window.history.replaceState(state, ''); - } - onCompleted(); - } - function onDisconnect() { - // When the connection fails, ignore the error and call the callback. - port = null; - callback(); - } - function onCompleted() { - port.onDisconnect.removeListener(onDisconnect); - port.onMessage.removeListener(onMessage); - callback(); - } + function onCompleted() { + port.onDisconnect.removeListener(onDisconnect); + port.onMessage.removeListener(onMessage); + callback(); } +} - // chrome.storage.sync is not supported in every Chromium-derivate. - // Note: The background page takes care of migrating values from - // chrome.storage.local to chrome.storage.sync when needed. - var storageArea = chrome.storage.sync || chrome.storage.local; +// chrome.storage.sync is not supported in every Chromium-derivate. +// Note: The background page takes care of migrating values from +// chrome.storage.local to chrome.storage.sync when needed. +var storageArea = chrome.storage.sync || chrome.storage.local; - Preferences._writeToStorage = function (prefObj) { - return new Promise(function (resolve) { - if (prefObj === Preferences.defaults) { - var keysToRemove = Object.keys(Preferences.defaults); - // If the storage is reset, remove the keys so that the values from - // managed storage are applied again. - storageArea.remove(keysToRemove, function() { - resolve(); - }); - } else { - storageArea.set(prefObj, function() { - resolve(); - }); +Preferences._writeToStorage = function (prefObj) { + return new Promise(function (resolve) { + if (prefObj === Preferences.defaults) { + var keysToRemove = Object.keys(Preferences.defaults); + // If the storage is reset, remove the keys so that the values from + // managed storage are applied again. + storageArea.remove(keysToRemove, function() { + resolve(); + }); + } else { + storageArea.set(prefObj, function() { + resolve(); + }); + } + }); +}; + +Preferences._readFromStorage = function (prefObj) { + return new Promise(function (resolve) { + if (chrome.storage.managed) { + // Get preferences as set by the system administrator. + // See extensions/chromium/preferences_schema.json for more information. + // These preferences can be overridden by the user. + chrome.storage.managed.get(Preferences.defaults, getPreferences); + } else { + // Managed storage not supported, e.g. in old Chromium versions. + getPreferences(Preferences.defaults); + } + + function getPreferences(defaultPrefs) { + if (chrome.runtime.lastError) { + // Managed storage not supported, e.g. in Opera. + defaultPrefs = Preferences.defaults; } - }); - }; + storageArea.get(defaultPrefs, function(readPrefs) { + resolve(readPrefs); + }); + } + }); +}; - Preferences._readFromStorage = function (prefObj) { - return new Promise(function (resolve) { - if (chrome.storage.managed) { - // Get preferences as set by the system administrator. - // See extensions/chromium/preferences_schema.json for more information. - // These preferences can be overridden by the user. - chrome.storage.managed.get(Preferences.defaults, getPreferences); - } else { - // Managed storage not supported, e.g. in old Chromium versions. - getPreferences(Preferences.defaults); - } +var ChromeExternalServices = Object.create(DefaultExternalServices); +ChromeExternalServices.initPassiveLoading = function (callbacks) { + var appConfig = PDFViewerApplication.appConfig; + ChromeCom.resolvePDFFile(appConfig.defaultUrl, + function (url, length, originalURL) { + callbacks.onOpenWithURL(url, length, originalURL); + }); +}; +PDFViewerApplication.externalServices = ChromeExternalServices; - function getPreferences(defaultPrefs) { - if (chrome.runtime.lastError) { - // Managed storage not supported, e.g. in Opera. - defaultPrefs = Preferences.defaults; - } - storageArea.get(defaultPrefs, function(readPrefs) { - resolve(readPrefs); - }); - } - }); - }; - - var ChromeExternalServices = Object.create(DefaultExternalServices); - ChromeExternalServices.initPassiveLoading = function (callbacks) { - var appConfig = PDFViewerApplication.appConfig; - ChromeCom.resolvePDFFile(appConfig.defaultUrl, - function (url, length, originalURL) { - callbacks.onOpenWithURL(url, length, originalURL); - }); - }; - PDFViewerApplication.externalServices = ChromeExternalServices; - - exports.ChromeCom = ChromeCom; -})); +export { + ChromeCom, +}; diff --git a/web/dom_events.js b/web/dom_events.js index ae580eb70..cf9be2732 100644 --- a/web/dom_events.js +++ b/web/dom_events.js @@ -13,142 +13,132 @@ * limitations under the License. */ -'use strict'; +import { EventBus } from 'pdfjs-web/ui_utils'; -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define('pdfjs-web/dom_events', ['exports', 'pdfjs-web/ui_utils'], factory); - } else if (typeof exports !== 'undefined') { - factory(exports, require('./ui_utils.js')); - } else { - factory((root.pdfjsWebDOMEvents = {}), root.pdfjsWebUIUtils); - } -}(this, function (exports, uiUtils) { - var EventBus = uiUtils.EventBus; - - // Attaching to the application event bus to dispatch events to the DOM for - // backwards viewer API compatibility. - function attachDOMEventsToEventBus(eventBus) { - eventBus.on('documentload', function () { - var event = document.createEvent('CustomEvent'); - event.initCustomEvent('documentload', true, true, {}); - window.dispatchEvent(event); +// Attaching to the application event bus to dispatch events to the DOM for +// backwards viewer API compatibility. +function attachDOMEventsToEventBus(eventBus) { + eventBus.on('documentload', function () { + var event = document.createEvent('CustomEvent'); + event.initCustomEvent('documentload', true, true, {}); + window.dispatchEvent(event); + }); + eventBus.on('pagerendered', function (e) { + var event = document.createEvent('CustomEvent'); + event.initCustomEvent('pagerendered', true, true, { + pageNumber: e.pageNumber, + cssTransform: e.cssTransform, }); - eventBus.on('pagerendered', function (e) { - var event = document.createEvent('CustomEvent'); - event.initCustomEvent('pagerendered', true, true, { - pageNumber: e.pageNumber, - cssTransform: e.cssTransform, - }); - e.source.div.dispatchEvent(event); + e.source.div.dispatchEvent(event); + }); + eventBus.on('textlayerrendered', function (e) { + var event = document.createEvent('CustomEvent'); + event.initCustomEvent('textlayerrendered', true, true, { + pageNumber: e.pageNumber }); - eventBus.on('textlayerrendered', function (e) { - var event = document.createEvent('CustomEvent'); - event.initCustomEvent('textlayerrendered', true, true, { - pageNumber: e.pageNumber - }); - e.source.textLayerDiv.dispatchEvent(event); + e.source.textLayerDiv.dispatchEvent(event); + }); + eventBus.on('pagechange', function (e) { + var event = document.createEvent('UIEvents'); + event.initUIEvent('pagechange', true, true, window, 0); + event.pageNumber = e.pageNumber; + e.source.container.dispatchEvent(event); + }); + eventBus.on('pagesinit', function (e) { + var event = document.createEvent('CustomEvent'); + event.initCustomEvent('pagesinit', true, true, null); + e.source.container.dispatchEvent(event); + }); + eventBus.on('pagesloaded', function (e) { + var event = document.createEvent('CustomEvent'); + event.initCustomEvent('pagesloaded', true, true, { + pagesCount: e.pagesCount }); - eventBus.on('pagechange', function (e) { - var event = document.createEvent('UIEvents'); - event.initUIEvent('pagechange', true, true, window, 0); - event.pageNumber = e.pageNumber; - e.source.container.dispatchEvent(event); - }); - eventBus.on('pagesinit', function (e) { - var event = document.createEvent('CustomEvent'); - event.initCustomEvent('pagesinit', true, true, null); - e.source.container.dispatchEvent(event); - }); - eventBus.on('pagesloaded', function (e) { - var event = document.createEvent('CustomEvent'); - event.initCustomEvent('pagesloaded', true, true, { - pagesCount: e.pagesCount - }); - e.source.container.dispatchEvent(event); - }); - eventBus.on('scalechange', function (e) { - var event = document.createEvent('UIEvents'); - event.initUIEvent('scalechange', true, true, window, 0); - event.scale = e.scale; - event.presetValue = e.presetValue; - e.source.container.dispatchEvent(event); - }); - eventBus.on('updateviewarea', function (e) { - var event = document.createEvent('UIEvents'); - event.initUIEvent('updateviewarea', true, true, window, 0); - event.location = e.location; - e.source.container.dispatchEvent(event); - }); - eventBus.on('find', function (e) { - if (e.source === window) { - return; // event comes from FirefoxCom, no need to replicate - } - var event = document.createEvent('CustomEvent'); - event.initCustomEvent('find' + e.type, true, true, { - query: e.query, - phraseSearch: e.phraseSearch, - caseSensitive: e.caseSensitive, - highlightAll: e.highlightAll, - findPrevious: e.findPrevious - }); - window.dispatchEvent(event); - }); - eventBus.on('attachmentsloaded', function (e) { - var event = document.createEvent('CustomEvent'); - event.initCustomEvent('attachmentsloaded', true, true, { - attachmentsCount: e.attachmentsCount - }); - e.source.container.dispatchEvent(event); - }); - eventBus.on('sidebarviewchanged', function (e) { - var event = document.createEvent('CustomEvent'); - event.initCustomEvent('sidebarviewchanged', true, true, { - view: e.view, - }); - e.source.outerContainer.dispatchEvent(event); - }); - eventBus.on('pagemode', function (e) { - var event = document.createEvent('CustomEvent'); - event.initCustomEvent('pagemode', true, true, { - mode: e.mode, - }); - e.source.pdfViewer.container.dispatchEvent(event); - }); - eventBus.on('namedaction', function (e) { - var event = document.createEvent('CustomEvent'); - event.initCustomEvent('namedaction', true, true, { - action: e.action - }); - e.source.pdfViewer.container.dispatchEvent(event); - }); - eventBus.on('presentationmodechanged', function (e) { - var event = document.createEvent('CustomEvent'); - event.initCustomEvent('presentationmodechanged', true, true, { - active: e.active, - switchInProgress: e.switchInProgress - }); - window.dispatchEvent(event); - }); - eventBus.on('outlineloaded', function (e) { - var event = document.createEvent('CustomEvent'); - event.initCustomEvent('outlineloaded', true, true, { - outlineCount: e.outlineCount - }); - e.source.container.dispatchEvent(event); - }); - } - - var globalEventBus = null; - function getGlobalEventBus() { - if (globalEventBus) { - return globalEventBus; + e.source.container.dispatchEvent(event); + }); + eventBus.on('scalechange', function (e) { + var event = document.createEvent('UIEvents'); + event.initUIEvent('scalechange', true, true, window, 0); + event.scale = e.scale; + event.presetValue = e.presetValue; + e.source.container.dispatchEvent(event); + }); + eventBus.on('updateviewarea', function (e) { + var event = document.createEvent('UIEvents'); + event.initUIEvent('updateviewarea', true, true, window, 0); + event.location = e.location; + e.source.container.dispatchEvent(event); + }); + eventBus.on('find', function (e) { + if (e.source === window) { + return; // event comes from FirefoxCom, no need to replicate } - globalEventBus = new EventBus(); - attachDOMEventsToEventBus(globalEventBus); + var event = document.createEvent('CustomEvent'); + event.initCustomEvent('find' + e.type, true, true, { + query: e.query, + phraseSearch: e.phraseSearch, + caseSensitive: e.caseSensitive, + highlightAll: e.highlightAll, + findPrevious: e.findPrevious + }); + window.dispatchEvent(event); + }); + eventBus.on('attachmentsloaded', function (e) { + var event = document.createEvent('CustomEvent'); + event.initCustomEvent('attachmentsloaded', true, true, { + attachmentsCount: e.attachmentsCount + }); + e.source.container.dispatchEvent(event); + }); + eventBus.on('sidebarviewchanged', function (e) { + var event = document.createEvent('CustomEvent'); + event.initCustomEvent('sidebarviewchanged', true, true, { + view: e.view, + }); + e.source.outerContainer.dispatchEvent(event); + }); + eventBus.on('pagemode', function (e) { + var event = document.createEvent('CustomEvent'); + event.initCustomEvent('pagemode', true, true, { + mode: e.mode, + }); + e.source.pdfViewer.container.dispatchEvent(event); + }); + eventBus.on('namedaction', function (e) { + var event = document.createEvent('CustomEvent'); + event.initCustomEvent('namedaction', true, true, { + action: e.action + }); + e.source.pdfViewer.container.dispatchEvent(event); + }); + eventBus.on('presentationmodechanged', function (e) { + var event = document.createEvent('CustomEvent'); + event.initCustomEvent('presentationmodechanged', true, true, { + active: e.active, + switchInProgress: e.switchInProgress + }); + window.dispatchEvent(event); + }); + eventBus.on('outlineloaded', function (e) { + var event = document.createEvent('CustomEvent'); + event.initCustomEvent('outlineloaded', true, true, { + outlineCount: e.outlineCount + }); + e.source.container.dispatchEvent(event); + }); +} + +var globalEventBus = null; +function getGlobalEventBus() { + if (globalEventBus) { return globalEventBus; } + globalEventBus = new EventBus(); + attachDOMEventsToEventBus(globalEventBus); + return globalEventBus; +} - exports.attachDOMEventsToEventBus = attachDOMEventsToEventBus; - exports.getGlobalEventBus = getGlobalEventBus; -})); +export { + attachDOMEventsToEventBus, + getGlobalEventBus, +}; diff --git a/web/download_manager.js b/web/download_manager.js index a489899b4..206ecd209 100644 --- a/web/download_manager.js +++ b/web/download_manager.js @@ -13,27 +13,14 @@ * limitations under the License. */ -'use strict'; +import * as pdfjsLib from 'pdfjs-web/pdfjs'; +import { DefaultExternalServices, PDFViewerApplication } from 'pdfjs-web/app'; -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define('pdfjs-web/download_manager', ['exports', 'pdfjs-web/app', - 'pdfjs-web/pdfjs'], factory); - } else if (typeof exports !== 'undefined') { - factory(exports, require('./app.js'), require('./pdfjs.js')); - } else { - factory((root.pdfjsWebDownloadManager = {}), root.pdfjsWebApp, - root.pdfjsWebPDFJS); - } -}(this, function (exports, app, pdfjsLib) { if (typeof PDFJSDev !== 'undefined' && !PDFJSDev.test('CHROME || GENERIC')) { throw new Error('Module "pdfjs-web/download_manager" shall not be used ' + 'outside CHROME and GENERIC builds.'); } -var PDFViewerApplication = app.PDFViewerApplication; -var DefaultExternalServices = app.DefaultExternalServices; - function download(blobUrl, filename) { var a = document.createElement('a'); if (a.click) { @@ -118,5 +105,6 @@ GenericExternalServices.createDownloadManager = function () { }; PDFViewerApplication.externalServices = GenericExternalServices; -exports.DownloadManager = DownloadManager; -})); +export { + DownloadManager, +}; diff --git a/web/firefox_print_service.js b/web/firefox_print_service.js index 4d7b6efc9..3f128c5db 100644 --- a/web/firefox_print_service.js +++ b/web/firefox_print_service.js @@ -13,110 +13,98 @@ * limitations under the License. */ -'use strict'; +import * as pdfjsLib from 'pdfjs-web/pdfjs'; +import { CSS_UNITS } from 'pdfjs-web/ui_utils'; +import { PDFPrintServiceFactory } from 'pdfjs-web/app'; -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define('pdfjs-web/firefox_print_service', ['exports', 'pdfjs-web/ui_utils', - 'pdfjs-web/app', 'pdfjs-web/pdfjs'], factory); - } else if (typeof exports !== 'undefined') { - factory(exports, require('./ui_utils.js'), require('./app.js'), - require('./pdfjs.js')); - } else { - factory((root.pdfjsWebFirefoxPrintService = {}), root.pdfjsWebUIUtils, - root.pdfjsWebApp, root.pdfjsWebPDFJS); - } -}(this, function (exports, uiUtils, app, pdfjsLib) { - var CSS_UNITS = uiUtils.CSS_UNITS; - var PDFPrintServiceFactory = app.PDFPrintServiceFactory; +// Creates a placeholder with div and canvas with right size for the page. +function composePage(pdfDocument, pageNumber, size, printContainer) { + var canvas = document.createElement('canvas'); - // Creates a placeholder with div and canvas with right size for the page. - function composePage(pdfDocument, pageNumber, size, printContainer) { - var canvas = document.createElement('canvas'); + // The size of the canvas in pixels for printing. + var PRINT_RESOLUTION = 150; + var PRINT_UNITS = PRINT_RESOLUTION / 72.0; + canvas.width = Math.floor(size.width * PRINT_UNITS); + canvas.height = Math.floor(size.height * PRINT_UNITS); - // The size of the canvas in pixels for printing. - var PRINT_RESOLUTION = 150; - var PRINT_UNITS = PRINT_RESOLUTION / 72.0; - canvas.width = Math.floor(size.width * PRINT_UNITS); - canvas.height = Math.floor(size.height * PRINT_UNITS); + // The physical size of the canvas as specified by the PDF document. + canvas.style.width = Math.floor(size.width * CSS_UNITS) + 'px'; + canvas.style.height = Math.floor(size.height * CSS_UNITS) + 'px'; - // The physical size of the canvas as specified by the PDF document. - canvas.style.width = Math.floor(size.width * CSS_UNITS) + 'px'; - canvas.style.height = Math.floor(size.height * CSS_UNITS) + 'px'; + var canvasWrapper = document.createElement('div'); + canvasWrapper.appendChild(canvas); + printContainer.appendChild(canvasWrapper); - var canvasWrapper = document.createElement('div'); - canvasWrapper.appendChild(canvas); - printContainer.appendChild(canvasWrapper); + canvas.mozPrintCallback = function(obj) { + // Printing/rendering the page. + var ctx = obj.context; - canvas.mozPrintCallback = function(obj) { - // Printing/rendering the page. - var ctx = obj.context; + ctx.save(); + ctx.fillStyle = 'rgb(255, 255, 255)'; + ctx.fillRect(0, 0, canvas.width, canvas.height); + ctx.restore(); - ctx.save(); - ctx.fillStyle = 'rgb(255, 255, 255)'; - ctx.fillRect(0, 0, canvas.width, canvas.height); - ctx.restore(); - - pdfDocument.getPage(pageNumber).then(function (pdfPage) { - var renderContext = { - canvasContext: ctx, - transform: [PRINT_UNITS, 0, 0, PRINT_UNITS, 0, 0], - viewport: pdfPage.getViewport(1, size.rotation), - intent: 'print' - }; - return pdfPage.render(renderContext).promise; - }).then(function() { - // Tell the printEngine that rendering this canvas/page has finished. + pdfDocument.getPage(pageNumber).then(function (pdfPage) { + var renderContext = { + canvasContext: ctx, + transform: [PRINT_UNITS, 0, 0, PRINT_UNITS, 0, 0], + viewport: pdfPage.getViewport(1, size.rotation), + intent: 'print' + }; + return pdfPage.render(renderContext).promise; + }).then(function() { + // Tell the printEngine that rendering this canvas/page has finished. + obj.done(); + }, function(error) { + console.error(error); + // Tell the printEngine that rendering this canvas/page has failed. + // This will make the print process stop. + if ('abort' in obj) { + obj.abort(); + } else { obj.done(); - }, function(error) { - console.error(error); - // Tell the printEngine that rendering this canvas/page has failed. - // This will make the print process stop. - if ('abort' in obj) { - obj.abort(); - } else { - obj.done(); - } - }); - }; - } - - function FirefoxPrintService(pdfDocument, pagesOverview, printContainer) { - this.pdfDocument = pdfDocument; - this.pagesOverview = pagesOverview; - this.printContainer = printContainer; - } - - FirefoxPrintService.prototype = { - layout: function () { - var pdfDocument = this.pdfDocument; - var printContainer = this.printContainer; - var body = document.querySelector('body'); - body.setAttribute('data-pdfjsprinting', true); - - for (var i = 0, ii = this.pagesOverview.length; i < ii; ++i) { - composePage(pdfDocument, i + 1, this.pagesOverview[i], printContainer); } - }, - - destroy: function () { - this.printContainer.textContent = ''; - } + }); }; +} - PDFPrintServiceFactory.instance = { - get supportsPrinting() { - var canvas = document.createElement('canvas'); - var value = 'mozPrintCallback' in canvas; +function FirefoxPrintService(pdfDocument, pagesOverview, printContainer) { + this.pdfDocument = pdfDocument; + this.pagesOverview = pagesOverview; + this.printContainer = printContainer; +} - return pdfjsLib.shadow(this, 'supportsPrinting', value); - }, +FirefoxPrintService.prototype = { + layout: function () { + var pdfDocument = this.pdfDocument; + var printContainer = this.printContainer; + var body = document.querySelector('body'); + body.setAttribute('data-pdfjsprinting', true); - createPrintService: function (pdfDocument, pagesOverview, printContainer) { - return new FirefoxPrintService(pdfDocument, pagesOverview, - printContainer); + for (var i = 0, ii = this.pagesOverview.length; i < ii; ++i) { + composePage(pdfDocument, i + 1, this.pagesOverview[i], printContainer); } - }; + }, - exports.FirefoxPrintService = FirefoxPrintService; -})); + destroy: function () { + this.printContainer.textContent = ''; + } +}; + +PDFPrintServiceFactory.instance = { + get supportsPrinting() { + var canvas = document.createElement('canvas'); + var value = 'mozPrintCallback' in canvas; + + return pdfjsLib.shadow(this, 'supportsPrinting', value); + }, + + createPrintService: function (pdfDocument, pagesOverview, printContainer) { + return new FirefoxPrintService(pdfDocument, pagesOverview, + printContainer); + } +}; + +export { + FirefoxPrintService, +}; diff --git a/web/firefoxcom.js b/web/firefoxcom.js index 56a165511..f3d956334 100644 --- a/web/firefoxcom.js +++ b/web/firefoxcom.js @@ -13,29 +13,16 @@ * limitations under the License. */ -'use strict'; +import * as pdfjsLib from 'pdfjs-web/pdfjs'; +import { PDFViewerApplication } from 'pdfjs-web/app'; +import { Preferences } from 'pdfjs-web/preferences'; -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define('pdfjs-web/firefoxcom', ['exports', 'pdfjs-web/preferences', - 'pdfjs-web/app', 'pdfjs-web/pdfjs'], factory); - } else if (typeof exports !== 'undefined') { - factory(exports, require('./preferences.js'), require('./app.js'), - require('./pdfjs.js')); - } else { - factory((root.pdfjsWebFirefoxCom = {}), root.pdfjsWebPreferences, - root.pdfjsWebApp, root.pdfjsWebPDFJS); - } -}(this, function (exports, preferences, app, pdfjsLib) { if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('FIREFOX || MOZCENTRAL')) { throw new Error('Module "pdfjs-web/firefoxcom" shall not be used outside ' + 'FIREFOX and MOZCENTRAL builds.'); } -var Preferences = preferences.Preferences; -var PDFViewerApplication = app.PDFViewerApplication; - var FirefoxCom = (function FirefoxComClosure() { return { /** @@ -291,6 +278,7 @@ document.mozL10n.setExternalLocalizerServices({ } }); -exports.DownloadManager = DownloadManager; -exports.FirefoxCom = FirefoxCom; -})); +export { + DownloadManager, + FirefoxCom, +}; diff --git a/web/grab_to_pan.js b/web/grab_to_pan.js index bdd37a5dd..3f230d757 100644 --- a/web/grab_to_pan.js +++ b/web/grab_to_pan.js @@ -14,224 +14,214 @@ * limitations under the License. */ -'use strict'; - -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define('pdfjs-web/grab_to_pan', ['exports'], factory); - } else if (typeof exports !== 'undefined') { - factory(exports); - } else { - factory((root.pdfjsWebGrabToPan = {})); +/** + * Construct a GrabToPan instance for a given HTML element. + * @param options.element {Element} + * @param options.ignoreTarget {function} optional. See `ignoreTarget(node)` + * @param options.onActiveChanged {function(boolean)} optional. Called + * when grab-to-pan is (de)activated. The first argument is a boolean that + * shows whether grab-to-pan is activated. + */ +function GrabToPan(options) { + this.element = options.element; + this.document = options.element.ownerDocument; + if (typeof options.ignoreTarget === 'function') { + this.ignoreTarget = options.ignoreTarget; } -}(this, function (exports) { + this.onActiveChanged = options.onActiveChanged; + + // Bind the contexts to ensure that `this` always points to + // the GrabToPan instance. + this.activate = this.activate.bind(this); + this.deactivate = this.deactivate.bind(this); + this.toggle = this.toggle.bind(this); + this._onmousedown = this._onmousedown.bind(this); + this._onmousemove = this._onmousemove.bind(this); + this._endPan = this._endPan.bind(this); + + // This overlay will be inserted in the document when the mouse moves during + // a grab operation, to ensure that the cursor has the desired appearance. + var overlay = this.overlay = document.createElement('div'); + overlay.className = 'grab-to-pan-grabbing'; +} +GrabToPan.prototype = { /** - * Construct a GrabToPan instance for a given HTML element. - * @param options.element {Element} - * @param options.ignoreTarget {function} optional. See `ignoreTarget(node)` - * @param options.onActiveChanged {function(boolean)} optional. Called - * when grab-to-pan is (de)activated. The first argument is a boolean that - * shows whether grab-to-pan is activated. + * Class name of element which can be grabbed */ - function GrabToPan(options) { - this.element = options.element; - this.document = options.element.ownerDocument; - if (typeof options.ignoreTarget === 'function') { - this.ignoreTarget = options.ignoreTarget; - } - this.onActiveChanged = options.onActiveChanged; - - // Bind the contexts to ensure that `this` always points to - // the GrabToPan instance. - this.activate = this.activate.bind(this); - this.deactivate = this.deactivate.bind(this); - this.toggle = this.toggle.bind(this); - this._onmousedown = this._onmousedown.bind(this); - this._onmousemove = this._onmousemove.bind(this); - this._endPan = this._endPan.bind(this); - - // This overlay will be inserted in the document when the mouse moves during - // a grab operation, to ensure that the cursor has the desired appearance. - var overlay = this.overlay = document.createElement('div'); - overlay.className = 'grab-to-pan-grabbing'; - } - GrabToPan.prototype = { - /** - * Class name of element which can be grabbed - */ - CSS_CLASS_GRAB: 'grab-to-pan-grab', - - /** - * Bind a mousedown event to the element to enable grab-detection. - */ - activate: function GrabToPan_activate() { - if (!this.active) { - this.active = true; - this.element.addEventListener('mousedown', this._onmousedown, true); - this.element.classList.add(this.CSS_CLASS_GRAB); - if (this.onActiveChanged) { - this.onActiveChanged(true); - } - } - }, - - /** - * Removes all events. Any pending pan session is immediately stopped. - */ - deactivate: function GrabToPan_deactivate() { - if (this.active) { - this.active = false; - this.element.removeEventListener('mousedown', this._onmousedown, true); - this._endPan(); - this.element.classList.remove(this.CSS_CLASS_GRAB); - if (this.onActiveChanged) { - this.onActiveChanged(false); - } - } - }, - - toggle: function GrabToPan_toggle() { - if (this.active) { - this.deactivate(); - } else { - this.activate(); - } - }, - - /** - * Whether to not pan if the target element is clicked. - * Override this method to change the default behaviour. - * - * @param node {Element} The target of the event - * @return {boolean} Whether to not react to the click event. - */ - ignoreTarget: function GrabToPan_ignoreTarget(node) { - // Use matchesSelector to check whether the clicked element - // is (a child of) an input element / link - return node[matchesSelector]( - 'a[href], a[href] *, input, textarea, button, button *, select, option' - ); - }, - - /** - * @private - */ - _onmousedown: function GrabToPan__onmousedown(event) { - if (event.button !== 0 || this.ignoreTarget(event.target)) { - return; - } - if (event.originalTarget) { - try { - // eslint-disable-next-line no-unused-expressions - event.originalTarget.tagName; - } catch (e) { - // Mozilla-specific: element is a scrollbar (XUL element) - return; - } - } - - this.scrollLeftStart = this.element.scrollLeft; - this.scrollTopStart = this.element.scrollTop; - this.clientXStart = event.clientX; - this.clientYStart = event.clientY; - this.document.addEventListener('mousemove', this._onmousemove, true); - this.document.addEventListener('mouseup', this._endPan, true); - // When a scroll event occurs before a mousemove, assume that the user - // dragged a scrollbar (necessary for Opera Presto, Safari and IE) - // (not needed for Chrome/Firefox) - this.element.addEventListener('scroll', this._endPan, true); - event.preventDefault(); - event.stopPropagation(); - - var focusedElement = document.activeElement; - if (focusedElement && !focusedElement.contains(event.target)) { - focusedElement.blur(); - } - }, - - /** - * @private - */ - _onmousemove: function GrabToPan__onmousemove(event) { - this.element.removeEventListener('scroll', this._endPan, true); - if (isLeftMouseReleased(event)) { - this._endPan(); - return; - } - var xDiff = event.clientX - this.clientXStart; - var yDiff = event.clientY - this.clientYStart; - var scrollTop = this.scrollTopStart - yDiff; - var scrollLeft = this.scrollLeftStart - xDiff; - if (this.element.scrollTo) { - this.element.scrollTo({ - top: scrollTop, - left: scrollLeft, - behavior: 'instant', - }); - } else { - this.element.scrollTop = scrollTop; - this.element.scrollLeft = scrollLeft; - } - if (!this.overlay.parentNode) { - document.body.appendChild(this.overlay); - } - }, - - /** - * @private - */ - _endPan: function GrabToPan__endPan() { - this.element.removeEventListener('scroll', this._endPan, true); - this.document.removeEventListener('mousemove', this._onmousemove, true); - this.document.removeEventListener('mouseup', this._endPan, true); - // Note: ChildNode.remove doesn't throw if the parentNode is undefined. - this.overlay.remove(); - } - }; - - // Get the correct (vendor-prefixed) name of the matches method. - var matchesSelector; - ['webkitM', 'mozM', 'msM', 'oM', 'm'].some(function(prefix) { - var name = prefix + 'atches'; - if (name in document.documentElement) { - matchesSelector = name; - } - name += 'Selector'; - if (name in document.documentElement) { - matchesSelector = name; - } - return matchesSelector; // If found, then truthy, and [].some() ends. - }); - - // Browser sniffing because it's impossible to feature-detect - // whether event.which for onmousemove is reliable - var isNotIEorIsIE10plus = !document.documentMode || document.documentMode > 9; - var chrome = window.chrome; - var isChrome15OrOpera15plus = chrome && (chrome.webstore || chrome.app); - // ^ Chrome 15+ ^ Opera 15+ - var isSafari6plus = /Apple/.test(navigator.vendor) && - /Version\/([6-9]\d*|[1-5]\d+)/.test(navigator.userAgent); + CSS_CLASS_GRAB: 'grab-to-pan-grab', /** - * Whether the left mouse is not pressed. - * @param event {MouseEvent} - * @return {boolean} True if the left mouse button is not pressed. - * False if unsure or if the left mouse button is pressed. + * Bind a mousedown event to the element to enable grab-detection. */ - function isLeftMouseReleased(event) { - if ('buttons' in event && isNotIEorIsIE10plus) { - // http://www.w3.org/TR/DOM-Level-3-Events/#events-MouseEvent-buttons - // Firefox 15+ - // Internet Explorer 10+ - return !(event.buttons & 1); + activate: function GrabToPan_activate() { + if (!this.active) { + this.active = true; + this.element.addEventListener('mousedown', this._onmousedown, true); + this.element.classList.add(this.CSS_CLASS_GRAB); + if (this.onActiveChanged) { + this.onActiveChanged(true); + } } - if (isChrome15OrOpera15plus || isSafari6plus) { - // Chrome 14+ - // Opera 15+ - // Safari 6.0+ - return event.which === 0; - } - } + }, - exports.GrabToPan = GrabToPan; -})); + /** + * Removes all events. Any pending pan session is immediately stopped. + */ + deactivate: function GrabToPan_deactivate() { + if (this.active) { + this.active = false; + this.element.removeEventListener('mousedown', this._onmousedown, true); + this._endPan(); + this.element.classList.remove(this.CSS_CLASS_GRAB); + if (this.onActiveChanged) { + this.onActiveChanged(false); + } + } + }, + + toggle: function GrabToPan_toggle() { + if (this.active) { + this.deactivate(); + } else { + this.activate(); + } + }, + + /** + * Whether to not pan if the target element is clicked. + * Override this method to change the default behaviour. + * + * @param node {Element} The target of the event + * @return {boolean} Whether to not react to the click event. + */ + ignoreTarget: function GrabToPan_ignoreTarget(node) { + // Use matchesSelector to check whether the clicked element + // is (a child of) an input element / link + return node[matchesSelector]( + 'a[href], a[href] *, input, textarea, button, button *, select, option' + ); + }, + + /** + * @private + */ + _onmousedown: function GrabToPan__onmousedown(event) { + if (event.button !== 0 || this.ignoreTarget(event.target)) { + return; + } + if (event.originalTarget) { + try { + // eslint-disable-next-line no-unused-expressions + event.originalTarget.tagName; + } catch (e) { + // Mozilla-specific: element is a scrollbar (XUL element) + return; + } + } + + this.scrollLeftStart = this.element.scrollLeft; + this.scrollTopStart = this.element.scrollTop; + this.clientXStart = event.clientX; + this.clientYStart = event.clientY; + this.document.addEventListener('mousemove', this._onmousemove, true); + this.document.addEventListener('mouseup', this._endPan, true); + // When a scroll event occurs before a mousemove, assume that the user + // dragged a scrollbar (necessary for Opera Presto, Safari and IE) + // (not needed for Chrome/Firefox) + this.element.addEventListener('scroll', this._endPan, true); + event.preventDefault(); + event.stopPropagation(); + + var focusedElement = document.activeElement; + if (focusedElement && !focusedElement.contains(event.target)) { + focusedElement.blur(); + } + }, + + /** + * @private + */ + _onmousemove: function GrabToPan__onmousemove(event) { + this.element.removeEventListener('scroll', this._endPan, true); + if (isLeftMouseReleased(event)) { + this._endPan(); + return; + } + var xDiff = event.clientX - this.clientXStart; + var yDiff = event.clientY - this.clientYStart; + var scrollTop = this.scrollTopStart - yDiff; + var scrollLeft = this.scrollLeftStart - xDiff; + if (this.element.scrollTo) { + this.element.scrollTo({ + top: scrollTop, + left: scrollLeft, + behavior: 'instant', + }); + } else { + this.element.scrollTop = scrollTop; + this.element.scrollLeft = scrollLeft; + } + if (!this.overlay.parentNode) { + document.body.appendChild(this.overlay); + } + }, + + /** + * @private + */ + _endPan: function GrabToPan__endPan() { + this.element.removeEventListener('scroll', this._endPan, true); + this.document.removeEventListener('mousemove', this._onmousemove, true); + this.document.removeEventListener('mouseup', this._endPan, true); + // Note: ChildNode.remove doesn't throw if the parentNode is undefined. + this.overlay.remove(); + } +}; + +// Get the correct (vendor-prefixed) name of the matches method. +var matchesSelector; +['webkitM', 'mozM', 'msM', 'oM', 'm'].some(function(prefix) { + var name = prefix + 'atches'; + if (name in document.documentElement) { + matchesSelector = name; + } + name += 'Selector'; + if (name in document.documentElement) { + matchesSelector = name; + } + return matchesSelector; // If found, then truthy, and [].some() ends. +}); + +// Browser sniffing because it's impossible to feature-detect +// whether event.which for onmousemove is reliable +var isNotIEorIsIE10plus = !document.documentMode || document.documentMode > 9; +var chrome = window.chrome; +var isChrome15OrOpera15plus = chrome && (chrome.webstore || chrome.app); +// ^ Chrome 15+ ^ Opera 15+ +var isSafari6plus = /Apple/.test(navigator.vendor) && + /Version\/([6-9]\d*|[1-5]\d+)/.test(navigator.userAgent); + +/** + * Whether the left mouse is not pressed. + * @param event {MouseEvent} + * @return {boolean} True if the left mouse button is not pressed. + * False if unsure or if the left mouse button is pressed. + */ +function isLeftMouseReleased(event) { + if ('buttons' in event && isNotIEorIsIE10plus) { + // http://www.w3.org/TR/DOM-Level-3-Events/#events-MouseEvent-buttons + // Firefox 15+ + // Internet Explorer 10+ + return !(event.buttons & 1); + } + if (isChrome15OrOpera15plus || isSafari6plus) { + // Chrome 14+ + // Opera 15+ + // Safari 6.0+ + return event.which === 0; + } +} + +export { + GrabToPan, +}; diff --git a/web/hand_tool.js b/web/hand_tool.js index e4e401284..eff267db9 100644 --- a/web/hand_tool.js +++ b/web/hand_tool.js @@ -13,24 +13,9 @@ * limitations under the License. */ -'use strict'; - -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define('pdfjs-web/hand_tool', ['exports', 'pdfjs-web/grab_to_pan', - 'pdfjs-web/preferences', 'pdfjs-web/ui_utils'], factory); - } else if (typeof exports !== 'undefined') { - factory(exports, require('./grab_to_pan.js'), require('./preferences.js'), - require('./ui_utils.js')); - } else { - factory((root.pdfjsWebHandTool = {}), root.pdfjsWebGrabToPan, - root.pdfjsWebPreferences, root.pdfjsWebUIUtils); - } -}(this, function (exports, grabToPan, preferences, uiUtils) { - -var GrabToPan = grabToPan.GrabToPan; -var Preferences = preferences.Preferences; -var localized = uiUtils.localized; +import { GrabToPan } from 'pdfjs-web/grab_to_pan'; +import { localized } from 'pdfjs-web/ui_utils'; +import { Preferences } from 'pdfjs-web/preferences'; /** * @typedef {Object} HandToolOptions @@ -110,5 +95,6 @@ var HandTool = (function HandToolClosure() { return HandTool; })(); -exports.HandTool = HandTool; -})); +export { + HandTool, +}; diff --git a/web/overlay_manager.js b/web/overlay_manager.js index 357d8c747..732734270 100644 --- a/web/overlay_manager.js +++ b/web/overlay_manager.js @@ -13,18 +13,6 @@ * limitations under the License. */ -'use strict'; - -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define('pdfjs-web/overlay_manager', ['exports'], factory); - } else if (typeof exports !== 'undefined') { - factory(exports); - } else { - factory((root.pdfjsWebOverlayManager = {})); - } -}(this, function (exports) { - var OverlayManager = { overlays: {}, active: null, @@ -151,5 +139,6 @@ var OverlayManager = { } }; -exports.OverlayManager = OverlayManager; -})); +export { + OverlayManager, +}; diff --git a/web/password_prompt.js b/web/password_prompt.js index e35b7ae5f..771ab8aba 100644 --- a/web/password_prompt.js +++ b/web/password_prompt.js @@ -13,24 +13,9 @@ * limitations under the License. */ -'use strict'; - -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define('pdfjs-web/password_prompt', ['exports', - 'pdfjs-web/ui_utils', 'pdfjs-web/overlay_manager', 'pdfjs-web/pdfjs'], - factory); - } else if (typeof exports !== 'undefined') { - factory(exports, require('./ui_utils.js'), require('./overlay_manager.js'), - require('./pdfjs.js')); - } else { - factory((root.pdfjsWebPasswordPrompt = {}), root.pdfjsWebUIUtils, - root.pdfjsWebOverlayManager, root.pdfjsWebPDFJS); - } -}(this, function (exports, uiUtils, overlayManager, pdfjsLib) { - -var mozL10n = uiUtils.mozL10n; -var OverlayManager = overlayManager.OverlayManager; +import * as pdfjsLib from 'pdfjs-web/pdfjs'; +import { mozL10n } from 'pdfjs-web/ui_utils'; +import { OverlayManager } from 'pdfjs-web/overlay_manager'; /** * @typedef {Object} PasswordPromptOptions @@ -120,5 +105,6 @@ var PasswordPrompt = (function PasswordPromptClosure() { return PasswordPrompt; })(); -exports.PasswordPrompt = PasswordPrompt; -})); +export { + PasswordPrompt, +}; diff --git a/web/pdf_attachment_viewer.js b/web/pdf_attachment_viewer.js index ad05b0f3a..0b0b64ca5 100644 --- a/web/pdf_attachment_viewer.js +++ b/web/pdf_attachment_viewer.js @@ -13,18 +13,7 @@ * limitations under the License. */ -'use strict'; - -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define('pdfjs-web/pdf_attachment_viewer', ['exports', 'pdfjs-web/pdfjs'], - factory); - } else if (typeof exports !== 'undefined') { - factory(exports, require('./pdfjs.js')); - } else { - factory((root.pdfjsWebPDFAttachmentViewer = {}), root.pdfjsWebPDFJS); - } -}(this, function (exports, pdfjsLib) { +import * as pdfjsLib from 'pdfjs-web/pdfjs'; /** * @typedef {Object} PDFAttachmentViewerOptions @@ -205,5 +194,6 @@ var PDFAttachmentViewer = (function PDFAttachmentViewerClosure() { return PDFAttachmentViewer; })(); -exports.PDFAttachmentViewer = PDFAttachmentViewer; -})); +export { + PDFAttachmentViewer, +}; diff --git a/web/pdf_document_properties.js b/web/pdf_document_properties.js index c06bcdb48..1f9acdf2c 100644 --- a/web/pdf_document_properties.js +++ b/web/pdf_document_properties.js @@ -13,23 +13,8 @@ * limitations under the License. */ -'use strict'; - -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define('pdfjs-web/pdf_document_properties', ['exports', - 'pdfjs-web/ui_utils', 'pdfjs-web/overlay_manager'], factory); - } else if (typeof exports !== 'undefined') { - factory(exports, require('./ui_utils.js'), require('./overlay_manager.js')); - } else { - factory((root.pdfjsWebPDFDocumentProperties = {}), root.pdfjsWebUIUtils, - root.pdfjsWebOverlayManager); - } -}(this, function (exports, uiUtils, overlayManager) { - -var getPDFFileNameFromURL = uiUtils.getPDFFileNameFromURL; -var mozL10n = uiUtils.mozL10n; -var OverlayManager = overlayManager.OverlayManager; +import { getPDFFileNameFromURL, mozL10n } from 'pdfjs-web/ui_utils'; +import { OverlayManager } from 'pdfjs-web/overlay_manager'; /** * @typedef {Object} PDFDocumentPropertiesOptions @@ -239,5 +224,6 @@ var PDFDocumentProperties = (function PDFDocumentPropertiesClosure() { return PDFDocumentProperties; })(); -exports.PDFDocumentProperties = PDFDocumentProperties; -})); +export { + PDFDocumentProperties, +}; diff --git a/web/pdf_find_bar.js b/web/pdf_find_bar.js index 3c2e93562..818714a24 100644 --- a/web/pdf_find_bar.js +++ b/web/pdf_find_bar.js @@ -13,23 +13,8 @@ * limitations under the License. */ -'use strict'; - -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define('pdfjs-web/pdf_find_bar', ['exports', - 'pdfjs-web/ui_utils', 'pdfjs-web/pdf_find_controller'], factory); - } else if (typeof exports !== 'undefined') { - factory(exports, require('./ui_utils.js'), - require('./pdf_find_controller.js')); - } else { - factory((root.pdfjsWebPDFFindBar = {}), root.pdfjsWebUIUtils, - root.pdfjsWebPDFFindController); - } -}(this, function (exports, uiUtils, pdfFindController) { - -var mozL10n = uiUtils.mozL10n; -var FindStates = pdfFindController.FindStates; +import { FindStates } from 'pdfjs-web/pdf_find_controller'; +import { mozL10n } from 'pdfjs-web/ui_utils'; /** * Creates a "search bar" given a set of DOM elements that act as controls @@ -236,5 +221,6 @@ var PDFFindBar = (function PDFFindBarClosure() { return PDFFindBar; })(); -exports.PDFFindBar = PDFFindBar; -})); +export { + PDFFindBar, +}; diff --git a/web/pdf_find_controller.js b/web/pdf_find_controller.js index 5017155b3..d5d49fcba 100644 --- a/web/pdf_find_controller.js +++ b/web/pdf_find_controller.js @@ -13,20 +13,7 @@ * limitations under the License. */ -'use strict'; - -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define('pdfjs-web/pdf_find_controller', ['exports', 'pdfjs-web/ui_utils'], - factory); - } else if (typeof exports !== 'undefined') { - factory(exports, require('./ui_utils.js')); - } else { - factory((root.pdfjsWebPDFFindController = {}), root.pdfjsWebUIUtils); - } -}(this, function (exports, uiUtils) { - -var scrollIntoView = uiUtils.scrollIntoView; +import { scrollIntoView } from 'pdfjs-web/ui_utils'; var FindStates = { FIND_FOUND: 0, @@ -505,6 +492,7 @@ var PDFFindController = (function PDFFindControllerClosure() { return PDFFindController; })(); -exports.FindStates = FindStates; -exports.PDFFindController = PDFFindController; -})); +export { + FindStates, + PDFFindController, +}; diff --git a/web/pdf_history.js b/web/pdf_history.js index 7bc208075..5a4691cdb 100644 --- a/web/pdf_history.js +++ b/web/pdf_history.js @@ -14,423 +14,413 @@ */ /* globals chrome */ -'use strict'; +import { domEvents } from 'pdfjs-web/dom_events'; -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define('pdfjs-web/pdf_history', ['exports', 'pdfjs-web/dom_events'], - factory); - } else if (typeof exports !== 'undefined') { - factory(exports, require('./dom_events.js')); - } else { - factory((root.pdfjsWebPDFHistory = {}), root.pdfjsWebDOMEvents); - } -}(this, function (exports, domEvents) { +function PDFHistory(options) { + this.linkService = options.linkService; + this.eventBus = options.eventBus || domEvents.getGlobalEventBus(); - function PDFHistory(options) { - this.linkService = options.linkService; - this.eventBus = options.eventBus || domEvents.getGlobalEventBus(); + this.initialized = false; + this.initialDestination = null; + this.initialBookmark = null; +} - this.initialized = false; - this.initialDestination = null; - this.initialBookmark = null; - } +PDFHistory.prototype = { + /** + * @param {string} fingerprint + */ + initialize: function pdfHistoryInitialize(fingerprint) { + this.initialized = true; + this.reInitialized = false; + this.allowHashChange = true; + this.historyUnlocked = true; + this.isViewerInPresentationMode = false; - PDFHistory.prototype = { - /** - * @param {string} fingerprint - */ - initialize: function pdfHistoryInitialize(fingerprint) { - this.initialized = true; - this.reInitialized = false; - this.allowHashChange = true; - this.historyUnlocked = true; - this.isViewerInPresentationMode = false; + this.previousHash = window.location.hash.substring(1); + this.currentBookmark = ''; + this.currentPage = 0; + this.updatePreviousBookmark = false; + this.previousBookmark = ''; + this.previousPage = 0; + this.nextHashParam = ''; - this.previousHash = window.location.hash.substring(1); - this.currentBookmark = ''; - this.currentPage = 0; - this.updatePreviousBookmark = false; - this.previousBookmark = ''; - this.previousPage = 0; - this.nextHashParam = ''; - - this.fingerprint = fingerprint; - this.currentUid = this.uid = 0; - this.current = {}; - - var state = window.history.state; - if (this._isStateObjectDefined(state)) { - // This corresponds to navigating back to the document - // from another page in the browser history. - if (state.target.dest) { - this.initialDestination = state.target.dest; - } else { - this.initialBookmark = state.target.hash; - } - this.currentUid = state.uid; - this.uid = state.uid + 1; - this.current = state.target; - } else { - // This corresponds to the loading of a new document. - if (state && state.fingerprint && - this.fingerprint !== state.fingerprint) { - // Reinitialize the browsing history when a new document - // is opened in the web viewer. - this.reInitialized = true; - } - this._pushOrReplaceState({fingerprint: this.fingerprint}, true); - } - - var self = this; - window.addEventListener('popstate', function pdfHistoryPopstate(evt) { - if (!self.historyUnlocked) { - return; - } - if (evt.state) { - // Move back/forward in the history. - self._goTo(evt.state); - return; - } - - // If the state is not set, then the user tried to navigate to a - // different hash by manually editing the URL and pressing Enter, or by - // clicking on an in-page link (e.g. the "current view" link). - // Save the current view state to the browser history. - - // Note: In Firefox, history.null could also be null after an in-page - // navigation to the same URL, and without dispatching the popstate - // event: https://bugzilla.mozilla.org/show_bug.cgi?id=1183881 - - if (self.uid === 0) { - // Replace the previous state if it was not explicitly set. - var previousParams = (self.previousHash && self.currentBookmark && - self.previousHash !== self.currentBookmark) ? - {hash: self.currentBookmark, page: self.currentPage} : - {page: 1}; - replacePreviousHistoryState(previousParams, function() { - updateHistoryWithCurrentHash(); - }); - } else { - updateHistoryWithCurrentHash(); - } - }); - - - function updateHistoryWithCurrentHash() { - self.previousHash = window.location.hash.slice(1); - self._pushToHistory({hash: self.previousHash}, false, true); - self._updatePreviousBookmark(); - } - - function replacePreviousHistoryState(params, callback) { - // To modify the previous history entry, the following happens: - // 1. history.back() - // 2. _pushToHistory, which calls history.replaceState( ... ) - // 3. history.forward() - // Because a navigation via the history API does not immediately update - // the history state, the popstate event is used for synchronization. - self.historyUnlocked = false; - - // Suppress the hashchange event to avoid side effects caused by - // navigating back and forward. - self.allowHashChange = false; - window.addEventListener('popstate', rewriteHistoryAfterBack); - history.back(); - - function rewriteHistoryAfterBack() { - window.removeEventListener('popstate', rewriteHistoryAfterBack); - window.addEventListener('popstate', rewriteHistoryAfterForward); - self._pushToHistory(params, false, true); - history.forward(); - } - function rewriteHistoryAfterForward() { - window.removeEventListener('popstate', rewriteHistoryAfterForward); - self.allowHashChange = true; - self.historyUnlocked = true; - callback(); - } - } - - function pdfHistoryBeforeUnload() { - var previousParams = self._getPreviousParams(null, true); - if (previousParams) { - var replacePrevious = (!self.current.dest && - self.current.hash !== self.previousHash); - self._pushToHistory(previousParams, false, replacePrevious); - self._updatePreviousBookmark(); - } - // Remove the event listener when navigating away from the document, - // since 'beforeunload' prevents Firefox from caching the document. - window.removeEventListener('beforeunload', pdfHistoryBeforeUnload); - } - - window.addEventListener('beforeunload', pdfHistoryBeforeUnload); - - window.addEventListener('pageshow', function pdfHistoryPageShow(evt) { - // If the entire viewer (including the PDF file) is cached in - // the browser, we need to reattach the 'beforeunload' event listener - // since the 'DOMContentLoaded' event is not fired on 'pageshow'. - window.addEventListener('beforeunload', pdfHistoryBeforeUnload); - }); - - self.eventBus.on('presentationmodechanged', function(e) { - self.isViewerInPresentationMode = e.active; - }); - }, - - clearHistoryState: function pdfHistory_clearHistoryState() { - this._pushOrReplaceState(null, true); - }, - - _isStateObjectDefined: function pdfHistory_isStateObjectDefined(state) { - return (state && state.uid >= 0 && - state.fingerprint && this.fingerprint === state.fingerprint && - state.target && state.target.hash) ? true : false; - }, - - _pushOrReplaceState: function pdfHistory_pushOrReplaceState(stateObj, - replace) { - // history.state.chromecomState is managed by chromecom.js. - if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('CHROME') && - window.history.state && 'chromecomState' in window.history.state) { - stateObj = stateObj || {}; - stateObj.chromecomState = window.history.state.chromecomState; - } - if (replace) { - if (typeof PDFJSDev === 'undefined' || - PDFJSDev.test('GENERIC || CHROME')) { - window.history.replaceState(stateObj, '', document.URL); - } else { - window.history.replaceState(stateObj, ''); - } - } else { - if (typeof PDFJSDev === 'undefined' || - PDFJSDev.test('GENERIC || CHROME')) { - window.history.pushState(stateObj, '', document.URL); - } else { - window.history.pushState(stateObj, ''); - } - if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('CHROME') && - top === window) { - chrome.runtime.sendMessage('showPageAction'); - } - } - }, - - get isHashChangeUnlocked() { - if (!this.initialized) { - return true; - } - return this.allowHashChange; - }, - - _updatePreviousBookmark: function pdfHistory_updatePreviousBookmark() { - if (this.updatePreviousBookmark && - this.currentBookmark && this.currentPage) { - this.previousBookmark = this.currentBookmark; - this.previousPage = this.currentPage; - this.updatePreviousBookmark = false; - } - }, - - updateCurrentBookmark: function pdfHistoryUpdateCurrentBookmark(bookmark, - pageNum) { - if (this.initialized) { - this.currentBookmark = bookmark.substring(1); - this.currentPage = pageNum | 0; - this._updatePreviousBookmark(); - } - }, - - updateNextHashParam: function pdfHistoryUpdateNextHashParam(param) { - if (this.initialized) { - this.nextHashParam = param; - } - }, - - push: function pdfHistoryPush(params, isInitialBookmark) { - if (!(this.initialized && this.historyUnlocked)) { - return; - } - if (params.dest && !params.hash) { - params.hash = (this.current.hash && this.current.dest && - this.current.dest === params.dest) ? - this.current.hash : - this.linkService.getDestinationHash(params.dest).split('#')[1]; - } - if (params.page) { - params.page |= 0; - } - if (isInitialBookmark) { - var target = window.history.state.target; - if (!target) { - // Invoked when the user specifies an initial bookmark, - // thus setting initialBookmark, when the document is loaded. - this._pushToHistory(params, false); - this.previousHash = window.location.hash.substring(1); - } - this.updatePreviousBookmark = this.nextHashParam ? false : true; - if (target) { - // If the current document is reloaded, - // avoid creating duplicate entries in the history. - this._updatePreviousBookmark(); - } - return; - } - if (this.nextHashParam) { - if (this.nextHashParam === params.hash) { - this.nextHashParam = null; - this.updatePreviousBookmark = true; - return; - } - this.nextHashParam = null; - } - - if (params.hash) { - if (this.current.hash) { - if (this.current.hash !== params.hash) { - this._pushToHistory(params, true); - } else { - if (!this.current.page && params.page) { - this._pushToHistory(params, false, true); - } - this.updatePreviousBookmark = true; - } - } else { - this._pushToHistory(params, true); - } - } else if (this.current.page && params.page && - this.current.page !== params.page) { - this._pushToHistory(params, true); - } - }, - - _getPreviousParams: function pdfHistory_getPreviousParams(onlyCheckPage, - beforeUnload) { - if (!(this.currentBookmark && this.currentPage)) { - return null; - } else if (this.updatePreviousBookmark) { - this.updatePreviousBookmark = false; - } - if (this.uid > 0 && !(this.previousBookmark && this.previousPage)) { - // Prevent the history from getting stuck in the current state, - // effectively preventing the user from going back/forward in - // the history. - // - // This happens if the current position in the document didn't change - // when the history was previously updated. The reasons for this are - // either: - // 1. The current zoom value is such that the document does not need to, - // or cannot, be scrolled to display the destination. - // 2. The previous destination is broken, and doesn't actally point to a - // position within the document. - // (This is either due to a bad PDF generator, or the user making a - // mistake when entering a destination in the hash parameters.) - return null; - } - if ((!this.current.dest && !onlyCheckPage) || beforeUnload) { - if (this.previousBookmark === this.currentBookmark) { - return null; - } - } else if (this.current.page || onlyCheckPage) { - if (this.previousPage === this.currentPage) { - return null; - } - } else { - return null; - } - var params = {hash: this.currentBookmark, page: this.currentPage}; - if (this.isViewerInPresentationMode) { - params.hash = null; - } - return params; - }, - - _stateObj: function pdfHistory_stateObj(params) { - return {fingerprint: this.fingerprint, uid: this.uid, target: params}; - }, - - _pushToHistory: function pdfHistory_pushToHistory(params, - addPrevious, overwrite) { - if (!this.initialized) { - return; - } - if (!params.hash && params.page) { - params.hash = ('page=' + params.page); - } - if (addPrevious && !overwrite) { - var previousParams = this._getPreviousParams(); - if (previousParams) { - var replacePrevious = (!this.current.dest && - this.current.hash !== this.previousHash); - this._pushToHistory(previousParams, false, replacePrevious); - } - } - this._pushOrReplaceState(this._stateObj(params), - (overwrite || this.uid === 0)); - this.currentUid = this.uid++; - this.current = params; - this.updatePreviousBookmark = true; - }, - - _goTo: function pdfHistory_goTo(state) { - if (!(this.initialized && this.historyUnlocked && - this._isStateObjectDefined(state))) { - return; - } - if (!this.reInitialized && state.uid < this.currentUid) { - var previousParams = this._getPreviousParams(true); - if (previousParams) { - this._pushToHistory(this.current, false); - this._pushToHistory(previousParams, false); - this.currentUid = state.uid; - window.history.back(); - return; - } - } - this.historyUnlocked = false; + this.fingerprint = fingerprint; + this.currentUid = this.uid = 0; + this.current = {}; + var state = window.history.state; + if (this._isStateObjectDefined(state)) { + // This corresponds to navigating back to the document + // from another page in the browser history. if (state.target.dest) { - this.linkService.navigateTo(state.target.dest); + this.initialDestination = state.target.dest; } else { - this.linkService.setHash(state.target.hash); + this.initialBookmark = state.target.hash; } this.currentUid = state.uid; - if (state.uid > this.uid) { - this.uid = state.uid; - } + this.uid = state.uid + 1; this.current = state.target; - this.updatePreviousBookmark = true; - - var currentHash = window.location.hash.substring(1); - if (this.previousHash !== currentHash) { - this.allowHashChange = false; + } else { + // This corresponds to the loading of a new document. + if (state && state.fingerprint && + this.fingerprint !== state.fingerprint) { + // Reinitialize the browsing history when a new document + // is opened in the web viewer. + this.reInitialized = true; } - this.previousHash = currentHash; + this._pushOrReplaceState({fingerprint: this.fingerprint}, true); + } - this.historyUnlocked = true; - }, + var self = this; + window.addEventListener('popstate', function pdfHistoryPopstate(evt) { + if (!self.historyUnlocked) { + return; + } + if (evt.state) { + // Move back/forward in the history. + self._goTo(evt.state); + return; + } - back: function pdfHistoryBack() { - this.go(-1); - }, + // If the state is not set, then the user tried to navigate to a + // different hash by manually editing the URL and pressing Enter, or by + // clicking on an in-page link (e.g. the "current view" link). + // Save the current view state to the browser history. - forward: function pdfHistoryForward() { - this.go(1); - }, + // Note: In Firefox, history.null could also be null after an in-page + // navigation to the same URL, and without dispatching the popstate + // event: https://bugzilla.mozilla.org/show_bug.cgi?id=1183881 - go: function pdfHistoryGo(direction) { - if (this.initialized && this.historyUnlocked) { - var state = window.history.state; - if (direction === -1 && state && state.uid > 0) { - window.history.back(); - } else if (direction === 1 && state && state.uid < (this.uid - 1)) { - window.history.forward(); - } + if (self.uid === 0) { + // Replace the previous state if it was not explicitly set. + var previousParams = (self.previousHash && self.currentBookmark && + self.previousHash !== self.currentBookmark) ? + {hash: self.currentBookmark, page: self.currentPage} : + {page: 1}; + replacePreviousHistoryState(previousParams, function() { + updateHistoryWithCurrentHash(); + }); + } else { + updateHistoryWithCurrentHash(); + } + }); + + + function updateHistoryWithCurrentHash() { + self.previousHash = window.location.hash.slice(1); + self._pushToHistory({hash: self.previousHash}, false, true); + self._updatePreviousBookmark(); + } + + function replacePreviousHistoryState(params, callback) { + // To modify the previous history entry, the following happens: + // 1. history.back() + // 2. _pushToHistory, which calls history.replaceState( ... ) + // 3. history.forward() + // Because a navigation via the history API does not immediately update + // the history state, the popstate event is used for synchronization. + self.historyUnlocked = false; + + // Suppress the hashchange event to avoid side effects caused by + // navigating back and forward. + self.allowHashChange = false; + window.addEventListener('popstate', rewriteHistoryAfterBack); + history.back(); + + function rewriteHistoryAfterBack() { + window.removeEventListener('popstate', rewriteHistoryAfterBack); + window.addEventListener('popstate', rewriteHistoryAfterForward); + self._pushToHistory(params, false, true); + history.forward(); + } + function rewriteHistoryAfterForward() { + window.removeEventListener('popstate', rewriteHistoryAfterForward); + self.allowHashChange = true; + self.historyUnlocked = true; + callback(); } } - }; - exports.PDFHistory = PDFHistory; -})); + function pdfHistoryBeforeUnload() { + var previousParams = self._getPreviousParams(null, true); + if (previousParams) { + var replacePrevious = (!self.current.dest && + self.current.hash !== self.previousHash); + self._pushToHistory(previousParams, false, replacePrevious); + self._updatePreviousBookmark(); + } + // Remove the event listener when navigating away from the document, + // since 'beforeunload' prevents Firefox from caching the document. + window.removeEventListener('beforeunload', pdfHistoryBeforeUnload); + } + + window.addEventListener('beforeunload', pdfHistoryBeforeUnload); + + window.addEventListener('pageshow', function pdfHistoryPageShow(evt) { + // If the entire viewer (including the PDF file) is cached in + // the browser, we need to reattach the 'beforeunload' event listener + // since the 'DOMContentLoaded' event is not fired on 'pageshow'. + window.addEventListener('beforeunload', pdfHistoryBeforeUnload); + }); + + self.eventBus.on('presentationmodechanged', function(e) { + self.isViewerInPresentationMode = e.active; + }); + }, + + clearHistoryState: function pdfHistory_clearHistoryState() { + this._pushOrReplaceState(null, true); + }, + + _isStateObjectDefined: function pdfHistory_isStateObjectDefined(state) { + return (state && state.uid >= 0 && + state.fingerprint && this.fingerprint === state.fingerprint && + state.target && state.target.hash) ? true : false; + }, + + _pushOrReplaceState: function pdfHistory_pushOrReplaceState(stateObj, + replace) { + // history.state.chromecomState is managed by chromecom.js. + if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('CHROME') && + window.history.state && 'chromecomState' in window.history.state) { + stateObj = stateObj || {}; + stateObj.chromecomState = window.history.state.chromecomState; + } + if (replace) { + if (typeof PDFJSDev === 'undefined' || + PDFJSDev.test('GENERIC || CHROME')) { + window.history.replaceState(stateObj, '', document.URL); + } else { + window.history.replaceState(stateObj, ''); + } + } else { + if (typeof PDFJSDev === 'undefined' || + PDFJSDev.test('GENERIC || CHROME')) { + window.history.pushState(stateObj, '', document.URL); + } else { + window.history.pushState(stateObj, ''); + } + if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('CHROME') && + top === window) { + chrome.runtime.sendMessage('showPageAction'); + } + } + }, + + get isHashChangeUnlocked() { + if (!this.initialized) { + return true; + } + return this.allowHashChange; + }, + + _updatePreviousBookmark: function pdfHistory_updatePreviousBookmark() { + if (this.updatePreviousBookmark && + this.currentBookmark && this.currentPage) { + this.previousBookmark = this.currentBookmark; + this.previousPage = this.currentPage; + this.updatePreviousBookmark = false; + } + }, + + updateCurrentBookmark: function pdfHistoryUpdateCurrentBookmark(bookmark, + pageNum) { + if (this.initialized) { + this.currentBookmark = bookmark.substring(1); + this.currentPage = pageNum | 0; + this._updatePreviousBookmark(); + } + }, + + updateNextHashParam: function pdfHistoryUpdateNextHashParam(param) { + if (this.initialized) { + this.nextHashParam = param; + } + }, + + push: function pdfHistoryPush(params, isInitialBookmark) { + if (!(this.initialized && this.historyUnlocked)) { + return; + } + if (params.dest && !params.hash) { + params.hash = (this.current.hash && this.current.dest && + this.current.dest === params.dest) ? + this.current.hash : + this.linkService.getDestinationHash(params.dest).split('#')[1]; + } + if (params.page) { + params.page |= 0; + } + if (isInitialBookmark) { + var target = window.history.state.target; + if (!target) { + // Invoked when the user specifies an initial bookmark, + // thus setting initialBookmark, when the document is loaded. + this._pushToHistory(params, false); + this.previousHash = window.location.hash.substring(1); + } + this.updatePreviousBookmark = this.nextHashParam ? false : true; + if (target) { + // If the current document is reloaded, + // avoid creating duplicate entries in the history. + this._updatePreviousBookmark(); + } + return; + } + if (this.nextHashParam) { + if (this.nextHashParam === params.hash) { + this.nextHashParam = null; + this.updatePreviousBookmark = true; + return; + } + this.nextHashParam = null; + } + + if (params.hash) { + if (this.current.hash) { + if (this.current.hash !== params.hash) { + this._pushToHistory(params, true); + } else { + if (!this.current.page && params.page) { + this._pushToHistory(params, false, true); + } + this.updatePreviousBookmark = true; + } + } else { + this._pushToHistory(params, true); + } + } else if (this.current.page && params.page && + this.current.page !== params.page) { + this._pushToHistory(params, true); + } + }, + + _getPreviousParams: function pdfHistory_getPreviousParams(onlyCheckPage, + beforeUnload) { + if (!(this.currentBookmark && this.currentPage)) { + return null; + } else if (this.updatePreviousBookmark) { + this.updatePreviousBookmark = false; + } + if (this.uid > 0 && !(this.previousBookmark && this.previousPage)) { + // Prevent the history from getting stuck in the current state, + // effectively preventing the user from going back/forward in + // the history. + // + // This happens if the current position in the document didn't change + // when the history was previously updated. The reasons for this are + // either: + // 1. The current zoom value is such that the document does not need to, + // or cannot, be scrolled to display the destination. + // 2. The previous destination is broken, and doesn't actally point to a + // position within the document. + // (This is either due to a bad PDF generator, or the user making a + // mistake when entering a destination in the hash parameters.) + return null; + } + if ((!this.current.dest && !onlyCheckPage) || beforeUnload) { + if (this.previousBookmark === this.currentBookmark) { + return null; + } + } else if (this.current.page || onlyCheckPage) { + if (this.previousPage === this.currentPage) { + return null; + } + } else { + return null; + } + var params = {hash: this.currentBookmark, page: this.currentPage}; + if (this.isViewerInPresentationMode) { + params.hash = null; + } + return params; + }, + + _stateObj: function pdfHistory_stateObj(params) { + return {fingerprint: this.fingerprint, uid: this.uid, target: params}; + }, + + _pushToHistory: function pdfHistory_pushToHistory(params, + addPrevious, overwrite) { + if (!this.initialized) { + return; + } + if (!params.hash && params.page) { + params.hash = ('page=' + params.page); + } + if (addPrevious && !overwrite) { + var previousParams = this._getPreviousParams(); + if (previousParams) { + var replacePrevious = (!this.current.dest && + this.current.hash !== this.previousHash); + this._pushToHistory(previousParams, false, replacePrevious); + } + } + this._pushOrReplaceState(this._stateObj(params), + (overwrite || this.uid === 0)); + this.currentUid = this.uid++; + this.current = params; + this.updatePreviousBookmark = true; + }, + + _goTo: function pdfHistory_goTo(state) { + if (!(this.initialized && this.historyUnlocked && + this._isStateObjectDefined(state))) { + return; + } + if (!this.reInitialized && state.uid < this.currentUid) { + var previousParams = this._getPreviousParams(true); + if (previousParams) { + this._pushToHistory(this.current, false); + this._pushToHistory(previousParams, false); + this.currentUid = state.uid; + window.history.back(); + return; + } + } + this.historyUnlocked = false; + + if (state.target.dest) { + this.linkService.navigateTo(state.target.dest); + } else { + this.linkService.setHash(state.target.hash); + } + this.currentUid = state.uid; + if (state.uid > this.uid) { + this.uid = state.uid; + } + this.current = state.target; + this.updatePreviousBookmark = true; + + var currentHash = window.location.hash.substring(1); + if (this.previousHash !== currentHash) { + this.allowHashChange = false; + } + this.previousHash = currentHash; + + this.historyUnlocked = true; + }, + + back: function pdfHistoryBack() { + this.go(-1); + }, + + forward: function pdfHistoryForward() { + this.go(1); + }, + + go: function pdfHistoryGo(direction) { + if (this.initialized && this.historyUnlocked) { + var state = window.history.state; + if (direction === -1 && state && state.uid > 0) { + window.history.back(); + } else if (direction === 1 && state && state.uid < (this.uid - 1)) { + window.history.forward(); + } + } + } +}; + +export { + PDFHistory, +}; diff --git a/web/pdf_link_service.js b/web/pdf_link_service.js index 15ca78b17..446ed98ba 100644 --- a/web/pdf_link_service.js +++ b/web/pdf_link_service.js @@ -13,21 +13,8 @@ * limitations under the License. */ -'use strict'; - -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define('pdfjs-web/pdf_link_service', ['exports', 'pdfjs-web/ui_utils', - 'pdfjs-web/dom_events'], factory); - } else if (typeof exports !== 'undefined') { - factory(exports, require('./ui_utils.js'), require('./dom_events.js')); - } else { - factory((root.pdfjsWebPDFLinkService = {}), root.pdfjsWebUIUtils, - root.pdfjsWebDOMEvents); - } -}(this, function (exports, uiUtils, domEvents) { - -var parseQueryString = uiUtils.parseQueryString; +import { domEvents } from 'pdfjs-web/dom_events'; +import { parseQueryString } from 'pdfjs-web/ui_utils'; var PageNumberRegExp = /^\d+$/; function isPageNumber(str) { @@ -487,6 +474,7 @@ var SimpleLinkService = (function SimpleLinkServiceClosure() { return SimpleLinkService; })(); -exports.PDFLinkService = PDFLinkService; -exports.SimpleLinkService = SimpleLinkService; -})); +export { + PDFLinkService, + SimpleLinkService, +}; diff --git a/web/pdf_outline_viewer.js b/web/pdf_outline_viewer.js index 0d080bdc0..0098489f0 100644 --- a/web/pdf_outline_viewer.js +++ b/web/pdf_outline_viewer.js @@ -13,18 +13,7 @@ * limitations under the License. */ -'use strict'; - -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define('pdfjs-web/pdf_outline_viewer', ['exports', 'pdfjs-web/pdfjs'], - factory); - } else if (typeof exports !== 'undefined') { - factory(exports, require('./pdfjs.js')); - } else { - factory((root.pdfjsWebPDFOutlineViewer = {}), root.pdfjsWebPDFJS); - } -}(this, function (exports, pdfjsLib) { +import * as pdfjsLib from 'pdfjs-web/pdfjs'; var PDFJS = pdfjsLib.PDFJS; @@ -231,5 +220,6 @@ var PDFOutlineViewer = (function PDFOutlineViewerClosure() { return PDFOutlineViewer; })(); -exports.PDFOutlineViewer = PDFOutlineViewer; -})); +export { + PDFOutlineViewer, +}; diff --git a/web/pdf_page_view.js b/web/pdf_page_view.js index 48289d2d2..5718bb102 100644 --- a/web/pdf_page_view.js +++ b/web/pdf_page_view.js @@ -13,31 +13,13 @@ * limitations under the License. */ -'use strict'; - -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define('pdfjs-web/pdf_page_view', ['exports', - 'pdfjs-web/ui_utils', 'pdfjs-web/pdf_rendering_queue', - 'pdfjs-web/dom_events', 'pdfjs-web/pdfjs'], factory); - } else if (typeof exports !== 'undefined') { - factory(exports, require('./ui_utils.js'), - require('./pdf_rendering_queue.js'), require('./dom_events.js'), - require('./pdfjs.js')); - } else { - factory((root.pdfjsWebPDFPageView = {}), root.pdfjsWebUIUtils, - root.pdfjsWebPDFRenderingQueue, root.pdfjsWebDOMEvents, - root.pdfjsWebPDFJS); - } -}(this, function (exports, uiUtils, pdfRenderingQueue, domEvents, pdfjsLib) { - -var CSS_UNITS = uiUtils.CSS_UNITS; -var DEFAULT_SCALE = uiUtils.DEFAULT_SCALE; -var getOutputScale = uiUtils.getOutputScale; -var approximateFraction = uiUtils.approximateFraction; -var roundToDivide = uiUtils.roundToDivide; -var RendererType = uiUtils.RendererType; -var RenderingStates = pdfRenderingQueue.RenderingStates; +import * as pdfjsLib from 'pdfjs-web/pdfjs'; +import { + approximateFraction, CSS_UNITS, DEFAULT_SCALE, getOutputScale, RendererType, + roundToDivide +} from 'pdfjs-web/ui_utils'; +import { domEvents } from 'pdfjs-web/dom_events'; +import { RenderingStates } from 'pdfjs-web/pdf_rendering_queue'; var TEXT_LAYER_RENDER_DELAY = 200; // ms @@ -691,5 +673,6 @@ var PDFPageView = (function PDFPageViewClosure() { return PDFPageView; })(); -exports.PDFPageView = PDFPageView; -})); +export { + PDFPageView, +}; diff --git a/web/pdf_presentation_mode.js b/web/pdf_presentation_mode.js index 036408aa4..c55162ce9 100644 --- a/web/pdf_presentation_mode.js +++ b/web/pdf_presentation_mode.js @@ -13,19 +13,7 @@ * limitations under the License. */ -'use strict'; - -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define('pdfjs-web/pdf_presentation_mode', ['exports', 'pdfjs-web/ui_utils'], - factory); - } else if (typeof exports !== 'undefined') { - factory(exports, require('./ui_utils.js')); - } else { - factory((root.pdfjsWebPDFPresentationMode = {}), root.pdfjsWebUIUtils); - } -}(this, function (exports, uiUtils) { -var normalizeWheelEventDelta = uiUtils.normalizeWheelEventDelta; +import { normalizeWheelEventDelta } from 'pdfjs-web/ui_utils'; var DELAY_BEFORE_RESETTING_SWITCH_IN_PROGRESS = 1500; // in ms var DELAY_BEFORE_HIDING_CONTROLS = 3000; // in ms @@ -517,5 +505,6 @@ var PDFPresentationMode = (function PDFPresentationModeClosure() { return PDFPresentationMode; })(); -exports.PDFPresentationMode = PDFPresentationMode; -})); +export { + PDFPresentationMode, +}; diff --git a/web/pdf_print_service.js b/web/pdf_print_service.js index 6e6b8da70..02f677bb7 100644 --- a/web/pdf_print_service.js +++ b/web/pdf_print_service.js @@ -13,338 +13,324 @@ * limitations under the License. */ -'use strict'; +import * as pdfjsLib from 'pdfjs-web/pdfjs'; +import { CSS_UNITS, mozL10n } from 'pdfjs-web/ui_utils'; +import { OverlayManager } from 'pdfjs-web/overlay_manager'; +import { PDFPrintServiceFactory } from 'pdfjs-web/app'; -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define('pdfjs-web/pdf_print_service', ['exports', 'pdfjs-web/ui_utils', - 'pdfjs-web/overlay_manager', 'pdfjs-web/app', 'pdfjs-web/pdfjs'], - factory); - } else if (typeof exports !== 'undefined') { - factory(exports, require('./ui_utils.js'), require('./overlay_manager.js'), - require('./app.js'), require('./pdfjs.js')); - } else { - factory((root.pdfjsWebPDFPrintService = {}), root.pdfjsWebUIUtils, - root.pdfjsWebOverlayManager, root.pdfjsWebApp, root.pdfjsWebPDFJS); - } -}(this, function (exports, uiUtils, overlayManager, app, pdfjsLib) { - var mozL10n = uiUtils.mozL10n; - var CSS_UNITS = uiUtils.CSS_UNITS; - var PDFPrintServiceFactory = app.PDFPrintServiceFactory; - var OverlayManager = overlayManager.OverlayManager; +var activeService = null; - var activeService = null; +// Renders the page to the canvas of the given print service, and returns +// the suggested dimensions of the output page. +function renderPage(activeServiceOnEntry, pdfDocument, pageNumber, size) { + var scratchCanvas = activeService.scratchCanvas; - // Renders the page to the canvas of the given print service, and returns - // the suggested dimensions of the output page. - function renderPage(activeServiceOnEntry, pdfDocument, pageNumber, size) { - var scratchCanvas = activeService.scratchCanvas; + // The size of the canvas in pixels for printing. + var PRINT_RESOLUTION = 150; + var PRINT_UNITS = PRINT_RESOLUTION / 72.0; + scratchCanvas.width = Math.floor(size.width * PRINT_UNITS); + scratchCanvas.height = Math.floor(size.height * PRINT_UNITS); - // The size of the canvas in pixels for printing. - var PRINT_RESOLUTION = 150; - var PRINT_UNITS = PRINT_RESOLUTION / 72.0; - scratchCanvas.width = Math.floor(size.width * PRINT_UNITS); - scratchCanvas.height = Math.floor(size.height * PRINT_UNITS); + // The physical size of the img as specified by the PDF document. + var width = Math.floor(size.width * CSS_UNITS) + 'px'; + var height = Math.floor(size.height * CSS_UNITS) + 'px'; - // The physical size of the img as specified by the PDF document. - var width = Math.floor(size.width * CSS_UNITS) + 'px'; - var height = Math.floor(size.height * CSS_UNITS) + 'px'; + var ctx = scratchCanvas.getContext('2d'); + ctx.save(); + ctx.fillStyle = 'rgb(255, 255, 255)'; + ctx.fillRect(0, 0, scratchCanvas.width, scratchCanvas.height); + ctx.restore(); - var ctx = scratchCanvas.getContext('2d'); - ctx.save(); - ctx.fillStyle = 'rgb(255, 255, 255)'; - ctx.fillRect(0, 0, scratchCanvas.width, scratchCanvas.height); - ctx.restore(); + return pdfDocument.getPage(pageNumber).then(function (pdfPage) { + var renderContext = { + canvasContext: ctx, + transform: [PRINT_UNITS, 0, 0, PRINT_UNITS, 0, 0], + viewport: pdfPage.getViewport(1, size.rotation), + intent: 'print' + }; + return pdfPage.render(renderContext).promise; + }).then(function () { + return { + width: width, + height: height, + }; + }); +} - return pdfDocument.getPage(pageNumber).then(function (pdfPage) { - var renderContext = { - canvasContext: ctx, - transform: [PRINT_UNITS, 0, 0, PRINT_UNITS, 0, 0], - viewport: pdfPage.getViewport(1, size.rotation), - intent: 'print' - }; - return pdfPage.render(renderContext).promise; - }).then(function () { - return { - width: width, - height: height, - }; - }); - } +function PDFPrintService(pdfDocument, pagesOverview, printContainer) { + this.pdfDocument = pdfDocument; + this.pagesOverview = pagesOverview; + this.printContainer = printContainer; + this.currentPage = -1; + // The temporary canvas where renderPage paints one page at a time. + this.scratchCanvas = document.createElement('canvas'); +} - function PDFPrintService(pdfDocument, pagesOverview, printContainer) { - this.pdfDocument = pdfDocument; - this.pagesOverview = pagesOverview; - this.printContainer = printContainer; - this.currentPage = -1; - // The temporary canvas where renderPage paints one page at a time. - this.scratchCanvas = document.createElement('canvas'); - } +PDFPrintService.prototype = { + layout: function () { + this.throwIfInactive(); - PDFPrintService.prototype = { - layout: function () { - this.throwIfInactive(); + var body = document.querySelector('body'); + body.setAttribute('data-pdfjsprinting', true); - var body = document.querySelector('body'); - body.setAttribute('data-pdfjsprinting', true); + var hasEqualPageSizes = this.pagesOverview.every(function (size) { + return size.width === this.pagesOverview[0].width && + size.height === this.pagesOverview[0].height; + }, this); + if (!hasEqualPageSizes) { + console.warn('Not all pages have the same size. The printed ' + + 'result may be incorrect!'); + } - var hasEqualPageSizes = this.pagesOverview.every(function (size) { - return size.width === this.pagesOverview[0].width && - size.height === this.pagesOverview[0].height; - }, this); - if (!hasEqualPageSizes) { - console.warn('Not all pages have the same size. The printed ' + - 'result may be incorrect!'); + // Insert a @page + size rule to make sure that the page size is correctly + // set. Note that we assume that all pages have the same size, because + // variable-size pages are not supported yet (e.g. in Chrome & Firefox). + // TODO(robwu): Use named pages when size calculation bugs get resolved + // (e.g. https://crbug.com/355116) AND when support for named pages is + // added (http://www.w3.org/TR/css3-page/#using-named-pages). + // In browsers where @page + size is not supported (such as Firefox, + // https://bugzil.la/851441), the next stylesheet will be ignored and the + // user has to select the correct paper size in the UI if wanted. + this.pageStyleSheet = document.createElement('style'); + var pageSize = this.pagesOverview[0]; + this.pageStyleSheet.textContent = + // "size: " is what we need. But also add "A4" because + // Firefox incorrectly reports support for the other value. + '@supports ((size:A4) and (size:1pt 1pt)) {' + + '@page { size: ' + pageSize.width + 'pt ' + pageSize.height + 'pt;}' + + '}'; + body.appendChild(this.pageStyleSheet); + }, + + destroy: function () { + if (activeService !== this) { + // |activeService| cannot be replaced without calling destroy() first, + // so if it differs then an external consumer has a stale reference to + // us. + return; + } + this.printContainer.textContent = ''; + if (this.pageStyleSheet && this.pageStyleSheet.parentNode) { + this.pageStyleSheet.parentNode.removeChild(this.pageStyleSheet); + this.pageStyleSheet = null; + } + this.scratchCanvas.width = this.scratchCanvas.height = 0; + this.scratchCanvas = null; + activeService = null; + ensureOverlay().then(function () { + if (OverlayManager.active !== 'printServiceOverlay') { + return; // overlay was already closed } + OverlayManager.close('printServiceOverlay'); + }); + }, - // Insert a @page + size rule to make sure that the page size is correctly - // set. Note that we assume that all pages have the same size, because - // variable-size pages are not supported yet (e.g. in Chrome & Firefox). - // TODO(robwu): Use named pages when size calculation bugs get resolved - // (e.g. https://crbug.com/355116) AND when support for named pages is - // added (http://www.w3.org/TR/css3-page/#using-named-pages). - // In browsers where @page + size is not supported (such as Firefox, - // https://bugzil.la/851441), the next stylesheet will be ignored and the - // user has to select the correct paper size in the UI if wanted. - this.pageStyleSheet = document.createElement('style'); - var pageSize = this.pagesOverview[0]; - this.pageStyleSheet.textContent = - // "size: " is what we need. But also add "A4" because - // Firefox incorrectly reports support for the other value. - '@supports ((size:A4) and (size:1pt 1pt)) {' + - '@page { size: ' + pageSize.width + 'pt ' + pageSize.height + 'pt;}' + - '}'; - body.appendChild(this.pageStyleSheet); - }, - - destroy: function () { - if (activeService !== this) { - // |activeService| cannot be replaced without calling destroy() first, - // so if it differs then an external consumer has a stale reference to - // us. + renderPages: function () { + var pageCount = this.pagesOverview.length; + var renderNextPage = function (resolve, reject) { + this.throwIfInactive(); + if (++this.currentPage >= pageCount) { + renderProgress(pageCount, pageCount); + resolve(); return; } - this.printContainer.textContent = ''; - if (this.pageStyleSheet && this.pageStyleSheet.parentNode) { - this.pageStyleSheet.parentNode.removeChild(this.pageStyleSheet); - this.pageStyleSheet = null; - } - this.scratchCanvas.width = this.scratchCanvas.height = 0; - this.scratchCanvas = null; - activeService = null; - ensureOverlay().then(function () { - if (OverlayManager.active !== 'printServiceOverlay') { - return; // overlay was already closed - } - OverlayManager.close('printServiceOverlay'); - }); - }, + var index = this.currentPage; + renderProgress(index, pageCount); + renderPage(this, this.pdfDocument, index + 1, this.pagesOverview[index]) + .then(this.useRenderedPage.bind(this)) + .then(function () { + renderNextPage(resolve, reject); + }, reject); + }.bind(this); + return new Promise(renderNextPage); + }, - renderPages: function () { - var pageCount = this.pagesOverview.length; - var renderNextPage = function (resolve, reject) { - this.throwIfInactive(); - if (++this.currentPage >= pageCount) { - renderProgress(pageCount, pageCount); + useRenderedPage: function (printItem) { + this.throwIfInactive(); + var img = document.createElement('img'); + img.style.width = printItem.width; + img.style.height = printItem.height; + + var scratchCanvas = this.scratchCanvas; + if (('toBlob' in scratchCanvas) && + !pdfjsLib.PDFJS.disableCreateObjectURL) { + scratchCanvas.toBlob(function (blob) { + img.src = URL.createObjectURL(blob); + }); + } else { + img.src = scratchCanvas.toDataURL(); + } + + var wrapper = document.createElement('div'); + wrapper.appendChild(img); + this.printContainer.appendChild(wrapper); + + return new Promise(function (resolve, reject) { + img.onload = resolve; + img.onerror = reject; + }); + }, + + performPrint: function () { + this.throwIfInactive(); + return new Promise(function (resolve) { + // Push window.print in the macrotask queue to avoid being affected by + // the deprecation of running print() code in a microtask, see + // https://github.com/mozilla/pdf.js/issues/7547. + setTimeout(function () { + if (!this.active) { resolve(); return; } - var index = this.currentPage; - renderProgress(index, pageCount); - renderPage(this, this.pdfDocument, index + 1, this.pagesOverview[index]) - .then(this.useRenderedPage.bind(this)) - .then(function () { - renderNextPage(resolve, reject); - }, reject); - }.bind(this); - return new Promise(renderNextPage); - }, + print.call(window); + // Delay promise resolution in case print() was not synchronous. + setTimeout(resolve, 20); // Tidy-up. + }.bind(this), 0); + }.bind(this)); + }, - useRenderedPage: function (printItem) { - this.throwIfInactive(); - var img = document.createElement('img'); - img.style.width = printItem.width; - img.style.height = printItem.height; + get active() { + return this === activeService; + }, - var scratchCanvas = this.scratchCanvas; - if (('toBlob' in scratchCanvas) && - !pdfjsLib.PDFJS.disableCreateObjectURL) { - scratchCanvas.toBlob(function (blob) { - img.src = URL.createObjectURL(blob); - }); - } else { - img.src = scratchCanvas.toDataURL(); - } - - var wrapper = document.createElement('div'); - wrapper.appendChild(img); - this.printContainer.appendChild(wrapper); - - return new Promise(function (resolve, reject) { - img.onload = resolve; - img.onerror = reject; - }); - }, - - performPrint: function () { - this.throwIfInactive(); - return new Promise(function (resolve) { - // Push window.print in the macrotask queue to avoid being affected by - // the deprecation of running print() code in a microtask, see - // https://github.com/mozilla/pdf.js/issues/7547. - setTimeout(function () { - if (!this.active) { - resolve(); - return; - } - print.call(window); - // Delay promise resolution in case print() was not synchronous. - setTimeout(resolve, 20); // Tidy-up. - }.bind(this), 0); - }.bind(this)); - }, - - get active() { - return this === activeService; - }, - - throwIfInactive: function () { - if (!this.active) { - throw new Error('This print request was cancelled or completed.'); - } - }, - }; + throwIfInactive: function () { + if (!this.active) { + throw new Error('This print request was cancelled or completed.'); + } + }, +}; - var print = window.print; - window.print = function print() { +var print = window.print; +window.print = function print() { + if (activeService) { + console.warn('Ignored window.print() because of a pending print job.'); + return; + } + ensureOverlay().then(function () { if (activeService) { - console.warn('Ignored window.print() because of a pending print job.'); - return; + OverlayManager.open('printServiceOverlay'); } - ensureOverlay().then(function () { - if (activeService) { - OverlayManager.open('printServiceOverlay'); - } - }); + }); - try { - dispatchEvent('beforeprint'); - } finally { - if (!activeService) { - console.error('Expected print service to be initialized.'); - if (OverlayManager.active === 'printServiceOverlay') { - OverlayManager.close('printServiceOverlay'); - } - return; // eslint-disable-line no-unsafe-finally + try { + dispatchEvent('beforeprint'); + } finally { + if (!activeService) { + console.error('Expected print service to be initialized.'); + if (OverlayManager.active === 'printServiceOverlay') { + OverlayManager.close('printServiceOverlay'); } - var activeServiceOnEntry = activeService; - activeService.renderPages().then(function () { - return activeServiceOnEntry.performPrint(); - }).catch(function () { - // Ignore any error messages. - }).then(function () { - // aborts acts on the "active" print request, so we need to check - // whether the print request (activeServiceOnEntry) is still active. - // Without the check, an unrelated print request (created after aborting - // this print request while the pages were being generated) would be - // aborted. - if (activeServiceOnEntry.active) { - abort(); - } - }); + return; // eslint-disable-line no-unsafe-finally } - }; - - function dispatchEvent(eventType) { - var event = document.createEvent('CustomEvent'); - event.initCustomEvent(eventType, false, false, 'custom'); - window.dispatchEvent(event); - } - - function abort() { - if (activeService) { - activeService.destroy(); - dispatchEvent('afterprint'); - } - } - - function renderProgress(index, total) { - var progressContainer = document.getElementById('printServiceOverlay'); - var progress = Math.round(100 * index / total); - var progressBar = progressContainer.querySelector('progress'); - var progressPerc = progressContainer.querySelector('.relative-progress'); - progressBar.value = progress; - progressPerc.textContent = mozL10n.get('print_progress_percent', - {progress: progress}, progress + '%'); - } - - var hasAttachEvent = !!document.attachEvent; - - window.addEventListener('keydown', function(event) { - // Intercept Cmd/Ctrl + P in all browsers. - // Also intercept Cmd/Ctrl + Shift + P in Chrome and Opera - if (event.keyCode === /* P= */ 80 && (event.ctrlKey || event.metaKey) && - !event.altKey && (!event.shiftKey || window.chrome || window.opera)) { - window.print(); - if (hasAttachEvent) { - // Only attachEvent can cancel Ctrl + P dialog in IE <=10 - // attachEvent is gone in IE11, so the dialog will re-appear in IE11. - return; - } - event.preventDefault(); - if (event.stopImmediatePropagation) { - event.stopImmediatePropagation(); - } else { - event.stopPropagation(); - } - return; - } - }, true); - if (hasAttachEvent) { - document.attachEvent('onkeydown', function(event) { - event = event || window.event; - if (event.keyCode === /* P= */ 80 && event.ctrlKey) { - event.keyCode = 0; - return false; + var activeServiceOnEntry = activeService; + activeService.renderPages().then(function () { + return activeServiceOnEntry.performPrint(); + }).catch(function () { + // Ignore any error messages. + }).then(function () { + // aborts acts on the "active" print request, so we need to check + // whether the print request (activeServiceOnEntry) is still active. + // Without the check, an unrelated print request (created after aborting + // this print request while the pages were being generated) would be + // aborted. + if (activeServiceOnEntry.active) { + abort(); } }); } +}; - if ('onbeforeprint' in window) { - // Do not propagate before/afterprint events when they are not triggered - // from within this polyfill. (FF/IE). - var stopPropagationIfNeeded = function(event) { - if (event.detail !== 'custom' && event.stopImmediatePropagation) { - event.stopImmediatePropagation(); - } - }; - window.addEventListener('beforeprint', stopPropagationIfNeeded); - window.addEventListener('afterprint', stopPropagationIfNeeded); +function dispatchEvent(eventType) { + var event = document.createEvent('CustomEvent'); + event.initCustomEvent(eventType, false, false, 'custom'); + window.dispatchEvent(event); +} + +function abort() { + if (activeService) { + activeService.destroy(); + dispatchEvent('afterprint'); } +} - var overlayPromise; - function ensureOverlay() { - if (!overlayPromise) { - overlayPromise = OverlayManager.register('printServiceOverlay', - document.getElementById('printServiceOverlay'), abort, true); - document.getElementById('printCancel').onclick = abort; +function renderProgress(index, total) { + var progressContainer = document.getElementById('printServiceOverlay'); + var progress = Math.round(100 * index / total); + var progressBar = progressContainer.querySelector('progress'); + var progressPerc = progressContainer.querySelector('.relative-progress'); + progressBar.value = progress; + progressPerc.textContent = mozL10n.get('print_progress_percent', + {progress: progress}, progress + '%'); +} + +var hasAttachEvent = !!document.attachEvent; + +window.addEventListener('keydown', function(event) { + // Intercept Cmd/Ctrl + P in all browsers. + // Also intercept Cmd/Ctrl + Shift + P in Chrome and Opera + if (event.keyCode === /* P= */ 80 && (event.ctrlKey || event.metaKey) && + !event.altKey && (!event.shiftKey || window.chrome || window.opera)) { + window.print(); + if (hasAttachEvent) { + // Only attachEvent can cancel Ctrl + P dialog in IE <=10 + // attachEvent is gone in IE11, so the dialog will re-appear in IE11. + return; } - return overlayPromise; + event.preventDefault(); + if (event.stopImmediatePropagation) { + event.stopImmediatePropagation(); + } else { + event.stopPropagation(); + } + return; } +}, true); +if (hasAttachEvent) { + document.attachEvent('onkeydown', function(event) { + event = event || window.event; + if (event.keyCode === /* P= */ 80 && event.ctrlKey) { + event.keyCode = 0; + return false; + } + }); +} - PDFPrintServiceFactory.instance = { - supportsPrinting: true, - - createPrintService: function (pdfDocument, pagesOverview, printContainer) { - if (activeService) { - throw new Error('The print service is created and active.'); - } - activeService = new PDFPrintService(pdfDocument, pagesOverview, - printContainer); - return activeService; +if ('onbeforeprint' in window) { + // Do not propagate before/afterprint events when they are not triggered + // from within this polyfill. (FF/IE). + var stopPropagationIfNeeded = function(event) { + if (event.detail !== 'custom' && event.stopImmediatePropagation) { + event.stopImmediatePropagation(); } }; + window.addEventListener('beforeprint', stopPropagationIfNeeded); + window.addEventListener('afterprint', stopPropagationIfNeeded); +} - exports.PDFPrintService = PDFPrintService; -})); +var overlayPromise; +function ensureOverlay() { + if (!overlayPromise) { + overlayPromise = OverlayManager.register('printServiceOverlay', + document.getElementById('printServiceOverlay'), abort, true); + document.getElementById('printCancel').onclick = abort; + } + return overlayPromise; +} + +PDFPrintServiceFactory.instance = { + supportsPrinting: true, + + createPrintService: function (pdfDocument, pagesOverview, printContainer) { + if (activeService) { + throw new Error('The print service is created and active.'); + } + activeService = new PDFPrintService(pdfDocument, pagesOverview, + printContainer); + return activeService; + } +}; + +export { + PDFPrintService, +}; diff --git a/web/pdf_rendering_queue.js b/web/pdf_rendering_queue.js index 63f0ba4bb..08666eebf 100644 --- a/web/pdf_rendering_queue.js +++ b/web/pdf_rendering_queue.js @@ -13,18 +13,6 @@ * limitations under the License. */ -'use strict'; - -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define('pdfjs-web/pdf_rendering_queue', ['exports'], factory); - } else if (typeof exports !== 'undefined') { - factory(exports); - } else { - factory((root.pdfjsWebPDFRenderingQueue = {})); - } -}(this, function (exports) { - var CLEANUP_TIMEOUT = 30000; var RenderingStates = { @@ -186,6 +174,7 @@ var PDFRenderingQueue = (function PDFRenderingQueueClosure() { return PDFRenderingQueue; })(); -exports.RenderingStates = RenderingStates; -exports.PDFRenderingQueue = PDFRenderingQueue; -})); +export { + RenderingStates, + PDFRenderingQueue, +}; diff --git a/web/pdf_sidebar.js b/web/pdf_sidebar.js index f91069841..ee7f632c6 100644 --- a/web/pdf_sidebar.js +++ b/web/pdf_sidebar.js @@ -13,23 +13,8 @@ * limitations under the License. */ -'use strict'; - -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define('pdfjs-web/pdf_sidebar', ['exports', - 'pdfjs-web/pdf_rendering_queue', 'pdfjs-web/ui_utils'], factory); - } else if (typeof exports !== 'undefined') { - factory(exports, require('./pdf_rendering_queue.js'), - require('./ui_utils.js')); - } else { - factory((root.pdfjsWebPDFSidebar = {}), root.pdfjsWebPDFRenderingQueue, - root.pdfjsWebUIUtils); - } -}(this, function (exports, pdfRenderingQueue, uiUtils) { - -var RenderingStates = pdfRenderingQueue.RenderingStates; -var mozL10n = uiUtils.mozL10n; +import { mozL10n } from 'pdfjs-web/ui_utils'; +import { RenderingStates } from 'pdfjs-web/pdf_rendering_queue'; var UI_NOTIFICATION_CLASS = 'pdfSidebarNotification'; @@ -460,6 +445,7 @@ var PDFSidebar = (function PDFSidebarClosure() { return PDFSidebar; })(); -exports.SidebarView = SidebarView; -exports.PDFSidebar = PDFSidebar; -})); +export { + SidebarView, + PDFSidebar, +}; diff --git a/web/pdf_thumbnail_view.js b/web/pdf_thumbnail_view.js index e8d8e3a73..cf814b989 100644 --- a/web/pdf_thumbnail_view.js +++ b/web/pdf_thumbnail_view.js @@ -13,24 +13,8 @@ * limitations under the License. */ -'use strict'; - -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define('pdfjs-web/pdf_thumbnail_view', ['exports', - 'pdfjs-web/ui_utils', 'pdfjs-web/pdf_rendering_queue'], factory); - } else if (typeof exports !== 'undefined') { - factory(exports, require('./ui_utils.js'), - require('./pdf_rendering_queue.js')); - } else { - factory((root.pdfjsWebPDFThumbnailView = {}), root.pdfjsWebUIUtils, - root.pdfjsWebPDFRenderingQueue); - } -}(this, function (exports, uiUtils, pdfRenderingQueue) { - -var mozL10n = uiUtils.mozL10n; -var getOutputScale = uiUtils.getOutputScale; -var RenderingStates = pdfRenderingQueue.RenderingStates; +import { getOutputScale, mozL10n } from 'pdfjs-web/ui_utils'; +import { RenderingStates } from 'pdfjs-web/pdf_rendering_queue'; var THUMBNAIL_WIDTH = 98; // px var THUMBNAIL_CANVAS_BORDER_WIDTH = 1; // px @@ -430,5 +414,6 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() { PDFThumbnailView.tempImageCache = null; -exports.PDFThumbnailView = PDFThumbnailView; -})); +export { + PDFThumbnailView, +}; diff --git a/web/pdf_thumbnail_viewer.js b/web/pdf_thumbnail_viewer.js index 05eea7c83..abd64a54a 100644 --- a/web/pdf_thumbnail_viewer.js +++ b/web/pdf_thumbnail_viewer.js @@ -13,25 +13,10 @@ * limitations under the License. */ -'use strict'; - -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define('pdfjs-web/pdf_thumbnail_viewer', ['exports', - 'pdfjs-web/ui_utils', 'pdfjs-web/pdf_thumbnail_view'], factory); - } else if (typeof exports !== 'undefined') { - factory(exports, require('./ui_utils.js'), - require('./pdf_thumbnail_view.js')); - } else { - factory((root.pdfjsWebPDFThumbnailViewer = {}), root.pdfjsWebUIUtils, - root.pdfjsWebPDFThumbnailView); - } -}(this, function (exports, uiUtils, pdfThumbnailView) { - -var watchScroll = uiUtils.watchScroll; -var getVisibleElements = uiUtils.getVisibleElements; -var scrollIntoView = uiUtils.scrollIntoView; -var PDFThumbnailView = pdfThumbnailView.PDFThumbnailView; +import { + getVisibleElements, scrollIntoView, watchScroll +} from 'pdfjs-web/ui_utils'; +import { PDFThumbnailView } from 'pdfjs-web/pdf_thumbnail_view'; var THUMBNAIL_SCROLL_MARGIN = -19; @@ -247,5 +232,6 @@ var PDFThumbnailViewer = (function PDFThumbnailViewerClosure() { return PDFThumbnailViewer; })(); -exports.PDFThumbnailViewer = PDFThumbnailViewer; -})); +export { + PDFThumbnailViewer, +}; diff --git a/web/pdf_viewer.js b/web/pdf_viewer.js index 95bf67e5b..5ce49efba 100644 --- a/web/pdf_viewer.js +++ b/web/pdf_viewer.js @@ -13,48 +13,20 @@ * limitations under the License. */ -'use strict'; - -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define('pdfjs-web/pdf_viewer', ['exports', 'pdfjs-web/ui_utils', - 'pdfjs-web/pdf_page_view', 'pdfjs-web/pdf_rendering_queue', - 'pdfjs-web/text_layer_builder', 'pdfjs-web/annotation_layer_builder', - 'pdfjs-web/pdf_link_service', 'pdfjs-web/dom_events', 'pdfjs-web/pdfjs'], - factory); - } else if (typeof exports !== 'undefined') { - factory(exports, require('./ui_utils.js'), require('./pdf_page_view.js'), - require('./pdf_rendering_queue.js'), require('./text_layer_builder.js'), - require('./annotation_layer_builder.js'), - require('./pdf_link_service.js'), require('./dom_events.js'), - require('./pdfjs.js')); - } else { - factory((root.pdfjsWebPDFViewer = {}), root.pdfjsWebUIUtils, - root.pdfjsWebPDFPageView, root.pdfjsWebPDFRenderingQueue, - root.pdfjsWebTextLayerBuilder, root.pdfjsWebAnnotationLayerBuilder, - root.pdfjsWebPDFLinkService, root.pdfjsWebDOMEvents, root.pdfjsWebPDFJS); - } -}(this, function (exports, uiUtils, pdfPageView, pdfRenderingQueue, - textLayerBuilder, annotationLayerBuilder, pdfLinkService, - domEvents, pdfjsLib) { - -var UNKNOWN_SCALE = uiUtils.UNKNOWN_SCALE; -var SCROLLBAR_PADDING = uiUtils.SCROLLBAR_PADDING; -var VERTICAL_PADDING = uiUtils.VERTICAL_PADDING; -var MAX_AUTO_SCALE = uiUtils.MAX_AUTO_SCALE; -var CSS_UNITS = uiUtils.CSS_UNITS; -var DEFAULT_SCALE = uiUtils.DEFAULT_SCALE; -var DEFAULT_SCALE_VALUE = uiUtils.DEFAULT_SCALE_VALUE; -var RendererType = uiUtils.RendererType; -var scrollIntoView = uiUtils.scrollIntoView; -var watchScroll = uiUtils.watchScroll; -var getVisibleElements = uiUtils.getVisibleElements; -var PDFPageView = pdfPageView.PDFPageView; -var RenderingStates = pdfRenderingQueue.RenderingStates; -var PDFRenderingQueue = pdfRenderingQueue.PDFRenderingQueue; -var TextLayerBuilder = textLayerBuilder.TextLayerBuilder; -var AnnotationLayerBuilder = annotationLayerBuilder.AnnotationLayerBuilder; -var SimpleLinkService = pdfLinkService.SimpleLinkService; +import * as pdfjsLib from 'pdfjs-web/pdfjs'; +import { + CSS_UNITS, DEFAULT_SCALE, DEFAULT_SCALE_VALUE, getVisibleElements, + MAX_AUTO_SCALE, RendererType, SCROLLBAR_PADDING, scrollIntoView, + UNKNOWN_SCALE, VERTICAL_PADDING, watchScroll +} from 'pdfjs-web/ui_utils'; +import { + PDFRenderingQueue, RenderingStates, +} from 'pdfjs-web/pdf_rendering_queue'; +import { AnnotationLayerBuilder } from 'pdfjs-web/annotation_layer_builder'; +import { domEvents } from 'pdfjs-web/dom_events'; +import { PDFPageView } from 'pdfjs-web/pdf_page_view'; +import { SimpleLinkService } from 'pdfjs-web/pdf_link_service'; +import { TextLayerBuilder } from 'pdfjs-web/text_layer_builder'; var PresentationModeState = { UNKNOWN: 0, @@ -988,6 +960,7 @@ var PDFViewer = (function pdfViewer() { return PDFViewer; })(); -exports.PresentationModeState = PresentationModeState; -exports.PDFViewer = PDFViewer; -})); +export { + PresentationModeState, + PDFViewer, +}; diff --git a/web/preferences.js b/web/preferences.js index 471808fd8..137058cc6 100644 --- a/web/preferences.js +++ b/web/preferences.js @@ -13,18 +13,6 @@ * limitations under the License. */ -'use strict'; - -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define('pdfjs-web/preferences', ['exports'], factory); - } else if (typeof exports !== 'undefined') { - factory(exports); - } else { - factory((root.pdfjsWebPreferences = {})); - } -}(this, function (exports) { - var defaultPreferences = null; function getDefaultPreferences() { if (!defaultPreferences) { @@ -221,5 +209,6 @@ if (typeof PDFJSDev === 'undefined' || }; } -exports.Preferences = Preferences; -})); +export { + Preferences, +}; diff --git a/web/secondary_toolbar.js b/web/secondary_toolbar.js index 427b947a0..d9e2f1145 100644 --- a/web/secondary_toolbar.js +++ b/web/secondary_toolbar.js @@ -13,21 +13,7 @@ * limitations under the License. */ -'use strict'; - -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define('pdfjs-web/secondary_toolbar', ['exports', 'pdfjs-web/ui_utils'], - factory); - } else if (typeof exports !== 'undefined') { - factory(exports, require('./ui_utils.js')); - } else { - factory((root.pdfjsWebSecondaryToolbar = {}), root.pdfjsWebUIUtils); - } -}(this, function (exports, uiUtils) { - -var SCROLLBAR_PADDING = uiUtils.SCROLLBAR_PADDING; -var mozL10n = uiUtils.mozL10n; +import { mozL10n, SCROLLBAR_PADDING } from 'pdfjs-web/ui_utils'; /** * @typedef {Object} SecondaryToolbarOptions @@ -241,5 +227,6 @@ var SecondaryToolbar = (function SecondaryToolbarClosure() { return SecondaryToolbar; })(); -exports.SecondaryToolbar = SecondaryToolbar; -})); +export { + SecondaryToolbar, +}; diff --git a/web/text_layer_builder.js b/web/text_layer_builder.js index 110f75b12..aca55f206 100644 --- a/web/text_layer_builder.js +++ b/web/text_layer_builder.js @@ -13,19 +13,8 @@ * limitations under the License. */ -'use strict'; - -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define('pdfjs-web/text_layer_builder', ['exports', 'pdfjs-web/dom_events', - 'pdfjs-web/pdfjs'], factory); - } else if (typeof exports !== 'undefined') { - factory(exports, require('./dom_events.js'), require('./pdfjs.js')); - } else { - factory((root.pdfjsWebTextLayerBuilder = {}), root.pdfjsWebDOMEvents, - root.pdfjsWebPDFJS); - } -}(this, function (exports, domEvents, pdfjsLib) { +import * as pdfjsLib from 'pdfjs-web/pdfjs'; +import { domEvents } from 'pdfjs-web/dom_events'; var EXPAND_DIVS_TIMEOUT = 300; // ms @@ -419,6 +408,7 @@ DefaultTextLayerFactory.prototype = { } }; -exports.TextLayerBuilder = TextLayerBuilder; -exports.DefaultTextLayerFactory = DefaultTextLayerFactory; -})); +export { + TextLayerBuilder, + DefaultTextLayerFactory, +}; diff --git a/web/toolbar.js b/web/toolbar.js index 776858c16..696dd5855 100644 --- a/web/toolbar.js +++ b/web/toolbar.js @@ -13,28 +13,10 @@ * limitations under the License. */ -'use strict'; - -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define('pdfjs-web/toolbar', ['exports', 'pdfjs-web/ui_utils'], - factory); - } else if (typeof exports !== 'undefined') { - factory(exports, require('./ui_utils.js')); - } else { - factory((root.pdfjsWebToolbar = {}), root.pdfjsWebUIUtils); - } -}(this, function (exports, uiUtils) { - -var mozL10n = uiUtils.mozL10n; -var noContextMenuHandler = uiUtils.noContextMenuHandler; -var animationStarted = uiUtils.animationStarted; -var localized = uiUtils.localized; - -var DEFAULT_SCALE_VALUE = uiUtils.DEFAULT_SCALE_VALUE; -var DEFAULT_SCALE = uiUtils.DEFAULT_SCALE; -var MIN_SCALE = uiUtils.MIN_SCALE; -var MAX_SCALE = uiUtils.MAX_SCALE; +import { + animationStarted, DEFAULT_SCALE, DEFAULT_SCALE_VALUE, localized, MAX_SCALE, + MIN_SCALE, mozL10n, noContextMenuHandler +} from 'pdfjs-web/ui_utils'; var PAGE_NUMBER_LOADING_INDICATOR = 'visiblePageIsLoading'; var SCALE_SELECT_CONTAINER_PADDING = 8; @@ -286,5 +268,6 @@ var Toolbar = (function ToolbarClosure() { return Toolbar; })(); -exports.Toolbar = Toolbar; -})); +export { + Toolbar, +}; diff --git a/web/ui_utils.js b/web/ui_utils.js index 54b4d9226..2c7ce599d 100644 --- a/web/ui_utils.js +++ b/web/ui_utils.js @@ -13,17 +13,7 @@ * limitations under the License. */ -'use strict'; - -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define('pdfjs-web/ui_utils', ['exports', 'pdfjs-web/pdfjs'], factory); - } else if (typeof exports !== 'undefined') { - factory(exports, require('./pdfjs.js')); - } else { - factory((root.pdfjsWebUIUtils = {}), root.pdfjsWebPDFJS); - } -}(this, function (exports, pdfjsLib) { +import * as pdfjsLib from 'pdfjs-web/pdfjs'; var CSS_UNITS = 96.0 / 72.0; var DEFAULT_SCALE_VALUE = 'auto'; @@ -94,7 +84,7 @@ if (typeof PDFJSDev === 'undefined' || * @var {string} */ PDFJS.locale = (PDFJS.locale === undefined ? navigator.language : - PDFJS.locale); + PDFJS.locale); } /** @@ -571,30 +561,31 @@ var ProgressBar = (function ProgressBarClosure() { return ProgressBar; })(); -exports.CSS_UNITS = CSS_UNITS; -exports.DEFAULT_SCALE_VALUE = DEFAULT_SCALE_VALUE; -exports.DEFAULT_SCALE = DEFAULT_SCALE; -exports.MIN_SCALE = MIN_SCALE; -exports.MAX_SCALE = MAX_SCALE; -exports.UNKNOWN_SCALE = UNKNOWN_SCALE; -exports.MAX_AUTO_SCALE = MAX_AUTO_SCALE; -exports.SCROLLBAR_PADDING = SCROLLBAR_PADDING; -exports.VERTICAL_PADDING = VERTICAL_PADDING; -exports.RendererType = RendererType; -exports.mozL10n = mozL10n; -exports.EventBus = EventBus; -exports.ProgressBar = ProgressBar; -exports.getPDFFileNameFromURL = getPDFFileNameFromURL; -exports.noContextMenuHandler = noContextMenuHandler; -exports.parseQueryString = parseQueryString; -exports.getVisibleElements = getVisibleElements; -exports.roundToDivide = roundToDivide; -exports.approximateFraction = approximateFraction; -exports.getOutputScale = getOutputScale; -exports.scrollIntoView = scrollIntoView; -exports.watchScroll = watchScroll; -exports.binarySearchFirstItem = binarySearchFirstItem; -exports.normalizeWheelEventDelta = normalizeWheelEventDelta; -exports.animationStarted = animationStarted; -exports.localized = localized; -})); +export { + CSS_UNITS, + DEFAULT_SCALE_VALUE, + DEFAULT_SCALE, + MIN_SCALE, + MAX_SCALE, + UNKNOWN_SCALE, + MAX_AUTO_SCALE, + SCROLLBAR_PADDING, + VERTICAL_PADDING, + RendererType, + mozL10n, + EventBus, + ProgressBar, + getPDFFileNameFromURL, + noContextMenuHandler, + parseQueryString, + getVisibleElements, + roundToDivide, + approximateFraction, + getOutputScale, + scrollIntoView, + watchScroll, + binarySearchFirstItem, + normalizeWheelEventDelta, + animationStarted, + localized, +}; diff --git a/web/view_history.js b/web/view_history.js index 2cd1aa3fe..d79ac7886 100644 --- a/web/view_history.js +++ b/web/view_history.js @@ -13,18 +13,6 @@ * limitations under the License. */ -'use strict'; - -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define('pdfjs-web/view_history', ['exports'], factory); - } else if (typeof exports !== 'undefined') { - factory(exports); - } else { - factory((root.pdfjsWebViewHistory = {})); - } -}(this, function (exports) { - var DEFAULT_VIEW_HISTORY_CACHE_SIZE = 20; /** @@ -142,5 +130,6 @@ var ViewHistory = (function ViewHistoryClosure() { return ViewHistory; })(); -exports.ViewHistory = ViewHistory; -})); +export { + ViewHistory, +}; From b2c3f8f081924d38f38f37713f3c379ac25eaa76 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Tue, 28 Mar 2017 10:15:02 +0200 Subject: [PATCH 3/3] Convert a number of `import * as pdfjsLib from 'pdfjs-web/pdfjs';` cases to only specify the necessary imports Rather than always importing everything from the `web/pdfjs.js`, similar to all other imports we can just choose what we actually need. --- web/annotation_layer_builder.js | 6 ++-- web/app.js | 53 +++++++++++++++++---------------- web/chromecom.js | 4 +-- web/download_manager.js | 12 ++++---- web/firefox_print_service.js | 4 +-- web/firefoxcom.js | 19 ++++++------ web/password_prompt.js | 4 +-- web/pdf_attachment_viewer.js | 16 +++++----- web/pdf_outline_viewer.js | 10 +++---- web/pdf_page_view.js | 26 ++++++++-------- web/pdf_print_service.js | 5 ++-- web/pdf_viewer.js | 8 ++--- web/text_layer_builder.js | 4 +-- web/ui_utils.js | 4 +-- 14 files changed, 89 insertions(+), 86 deletions(-) diff --git a/web/annotation_layer_builder.js b/web/annotation_layer_builder.js index 8ef9dbdb5..c68051d36 100644 --- a/web/annotation_layer_builder.js +++ b/web/annotation_layer_builder.js @@ -13,7 +13,7 @@ * limitations under the License. */ -import * as pdfjsLib from 'pdfjs-web/pdfjs'; +import { AnnotationLayer } from 'pdfjs-web/pdfjs'; import { mozL10n } from 'pdfjs-web/ui_utils'; import { SimpleLinkService } from 'pdfjs-web/pdf_link_service'; @@ -72,7 +72,7 @@ var AnnotationLayerBuilder = (function AnnotationLayerBuilderClosure() { if (self.div) { // If an annotationLayer already exists, refresh its children's // transformation matrices. - pdfjsLib.AnnotationLayer.update(parameters); + AnnotationLayer.update(parameters); } else { // Create an annotation layer div and render the annotations // if there is at least one annotation. @@ -85,7 +85,7 @@ var AnnotationLayerBuilder = (function AnnotationLayerBuilderClosure() { self.pageDiv.appendChild(self.div); parameters.div = self.div; - pdfjsLib.AnnotationLayer.render(parameters); + AnnotationLayer.render(parameters); if (typeof mozL10n !== 'undefined') { mozL10n.translate(self.div); } diff --git a/web/app.js b/web/app.js index e0cdc0df4..237f9e8fe 100644 --- a/web/app.js +++ b/web/app.js @@ -14,12 +14,16 @@ */ /* globals PDFBug, Stats */ -import * as pdfjsLib from 'pdfjs-web/pdfjs'; import { animationStarted, DEFAULT_SCALE_VALUE, getPDFFileNameFromURL, localized, MAX_SCALE, MIN_SCALE, mozL10n, noContextMenuHandler, normalizeWheelEventDelta, parseQueryString, ProgressBar, RendererType, UNKNOWN_SCALE } from 'pdfjs-web/ui_utils'; +import { + build, createBlob, getDocument, getFilenameFromUrl, InvalidPDFException, + MissingPDFException, OPS, PDFJS, shadow, UnexpectedResponseException, + UNSUPPORTED_FEATURES, version, +} from 'pdfjs-web/pdfjs'; import { PDFRenderingQueue, RenderingStates } from 'pdfjs-web/pdf_rendering_queue'; @@ -140,7 +144,6 @@ var PDFViewerApplication = { // called once when the document is loaded initialize: function pdfViewInitialize(appConfig) { var self = this; - var PDFJS = pdfjsLib.PDFJS; Preferences.initialize(); this.preferences = Preferences; @@ -179,7 +182,6 @@ var PDFViewerApplication = { */ _readPreferences: function () { var self = this; - var PDFJS = pdfjsLib.PDFJS; return Promise.all([ Preferences.get('enableWebGL').then(function resolved(value) { @@ -445,11 +447,11 @@ var PDFViewerApplication = { support = false; } } - if (support && pdfjsLib.PDFJS.disableFullscreen === true) { + if (support && PDFJS.disableFullscreen === true) { support = false; } - return pdfjsLib.shadow(this, 'supportsFullscreen', support); + return shadow(this, 'supportsFullscreen', support); }, get supportsIntegratedFind() { @@ -467,7 +469,7 @@ var PDFViewerApplication = { get loadingBar() { var bar = new ProgressBar('#loadingBar', {}); - return pdfjsLib.shadow(this, 'loadingBar', bar); + return shadow(this, 'loadingBar', bar); }, get supportedMouseWheelZoomModifierKeys() { @@ -517,7 +519,7 @@ var PDFViewerApplication = { var title = getPDFFileNameFromURL(url, ''); if (!title) { try { - title = decodeURIComponent(pdfjsLib.getFilenameFromUrl(url)) || url; + title = decodeURIComponent(getFilenameFromUrl(url)) || url; } catch (e) { // decodeURIComponent may throw URIError, // fall back to using the unprocessed url in that case @@ -632,7 +634,7 @@ var PDFViewerApplication = { var self = this; self.downloadComplete = false; - var loadingTask = pdfjsLib.getDocument(parameters); + var loadingTask = getDocument(parameters); this.pdfLoadingTask = loadingTask; loadingTask.onPassword = function passwordNeeded(updateCallback, reason) { @@ -656,15 +658,15 @@ var PDFViewerApplication = { var loadingErrorMessage = mozL10n.get('loading_error', null, 'An error occurred while loading the PDF.'); - if (exception instanceof pdfjsLib.InvalidPDFException) { + if (exception instanceof InvalidPDFException) { // change error message also for other builds loadingErrorMessage = mozL10n.get('invalid_file_error', null, 'Invalid or corrupted PDF file.'); - } else if (exception instanceof pdfjsLib.MissingPDFException) { + } else if (exception instanceof MissingPDFException) { // special message for missing PDF's loadingErrorMessage = mozL10n.get('missing_file_error', null, 'Missing PDF file.'); - } else if (exception instanceof pdfjsLib.UnexpectedResponseException) { + } else if (exception instanceof UnexpectedResponseException) { loadingErrorMessage = mozL10n.get('unexpected_response_error', null, 'Unexpected server response.'); } @@ -707,7 +709,7 @@ var PDFViewerApplication = { this.pdfDocument.getData().then( function getDataSuccess(data) { - var blob = pdfjsLib.createBlob(data, 'application/pdf'); + var blob = createBlob(data, 'application/pdf'); downloadManager.download(blob, url, filename); }, downloadByUrl // Error occurred try downloading with just the url. @@ -744,7 +746,7 @@ var PDFViewerApplication = { */ error: function pdfViewError(message, moreInfo) { var moreInfoText = mozL10n.get('error_version_info', - {version: pdfjsLib.version || '?', build: pdfjsLib.build || '?'}, + {version: version || '?', build: build || '?'}, 'PDF.js v{{version}} (build: {{build}})') + '\n'; if (moreInfo) { moreInfoText += @@ -822,7 +824,7 @@ var PDFViewerApplication = { // the loading bar will not be completely filled, nor will it be hidden. // To prevent displaying a partially filled loading bar permanently, we // hide it when no data has been loaded during a certain amount of time. - if (pdfjsLib.PDFJS.disableAutoFetch && percent) { + if (PDFJS.disableAutoFetch && percent) { if (this.disableAutoFetchLoadingBarTimeout) { clearTimeout(this.disableAutoFetchLoadingBarTimeout); this.disableAutoFetchLoadingBarTimeout = null; @@ -885,7 +887,7 @@ var PDFViewerApplication = { self.loadingBar.setWidth(self.appConfig.viewerContainer); - if (!pdfjsLib.PDFJS.disableHistory && !self.isViewerEmbedded) { + if (!PDFJS.disableHistory && !self.isViewerEmbedded) { // The browsing history is only enabled when the viewer is standalone, // i.e. not when it is embedded in a web page. if (!self.viewerPrefs['showPreviousViewOnLoad']) { @@ -989,7 +991,7 @@ var PDFViewerApplication = { pdfDocument.getJavaScript().then(function(javaScript) { if (javaScript.length) { console.warn('Warning: JavaScript is not supported'); - self.fallback(pdfjsLib.UNSUPPORTED_FEATURES.javaScript); + self.fallback(UNSUPPORTED_FEATURES.javaScript); } // Hack to support auto printing. var regex = /\bprint\s*\(/; @@ -1024,8 +1026,8 @@ var PDFViewerApplication = { console.log('PDF ' + pdfDocument.fingerprint + ' [' + info.PDFFormatVersion + ' ' + (info.Producer || '-').trim() + ' / ' + (info.Creator || '-').trim() + ']' + - ' (PDF.js: ' + (pdfjsLib.version || '-') + - (!pdfjsLib.PDFJS.disableWebGL ? ' [WebGL]' : '') + ')'); + ' (PDF.js: ' + (version || '-') + + (!PDFJS.disableWebGL ? ' [WebGL]' : '') + ')'); var pdfTitle; if (metadata && metadata.has('dc:title')) { @@ -1046,7 +1048,7 @@ var PDFViewerApplication = { if (info.IsAcroFormPresent) { console.warn('Warning: AcroForm/XFA is not supported'); - self.fallback(pdfjsLib.UNSUPPORTED_FEATURES.forms); + self.fallback(UNSUPPORTED_FEATURES.forms); } if (typeof PDFJSDev !== 'undefined' && @@ -1329,7 +1331,10 @@ function loadAndEnablePDFBug(enabledTabs) { script.src = appConfig.debuggerScriptPath; script.onload = function () { PDFBug.enable(enabledTabs); - PDFBug.init(pdfjsLib, appConfig.mainContainer); + PDFBug.init({ + PDFJS, + OPS, + }, appConfig.mainContainer); resolve(); }; script.onerror = function () { @@ -1375,8 +1380,6 @@ function webViewerInitialized() { appConfig.secondaryToolbar.openFileButton.setAttribute('hidden', 'true'); } - var PDFJS = pdfjsLib.PDFJS; - if ((typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION')) || PDFViewerApplication.viewerPrefs['pdfBugEnabled']) { // Special debugging flags in the hash section of the URL. @@ -1555,7 +1558,7 @@ function webViewerPageRendered(e) { thumbnailView.setImage(pageView); } - if (pdfjsLib.PDFJS.pdfBug && Stats.enabled && pageView.stats) { + if (PDFJS.pdfBug && Stats.enabled && pageView.stats) { Stats.add(pageNumber, pageView.stats); } @@ -1720,7 +1723,7 @@ if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) { webViewerFileInputChange = function webViewerFileInputChange(e) { var file = e.fileInput.files[0]; - if (!pdfjsLib.PDFJS.disableCreateObjectURL && + if (!PDFJS.disableCreateObjectURL && typeof URL !== 'undefined' && URL.createObjectURL) { PDFViewerApplication.open(URL.createObjectURL(file)); } else { @@ -1843,7 +1846,7 @@ function webViewerPageChanging(e) { } // we need to update stats - if (pdfjsLib.PDFJS.pdfBug && Stats.enabled) { + if (PDFJS.pdfBug && Stats.enabled) { var pageView = PDFViewerApplication.pdfViewer.getPageView(page - 1); if (pageView.stats) { Stats.add(page, pageView.stats); diff --git a/web/chromecom.js b/web/chromecom.js index decff7590..d0e1a93d1 100644 --- a/web/chromecom.js +++ b/web/chromecom.js @@ -14,9 +14,9 @@ */ /* globals chrome */ -import * as pdfjsLib from 'pdfjs-web/pdfjs'; import { DefaultExternalServices, PDFViewerApplication } from 'pdfjs-web/app'; import { OverlayManager } from 'pdfjs-web/overlay_manager'; +import { PDFJS } from 'pdfjs-web/pdfjs'; import { Preferences } from 'pdfjs-web/preferences'; if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('CHROME')) { @@ -63,7 +63,7 @@ ChromeCom.resolvePDFFile = function ChromeCom_resolvePDFFile(file, callback) { file = file.replace(/^drive:/i, 'filesystem:' + location.origin + '/external/'); - if (/^filesystem:/.test(file) && !pdfjsLib.PDFJS.disableWorker) { + if (/^filesystem:/.test(file) && !PDFJS.disableWorker) { // The security origin of filesystem:-URLs are not preserved when the // URL is passed to a Web worker, (http://crbug.com/362061), so we have // to create an intermediate blob:-URL as a work-around. diff --git a/web/download_manager.js b/web/download_manager.js index 206ecd209..dfcc95ad3 100644 --- a/web/download_manager.js +++ b/web/download_manager.js @@ -13,7 +13,9 @@ * limitations under the License. */ -import * as pdfjsLib from 'pdfjs-web/pdfjs'; +import { + createObjectURL, createValidAbsoluteUrl, PDFJS +} from 'pdfjs-web/pdfjs'; import { DefaultExternalServices, PDFViewerApplication } from 'pdfjs-web/app'; if (typeof PDFJSDev !== 'undefined' && !PDFJSDev.test('CHROME || GENERIC')) { @@ -61,7 +63,7 @@ function DownloadManager() {} DownloadManager.prototype = { downloadUrl: function DownloadManager_downloadUrl(url, filename) { - if (!pdfjsLib.createValidAbsoluteUrl(url, 'http://example.com')) { + if (!createValidAbsoluteUrl(url, 'http://example.com')) { return; // restricted/invalid URL } download(url + '#pdfjs.action=download', filename); @@ -74,8 +76,8 @@ DownloadManager.prototype = { filename); } - var blobUrl = pdfjsLib.createObjectURL(data, contentType, - pdfjsLib.PDFJS.disableCreateObjectURL); + var blobUrl = createObjectURL(data, contentType, + PDFJS.disableCreateObjectURL); download(blobUrl, filename); }, @@ -88,7 +90,7 @@ DownloadManager.prototype = { return; } - if (pdfjsLib.PDFJS.disableCreateObjectURL) { + if (PDFJS.disableCreateObjectURL) { // URL.createObjectURL is not supported this.downloadUrl(url, filename); return; diff --git a/web/firefox_print_service.js b/web/firefox_print_service.js index 3f128c5db..a8dd45b9e 100644 --- a/web/firefox_print_service.js +++ b/web/firefox_print_service.js @@ -13,9 +13,9 @@ * limitations under the License. */ -import * as pdfjsLib from 'pdfjs-web/pdfjs'; import { CSS_UNITS } from 'pdfjs-web/ui_utils'; import { PDFPrintServiceFactory } from 'pdfjs-web/app'; +import { shadow } from 'pdfjs-web/pdfjs'; // Creates a placeholder with div and canvas with right size for the page. function composePage(pdfDocument, pageNumber, size, printContainer) { @@ -96,7 +96,7 @@ PDFPrintServiceFactory.instance = { var canvas = document.createElement('canvas'); var value = 'mozPrintCallback' in canvas; - return pdfjsLib.shadow(this, 'supportsPrinting', value); + return shadow(this, 'supportsPrinting', value); }, createPrintService: function (pdfDocument, pagesOverview, printContainer) { diff --git a/web/firefoxcom.js b/web/firefoxcom.js index f3d956334..64e2085e5 100644 --- a/web/firefoxcom.js +++ b/web/firefoxcom.js @@ -13,7 +13,9 @@ * limitations under the License. */ -import * as pdfjsLib from 'pdfjs-web/pdfjs'; +import { + createObjectURL, PDFDataRangeTransport, shadow +} from 'pdfjs-web/pdfjs'; import { PDFViewerApplication } from 'pdfjs-web/app'; import { Preferences } from 'pdfjs-web/preferences'; @@ -94,7 +96,7 @@ var DownloadManager = (function DownloadManagerClosure() { downloadData: function DownloadManager_downloadData(data, filename, contentType) { - var blobUrl = pdfjsLib.createObjectURL(data, contentType, false); + var blobUrl = createObjectURL(data, contentType, false); FirefoxCom.request('download', { blobUrl: blobUrl, @@ -168,10 +170,10 @@ Preferences._readFromStorage = function (prefObj) { })(); function FirefoxComDataRangeTransport(length, initialData) { - pdfjsLib.PDFDataRangeTransport.call(this, length, initialData); + PDFDataRangeTransport.call(this, length, initialData); } FirefoxComDataRangeTransport.prototype = - Object.create(pdfjsLib.PDFDataRangeTransport.prototype); + Object.create(PDFDataRangeTransport.prototype); FirefoxComDataRangeTransport.prototype.requestDataRange = function FirefoxComDataRangeTransport_requestDataRange(begin, end) { FirefoxCom.request('requestDataRange', { begin: begin, end: end }); @@ -247,23 +249,22 @@ PDFViewerApplication.externalServices = { get supportsIntegratedFind() { var support = FirefoxCom.requestSync('supportsIntegratedFind'); - return pdfjsLib.shadow(this, 'supportsIntegratedFind', support); + return shadow(this, 'supportsIntegratedFind', support); }, get supportsDocumentFonts() { var support = FirefoxCom.requestSync('supportsDocumentFonts'); - return pdfjsLib.shadow(this, 'supportsDocumentFonts', support); + return shadow(this, 'supportsDocumentFonts', support); }, get supportsDocumentColors() { var support = FirefoxCom.requestSync('supportsDocumentColors'); - return pdfjsLib.shadow(this, 'supportsDocumentColors', support); + return shadow(this, 'supportsDocumentColors', support); }, get supportedMouseWheelZoomModifierKeys() { var support = FirefoxCom.requestSync('supportedMouseWheelZoomModifierKeys'); - return pdfjsLib.shadow(this, 'supportedMouseWheelZoomModifierKeys', - support); + return shadow(this, 'supportedMouseWheelZoomModifierKeys', support); }, }; diff --git a/web/password_prompt.js b/web/password_prompt.js index 771ab8aba..710ddd370 100644 --- a/web/password_prompt.js +++ b/web/password_prompt.js @@ -13,9 +13,9 @@ * limitations under the License. */ -import * as pdfjsLib from 'pdfjs-web/pdfjs'; import { mozL10n } from 'pdfjs-web/ui_utils'; import { OverlayManager } from 'pdfjs-web/overlay_manager'; +import { PasswordResponses } from 'pdfjs-web/pdfjs'; /** * @typedef {Object} PasswordPromptOptions @@ -71,7 +71,7 @@ var PasswordPrompt = (function PasswordPromptClosure() { var promptString = mozL10n.get('password_label', null, 'Enter the password to open this PDF file.'); - if (this.reason === pdfjsLib.PasswordResponses.INCORRECT_PASSWORD) { + if (this.reason === PasswordResponses.INCORRECT_PASSWORD) { promptString = mozL10n.get('password_invalid', null, 'Invalid password. Please try again.'); } diff --git a/web/pdf_attachment_viewer.js b/web/pdf_attachment_viewer.js index 0b0b64ca5..141c480bd 100644 --- a/web/pdf_attachment_viewer.js +++ b/web/pdf_attachment_viewer.js @@ -13,7 +13,10 @@ * limitations under the License. */ -import * as pdfjsLib from 'pdfjs-web/pdfjs'; +import { + createObjectURL, createPromiseCapability, getFilenameFromUrl, PDFJS, + removeNullCharacters +} from 'pdfjs-web/pdfjs'; /** * @typedef {Object} PDFAttachmentViewerOptions @@ -41,7 +44,7 @@ var PDFAttachmentViewer = (function PDFAttachmentViewerClosure() { this.eventBus = options.eventBus; this.downloadManager = options.downloadManager; - this._renderedCapability = pdfjsLib.createPromiseCapability(); + this._renderedCapability = createPromiseCapability(); this.eventBus.on('fileattachmentannotation', this._appendAttachment.bind(this)); } @@ -56,7 +59,7 @@ var PDFAttachmentViewer = (function PDFAttachmentViewerClosure() { if (!keepRenderedCapability) { // NOTE: The *only* situation in which the `_renderedCapability` should // not be replaced is when appending file attachment annotations. - this._renderedCapability = pdfjsLib.createPromiseCapability(); + this._renderedCapability = createPromiseCapability(); } }, @@ -81,8 +84,8 @@ var PDFAttachmentViewer = (function PDFAttachmentViewerClosure() { var blobUrl; button.onclick = function() { if (!blobUrl) { - blobUrl = pdfjsLib.createObjectURL( - content, 'application/pdf', pdfjsLib.PDFJS.disableCreateObjectURL); + blobUrl = createObjectURL( + content, 'application/pdf', PDFJS.disableCreateObjectURL); } var viewerUrl; if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) { @@ -142,8 +145,7 @@ var PDFAttachmentViewer = (function PDFAttachmentViewerClosure() { for (var i = 0; i < attachmentsCount; i++) { var item = attachments[names[i]]; - var filename = pdfjsLib.getFilenameFromUrl(item.filename); - filename = pdfjsLib.removeNullCharacters(filename); + var filename = removeNullCharacters(getFilenameFromUrl(item.filename)); var div = document.createElement('div'); div.className = 'attachmentsItem'; diff --git a/web/pdf_outline_viewer.js b/web/pdf_outline_viewer.js index 0098489f0..ce8d2e909 100644 --- a/web/pdf_outline_viewer.js +++ b/web/pdf_outline_viewer.js @@ -13,9 +13,9 @@ * limitations under the License. */ -import * as pdfjsLib from 'pdfjs-web/pdfjs'; - -var PDFJS = pdfjsLib.PDFJS; +import { + addLinkAttributes, PDFJS, removeNullCharacters +} from 'pdfjs-web/pdfjs'; var DEFAULT_TITLE = '\u2013'; @@ -74,7 +74,7 @@ var PDFOutlineViewer = (function PDFOutlineViewerClosure() { */ _bindLink: function PDFOutlineViewer_bindLink(element, item) { if (item.url) { - pdfjsLib.addLinkAttributes(element, { + addLinkAttributes(element, { url: item.url, target: (item.newWindow ? PDFJS.LinkTarget.BLANK : undefined), }); @@ -189,7 +189,7 @@ var PDFOutlineViewer = (function PDFOutlineViewerClosure() { this._bindLink(element, item); this._setStyles(element, item); element.textContent = - pdfjsLib.removeNullCharacters(item.title) || DEFAULT_TITLE; + removeNullCharacters(item.title) || DEFAULT_TITLE; div.appendChild(element); diff --git a/web/pdf_page_view.js b/web/pdf_page_view.js index 5718bb102..37c5c6f31 100644 --- a/web/pdf_page_view.js +++ b/web/pdf_page_view.js @@ -13,11 +13,13 @@ * limitations under the License. */ -import * as pdfjsLib from 'pdfjs-web/pdfjs'; import { approximateFraction, CSS_UNITS, DEFAULT_SCALE, getOutputScale, RendererType, roundToDivide } from 'pdfjs-web/ui_utils'; +import { + CustomStyle, PDFJS, RenderingCancelledException, SVGGraphics +} from 'pdfjs-web/pdfjs'; import { domEvents } from 'pdfjs-web/dom_events'; import { RenderingStates } from 'pdfjs-web/pdf_rendering_queue'; @@ -216,17 +218,17 @@ var PDFPageView = (function PDFPageViewClosure() { } var isScalingRestricted = false; - if (this.canvas && pdfjsLib.PDFJS.maxCanvasPixels > 0) { + if (this.canvas && PDFJS.maxCanvasPixels > 0) { var outputScale = this.outputScale; if (((Math.floor(this.viewport.width) * outputScale.sx) | 0) * ((Math.floor(this.viewport.height) * outputScale.sy) | 0) > - pdfjsLib.PDFJS.maxCanvasPixels) { + PDFJS.maxCanvasPixels) { isScalingRestricted = true; } } if (this.canvas) { - if (pdfjsLib.PDFJS.useOnlyCssZoom || + if (PDFJS.useOnlyCssZoom || (this.hasRestrictedScaling && isScalingRestricted)) { this.cssTransform(this.canvas, true); @@ -272,8 +274,6 @@ var PDFPageView = (function PDFPageViewClosure() { }, cssTransform: function PDFPageView_transform(target, redrawAnnotations) { - var CustomStyle = pdfjsLib.CustomStyle; - // Scale target (canvas or svg), its wrapper, and page container. var width = this.viewport.width; var height = this.viewport.height; @@ -425,7 +425,7 @@ var PDFPageView = (function PDFPageViewClosure() { if (((typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PDFJS_NEXT')) && error === 'cancelled') || - error instanceof pdfjsLib.RenderingCancelledException) { + error instanceof RenderingCancelledException) { self.error = null; return Promise.resolve(undefined); } @@ -535,7 +535,7 @@ var PDFPageView = (function PDFPageViewClosure() { var outputScale = getOutputScale(ctx); this.outputScale = outputScale; - if (pdfjsLib.PDFJS.useOnlyCssZoom) { + if (PDFJS.useOnlyCssZoom) { var actualSizeViewport = viewport.clone({scale: CSS_UNITS}); // Use a scale that will make the canvas be the original intended size // of the page. @@ -544,10 +544,9 @@ var PDFPageView = (function PDFPageViewClosure() { outputScale.scaled = true; } - if (pdfjsLib.PDFJS.maxCanvasPixels > 0) { + if (PDFJS.maxCanvasPixels > 0) { var pixelsInViewport = viewport.width * viewport.height; - var maxScale = - Math.sqrt(pdfjsLib.PDFJS.maxCanvasPixels / pixelsInViewport); + var maxScale = Math.sqrt(PDFJS.maxCanvasPixels / pixelsInViewport); if (outputScale.sx > maxScale || outputScale.sy > maxScale) { outputScale.sx = maxScale; outputScale.sy = maxScale; @@ -617,8 +616,8 @@ var PDFPageView = (function PDFPageViewClosure() { var ensureNotCancelled = function () { if (cancelled) { if ((typeof PDFJSDev !== 'undefined' && - PDFJSDev.test('PDFJS_NEXT')) || pdfjsLib.PDFJS.pdfjsNext) { - throw new pdfjsLib.RenderingCancelledException( + PDFJSDev.test('PDFJS_NEXT')) || PDFJS.pdfjsNext) { + throw new RenderingCancelledException( 'Rendering cancelled, page ' + self.id, 'svg'); } else { throw 'cancelled'; // eslint-disable-line no-throw-literal @@ -628,7 +627,6 @@ var PDFPageView = (function PDFPageViewClosure() { var self = this; var pdfPage = this.pdfPage; - var SVGGraphics = pdfjsLib.SVGGraphics; var actualSizeViewport = this.viewport.clone({scale: CSS_UNITS}); var promise = pdfPage.getOperatorList().then(function (opList) { ensureNotCancelled(); diff --git a/web/pdf_print_service.js b/web/pdf_print_service.js index 02f677bb7..e759d789b 100644 --- a/web/pdf_print_service.js +++ b/web/pdf_print_service.js @@ -13,9 +13,9 @@ * limitations under the License. */ -import * as pdfjsLib from 'pdfjs-web/pdfjs'; import { CSS_UNITS, mozL10n } from 'pdfjs-web/ui_utils'; import { OverlayManager } from 'pdfjs-web/overlay_manager'; +import { PDFJS } from 'pdfjs-web/pdfjs'; import { PDFPrintServiceFactory } from 'pdfjs-web/app'; var activeService = null; @@ -152,8 +152,7 @@ PDFPrintService.prototype = { img.style.height = printItem.height; var scratchCanvas = this.scratchCanvas; - if (('toBlob' in scratchCanvas) && - !pdfjsLib.PDFJS.disableCreateObjectURL) { + if (('toBlob' in scratchCanvas) && !PDFJS.disableCreateObjectURL) { scratchCanvas.toBlob(function (blob) { img.src = URL.createObjectURL(blob); }); diff --git a/web/pdf_viewer.js b/web/pdf_viewer.js index 5ce49efba..30925a9dc 100644 --- a/web/pdf_viewer.js +++ b/web/pdf_viewer.js @@ -13,7 +13,6 @@ * limitations under the License. */ -import * as pdfjsLib from 'pdfjs-web/pdfjs'; import { CSS_UNITS, DEFAULT_SCALE, DEFAULT_SCALE_VALUE, getVisibleElements, MAX_AUTO_SCALE, RendererType, SCROLLBAR_PADDING, scrollIntoView, @@ -24,6 +23,7 @@ import { } from 'pdfjs-web/pdf_rendering_queue'; import { AnnotationLayerBuilder } from 'pdfjs-web/annotation_layer_builder'; import { domEvents } from 'pdfjs-web/dom_events'; +import { PDFJS } from 'pdfjs-web/pdfjs'; import { PDFPageView } from 'pdfjs-web/pdf_page_view'; import { SimpleLinkService } from 'pdfjs-web/pdf_link_service'; import { TextLayerBuilder } from 'pdfjs-web/text_layer_builder'; @@ -362,7 +362,7 @@ var PDFViewer = (function pdfViewer() { var viewport = pdfPage.getViewport(scale * CSS_UNITS); for (var pageNum = 1; pageNum <= pagesCount; ++pageNum) { var textLayerFactory = null; - if (!pdfjsLib.PDFJS.disableTextLayer) { + if (!PDFJS.disableTextLayer) { textLayerFactory = this; } var pageView = new PDFPageView({ @@ -388,7 +388,7 @@ var PDFViewer = (function pdfViewer() { // starts to create the correct size canvas. Wait until one page is // rendered so we don't tie up too many resources early on. onePageRendered.then(function () { - if (!pdfjsLib.PDFJS.disableAutoFetch) { + if (!PDFJS.disableAutoFetch) { var getPagesLeft = pagesCount; for (var pageNum = 1; pageNum <= pagesCount; ++pageNum) { pdfDocument.getPage(pageNum).then(function (pageNum, pdfPage) { @@ -500,7 +500,7 @@ var PDFViewer = (function pdfViewer() { if (!noScroll) { var page = this._currentPageNumber, dest; - if (this._location && !pdfjsLib.PDFJS.ignoreCurrentPositionOnZoom && + if (this._location && !PDFJS.ignoreCurrentPositionOnZoom && !(this.isInPresentationMode || this.isChangingPresentationMode)) { page = this._location.pageNumber; dest = [null, { name: 'XYZ' }, this._location.left, diff --git a/web/text_layer_builder.js b/web/text_layer_builder.js index aca55f206..2552b68e7 100644 --- a/web/text_layer_builder.js +++ b/web/text_layer_builder.js @@ -13,8 +13,8 @@ * limitations under the License. */ -import * as pdfjsLib from 'pdfjs-web/pdfjs'; import { domEvents } from 'pdfjs-web/dom_events'; +import { renderTextLayer } from 'pdfjs-web/pdfjs'; var EXPAND_DIVS_TIMEOUT = 300; // ms @@ -86,7 +86,7 @@ var TextLayerBuilder = (function TextLayerBuilderClosure() { this.textDivs = []; var textLayerFrag = document.createDocumentFragment(); - this.textLayerRenderTask = pdfjsLib.renderTextLayer({ + this.textLayerRenderTask = renderTextLayer({ textContent: this.textContent, container: textLayerFrag, viewport: this.viewport, diff --git a/web/ui_utils.js b/web/ui_utils.js index 2c7ce599d..8cd6960ff 100644 --- a/web/ui_utils.js +++ b/web/ui_utils.js @@ -13,7 +13,7 @@ * limitations under the License. */ -import * as pdfjsLib from 'pdfjs-web/pdfjs'; +import { PDFJS } from 'pdfjs-web/pdfjs'; var CSS_UNITS = 96.0 / 72.0; var DEFAULT_SCALE_VALUE = 'auto'; @@ -32,8 +32,6 @@ var RendererType = { var mozL10n = document.mozL10n || document.webL10n; -var PDFJS = pdfjsLib.PDFJS; - /** * Disables fullscreen support, and by extension Presentation Mode, * in browsers which support the fullscreen API.