Browse Source

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.
Jonas Jenwald 8 years ago
parent
commit
3b35c15d42
  1. 28
      web/annotation_layer_builder.js
  2. 126
      web/app.js
  3. 611
      web/chromecom.js
  4. 238
      web/dom_events.js
  5. 22
      web/download_manager.js
  6. 188
      web/firefox_print_service.js
  7. 28
      web/firefoxcom.js
  8. 396
      web/grab_to_pan.js
  9. 26
      web/hand_tool.js
  10. 17
      web/overlay_manager.js
  11. 26
      web/password_prompt.js
  12. 18
      web/pdf_attachment_viewer.js
  13. 24
      web/pdf_document_properties.js
  14. 24
      web/pdf_find_bar.js
  15. 22
      web/pdf_find_controller.js
  16. 742
      web/pdf_history.js
  17. 24
      web/pdf_link_service.js
  18. 18
      web/pdf_outline_viewer.js
  19. 37
      web/pdf_page_view.js
  20. 19
      web/pdf_presentation_mode.js
  21. 602
      web/pdf_print_service.js
  22. 19
      web/pdf_rendering_queue.js
  23. 26
      web/pdf_sidebar.js
  24. 25
      web/pdf_thumbnail_view.js
  25. 28
      web/pdf_thumbnail_viewer.js
  26. 63
      web/pdf_viewer.js
  27. 17
      web/preferences.js
  28. 21
      web/secondary_toolbar.js
  29. 22
      web/text_layer_builder.js
  30. 31
      web/toolbar.js
  31. 69
      web/ui_utils.js
  32. 17
      web/view_history.js

28
web/annotation_layer_builder.js

@ -13,24 +13,9 @@
* limitations under the License. * limitations under the License.
*/ */
'use strict'; import * as pdfjsLib from 'pdfjs-web/pdfjs';
import { mozL10n } from 'pdfjs-web/ui_utils';
(function (root, factory) { import { SimpleLinkService } from 'pdfjs-web/pdf_link_service';
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;
/** /**
* @typedef {Object} AnnotationLayerBuilderOptions * @typedef {Object} AnnotationLayerBuilderOptions
@ -142,6 +127,7 @@ DefaultAnnotationLayerFactory.prototype = {
} }
}; };
exports.AnnotationLayerBuilder = AnnotationLayerBuilder; export {
exports.DefaultAnnotationLayerFactory = DefaultAnnotationLayerFactory; AnnotationLayerBuilder,
})); DefaultAnnotationLayerFactory,
};

126
web/app.js

@ -14,95 +14,34 @@
*/ */
/* globals PDFBug, Stats */ /* globals PDFBug, Stats */
'use strict'; import * as pdfjsLib from 'pdfjs-web/pdfjs';
import {
(function (root, factory) { animationStarted, DEFAULT_SCALE_VALUE, getPDFFileNameFromURL, localized,
if (typeof define === 'function' && define.amd) { MAX_SCALE, MIN_SCALE, mozL10n, noContextMenuHandler, normalizeWheelEventDelta,
define('pdfjs-web/app', ['exports', 'pdfjs-web/ui_utils', parseQueryString, ProgressBar, RendererType, UNKNOWN_SCALE
'pdfjs-web/pdf_history', } from 'pdfjs-web/ui_utils';
'pdfjs-web/preferences', 'pdfjs-web/pdf_sidebar', import {
'pdfjs-web/view_history', 'pdfjs-web/pdf_thumbnail_viewer', PDFRenderingQueue, RenderingStates
'pdfjs-web/toolbar', 'pdfjs-web/secondary_toolbar', } from 'pdfjs-web/pdf_rendering_queue';
'pdfjs-web/password_prompt', 'pdfjs-web/pdf_presentation_mode', import { PDFSidebar, SidebarView } from 'pdfjs-web/pdf_sidebar';
'pdfjs-web/pdf_document_properties', 'pdfjs-web/hand_tool', import { PDFViewer, PresentationModeState } from 'pdfjs-web/pdf_viewer';
'pdfjs-web/pdf_viewer', 'pdfjs-web/pdf_rendering_queue', import { getGlobalEventBus } from 'pdfjs-web/dom_events';
'pdfjs-web/pdf_link_service', 'pdfjs-web/pdf_outline_viewer', import { HandTool } from 'pdfjs-web/hand_tool';
'pdfjs-web/overlay_manager', 'pdfjs-web/pdf_attachment_viewer', import { OverlayManager } from 'pdfjs-web/overlay_manager';
'pdfjs-web/pdf_find_controller', 'pdfjs-web/pdf_find_bar', import { PasswordPrompt } from 'pdfjs-web/password_prompt';
'pdfjs-web/dom_events', 'pdfjs-web/pdfjs'], import { PDFAttachmentViewer } from 'pdfjs-web/pdf_attachment_viewer';
factory); import { PDFDocumentProperties } from 'pdfjs-web/pdf_document_properties';
} else if (typeof exports !== 'undefined') { import { PDFFindBar } from 'pdfjs-web/pdf_find_bar';
factory(exports, require('./ui_utils.js'), import { PDFFindController } from 'pdfjs-web/pdf_find_controller';
require('./pdf_history.js'), require('./preferences.js'), import { PDFHistory } from 'pdfjs-web/pdf_history';
require('./pdf_sidebar.js'), require('./view_history.js'), import { PDFLinkService } from 'pdfjs-web/pdf_link_service';
require('./pdf_thumbnail_viewer.js'), require('./toolbar.js'), import { PDFOutlineViewer } from 'pdfjs-web/pdf_outline_viewer';
require('./secondary_toolbar.js'), require('./password_prompt.js'), import { PDFPresentationMode } from 'pdfjs-web/pdf_presentation_mode';
require('./pdf_presentation_mode.js'), import { PDFThumbnailViewer } from 'pdfjs-web/pdf_thumbnail_viewer';
require('./pdf_document_properties.js'), require('./hand_tool.js'), import { Preferences } from 'pdfjs-web/preferences';
require('./pdf_viewer.js'), require('./pdf_rendering_queue.js'), import { SecondaryToolbar } from 'pdfjs-web/secondary_toolbar';
require('./pdf_link_service.js'), require('./pdf_outline_viewer.js'), import { Toolbar } from 'pdfjs-web/toolbar';
require('./overlay_manager.js'), require('./pdf_attachment_viewer.js'), import { ViewHistory } from 'pdfjs-web/view_history';
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;
var DEFAULT_SCALE_DELTA = 1.1; var DEFAULT_SCALE_DELTA = 1.1;
var DISABLE_AUTO_FETCH_LOADING_BAR_TIMEOUT = 5000; var DISABLE_AUTO_FETCH_LOADING_BAR_TIMEOUT = 5000;
@ -2269,7 +2208,8 @@ var PDFPrintServiceFactory = {
} }
}; };
exports.PDFViewerApplication = PDFViewerApplication; export {
exports.DefaultExternalServices = DefaultExternalServices; PDFViewerApplication,
exports.PDFPrintServiceFactory = PDFPrintServiceFactory; DefaultExternalServices,
})); PDFPrintServiceFactory,
};

611
web/chromecom.js

@ -14,350 +14,335 @@
*/ */
/* globals chrome */ /* 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 PDFJSDev === 'undefined' || !PDFJSDev.test('CHROME')) {
if (typeof define === 'function' && define.amd) { throw new Error('Module "pdfjs-web/chromecom" shall not be used outside ' +
define('pdfjs-web/chromecom', ['exports', 'pdfjs-web/app', 'CHROME build.');
'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'));
} else {
factory((root.pdfjsWebChromeCom = {}), root.pdfjsWebApp,
root.pdfjsWebOverlayManager, root.pdfjsWebPreferences,
root.pdfjsWebPDFJS);
}
}(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.');
}
var PDFViewerApplication = app.PDFViewerApplication; var ChromeCom = {};
var DefaultExternalServices = app.DefaultExternalServices; /**
var OverlayManager = overlayManager.OverlayManager; * Creates an event that the extension is listening for and will
var Preferences = preferences.Preferences; * asynchronously respond by calling the callback.
*
var ChromeCom = {}; * @param {String} action The action to trigger.
/** * @param {String} data Optional data to send.
* Creates an event that the extension is listening for and will * @param {Function} callback Optional response callback that will be called
* asynchronously respond by calling the callback. * with one data argument. When the request cannot be handled, the callback
* * is immediately invoked with no arguments.
* @param {String} action The action to trigger. */
* @param {String} data Optional data to send. ChromeCom.request = function ChromeCom_request(action, data, callback) {
* @param {Function} callback Optional response callback that will be called var message = {
* with one data argument. When the request cannot be handled, the callback action: action,
* is immediately invoked with no arguments. data: data
*/
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 {
chrome.runtime.sendMessage(message);
}
}; };
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);
}
};
/** /**
* Resolves a PDF file path and attempts to detects length. * Resolves a PDF file path and attempts to detects length.
* *
* @param {String} file Absolute URL of PDF file. * @param {String} file Absolute URL of PDF file.
* @param {Function} callback A callback with resolved URL and file length. * @param {Function} callback A callback with resolved URL and file length.
*/ */
ChromeCom.resolvePDFFile = function ChromeCom_resolvePDFFile(file, callback) { ChromeCom.resolvePDFFile = function ChromeCom_resolvePDFFile(file, callback) {
// Expand drive:-URLs to filesystem URLs (Chrome OS) // Expand drive:-URLs to filesystem URLs (Chrome OS)
file = file.replace(/^drive:/i, file = file.replace(/^drive:/i,
'filesystem:' + location.origin + '/external/'); 'filesystem:' + location.origin + '/external/');
if (/^filesystem:/.test(file) && !pdfjsLib.PDFJS.disableWorker) { if (/^filesystem:/.test(file) && !pdfjsLib.PDFJS.disableWorker) {
// The security origin of filesystem:-URLs are not preserved when the // 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 // URL is passed to a Web worker, (http://crbug.com/362061), so we have
// to create an intermediate blob:-URL as a work-around. // to create an intermediate blob:-URL as a work-around.
var resolveLocalFileSystemURL = window.resolveLocalFileSystemURL || var resolveLocalFileSystemURL = window.resolveLocalFileSystemURL ||
window.webkitResolveLocalFileSystemURL; window.webkitResolveLocalFileSystemURL;
resolveLocalFileSystemURL(file, function onResolvedFSURL(fileEntry) { resolveLocalFileSystemURL(file, function onResolvedFSURL(fileEntry) {
fileEntry.file(function(fileObject) { fileEntry.file(function(fileObject) {
var blobUrl = URL.createObjectURL(fileObject); var blobUrl = URL.createObjectURL(fileObject);
callback(blobUrl, fileObject.size); 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; }, function onFileSystemError(error) {
} // This should not happen. When it happens, just fall back to the
if (/^file?:/.test(file)) { // usual way of getting the File's data (via the Web worker).
getEmbedderOrigin(function(origin) { console.warn('Cannot resolve file ' + file + ', ' + error.name + ' ' +
// If the origin cannot be determined, let Chrome decide whether to error.message);
// allow embedding files. Otherwise, only allow local files to be callback(file);
// embedded from local files or Chrome extensions. });
// Even without this check, the file load in frames is still blocked, return;
// but this may change in the future (https://crbug.com/550151). }
if (origin && !/^file:|^chrome-extension:/.test(origin)) { if (/^https?:/.test(file)) {
PDFViewerApplication.error('Blocked ' + origin + ' from loading ' + // Assumption: The file being opened is the file that was requested.
file + '. Refused to load a local file in a non-local page ' + // There is no UI to input a different URL, so this assumption will hold
'for security reasons.'); // for now.
return; 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);
} }
isAllowedFileSchemeAccess(function(isAllowedAccess) {
if (isAllowedAccess) {
callback(file);
} else {
requestAccessToLocalFile(file);
}
});
}); });
return; });
} 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);
}
} }
callback(file);
};
function getParentOrigin(callback) { function getEmbedderOrigin(callback) {
ChromeCom.request('getParentOrigin', null, 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);
} }
}
function isAllowedFileSchemeAccess(callback) { function getParentOrigin(callback) {
ChromeCom.request('isAllowedFileSchemeAccess', null, callback); ChromeCom.request('getParentOrigin', null, callback);
} }
function isRuntimeAvailable() { function isAllowedFileSchemeAccess(callback) {
try { ChromeCom.request('isAllowedFileSchemeAccess', null, callback);
// 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() { function isRuntimeAvailable() {
if (!isRuntimeAvailable()) { try {
location.reload(); // 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;
}
var chromeFileAccessOverlayPromise; function reloadIfRuntimeIsUnavailable() {
function requestAccessToLocalFile(fileUrl) { if (!isRuntimeAvailable()) {
var onCloseOverlay = null; location.reload();
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 (!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=..., var chromeFileAccessOverlayPromise;
// because the shown string should match the UI at chrome://extensions. function requestAccessToLocalFile(fileUrl) {
// These strings are from chrome/app/resources/generated_resources_*.xtb. var onCloseOverlay = null;
/* eslint-disable no-unexpected-multiline */ if (top !== window) {
var i18nFileAccessLabel = // When the extension reloads after receiving new permissions, the pages
PDFJSDev.json('$ROOT/web/chrome-i18n-allow-access-to-file-urls.json') // have to be reloaded to restore the extension runtime. Auto-reload
[chrome.i18n.getUILanguage && chrome.i18n.getUILanguage()]; // frames, because users should not have to reload the whole page just to
/* eslint-enable no-unexpected-multiline */ // 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 (!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) + ')';
if (i18nFileAccessLabel) { // Use Chrome's definition of UI language instead of PDF.js's #lang=...,
document.getElementById('chrome-file-access-label').textContent = // because the shown string should match the UI at chrome://extensions.
i18nFileAccessLabel; // 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 */
var link = document.getElementById('chrome-link-to-extensions-page'); if (i18nFileAccessLabel) {
link.href = 'chrome://extensions/?id=' + chrome.runtime.id; document.getElementById('chrome-file-access-label').textContent =
link.onclick = function(e) { i18nFileAccessLabel;
// 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 var link = document.getElementById('chrome-link-to-extensions-page');
// why this permission request is shown. link.href = 'chrome://extensions/?id=' + chrome.runtime.id;
document.getElementById('chrome-url-of-local-file').textContent = fileUrl; 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
});
};
OverlayManager.open('chromeFileAccessOverlay'); // 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;
if (window === top) { OverlayManager.open('chromeFileAccessOverlay');
// 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));
}
});
}
// This port is used for several purposes: if (window === top) {
// 1. When disconnected, the background page knows that the frame has unload. // Chrome closes all extension tabs (crbug.com/511670) when the extension
// 2. When the referrer was saved in history.state.chromecomState, it is sent // reloads. To counter this, the tab URL and history state is saved to
// to the background page. // localStorage and restored by extension-router.js.
// 3. When the background page knows the referrer of the page, the referrer is // Unfortunately, the window and tab index are not restored. And if it was
// saved in history.state.chromecomState. // the only tab in an incognito window, then the tab is not restored either.
var port; addEventListener('unload', function() {
// Set the referer for the given URL. // If the runtime is still available, the unload is most likely a normal
// 0. Background: If loaded via a http(s) URL: Save referer. // tab closure. Otherwise it is most likely an extension reload.
// 1. Page -> background: send URL and referer from history.state if (!isRuntimeAvailable()) {
// 2. Background: Bind referer to URL (via webRequest). localStorage.setItem(
// 3. Background -> page: Send latest referer and save to history. 'unload-' + Date.now() + '-' + document.hidden + '-' + location.href,
// 4. Page: Invoke callback. JSON.stringify(history.state));
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) { // This port is used for several purposes:
if (referer) { // 1. When disconnected, the background page knows that the frame has unload.
// The background extracts the Referer from the initial HTTP request for // 2. When the referrer was saved in history.state.chromecomState, it is sent
// the PDF file. When the viewer is reloaded or when the user navigates // to the background page.
// back and forward, the background page will not observe a HTTP request // 3. When the background page knows the referrer of the page, the referrer is
// with Referer. To make sure that the Referer is preserved, store it in // saved in history.state.chromecomState.
// history.state, which is preserved across reloads/navigations. var port;
var state = window.history.state || {}; // Set the referer for the given URL.
state.chromecomState = referer; // 0. Background: If loaded via a http(s) URL: Save referer.
window.history.replaceState(state, ''); // 1. Page -> background: send URL and referer from history.state
} // 2. Background: Bind referer to URL (via webRequest).
onCompleted(); // 3. Background -> page: Send latest referer and save to history.
} // 4. Page: Invoke callback.
function onDisconnect() { function setReferer(url, callback) {
// When the connection fails, ignore the error and call the callback. if (!port) {
port = null; // The background page will accept the port, and keep adding the Referer
callback(); // request header to requests to |url| until the port is disconnected.
} port = chrome.runtime.connect({name: 'chromecom-referrer'});
function onCompleted() { }
port.onDisconnect.removeListener(onDisconnect); port.onDisconnect.addListener(onDisconnect);
port.onMessage.removeListener(onMessage); port.onMessage.addListener(onMessage);
callback(); // 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();
}
}
// chrome.storage.sync is not supported in every Chromium-derivate. // chrome.storage.sync is not supported in every Chromium-derivate.
// Note: The background page takes care of migrating values from // Note: The background page takes care of migrating values from
// chrome.storage.local to chrome.storage.sync when needed. // chrome.storage.local to chrome.storage.sync when needed.
var storageArea = chrome.storage.sync || chrome.storage.local; var storageArea = chrome.storage.sync || chrome.storage.local;
Preferences._writeToStorage = function (prefObj) { Preferences._writeToStorage = function (prefObj) {
return new Promise(function (resolve) { return new Promise(function (resolve) {
if (prefObj === Preferences.defaults) { if (prefObj === Preferences.defaults) {
var keysToRemove = Object.keys(Preferences.defaults); var keysToRemove = Object.keys(Preferences.defaults);
// If the storage is reset, remove the keys so that the values from // If the storage is reset, remove the keys so that the values from
// managed storage are applied again. // managed storage are applied again.
storageArea.remove(keysToRemove, function() { storageArea.remove(keysToRemove, function() {
resolve(); resolve();
}); });
} else { } else {
storageArea.set(prefObj, function() { storageArea.set(prefObj, function() {
resolve(); resolve();
}); });
} }
}); });
}; };
Preferences._readFromStorage = function (prefObj) { Preferences._readFromStorage = function (prefObj) {
return new Promise(function (resolve) { return new Promise(function (resolve) {
if (chrome.storage.managed) { if (chrome.storage.managed) {
// Get preferences as set by the system administrator. // Get preferences as set by the system administrator.
// See extensions/chromium/preferences_schema.json for more information. // See extensions/chromium/preferences_schema.json for more information.
// These preferences can be overridden by the user. // These preferences can be overridden by the user.
chrome.storage.managed.get(Preferences.defaults, getPreferences); chrome.storage.managed.get(Preferences.defaults, getPreferences);
} else { } else {
// Managed storage not supported, e.g. in old Chromium versions. // Managed storage not supported, e.g. in old Chromium versions.
getPreferences(Preferences.defaults); getPreferences(Preferences.defaults);
} }
function getPreferences(defaultPrefs) { function getPreferences(defaultPrefs) {
if (chrome.runtime.lastError) { if (chrome.runtime.lastError) {
// Managed storage not supported, e.g. in Opera. // Managed storage not supported, e.g. in Opera.
defaultPrefs = Preferences.defaults; defaultPrefs = Preferences.defaults;
}
storageArea.get(defaultPrefs, function(readPrefs) {
resolve(readPrefs);
});
} }
}); storageArea.get(defaultPrefs, function(readPrefs) {
}; resolve(readPrefs);
});
}
});
};
var ChromeExternalServices = Object.create(DefaultExternalServices); var ChromeExternalServices = Object.create(DefaultExternalServices);
ChromeExternalServices.initPassiveLoading = function (callbacks) { ChromeExternalServices.initPassiveLoading = function (callbacks) {
var appConfig = PDFViewerApplication.appConfig; var appConfig = PDFViewerApplication.appConfig;
ChromeCom.resolvePDFFile(appConfig.defaultUrl, ChromeCom.resolvePDFFile(appConfig.defaultUrl,
function (url, length, originalURL) { function (url, length, originalURL) {
callbacks.onOpenWithURL(url, length, originalURL); callbacks.onOpenWithURL(url, length, originalURL);
}); });
}; };
PDFViewerApplication.externalServices = ChromeExternalServices; PDFViewerApplication.externalServices = ChromeExternalServices;
exports.ChromeCom = ChromeCom; export {
})); ChromeCom,
};

238
web/dom_events.js

@ -13,142 +13,132 @@
* limitations under the License. * limitations under the License.
*/ */
'use strict'; import { EventBus } from 'pdfjs-web/ui_utils';
(function (root, factory) { // Attaching to the application event bus to dispatch events to the DOM for
if (typeof define === 'function' && define.amd) { // backwards viewer API compatibility.
define('pdfjs-web/dom_events', ['exports', 'pdfjs-web/ui_utils'], factory); function attachDOMEventsToEventBus(eventBus) {
} else if (typeof exports !== 'undefined') { eventBus.on('documentload', function () {
factory(exports, require('./ui_utils.js')); var event = document.createEvent('CustomEvent');
} else { event.initCustomEvent('documentload', true, true, {});
factory((root.pdfjsWebDOMEvents = {}), root.pdfjsWebUIUtils); window.dispatchEvent(event);
} });
}(this, function (exports, uiUtils) { eventBus.on('pagerendered', function (e) {
var EventBus = uiUtils.EventBus; var event = document.createEvent('CustomEvent');
event.initCustomEvent('pagerendered', true, true, {
// Attaching to the application event bus to dispatch events to the DOM for pageNumber: e.pageNumber,
// backwards viewer API compatibility. cssTransform: e.cssTransform,
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,
});
e.source.div.dispatchEvent(event);
});
eventBus.on('textlayerrendered', function (e) {
var event = document.createEvent('CustomEvent');
event.initCustomEvent('textlayerrendered', true, true, {
pageNumber: e.pageNumber
});
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) { e.source.div.dispatchEvent(event);
var event = document.createEvent('CustomEvent'); });
event.initCustomEvent('pagesinit', true, true, null); eventBus.on('textlayerrendered', function (e) {
e.source.container.dispatchEvent(event); var event = document.createEvent('CustomEvent');
event.initCustomEvent('textlayerrendered', true, true, {
pageNumber: e.pageNumber
}); });
eventBus.on('pagesloaded', function (e) { e.source.textLayerDiv.dispatchEvent(event);
var event = document.createEvent('CustomEvent'); });
event.initCustomEvent('pagesloaded', true, true, { eventBus.on('pagechange', function (e) {
pagesCount: e.pagesCount var event = document.createEvent('UIEvents');
}); event.initUIEvent('pagechange', true, true, window, 0);
e.source.container.dispatchEvent(event); 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('scalechange', function (e) { e.source.container.dispatchEvent(event);
var event = document.createEvent('UIEvents'); });
event.initUIEvent('scalechange', true, true, window, 0); eventBus.on('scalechange', function (e) {
event.scale = e.scale; var event = document.createEvent('UIEvents');
event.presetValue = e.presetValue; event.initUIEvent('scalechange', true, true, window, 0);
e.source.container.dispatchEvent(event); event.scale = e.scale;
}); event.presetValue = e.presetValue;
eventBus.on('updateviewarea', function (e) { e.source.container.dispatchEvent(event);
var event = document.createEvent('UIEvents'); });
event.initUIEvent('updateviewarea', true, true, window, 0); eventBus.on('updateviewarea', function (e) {
event.location = e.location; var event = document.createEvent('UIEvents');
e.source.container.dispatchEvent(event); event.initUIEvent('updateviewarea', true, true, window, 0);
}); event.location = e.location;
eventBus.on('find', function (e) { e.source.container.dispatchEvent(event);
if (e.source === window) { });
return; // event comes from FirefoxCom, no need to replicate eventBus.on('find', function (e) {
} if (e.source === window) {
var event = document.createEvent('CustomEvent'); return; // event comes from FirefoxCom, no need to replicate
event.initCustomEvent('find' + e.type, true, true, { }
query: e.query, var event = document.createEvent('CustomEvent');
phraseSearch: e.phraseSearch, event.initCustomEvent('find' + e.type, true, true, {
caseSensitive: e.caseSensitive, query: e.query,
highlightAll: e.highlightAll, phraseSearch: e.phraseSearch,
findPrevious: e.findPrevious caseSensitive: e.caseSensitive,
}); highlightAll: e.highlightAll,
window.dispatchEvent(event); findPrevious: e.findPrevious
}); });
eventBus.on('attachmentsloaded', function (e) { window.dispatchEvent(event);
var event = document.createEvent('CustomEvent'); });
event.initCustomEvent('attachmentsloaded', true, true, { eventBus.on('attachmentsloaded', function (e) {
attachmentsCount: e.attachmentsCount var event = document.createEvent('CustomEvent');
}); event.initCustomEvent('attachmentsloaded', true, true, {
e.source.container.dispatchEvent(event); attachmentsCount: e.attachmentsCount
}); });
eventBus.on('sidebarviewchanged', function (e) { e.source.container.dispatchEvent(event);
var event = document.createEvent('CustomEvent'); });
event.initCustomEvent('sidebarviewchanged', true, true, { eventBus.on('sidebarviewchanged', function (e) {
view: e.view, var event = document.createEvent('CustomEvent');
}); event.initCustomEvent('sidebarviewchanged', true, true, {
e.source.outerContainer.dispatchEvent(event); view: e.view,
}); });
eventBus.on('pagemode', function (e) { e.source.outerContainer.dispatchEvent(event);
var event = document.createEvent('CustomEvent'); });
event.initCustomEvent('pagemode', true, true, { eventBus.on('pagemode', function (e) {
mode: e.mode, var event = document.createEvent('CustomEvent');
}); event.initCustomEvent('pagemode', true, true, {
e.source.pdfViewer.container.dispatchEvent(event); mode: e.mode,
}); });
eventBus.on('namedaction', function (e) { e.source.pdfViewer.container.dispatchEvent(event);
var event = document.createEvent('CustomEvent'); });
event.initCustomEvent('namedaction', true, true, { eventBus.on('namedaction', function (e) {
action: e.action var event = document.createEvent('CustomEvent');
}); event.initCustomEvent('namedaction', true, true, {
e.source.pdfViewer.container.dispatchEvent(event); action: e.action
}); });
eventBus.on('presentationmodechanged', function (e) { e.source.pdfViewer.container.dispatchEvent(event);
var event = document.createEvent('CustomEvent'); });
event.initCustomEvent('presentationmodechanged', true, true, { eventBus.on('presentationmodechanged', function (e) {
active: e.active, var event = document.createEvent('CustomEvent');
switchInProgress: e.switchInProgress event.initCustomEvent('presentationmodechanged', true, true, {
}); active: e.active,
window.dispatchEvent(event); switchInProgress: e.switchInProgress
}); });
eventBus.on('outlineloaded', function (e) { window.dispatchEvent(event);
var event = document.createEvent('CustomEvent'); });
event.initCustomEvent('outlineloaded', true, true, { eventBus.on('outlineloaded', function (e) {
outlineCount: e.outlineCount var event = document.createEvent('CustomEvent');
}); event.initCustomEvent('outlineloaded', true, true, {
e.source.container.dispatchEvent(event); outlineCount: e.outlineCount
}); });
} e.source.container.dispatchEvent(event);
});
}
var globalEventBus = null; var globalEventBus = null;
function getGlobalEventBus() { function getGlobalEventBus() {
if (globalEventBus) { if (globalEventBus) {
return globalEventBus;
}
globalEventBus = new EventBus();
attachDOMEventsToEventBus(globalEventBus);
return globalEventBus; return globalEventBus;
} }
globalEventBus = new EventBus();
attachDOMEventsToEventBus(globalEventBus);
return globalEventBus;
}
exports.attachDOMEventsToEventBus = attachDOMEventsToEventBus; export {
exports.getGlobalEventBus = getGlobalEventBus; attachDOMEventsToEventBus,
})); getGlobalEventBus,
};

22
web/download_manager.js

@ -13,27 +13,14 @@
* limitations under the License. * 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')) { if (typeof PDFJSDev !== 'undefined' && !PDFJSDev.test('CHROME || GENERIC')) {
throw new Error('Module "pdfjs-web/download_manager" shall not be used ' + throw new Error('Module "pdfjs-web/download_manager" shall not be used ' +
'outside CHROME and GENERIC builds.'); 'outside CHROME and GENERIC builds.');
} }
var PDFViewerApplication = app.PDFViewerApplication;
var DefaultExternalServices = app.DefaultExternalServices;
function download(blobUrl, filename) { function download(blobUrl, filename) {
var a = document.createElement('a'); var a = document.createElement('a');
if (a.click) { if (a.click) {
@ -118,5 +105,6 @@ GenericExternalServices.createDownloadManager = function () {
}; };
PDFViewerApplication.externalServices = GenericExternalServices; PDFViewerApplication.externalServices = GenericExternalServices;
exports.DownloadManager = DownloadManager; export {
})); DownloadManager,
};

188
web/firefox_print_service.js

@ -13,110 +13,98 @@
* limitations under the License. * limitations under the License.
*/ */
'use strict'; import * as pdfjsLib from 'pdfjs-web/pdfjs';
import { CSS_UNITS } from 'pdfjs-web/ui_utils';
(function (root, factory) { import { PDFPrintServiceFactory } from 'pdfjs-web/app';
if (typeof define === 'function' && define.amd) {
define('pdfjs-web/firefox_print_service', ['exports', 'pdfjs-web/ui_utils', // Creates a placeholder with div and canvas with right size for the page.
'pdfjs-web/app', 'pdfjs-web/pdfjs'], factory); function composePage(pdfDocument, pageNumber, size, printContainer) {
} else if (typeof exports !== 'undefined') { var canvas = document.createElement('canvas');
factory(exports, require('./ui_utils.js'), require('./app.js'),
require('./pdfjs.js')); // The size of the canvas in pixels for printing.
} else { var PRINT_RESOLUTION = 150;
factory((root.pdfjsWebFirefoxPrintService = {}), root.pdfjsWebUIUtils, var PRINT_UNITS = PRINT_RESOLUTION / 72.0;
root.pdfjsWebApp, root.pdfjsWebPDFJS); canvas.width = Math.floor(size.width * PRINT_UNITS);
} canvas.height = Math.floor(size.height * PRINT_UNITS);
}(this, function (exports, uiUtils, app, pdfjsLib) {
var CSS_UNITS = uiUtils.CSS_UNITS; // The physical size of the canvas as specified by the PDF document.
var PDFPrintServiceFactory = app.PDFPrintServiceFactory; canvas.style.width = Math.floor(size.width * CSS_UNITS) + 'px';
canvas.style.height = Math.floor(size.height * CSS_UNITS) + 'px';
// Creates a placeholder with div and canvas with right size for the page.
function composePage(pdfDocument, pageNumber, size, printContainer) { var canvasWrapper = document.createElement('div');
var canvas = document.createElement('canvas'); canvasWrapper.appendChild(canvas);
printContainer.appendChild(canvasWrapper);
// The size of the canvas in pixels for printing.
var PRINT_RESOLUTION = 150; canvas.mozPrintCallback = function(obj) {
var PRINT_UNITS = PRINT_RESOLUTION / 72.0; // Printing/rendering the page.
canvas.width = Math.floor(size.width * PRINT_UNITS); var ctx = obj.context;
canvas.height = Math.floor(size.height * PRINT_UNITS);
ctx.save();
// The physical size of the canvas as specified by the PDF document. ctx.fillStyle = 'rgb(255, 255, 255)';
canvas.style.width = Math.floor(size.width * CSS_UNITS) + 'px'; ctx.fillRect(0, 0, canvas.width, canvas.height);
canvas.style.height = Math.floor(size.height * CSS_UNITS) + 'px'; ctx.restore();
var canvasWrapper = document.createElement('div'); pdfDocument.getPage(pageNumber).then(function (pdfPage) {
canvasWrapper.appendChild(canvas); var renderContext = {
printContainer.appendChild(canvasWrapper); canvasContext: ctx,
transform: [PRINT_UNITS, 0, 0, PRINT_UNITS, 0, 0],
canvas.mozPrintCallback = function(obj) { viewport: pdfPage.getViewport(1, size.rotation),
// Printing/rendering the page. intent: 'print'
var ctx = obj.context; };
return pdfPage.render(renderContext).promise;
ctx.save(); }).then(function() {
ctx.fillStyle = 'rgb(255, 255, 255)'; // Tell the printEngine that rendering this canvas/page has finished.
ctx.fillRect(0, 0, canvas.width, canvas.height); obj.done();
ctx.restore(); }, function(error) {
console.error(error);
pdfDocument.getPage(pageNumber).then(function (pdfPage) { // Tell the printEngine that rendering this canvas/page has failed.
var renderContext = { // This will make the print process stop.
canvasContext: ctx, if ('abort' in obj) {
transform: [PRINT_UNITS, 0, 0, PRINT_UNITS, 0, 0], obj.abort();
viewport: pdfPage.getViewport(1, size.rotation), } else {
intent: 'print'
};
return pdfPage.render(renderContext).promise;
}).then(function() {
// Tell the printEngine that rendering this canvas/page has finished.
obj.done(); 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 = '';
}
}; };
}
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);
}
},
PDFPrintServiceFactory.instance = { destroy: function () {
get supportsPrinting() { this.printContainer.textContent = '';
var canvas = document.createElement('canvas'); }
var value = 'mozPrintCallback' in canvas; };
return pdfjsLib.shadow(this, 'supportsPrinting', value); PDFPrintServiceFactory.instance = {
}, get supportsPrinting() {
var canvas = document.createElement('canvas');
var value = 'mozPrintCallback' in canvas;
createPrintService: function (pdfDocument, pagesOverview, printContainer) { return pdfjsLib.shadow(this, 'supportsPrinting', value);
return new FirefoxPrintService(pdfDocument, pagesOverview, },
printContainer);
} createPrintService: function (pdfDocument, pagesOverview, printContainer) {
}; return new FirefoxPrintService(pdfDocument, pagesOverview,
printContainer);
}
};
exports.FirefoxPrintService = FirefoxPrintService; export {
})); FirefoxPrintService,
};

28
web/firefoxcom.js

@ -13,29 +13,16 @@
* limitations under the License. * limitations under the License.
*/ */
'use strict'; import * as pdfjsLib from 'pdfjs-web/pdfjs';
import { PDFViewerApplication } from 'pdfjs-web/app';
(function (root, factory) { import { Preferences } from 'pdfjs-web/preferences';
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' || if (typeof PDFJSDev === 'undefined' ||
!PDFJSDev.test('FIREFOX || MOZCENTRAL')) { !PDFJSDev.test('FIREFOX || MOZCENTRAL')) {
throw new Error('Module "pdfjs-web/firefoxcom" shall not be used outside ' + throw new Error('Module "pdfjs-web/firefoxcom" shall not be used outside ' +
'FIREFOX and MOZCENTRAL builds.'); 'FIREFOX and MOZCENTRAL builds.');
} }
var Preferences = preferences.Preferences;
var PDFViewerApplication = app.PDFViewerApplication;
var FirefoxCom = (function FirefoxComClosure() { var FirefoxCom = (function FirefoxComClosure() {
return { return {
/** /**
@ -291,6 +278,7 @@ document.mozL10n.setExternalLocalizerServices({
} }
}); });
exports.DownloadManager = DownloadManager; export {
exports.FirefoxCom = FirefoxCom; DownloadManager,
})); FirefoxCom,
};

396
web/grab_to_pan.js

@ -14,224 +14,214 @@
* limitations under the License. * limitations under the License.
*/ */
'use strict'; /**
* Construct a GrabToPan instance for a given HTML element.
(function (root, factory) { * @param options.element {Element}
if (typeof define === 'function' && define.amd) { * @param options.ignoreTarget {function} optional. See `ignoreTarget(node)`
define('pdfjs-web/grab_to_pan', ['exports'], factory); * @param options.onActiveChanged {function(boolean)} optional. Called
} else if (typeof exports !== 'undefined') { * when grab-to-pan is (de)activated. The first argument is a boolean that
factory(exports); * shows whether grab-to-pan is activated.
} else { */
factory((root.pdfjsWebGrabToPan = {})); 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. * Class name of element which can be grabbed
* @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) { CSS_CLASS_GRAB: 'grab-to-pan-grab',
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) { * Bind a mousedown event to the element to enable grab-detection.
this.deactivate(); */
} else { activate: function GrabToPan_activate() {
this.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) {
* Whether to not pan if the target element is clicked. this.onActiveChanged(true);
* 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; * Removes all events. Any pending pan session is immediately stopped.
this.clientXStart = event.clientX; */
this.clientYStart = event.clientY; deactivate: function GrabToPan_deactivate() {
this.document.addEventListener('mousemove', this._onmousemove, true); if (this.active) {
this.document.addEventListener('mouseup', this._endPan, true); this.active = false;
// When a scroll event occurs before a mousemove, assume that the user this.element.removeEventListener('mousedown', this._onmousedown, true);
// dragged a scrollbar (necessary for Opera Presto, Safari and IE) this._endPan();
// (not needed for Chrome/Firefox) this.element.classList.remove(this.CSS_CLASS_GRAB);
this.element.addEventListener('scroll', this._endPan, true); if (this.onActiveChanged) {
event.preventDefault(); this.onActiveChanged(false);
event.stopPropagation();
var focusedElement = document.activeElement;
if (focusedElement && !focusedElement.contains(event.target)) {
focusedElement.blur();
} }
}, }
},
/**
* @private toggle: function GrabToPan_toggle() {
*/ if (this.active) {
_onmousemove: function GrabToPan__onmousemove(event) { this.deactivate();
this.element.removeEventListener('scroll', this._endPan, true); } else {
if (isLeftMouseReleased(event)) { this.activate();
this._endPan(); }
},
/**
* 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; 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();
} }
};
this.scrollLeftStart = this.element.scrollLeft;
// Get the correct (vendor-prefixed) name of the matches method. this.scrollTopStart = this.element.scrollTop;
var matchesSelector; this.clientXStart = event.clientX;
['webkitM', 'mozM', 'msM', 'oM', 'm'].some(function(prefix) { this.clientYStart = event.clientY;
var name = prefix + 'atches'; this.document.addEventListener('mousemove', this._onmousemove, true);
if (name in document.documentElement) { this.document.addEventListener('mouseup', this._endPan, true);
matchesSelector = name; // When a scroll event occurs before a mousemove, assume that the user
} // dragged a scrollbar (necessary for Opera Presto, Safari and IE)
name += 'Selector'; // (not needed for Chrome/Firefox)
if (name in document.documentElement) { this.element.addEventListener('scroll', this._endPan, true);
matchesSelector = name; event.preventDefault();
event.stopPropagation();
var focusedElement = document.activeElement;
if (focusedElement && !focusedElement.contains(event.target)) {
focusedElement.blur();
} }
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. * @private
* @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) { _onmousemove: function GrabToPan__onmousemove(event) {
if ('buttons' in event && isNotIEorIsIE10plus) { this.element.removeEventListener('scroll', this._endPan, true);
// http://www.w3.org/TR/DOM-Level-3-Events/#events-MouseEvent-buttons if (isLeftMouseReleased(event)) {
// Firefox 15+ this._endPan();
// Internet Explorer 10+ return;
return !(event.buttons & 1);
} }
if (isChrome15OrOpera15plus || isSafari6plus) { var xDiff = event.clientX - this.clientXStart;
// Chrome 14+ var yDiff = event.clientY - this.clientYStart;
// Opera 15+ var scrollTop = this.scrollTopStart - yDiff;
// Safari 6.0+ var scrollLeft = this.scrollLeftStart - xDiff;
return event.which === 0; 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;
} }
}
exports.GrabToPan = GrabToPan; export {
})); GrabToPan,
};

26
web/hand_tool.js

@ -13,24 +13,9 @@
* limitations under the License. * limitations under the License.
*/ */
'use strict'; import { GrabToPan } from 'pdfjs-web/grab_to_pan';
import { localized } from 'pdfjs-web/ui_utils';
(function (root, factory) { import { Preferences } from 'pdfjs-web/preferences';
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;
/** /**
* @typedef {Object} HandToolOptions * @typedef {Object} HandToolOptions
@ -110,5 +95,6 @@ var HandTool = (function HandToolClosure() {
return HandTool; return HandTool;
})(); })();
exports.HandTool = HandTool; export {
})); HandTool,
};

17
web/overlay_manager.js

@ -13,18 +13,6 @@
* limitations under the License. * 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 = { var OverlayManager = {
overlays: {}, overlays: {},
active: null, active: null,
@ -151,5 +139,6 @@ var OverlayManager = {
} }
}; };
exports.OverlayManager = OverlayManager; export {
})); OverlayManager,
};

26
web/password_prompt.js

@ -13,24 +13,9 @@
* limitations under the License. * limitations under the License.
*/ */
'use strict'; import * as pdfjsLib from 'pdfjs-web/pdfjs';
import { mozL10n } from 'pdfjs-web/ui_utils';
(function (root, factory) { import { OverlayManager } from 'pdfjs-web/overlay_manager';
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;
/** /**
* @typedef {Object} PasswordPromptOptions * @typedef {Object} PasswordPromptOptions
@ -120,5 +105,6 @@ var PasswordPrompt = (function PasswordPromptClosure() {
return PasswordPrompt; return PasswordPrompt;
})(); })();
exports.PasswordPrompt = PasswordPrompt; export {
})); PasswordPrompt,
};

18
web/pdf_attachment_viewer.js

@ -13,18 +13,7 @@
* limitations under the License. * limitations under the License.
*/ */
'use strict'; import * as pdfjsLib from 'pdfjs-web/pdfjs';
(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) {
/** /**
* @typedef {Object} PDFAttachmentViewerOptions * @typedef {Object} PDFAttachmentViewerOptions
@ -205,5 +194,6 @@ var PDFAttachmentViewer = (function PDFAttachmentViewerClosure() {
return PDFAttachmentViewer; return PDFAttachmentViewer;
})(); })();
exports.PDFAttachmentViewer = PDFAttachmentViewer; export {
})); PDFAttachmentViewer,
};

24
web/pdf_document_properties.js

@ -13,23 +13,8 @@
* limitations under the License. * limitations under the License.
*/ */
'use strict'; import { getPDFFileNameFromURL, mozL10n } from 'pdfjs-web/ui_utils';
import { OverlayManager } from 'pdfjs-web/overlay_manager';
(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;
/** /**
* @typedef {Object} PDFDocumentPropertiesOptions * @typedef {Object} PDFDocumentPropertiesOptions
@ -239,5 +224,6 @@ var PDFDocumentProperties = (function PDFDocumentPropertiesClosure() {
return PDFDocumentProperties; return PDFDocumentProperties;
})(); })();
exports.PDFDocumentProperties = PDFDocumentProperties; export {
})); PDFDocumentProperties,
};

24
web/pdf_find_bar.js

@ -13,23 +13,8 @@
* limitations under the License. * limitations under the License.
*/ */
'use strict'; import { FindStates } from 'pdfjs-web/pdf_find_controller';
import { mozL10n } from 'pdfjs-web/ui_utils';
(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;
/** /**
* Creates a "search bar" given a set of DOM elements that act as controls * Creates a "search bar" given a set of DOM elements that act as controls
@ -236,5 +221,6 @@ var PDFFindBar = (function PDFFindBarClosure() {
return PDFFindBar; return PDFFindBar;
})(); })();
exports.PDFFindBar = PDFFindBar; export {
})); PDFFindBar,
};

22
web/pdf_find_controller.js

@ -13,20 +13,7 @@
* limitations under the License. * limitations under the License.
*/ */
'use strict'; import { scrollIntoView } from 'pdfjs-web/ui_utils';
(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;
var FindStates = { var FindStates = {
FIND_FOUND: 0, FIND_FOUND: 0,
@ -505,6 +492,7 @@ var PDFFindController = (function PDFFindControllerClosure() {
return PDFFindController; return PDFFindController;
})(); })();
exports.FindStates = FindStates; export {
exports.PDFFindController = PDFFindController; FindStates,
})); PDFFindController,
};

742
web/pdf_history.js

@ -14,423 +14,413 @@
*/ */
/* globals chrome */ /* globals chrome */
'use strict'; import { domEvents } from 'pdfjs-web/dom_events';
(function (root, factory) { function PDFHistory(options) {
if (typeof define === 'function' && define.amd) { this.linkService = options.linkService;
define('pdfjs-web/pdf_history', ['exports', 'pdfjs-web/dom_events'], this.eventBus = options.eventBus || domEvents.getGlobalEventBus();
factory);
} else if (typeof exports !== 'undefined') { this.initialized = false;
factory(exports, require('./dom_events.js')); this.initialDestination = null;
} else { this.initialBookmark = null;
factory((root.pdfjsWebPDFHistory = {}), root.pdfjsWebDOMEvents); }
}
}(this, function (exports, domEvents) { PDFHistory.prototype = {
/**
function PDFHistory(options) { * @param {string} fingerprint
this.linkService = options.linkService; */
this.eventBus = options.eventBus || domEvents.getGlobalEventBus(); initialize: function pdfHistoryInitialize(fingerprint) {
this.initialized = true;
this.initialized = false; this.reInitialized = false;
this.initialDestination = null; this.allowHashChange = true;
this.initialBookmark = null; this.historyUnlocked = true;
} this.isViewerInPresentationMode = false;
PDFHistory.prototype = { this.previousHash = window.location.hash.substring(1);
/** this.currentBookmark = '';
* @param {string} fingerprint this.currentPage = 0;
*/ this.updatePreviousBookmark = false;
initialize: function pdfHistoryInitialize(fingerprint) { this.previousBookmark = '';
this.initialized = true; this.previousPage = 0;
this.reInitialized = false; this.nextHashParam = '';
this.allowHashChange = true;
this.historyUnlocked = true; this.fingerprint = fingerprint;
this.isViewerInPresentationMode = false; this.currentUid = this.uid = 0;
this.current = {};
this.previousHash = window.location.hash.substring(1);
this.currentBookmark = ''; var state = window.history.state;
this.currentPage = 0; if (this._isStateObjectDefined(state)) {
this.updatePreviousBookmark = false; // This corresponds to navigating back to the document
this.previousBookmark = ''; // from another page in the browser history.
this.previousPage = 0; if (state.target.dest) {
this.nextHashParam = ''; this.initialDestination = state.target.dest;
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 { } else {
// This corresponds to the loading of a new document. this.initialBookmark = state.target.hash;
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);
} }
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; var self = this;
window.addEventListener('popstate', function pdfHistoryPopstate(evt) { window.addEventListener('popstate', function pdfHistoryPopstate(evt) {
if (!self.historyUnlocked) { if (!self.historyUnlocked) {
return; return;
} }
if (evt.state) { if (evt.state) {
// Move back/forward in the history. // Move back/forward in the history.
self._goTo(evt.state); self._goTo(evt.state);
return; return;
} }
// If the state is not set, then the user tried to navigate to a // 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 // different hash by manually editing the URL and pressing Enter, or by
// clicking on an in-page link (e.g. the "current view" link). // clicking on an in-page link (e.g. the "current view" link).
// Save the current view state to the browser history. // Save the current view state to the browser history.
// Note: In Firefox, history.null could also be null after an in-page // Note: In Firefox, history.null could also be null after an in-page
// navigation to the same URL, and without dispatching the popstate // navigation to the same URL, and without dispatching the popstate
// event: https://bugzilla.mozilla.org/show_bug.cgi?id=1183881 // event: https://bugzilla.mozilla.org/show_bug.cgi?id=1183881
if (self.uid === 0) { if (self.uid === 0) {
// Replace the previous state if it was not explicitly set. // Replace the previous state if it was not explicitly set.
var previousParams = (self.previousHash && self.currentBookmark && var previousParams = (self.previousHash && self.currentBookmark &&
self.previousHash !== self.currentBookmark) ? self.previousHash !== self.currentBookmark) ?
{hash: self.currentBookmark, page: self.currentPage} : {hash: self.currentBookmark, page: self.currentPage} :
{page: 1}; {page: 1};
replacePreviousHistoryState(previousParams, function() { replacePreviousHistoryState(previousParams, function() {
updateHistoryWithCurrentHash();
});
} else {
updateHistoryWithCurrentHash(); updateHistoryWithCurrentHash();
} });
}); } else {
updateHistoryWithCurrentHash();
}
});
function updateHistoryWithCurrentHash() { function updateHistoryWithCurrentHash() {
self.previousHash = window.location.hash.slice(1); self.previousHash = window.location.hash.slice(1);
self._pushToHistory({hash: self.previousHash}, false, true); self._pushToHistory({hash: self.previousHash}, false, true);
self._updatePreviousBookmark(); self._updatePreviousBookmark();
} }
function replacePreviousHistoryState(params, callback) { function replacePreviousHistoryState(params, callback) {
// To modify the previous history entry, the following happens: // To modify the previous history entry, the following happens:
// 1. history.back() // 1. history.back()
// 2. _pushToHistory, which calls history.replaceState( ... ) // 2. _pushToHistory, which calls history.replaceState( ... )
// 3. history.forward() // 3. history.forward()
// Because a navigation via the history API does not immediately update // Because a navigation via the history API does not immediately update
// the history state, the popstate event is used for synchronization. // the history state, the popstate event is used for synchronization.
self.historyUnlocked = false; self.historyUnlocked = false;
// Suppress the hashchange event to avoid side effects caused by // Suppress the hashchange event to avoid side effects caused by
// navigating back and forward. // navigating back and forward.
self.allowHashChange = false; self.allowHashChange = false;
window.addEventListener('popstate', rewriteHistoryAfterBack); window.addEventListener('popstate', rewriteHistoryAfterBack);
history.back(); history.back();
function rewriteHistoryAfterBack() { function rewriteHistoryAfterBack() {
window.removeEventListener('popstate', rewriteHistoryAfterBack); window.removeEventListener('popstate', rewriteHistoryAfterBack);
window.addEventListener('popstate', rewriteHistoryAfterForward); window.addEventListener('popstate', rewriteHistoryAfterForward);
self._pushToHistory(params, false, true); self._pushToHistory(params, false, true);
history.forward(); history.forward();
}
function rewriteHistoryAfterForward() {
window.removeEventListener('popstate', rewriteHistoryAfterForward);
self.allowHashChange = true;
self.historyUnlocked = true;
callback();
}
} }
function rewriteHistoryAfterForward() {
window.removeEventListener('popstate', rewriteHistoryAfterForward);
self.allowHashChange = true;
self.historyUnlocked = true;
callback();
}
}
function pdfHistoryBeforeUnload() { function pdfHistoryBeforeUnload() {
var previousParams = self._getPreviousParams(null, true); var previousParams = self._getPreviousParams(null, true);
if (previousParams) { if (previousParams) {
var replacePrevious = (!self.current.dest && var replacePrevious = (!self.current.dest &&
self.current.hash !== self.previousHash); self.current.hash !== self.previousHash);
self._pushToHistory(previousParams, false, replacePrevious); self._pushToHistory(previousParams, false, replacePrevious);
self._updatePreviousBookmark(); self._updatePreviousBookmark();
}
// Remove the event listener when navigating away from the document,
// since 'beforeunload' prevents Firefox from caching the document.
window.removeEventListener('beforeunload', pdfHistoryBeforeUnload);
} }
// 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('beforeunload', pdfHistoryBeforeUnload);
window.addEventListener('pageshow', function pdfHistoryPageShow(evt) { window.addEventListener('pageshow', function pdfHistoryPageShow(evt) {
// If the entire viewer (including the PDF file) is cached in // If the entire viewer (including the PDF file) is cached in
// the browser, we need to reattach the 'beforeunload' event listener // the browser, we need to reattach the 'beforeunload' event listener
// since the 'DOMContentLoaded' event is not fired on 'pageshow'. // since the 'DOMContentLoaded' event is not fired on 'pageshow'.
window.addEventListener('beforeunload', pdfHistoryBeforeUnload); window.addEventListener('beforeunload', pdfHistoryBeforeUnload);
}); });
self.eventBus.on('presentationmodechanged', function(e) { self.eventBus.on('presentationmodechanged', function(e) {
self.isViewerInPresentationMode = e.active; self.isViewerInPresentationMode = e.active;
}); });
}, },
clearHistoryState: function pdfHistory_clearHistoryState() { clearHistoryState: function pdfHistory_clearHistoryState() {
this._pushOrReplaceState(null, true); this._pushOrReplaceState(null, true);
}, },
_isStateObjectDefined: function pdfHistory_isStateObjectDefined(state) { _isStateObjectDefined: function pdfHistory_isStateObjectDefined(state) {
return (state && state.uid >= 0 && return (state && state.uid >= 0 &&
state.fingerprint && this.fingerprint === state.fingerprint && state.fingerprint && this.fingerprint === state.fingerprint &&
state.target && state.target.hash) ? true : false; state.target && state.target.hash) ? true : false;
}, },
_pushOrReplaceState: function pdfHistory_pushOrReplaceState(stateObj, _pushOrReplaceState: function pdfHistory_pushOrReplaceState(stateObj,
replace) { replace) {
// history.state.chromecomState is managed by chromecom.js. // history.state.chromecomState is managed by chromecom.js.
if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('CHROME') && if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('CHROME') &&
window.history.state && 'chromecomState' in window.history.state) { window.history.state && 'chromecomState' in window.history.state) {
stateObj = stateObj || {}; stateObj = stateObj || {};
stateObj.chromecomState = window.history.state.chromecomState; stateObj.chromecomState = window.history.state.chromecomState;
} }
if (replace) { if (replace) {
if (typeof PDFJSDev === 'undefined' || if (typeof PDFJSDev === 'undefined' ||
PDFJSDev.test('GENERIC || CHROME')) { PDFJSDev.test('GENERIC || CHROME')) {
window.history.replaceState(stateObj, '', document.URL); window.history.replaceState(stateObj, '', document.URL);
} else {
window.history.replaceState(stateObj, '');
}
} else { } else {
if (typeof PDFJSDev === 'undefined' || window.history.replaceState(stateObj, '');
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');
}
} }
}, } else {
if (typeof PDFJSDev === 'undefined' ||
get isHashChangeUnlocked() { PDFJSDev.test('GENERIC || CHROME')) {
if (!this.initialized) { window.history.pushState(stateObj, '', document.URL);
return true; } else {
window.history.pushState(stateObj, '');
} }
return this.allowHashChange; if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('CHROME') &&
}, top === window) {
chrome.runtime.sendMessage('showPageAction');
_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, get isHashChangeUnlocked() {
pageNum) { if (!this.initialized) {
if (this.initialized) { return true;
this.currentBookmark = bookmark.substring(1); }
this.currentPage = pageNum | 0; return this.allowHashChange;
this._updatePreviousBookmark(); },
}
}, _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) { updateNextHashParam: function pdfHistoryUpdateNextHashParam(param) {
if (this.initialized) { if (this.initialized) {
this.nextHashParam = param; this.nextHashParam = param;
} }
}, },
push: function pdfHistoryPush(params, isInitialBookmark) { push: function pdfHistoryPush(params, isInitialBookmark) {
if (!(this.initialized && this.historyUnlocked)) { if (!(this.initialized && this.historyUnlocked)) {
return; return;
} }
if (params.dest && !params.hash) { if (params.dest && !params.hash) {
params.hash = (this.current.hash && this.current.dest && params.hash = (this.current.hash && this.current.dest &&
this.current.dest === params.dest) ? this.current.dest === params.dest) ?
this.current.hash : this.current.hash :
this.linkService.getDestinationHash(params.dest).split('#')[1]; this.linkService.getDestinationHash(params.dest).split('#')[1];
} }
if (params.page) { if (params.page) {
params.page |= 0; 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);
} }
if (isInitialBookmark) { this.updatePreviousBookmark = this.nextHashParam ? false : true;
var target = window.history.state.target; if (target) {
if (!target) { // If the current document is reloaded,
// Invoked when the user specifies an initial bookmark, // avoid creating duplicate entries in the history.
// thus setting initialBookmark, when the document is loaded. this._updatePreviousBookmark();
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) { return;
if (this.nextHashParam === params.hash) { }
this.nextHashParam = null; if (this.nextHashParam) {
this.updatePreviousBookmark = true; if (this.nextHashParam === params.hash) {
return;
}
this.nextHashParam = null; this.nextHashParam = null;
this.updatePreviousBookmark = true;
return;
} }
this.nextHashParam = null;
}
if (params.hash) { if (params.hash) {
if (this.current.hash) { if (this.current.hash) {
if (this.current.hash !== params.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); this._pushToHistory(params, true);
} else {
if (!this.current.page && params.page) {
this._pushToHistory(params, false, true);
}
this.updatePreviousBookmark = true;
} }
} else if (this.current.page && params.page && } else {
this.current.page !== params.page) {
this._pushToHistory(params, true); 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, _getPreviousParams: function pdfHistory_getPreviousParams(onlyCheckPage,
beforeUnload) { beforeUnload) {
if (!(this.currentBookmark && this.currentPage)) { if (!(this.currentBookmark && this.currentPage)) {
return null; return null;
} else if (this.updatePreviousBookmark) { } else if (this.updatePreviousBookmark) {
this.updatePreviousBookmark = false; this.updatePreviousBookmark = false;
} }
if (this.uid > 0 && !(this.previousBookmark && this.previousPage)) { if (this.uid > 0 && !(this.previousBookmark && this.previousPage)) {
// Prevent the history from getting stuck in the current state, // Prevent the history from getting stuck in the current state,
// effectively preventing the user from going back/forward in // effectively preventing the user from going back/forward in
// the history. // the history.
// //
// This happens if the current position in the document didn't change // This happens if the current position in the document didn't change
// when the history was previously updated. The reasons for this are // when the history was previously updated. The reasons for this are
// either: // either:
// 1. The current zoom value is such that the document does not need to, // 1. The current zoom value is such that the document does not need to,
// or cannot, be scrolled to display the destination. // or cannot, be scrolled to display the destination.
// 2. The previous destination is broken, and doesn't actally point to a // 2. The previous destination is broken, and doesn't actally point to a
// position within the document. // position within the document.
// (This is either due to a bad PDF generator, or the user making a // (This is either due to a bad PDF generator, or the user making a
// mistake when entering a destination in the hash parameters.) // mistake when entering a destination in the hash parameters.)
return null;
}
if ((!this.current.dest && !onlyCheckPage) || beforeUnload) {
if (this.previousBookmark === this.currentBookmark) {
return null; return null;
} }
if ((!this.current.dest && !onlyCheckPage) || beforeUnload) { } else if (this.current.page || onlyCheckPage) {
if (this.previousBookmark === this.currentBookmark) { if (this.previousPage === this.currentPage) {
return null;
}
} else if (this.current.page || onlyCheckPage) {
if (this.previousPage === this.currentPage) {
return null;
}
} else {
return null; return null;
} }
var params = {hash: this.currentBookmark, page: this.currentPage}; } else {
if (this.isViewerInPresentationMode) { return null;
params.hash = null; }
} var params = {hash: this.currentBookmark, page: this.currentPage};
return params; if (this.isViewerInPresentationMode) {
}, params.hash = null;
}
return params;
},
_stateObj: function pdfHistory_stateObj(params) { _stateObj: function pdfHistory_stateObj(params) {
return {fingerprint: this.fingerprint, uid: this.uid, target: params}; return {fingerprint: this.fingerprint, uid: this.uid, target: params};
}, },
_pushToHistory: function pdfHistory_pushToHistory(params, _pushToHistory: function pdfHistory_pushToHistory(params,
addPrevious, overwrite) { addPrevious, overwrite) {
if (!this.initialized) { if (!this.initialized) {
return; return;
} }
if (!params.hash && params.page) { if (!params.hash && params.page) {
params.hash = ('page=' + params.page); params.hash = ('page=' + params.page);
} }
if (addPrevious && !overwrite) { if (addPrevious && !overwrite) {
var previousParams = this._getPreviousParams(); var previousParams = this._getPreviousParams();
if (previousParams) { if (previousParams) {
var replacePrevious = (!this.current.dest && var replacePrevious = (!this.current.dest &&
this.current.hash !== this.previousHash); this.current.hash !== this.previousHash);
this._pushToHistory(previousParams, false, replacePrevious); this._pushToHistory(previousParams, false, replacePrevious);
}
} }
this._pushOrReplaceState(this._stateObj(params), }
(overwrite || this.uid === 0)); this._pushOrReplaceState(this._stateObj(params),
this.currentUid = this.uid++; (overwrite || this.uid === 0));
this.current = params; this.currentUid = this.uid++;
this.updatePreviousBookmark = true; this.current = params;
}, this.updatePreviousBookmark = true;
},
_goTo: function pdfHistory_goTo(state) {
if (!(this.initialized && this.historyUnlocked && _goTo: function pdfHistory_goTo(state) {
this._isStateObjectDefined(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; return;
} }
if (!this.reInitialized && state.uid < this.currentUid) { }
var previousParams = this._getPreviousParams(true); this.historyUnlocked = false;
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) { if (state.target.dest) {
this.linkService.navigateTo(state.target.dest); this.linkService.navigateTo(state.target.dest);
} else { } else {
this.linkService.setHash(state.target.hash); this.linkService.setHash(state.target.hash);
} }
this.currentUid = state.uid; this.currentUid = state.uid;
if (state.uid > this.uid) { if (state.uid > this.uid) {
this.uid = state.uid; this.uid = state.uid;
} }
this.current = state.target; this.current = state.target;
this.updatePreviousBookmark = true; this.updatePreviousBookmark = true;
var currentHash = window.location.hash.substring(1); var currentHash = window.location.hash.substring(1);
if (this.previousHash !== currentHash) { if (this.previousHash !== currentHash) {
this.allowHashChange = false; this.allowHashChange = false;
} }
this.previousHash = currentHash; this.previousHash = currentHash;
this.historyUnlocked = true; this.historyUnlocked = true;
}, },
back: function pdfHistoryBack() { back: function pdfHistoryBack() {
this.go(-1); this.go(-1);
}, },
forward: function pdfHistoryForward() { forward: function pdfHistoryForward() {
this.go(1); this.go(1);
}, },
go: function pdfHistoryGo(direction) { go: function pdfHistoryGo(direction) {
if (this.initialized && this.historyUnlocked) { if (this.initialized && this.historyUnlocked) {
var state = window.history.state; var state = window.history.state;
if (direction === -1 && state && state.uid > 0) { if (direction === -1 && state && state.uid > 0) {
window.history.back(); window.history.back();
} else if (direction === 1 && state && state.uid < (this.uid - 1)) { } else if (direction === 1 && state && state.uid < (this.uid - 1)) {
window.history.forward(); window.history.forward();
}
} }
} }
}; }
};
exports.PDFHistory = PDFHistory; export {
})); PDFHistory,
};

24
web/pdf_link_service.js

@ -13,21 +13,8 @@
* limitations under the License. * limitations under the License.
*/ */
'use strict'; import { domEvents } from 'pdfjs-web/dom_events';
import { parseQueryString } from 'pdfjs-web/ui_utils';
(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;
var PageNumberRegExp = /^\d+$/; var PageNumberRegExp = /^\d+$/;
function isPageNumber(str) { function isPageNumber(str) {
@ -487,6 +474,7 @@ var SimpleLinkService = (function SimpleLinkServiceClosure() {
return SimpleLinkService; return SimpleLinkService;
})(); })();
exports.PDFLinkService = PDFLinkService; export {
exports.SimpleLinkService = SimpleLinkService; PDFLinkService,
})); SimpleLinkService,
};

18
web/pdf_outline_viewer.js

@ -13,18 +13,7 @@
* limitations under the License. * limitations under the License.
*/ */
'use strict'; import * as pdfjsLib from 'pdfjs-web/pdfjs';
(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) {
var PDFJS = pdfjsLib.PDFJS; var PDFJS = pdfjsLib.PDFJS;
@ -231,5 +220,6 @@ var PDFOutlineViewer = (function PDFOutlineViewerClosure() {
return PDFOutlineViewer; return PDFOutlineViewer;
})(); })();
exports.PDFOutlineViewer = PDFOutlineViewer; export {
})); PDFOutlineViewer,
};

37
web/pdf_page_view.js

@ -13,31 +13,13 @@
* limitations under the License. * limitations under the License.
*/ */
'use strict'; import * as pdfjsLib from 'pdfjs-web/pdfjs';
import {
(function (root, factory) { approximateFraction, CSS_UNITS, DEFAULT_SCALE, getOutputScale, RendererType,
if (typeof define === 'function' && define.amd) { roundToDivide
define('pdfjs-web/pdf_page_view', ['exports', } from 'pdfjs-web/ui_utils';
'pdfjs-web/ui_utils', 'pdfjs-web/pdf_rendering_queue', import { domEvents } from 'pdfjs-web/dom_events';
'pdfjs-web/dom_events', 'pdfjs-web/pdfjs'], factory); import { RenderingStates } from 'pdfjs-web/pdf_rendering_queue';
} 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;
var TEXT_LAYER_RENDER_DELAY = 200; // ms var TEXT_LAYER_RENDER_DELAY = 200; // ms
@ -691,5 +673,6 @@ var PDFPageView = (function PDFPageViewClosure() {
return PDFPageView; return PDFPageView;
})(); })();
exports.PDFPageView = PDFPageView; export {
})); PDFPageView,
};

19
web/pdf_presentation_mode.js

@ -13,19 +13,7 @@
* limitations under the License. * limitations under the License.
*/ */
'use strict'; import { normalizeWheelEventDelta } from 'pdfjs-web/ui_utils';
(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;
var DELAY_BEFORE_RESETTING_SWITCH_IN_PROGRESS = 1500; // in ms var DELAY_BEFORE_RESETTING_SWITCH_IN_PROGRESS = 1500; // in ms
var DELAY_BEFORE_HIDING_CONTROLS = 3000; // in ms var DELAY_BEFORE_HIDING_CONTROLS = 3000; // in ms
@ -517,5 +505,6 @@ var PDFPresentationMode = (function PDFPresentationModeClosure() {
return PDFPresentationMode; return PDFPresentationMode;
})(); })();
exports.PDFPresentationMode = PDFPresentationMode; export {
})); PDFPresentationMode,
};

602
web/pdf_print_service.js

@ -13,338 +13,324 @@
* limitations under the License. * limitations under the License.
*/ */
'use strict'; import * as pdfjsLib from 'pdfjs-web/pdfjs';
import { CSS_UNITS, mozL10n } from 'pdfjs-web/ui_utils';
(function (root, factory) { import { OverlayManager } from 'pdfjs-web/overlay_manager';
if (typeof define === 'function' && define.amd) { import { PDFPrintServiceFactory } from 'pdfjs-web/app';
define('pdfjs-web/pdf_print_service', ['exports', 'pdfjs-web/ui_utils',
'pdfjs-web/overlay_manager', 'pdfjs-web/app', 'pdfjs-web/pdfjs'], var activeService = null;
factory);
} else if (typeof exports !== 'undefined') { // Renders the page to the canvas of the given print service, and returns
factory(exports, require('./ui_utils.js'), require('./overlay_manager.js'), // the suggested dimensions of the output page.
require('./app.js'), require('./pdfjs.js')); function renderPage(activeServiceOnEntry, pdfDocument, pageNumber, size) {
} else { var scratchCanvas = activeService.scratchCanvas;
factory((root.pdfjsWebPDFPrintService = {}), root.pdfjsWebUIUtils,
root.pdfjsWebOverlayManager, root.pdfjsWebApp, root.pdfjsWebPDFJS); // The size of the canvas in pixels for printing.
} var PRINT_RESOLUTION = 150;
}(this, function (exports, uiUtils, overlayManager, app, pdfjsLib) { var PRINT_UNITS = PRINT_RESOLUTION / 72.0;
var mozL10n = uiUtils.mozL10n; scratchCanvas.width = Math.floor(size.width * PRINT_UNITS);
var CSS_UNITS = uiUtils.CSS_UNITS; scratchCanvas.height = Math.floor(size.height * PRINT_UNITS);
var PDFPrintServiceFactory = app.PDFPrintServiceFactory;
var OverlayManager = overlayManager.OverlayManager; // The physical size of the img as specified by the PDF document.
var width = Math.floor(size.width * CSS_UNITS) + 'px';
var activeService = null; var height = Math.floor(size.height * CSS_UNITS) + 'px';
// Renders the page to the canvas of the given print service, and returns var ctx = scratchCanvas.getContext('2d');
// the suggested dimensions of the output page. ctx.save();
function renderPage(activeServiceOnEntry, pdfDocument, pageNumber, size) { ctx.fillStyle = 'rgb(255, 255, 255)';
var scratchCanvas = activeService.scratchCanvas; ctx.fillRect(0, 0, scratchCanvas.width, scratchCanvas.height);
ctx.restore();
// The size of the canvas in pixels for printing.
var PRINT_RESOLUTION = 150; return pdfDocument.getPage(pageNumber).then(function (pdfPage) {
var PRINT_UNITS = PRINT_RESOLUTION / 72.0; var renderContext = {
scratchCanvas.width = Math.floor(size.width * PRINT_UNITS); canvasContext: ctx,
scratchCanvas.height = Math.floor(size.height * PRINT_UNITS); transform: [PRINT_UNITS, 0, 0, PRINT_UNITS, 0, 0],
viewport: pdfPage.getViewport(1, size.rotation),
// The physical size of the img as specified by the PDF document. intent: 'print'
var width = Math.floor(size.width * CSS_UNITS) + 'px'; };
var height = Math.floor(size.height * CSS_UNITS) + 'px'; return pdfPage.render(renderContext).promise;
}).then(function () {
var ctx = scratchCanvas.getContext('2d'); return {
ctx.save(); width: width,
ctx.fillStyle = 'rgb(255, 255, 255)'; height: height,
ctx.fillRect(0, 0, scratchCanvas.width, scratchCanvas.height); };
ctx.restore(); });
}
return pdfDocument.getPage(pageNumber).then(function (pdfPage) {
var renderContext = { function PDFPrintService(pdfDocument, pagesOverview, printContainer) {
canvasContext: ctx, this.pdfDocument = pdfDocument;
transform: [PRINT_UNITS, 0, 0, PRINT_UNITS, 0, 0], this.pagesOverview = pagesOverview;
viewport: pdfPage.getViewport(1, size.rotation), this.printContainer = printContainer;
intent: 'print' this.currentPage = -1;
}; // The temporary canvas where renderPage paints one page at a time.
return pdfPage.render(renderContext).promise; this.scratchCanvas = document.createElement('canvas');
}).then(function () { }
return {
width: width, PDFPrintService.prototype = {
height: height, layout: function () {
}; this.throwIfInactive();
});
} var body = document.querySelector('body');
body.setAttribute('data-pdfjsprinting', true);
function PDFPrintService(pdfDocument, pagesOverview, printContainer) {
this.pdfDocument = pdfDocument; var hasEqualPageSizes = this.pagesOverview.every(function (size) {
this.pagesOverview = pagesOverview; return size.width === this.pagesOverview[0].width &&
this.printContainer = printContainer; size.height === this.pagesOverview[0].height;
this.currentPage = -1; }, this);
// The temporary canvas where renderPage paints one page at a time. if (!hasEqualPageSizes) {
this.scratchCanvas = document.createElement('canvas'); console.warn('Not all pages have the same size. The printed ' +
} 'result may be incorrect!');
}
PDFPrintService.prototype = {
layout: function () {
this.throwIfInactive();
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!');
}
// 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:<width> <height>" 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');
});
},
renderPages: function () {
var pageCount = this.pagesOverview.length;
var renderNextPage = function (resolve, reject) {
this.throwIfInactive();
if (++this.currentPage >= pageCount) {
renderProgress(pageCount, pageCount);
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);
},
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;
}
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.');
}
},
};
var print = window.print; // Insert a @page + size rule to make sure that the page size is correctly
window.print = function print() { // set. Note that we assume that all pages have the same size, because
if (activeService) { // variable-size pages are not supported yet (e.g. in Chrome & Firefox).
console.warn('Ignored window.print() because of a pending print job.'); // 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:<width> <height>" 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; 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 () { ensureOverlay().then(function () {
if (activeService) { if (OverlayManager.active !== 'printServiceOverlay') {
OverlayManager.open('printServiceOverlay'); return; // overlay was already closed
} }
OverlayManager.close('printServiceOverlay');
}); });
},
try { renderPages: function () {
dispatchEvent('beforeprint'); var pageCount = this.pagesOverview.length;
} finally { var renderNextPage = function (resolve, reject) {
if (!activeService) { this.throwIfInactive();
console.error('Expected print service to be initialized.'); if (++this.currentPage >= pageCount) {
if (OverlayManager.active === 'printServiceOverlay') { renderProgress(pageCount, pageCount);
OverlayManager.close('printServiceOverlay'); resolve();
} return;
return; // eslint-disable-line no-unsafe-finally
} }
var activeServiceOnEntry = activeService; var index = this.currentPage;
activeService.renderPages().then(function () { renderProgress(index, pageCount);
return activeServiceOnEntry.performPrint(); renderPage(this, this.pdfDocument, index + 1, this.pagesOverview[index])
}).catch(function () { .then(this.useRenderedPage.bind(this))
// Ignore any error messages. .then(function () {
}).then(function () { renderNextPage(resolve, reject);
// aborts acts on the "active" print request, so we need to check }, reject);
// whether the print request (activeServiceOnEntry) is still active. }.bind(this);
// Without the check, an unrelated print request (created after aborting return new Promise(renderNextPage);
// this print request while the pages were being generated) would be },
// aborted.
if (activeServiceOnEntry.active) { useRenderedPage: function (printItem) {
abort(); 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();
} }
};
function dispatchEvent(eventType) { var wrapper = document.createElement('div');
var event = document.createEvent('CustomEvent'); wrapper.appendChild(img);
event.initCustomEvent(eventType, false, false, 'custom'); this.printContainer.appendChild(wrapper);
window.dispatchEvent(event);
}
function abort() { return new Promise(function (resolve, reject) {
if (activeService) { img.onload = resolve;
activeService.destroy(); img.onerror = reject;
dispatchEvent('afterprint'); });
},
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.');
} }
} },
};
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; var print = window.print;
window.print = function print() {
window.addEventListener('keydown', function(event) { if (activeService) {
// Intercept Cmd/Ctrl + P in all browsers. console.warn('Ignored window.print() because of a pending print job.');
// Also intercept Cmd/Ctrl + Shift + P in Chrome and Opera return;
if (event.keyCode === /* P= */ 80 && (event.ctrlKey || event.metaKey) && }
!event.altKey && (!event.shiftKey || window.chrome || window.opera)) { ensureOverlay().then(function () {
window.print(); if (activeService) {
if (hasAttachEvent) { OverlayManager.open('printServiceOverlay');
// Only attachEvent can cancel Ctrl + P dialog in IE <=10 }
// attachEvent is gone in IE11, so the dialog will re-appear in IE11. });
return;
} try {
event.preventDefault(); dispatchEvent('beforeprint');
if (event.stopImmediatePropagation) { } finally {
event.stopImmediatePropagation(); if (!activeService) {
} else { console.error('Expected print service to be initialized.');
event.stopPropagation(); if (OverlayManager.active === 'printServiceOverlay') {
OverlayManager.close('printServiceOverlay');
} }
return; return; // eslint-disable-line no-unsafe-finally
} }
}, true); var activeServiceOnEntry = activeService;
if (hasAttachEvent) { activeService.renderPages().then(function () {
document.attachEvent('onkeydown', function(event) { return activeServiceOnEntry.performPrint();
event = event || window.event; }).catch(function () {
if (event.keyCode === /* P= */ 80 && event.ctrlKey) { // Ignore any error messages.
event.keyCode = 0; }).then(function () {
return false; // 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 function dispatchEvent(eventType) {
// from within this polyfill. (FF/IE). var event = document.createEvent('CustomEvent');
var stopPropagationIfNeeded = function(event) { event.initCustomEvent(eventType, false, false, 'custom');
if (event.detail !== 'custom' && event.stopImmediatePropagation) { window.dispatchEvent(event);
event.stopImmediatePropagation(); }
}
}; function abort() {
window.addEventListener('beforeprint', stopPropagationIfNeeded); if (activeService) {
window.addEventListener('afterprint', stopPropagationIfNeeded); activeService.destroy();
dispatchEvent('afterprint');
} }
}
var overlayPromise;
function ensureOverlay() { function renderProgress(index, total) {
if (!overlayPromise) { var progressContainer = document.getElementById('printServiceOverlay');
overlayPromise = OverlayManager.register('printServiceOverlay', var progress = Math.round(100 * index / total);
document.getElementById('printServiceOverlay'), abort, true); var progressBar = progressContainer.querySelector('progress');
document.getElementById('printCancel').onclick = abort; 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 overlayPromise; 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;
}
});
}
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);
}
var overlayPromise;
function ensureOverlay() {
if (!overlayPromise) {
overlayPromise = OverlayManager.register('printServiceOverlay',
document.getElementById('printServiceOverlay'), abort, true);
document.getElementById('printCancel').onclick = abort;
}
return overlayPromise;
}
PDFPrintServiceFactory.instance = { PDFPrintServiceFactory.instance = {
supportsPrinting: true, supportsPrinting: true,
createPrintService: function (pdfDocument, pagesOverview, printContainer) { createPrintService: function (pdfDocument, pagesOverview, printContainer) {
if (activeService) { if (activeService) {
throw new Error('The print service is created and active.'); throw new Error('The print service is created and active.');
}
activeService = new PDFPrintService(pdfDocument, pagesOverview,
printContainer);
return activeService;
} }
}; activeService = new PDFPrintService(pdfDocument, pagesOverview,
printContainer);
return activeService;
}
};
exports.PDFPrintService = PDFPrintService; export {
})); PDFPrintService,
};

19
web/pdf_rendering_queue.js

@ -13,18 +13,6 @@
* limitations under the License. * 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 CLEANUP_TIMEOUT = 30000;
var RenderingStates = { var RenderingStates = {
@ -186,6 +174,7 @@ var PDFRenderingQueue = (function PDFRenderingQueueClosure() {
return PDFRenderingQueue; return PDFRenderingQueue;
})(); })();
exports.RenderingStates = RenderingStates; export {
exports.PDFRenderingQueue = PDFRenderingQueue; RenderingStates,
})); PDFRenderingQueue,
};

26
web/pdf_sidebar.js

@ -13,23 +13,8 @@
* limitations under the License. * limitations under the License.
*/ */
'use strict'; import { mozL10n } from 'pdfjs-web/ui_utils';
import { RenderingStates } from 'pdfjs-web/pdf_rendering_queue';
(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;
var UI_NOTIFICATION_CLASS = 'pdfSidebarNotification'; var UI_NOTIFICATION_CLASS = 'pdfSidebarNotification';
@ -460,6 +445,7 @@ var PDFSidebar = (function PDFSidebarClosure() {
return PDFSidebar; return PDFSidebar;
})(); })();
exports.SidebarView = SidebarView; export {
exports.PDFSidebar = PDFSidebar; SidebarView,
})); PDFSidebar,
};

25
web/pdf_thumbnail_view.js

@ -13,24 +13,8 @@
* limitations under the License. * limitations under the License.
*/ */
'use strict'; import { getOutputScale, mozL10n } from 'pdfjs-web/ui_utils';
import { RenderingStates } from 'pdfjs-web/pdf_rendering_queue';
(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;
var THUMBNAIL_WIDTH = 98; // px var THUMBNAIL_WIDTH = 98; // px
var THUMBNAIL_CANVAS_BORDER_WIDTH = 1; // px var THUMBNAIL_CANVAS_BORDER_WIDTH = 1; // px
@ -430,5 +414,6 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() {
PDFThumbnailView.tempImageCache = null; PDFThumbnailView.tempImageCache = null;
exports.PDFThumbnailView = PDFThumbnailView; export {
})); PDFThumbnailView,
};

28
web/pdf_thumbnail_viewer.js

@ -13,25 +13,10 @@
* limitations under the License. * limitations under the License.
*/ */
'use strict'; import {
getVisibleElements, scrollIntoView, watchScroll
(function (root, factory) { } from 'pdfjs-web/ui_utils';
if (typeof define === 'function' && define.amd) { import { PDFThumbnailView } from 'pdfjs-web/pdf_thumbnail_view';
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;
var THUMBNAIL_SCROLL_MARGIN = -19; var THUMBNAIL_SCROLL_MARGIN = -19;
@ -247,5 +232,6 @@ var PDFThumbnailViewer = (function PDFThumbnailViewerClosure() {
return PDFThumbnailViewer; return PDFThumbnailViewer;
})(); })();
exports.PDFThumbnailViewer = PDFThumbnailViewer; export {
})); PDFThumbnailViewer,
};

63
web/pdf_viewer.js

@ -13,48 +13,20 @@
* limitations under the License. * limitations under the License.
*/ */
'use strict'; import * as pdfjsLib from 'pdfjs-web/pdfjs';
import {
(function (root, factory) { CSS_UNITS, DEFAULT_SCALE, DEFAULT_SCALE_VALUE, getVisibleElements,
if (typeof define === 'function' && define.amd) { MAX_AUTO_SCALE, RendererType, SCROLLBAR_PADDING, scrollIntoView,
define('pdfjs-web/pdf_viewer', ['exports', 'pdfjs-web/ui_utils', UNKNOWN_SCALE, VERTICAL_PADDING, watchScroll
'pdfjs-web/pdf_page_view', 'pdfjs-web/pdf_rendering_queue', } from 'pdfjs-web/ui_utils';
'pdfjs-web/text_layer_builder', 'pdfjs-web/annotation_layer_builder', import {
'pdfjs-web/pdf_link_service', 'pdfjs-web/dom_events', 'pdfjs-web/pdfjs'], PDFRenderingQueue, RenderingStates,
factory); } from 'pdfjs-web/pdf_rendering_queue';
} else if (typeof exports !== 'undefined') { import { AnnotationLayerBuilder } from 'pdfjs-web/annotation_layer_builder';
factory(exports, require('./ui_utils.js'), require('./pdf_page_view.js'), import { domEvents } from 'pdfjs-web/dom_events';
require('./pdf_rendering_queue.js'), require('./text_layer_builder.js'), import { PDFPageView } from 'pdfjs-web/pdf_page_view';
require('./annotation_layer_builder.js'), import { SimpleLinkService } from 'pdfjs-web/pdf_link_service';
require('./pdf_link_service.js'), require('./dom_events.js'), import { TextLayerBuilder } from 'pdfjs-web/text_layer_builder';
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;
var PresentationModeState = { var PresentationModeState = {
UNKNOWN: 0, UNKNOWN: 0,
@ -988,6 +960,7 @@ var PDFViewer = (function pdfViewer() {
return PDFViewer; return PDFViewer;
})(); })();
exports.PresentationModeState = PresentationModeState; export {
exports.PDFViewer = PDFViewer; PresentationModeState,
})); PDFViewer,
};

17
web/preferences.js

@ -13,18 +13,6 @@
* limitations under the License. * 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; var defaultPreferences = null;
function getDefaultPreferences() { function getDefaultPreferences() {
if (!defaultPreferences) { if (!defaultPreferences) {
@ -221,5 +209,6 @@ if (typeof PDFJSDev === 'undefined' ||
}; };
} }
exports.Preferences = Preferences; export {
})); Preferences,
};

21
web/secondary_toolbar.js

@ -13,21 +13,7 @@
* limitations under the License. * limitations under the License.
*/ */
'use strict'; import { mozL10n, SCROLLBAR_PADDING } from 'pdfjs-web/ui_utils';
(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;
/** /**
* @typedef {Object} SecondaryToolbarOptions * @typedef {Object} SecondaryToolbarOptions
@ -241,5 +227,6 @@ var SecondaryToolbar = (function SecondaryToolbarClosure() {
return SecondaryToolbar; return SecondaryToolbar;
})(); })();
exports.SecondaryToolbar = SecondaryToolbar; export {
})); SecondaryToolbar,
};

22
web/text_layer_builder.js

@ -13,19 +13,8 @@
* limitations under the License. * limitations under the License.
*/ */
'use strict'; import * as pdfjsLib from 'pdfjs-web/pdfjs';
import { domEvents } from 'pdfjs-web/dom_events';
(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) {
var EXPAND_DIVS_TIMEOUT = 300; // ms var EXPAND_DIVS_TIMEOUT = 300; // ms
@ -419,6 +408,7 @@ DefaultTextLayerFactory.prototype = {
} }
}; };
exports.TextLayerBuilder = TextLayerBuilder; export {
exports.DefaultTextLayerFactory = DefaultTextLayerFactory; TextLayerBuilder,
})); DefaultTextLayerFactory,
};

31
web/toolbar.js

@ -13,28 +13,10 @@
* limitations under the License. * limitations under the License.
*/ */
'use strict'; import {
animationStarted, DEFAULT_SCALE, DEFAULT_SCALE_VALUE, localized, MAX_SCALE,
(function (root, factory) { MIN_SCALE, mozL10n, noContextMenuHandler
if (typeof define === 'function' && define.amd) { } from 'pdfjs-web/ui_utils';
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;
var PAGE_NUMBER_LOADING_INDICATOR = 'visiblePageIsLoading'; var PAGE_NUMBER_LOADING_INDICATOR = 'visiblePageIsLoading';
var SCALE_SELECT_CONTAINER_PADDING = 8; var SCALE_SELECT_CONTAINER_PADDING = 8;
@ -286,5 +268,6 @@ var Toolbar = (function ToolbarClosure() {
return Toolbar; return Toolbar;
})(); })();
exports.Toolbar = Toolbar; export {
})); Toolbar,
};

69
web/ui_utils.js

@ -13,17 +13,7 @@
* limitations under the License. * limitations under the License.
*/ */
'use strict'; import * as pdfjsLib from 'pdfjs-web/pdfjs';
(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) {
var CSS_UNITS = 96.0 / 72.0; var CSS_UNITS = 96.0 / 72.0;
var DEFAULT_SCALE_VALUE = 'auto'; var DEFAULT_SCALE_VALUE = 'auto';
@ -94,7 +84,7 @@ if (typeof PDFJSDev === 'undefined' ||
* @var {string} * @var {string}
*/ */
PDFJS.locale = (PDFJS.locale === undefined ? navigator.language : PDFJS.locale = (PDFJS.locale === undefined ? navigator.language :
PDFJS.locale); PDFJS.locale);
} }
/** /**
@ -571,30 +561,31 @@ var ProgressBar = (function ProgressBarClosure() {
return ProgressBar; return ProgressBar;
})(); })();
exports.CSS_UNITS = CSS_UNITS; export {
exports.DEFAULT_SCALE_VALUE = DEFAULT_SCALE_VALUE; CSS_UNITS,
exports.DEFAULT_SCALE = DEFAULT_SCALE; DEFAULT_SCALE_VALUE,
exports.MIN_SCALE = MIN_SCALE; DEFAULT_SCALE,
exports.MAX_SCALE = MAX_SCALE; MIN_SCALE,
exports.UNKNOWN_SCALE = UNKNOWN_SCALE; MAX_SCALE,
exports.MAX_AUTO_SCALE = MAX_AUTO_SCALE; UNKNOWN_SCALE,
exports.SCROLLBAR_PADDING = SCROLLBAR_PADDING; MAX_AUTO_SCALE,
exports.VERTICAL_PADDING = VERTICAL_PADDING; SCROLLBAR_PADDING,
exports.RendererType = RendererType; VERTICAL_PADDING,
exports.mozL10n = mozL10n; RendererType,
exports.EventBus = EventBus; mozL10n,
exports.ProgressBar = ProgressBar; EventBus,
exports.getPDFFileNameFromURL = getPDFFileNameFromURL; ProgressBar,
exports.noContextMenuHandler = noContextMenuHandler; getPDFFileNameFromURL,
exports.parseQueryString = parseQueryString; noContextMenuHandler,
exports.getVisibleElements = getVisibleElements; parseQueryString,
exports.roundToDivide = roundToDivide; getVisibleElements,
exports.approximateFraction = approximateFraction; roundToDivide,
exports.getOutputScale = getOutputScale; approximateFraction,
exports.scrollIntoView = scrollIntoView; getOutputScale,
exports.watchScroll = watchScroll; scrollIntoView,
exports.binarySearchFirstItem = binarySearchFirstItem; watchScroll,
exports.normalizeWheelEventDelta = normalizeWheelEventDelta; binarySearchFirstItem,
exports.animationStarted = animationStarted; normalizeWheelEventDelta,
exports.localized = localized; animationStarted,
})); localized,
};

17
web/view_history.js

@ -13,18 +13,6 @@
* limitations under the License. * 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; var DEFAULT_VIEW_HISTORY_CACHE_SIZE = 20;
/** /**
@ -142,5 +130,6 @@ var ViewHistory = (function ViewHistoryClosure() {
return ViewHistory; return ViewHistory;
})(); })();
exports.ViewHistory = ViewHistory; export {
})); ViewHistory,
};

Loading…
Cancel
Save