2012-09-01 07:48:21 +09:00
|
|
|
/* Copyright 2012 Mozilla Foundation
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
2017-02-09 07:32:15 +09:00
|
|
|
/* globals PDFBug, Stats */
|
2011-05-26 23:02:52 +09:00
|
|
|
|
2017-03-28 08:07:27 +09:00
|
|
|
import {
|
2018-01-14 12:04:29 +09:00
|
|
|
animationStarted, DEFAULT_SCALE_VALUE, getPDFFileNameFromURL, isFileSchema,
|
|
|
|
isValidRotation, MAX_SCALE, MIN_SCALE, noContextMenuHandler,
|
|
|
|
normalizeWheelEventDelta, parseQueryString, PresentationModeState,
|
2018-02-13 23:01:55 +09:00
|
|
|
ProgressBar, RendererType, TextLayerMode
|
2017-04-15 00:32:36 +09:00
|
|
|
} from './ui_utils';
|
2017-03-28 17:15:02 +09:00
|
|
|
import {
|
2018-02-14 22:49:24 +09:00
|
|
|
build, createBlob, getDocument, getFilenameFromUrl, GlobalWorkerOptions,
|
2018-02-18 07:13:49 +09:00
|
|
|
InvalidPDFException, LinkTarget, MissingPDFException, OPS, PDFWorker, shadow,
|
|
|
|
UnexpectedResponseException, UNSUPPORTED_FEATURES, version
|
2017-05-31 10:38:22 +09:00
|
|
|
} from 'pdfjs-lib';
|
2016-09-07 20:30:26 +09:00
|
|
|
import { CursorTool, PDFCursorTools } from './pdf_cursor_tools';
|
|
|
|
import { PDFRenderingQueue, RenderingStates } from './pdf_rendering_queue';
|
2017-04-15 00:32:36 +09:00
|
|
|
import { PDFSidebar, SidebarView } from './pdf_sidebar';
|
2018-02-17 23:08:28 +09:00
|
|
|
import { AppOptions } from './app_options';
|
2017-04-15 00:32:36 +09:00
|
|
|
import { getGlobalEventBus } from './dom_events';
|
|
|
|
import { OverlayManager } from './overlay_manager';
|
|
|
|
import { PasswordPrompt } from './password_prompt';
|
|
|
|
import { PDFAttachmentViewer } from './pdf_attachment_viewer';
|
|
|
|
import { PDFDocumentProperties } from './pdf_document_properties';
|
|
|
|
import { PDFFindBar } from './pdf_find_bar';
|
|
|
|
import { PDFFindController } from './pdf_find_controller';
|
|
|
|
import { PDFHistory } from './pdf_history';
|
|
|
|
import { PDFLinkService } from './pdf_link_service';
|
|
|
|
import { PDFOutlineViewer } from './pdf_outline_viewer';
|
|
|
|
import { PDFPresentationMode } from './pdf_presentation_mode';
|
Implement sidebar resizing for modern browsers, by utilizing CSS variables (issue 2072)
By making use of modern CSS features, in this case [CSS variables](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables), implementing sidebar resizing is actually quite simple. Not only will the amount of added code be fairly small, but it should also be easy to maintain since there's no need for complicated JavaScript hacks in order to update the CSS. Another benefit is that the JavaScript code doesn't need to make detailed assumptions about the exact structure of the HTML/CSS code.
Obviously this will not work in older browsers, such as IE, that lack support for CSS variables. In those cases sidebar resizing is simply disabled (via feature detection), and the resizing DOM element hidden, and the behaviour is thus *identical* to the current (fixed-width) sidebar.
However, considering the simplicity of the implementation, I really don't see why limiting this feature to "modern" browsers is a problem.
Finally, note that a few edge-cases meant that the patch is a bit larger than what the basic functionality would dictate. Among those is first of all proper RTL support, and secondly (automatic) resizing of the sidebar when the width of the *entire* viewer changes. Another, pre-existing, issue fixed here is the incomplete interface of `NullL10n`.
*Please note:* This patch has been successfully tested in both LTR and RTL viewer locales, in recent versions of Firefox and Chrome.
Fixes 2072.
2017-10-10 23:16:05 +09:00
|
|
|
import { PDFSidebarResizer } from './pdf_sidebar_resizer';
|
2017-04-15 00:32:36 +09:00
|
|
|
import { PDFThumbnailViewer } from './pdf_thumbnail_viewer';
|
2017-08-01 21:11:28 +09:00
|
|
|
import { PDFViewer } from './pdf_viewer';
|
2017-04-15 00:32:36 +09:00
|
|
|
import { SecondaryToolbar } from './secondary_toolbar';
|
|
|
|
import { Toolbar } from './toolbar';
|
|
|
|
import { ViewHistory } from './view_history';
|
2016-04-09 02:34:27 +09:00
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
const DEFAULT_SCALE_DELTA = 1.1;
|
|
|
|
const DISABLE_AUTO_FETCH_LOADING_BAR_TIMEOUT = 5000;
|
2012-06-19 01:48:47 +09:00
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
const DefaultExternalServices = {
|
2017-04-28 19:02:42 +09:00
|
|
|
updateFindControlState(data) {},
|
|
|
|
initPassiveLoading(callbacks) {},
|
|
|
|
fallback(data, callback) {},
|
|
|
|
reportTelemetry(data) {},
|
2018-02-18 06:51:03 +09:00
|
|
|
createDownloadManager(options) {
|
2017-03-28 06:37:14 +09:00
|
|
|
throw new Error('Not implemented: createDownloadManager');
|
2016-04-14 06:21:05 +09:00
|
|
|
},
|
2017-04-17 20:21:11 +09:00
|
|
|
createPreferences() {
|
|
|
|
throw new Error('Not implemented: createPreferences');
|
|
|
|
},
|
2018-02-17 23:08:28 +09:00
|
|
|
createL10n(options) {
|
2017-06-01 01:45:01 +09:00
|
|
|
throw new Error('Not implemented: createL10n');
|
|
|
|
},
|
2016-04-14 06:21:05 +09:00
|
|
|
supportsIntegratedFind: false,
|
|
|
|
supportsDocumentFonts: true,
|
|
|
|
supportsDocumentColors: true,
|
|
|
|
supportedMouseWheelZoomModifierKeys: {
|
|
|
|
ctrlKey: true,
|
|
|
|
metaKey: true,
|
2017-06-01 01:45:01 +09:00
|
|
|
},
|
2016-04-14 06:21:05 +09:00
|
|
|
};
|
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
let PDFViewerApplication = {
|
2011-10-02 03:54:37 +09:00
|
|
|
initialBookmark: document.location.hash.substring(1),
|
2012-05-01 05:05:32 +09:00
|
|
|
initialized: false,
|
2012-05-15 09:19:09 +09:00
|
|
|
fellback: false,
|
2016-04-22 01:39:11 +09:00
|
|
|
appConfig: null,
|
2012-06-02 06:17:09 +09:00
|
|
|
pdfDocument: null,
|
2015-10-23 22:49:02 +09:00
|
|
|
pdfLoadingTask: null,
|
2016-10-07 06:46:30 +09:00
|
|
|
printService: null,
|
2014-09-21 02:21:49 +09:00
|
|
|
/** @type {PDFViewer} */
|
2014-09-13 11:27:45 +09:00
|
|
|
pdfViewer: null,
|
2014-09-21 02:21:49 +09:00
|
|
|
/** @type {PDFThumbnailViewer} */
|
2014-09-13 04:48:44 +09:00
|
|
|
pdfThumbnailViewer: null,
|
2014-09-21 02:21:49 +09:00
|
|
|
/** @type {PDFRenderingQueue} */
|
2014-09-16 01:18:28 +09:00
|
|
|
pdfRenderingQueue: null,
|
2015-02-04 02:09:11 +09:00
|
|
|
/** @type {PDFPresentationMode} */
|
|
|
|
pdfPresentationMode: null,
|
2015-04-25 03:47:38 +09:00
|
|
|
/** @type {PDFDocumentProperties} */
|
|
|
|
pdfDocumentProperties: null,
|
2015-04-28 00:25:32 +09:00
|
|
|
/** @type {PDFLinkService} */
|
|
|
|
pdfLinkService: null,
|
2015-04-27 23:04:11 +09:00
|
|
|
/** @type {PDFHistory} */
|
|
|
|
pdfHistory: null,
|
2016-02-22 01:54:23 +09:00
|
|
|
/** @type {PDFSidebar} */
|
|
|
|
pdfSidebar: null,
|
Implement sidebar resizing for modern browsers, by utilizing CSS variables (issue 2072)
By making use of modern CSS features, in this case [CSS variables](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables), implementing sidebar resizing is actually quite simple. Not only will the amount of added code be fairly small, but it should also be easy to maintain since there's no need for complicated JavaScript hacks in order to update the CSS. Another benefit is that the JavaScript code doesn't need to make detailed assumptions about the exact structure of the HTML/CSS code.
Obviously this will not work in older browsers, such as IE, that lack support for CSS variables. In those cases sidebar resizing is simply disabled (via feature detection), and the resizing DOM element hidden, and the behaviour is thus *identical* to the current (fixed-width) sidebar.
However, considering the simplicity of the implementation, I really don't see why limiting this feature to "modern" browsers is a problem.
Finally, note that a few edge-cases meant that the patch is a bit larger than what the basic functionality would dictate. Among those is first of all proper RTL support, and secondly (automatic) resizing of the sidebar when the width of the *entire* viewer changes. Another, pre-existing, issue fixed here is the incomplete interface of `NullL10n`.
*Please note:* This patch has been successfully tested in both LTR and RTL viewer locales, in recent versions of Firefox and Chrome.
Fixes 2072.
2017-10-10 23:16:05 +09:00
|
|
|
/** @type {PDFSidebarResizer} */
|
|
|
|
pdfSidebarResizer: null,
|
2016-02-21 21:36:24 +09:00
|
|
|
/** @type {PDFOutlineViewer} */
|
|
|
|
pdfOutlineViewer: null,
|
|
|
|
/** @type {PDFAttachmentViewer} */
|
|
|
|
pdfAttachmentViewer: null,
|
2016-09-07 20:30:26 +09:00
|
|
|
/** @type {PDFCursorTools} */
|
|
|
|
pdfCursorTools: null,
|
2016-03-12 21:07:43 +09:00
|
|
|
/** @type {ViewHistory} */
|
|
|
|
store: null,
|
2016-04-14 06:21:05 +09:00
|
|
|
/** @type {DownloadManager} */
|
|
|
|
downloadManager: null,
|
2017-05-26 21:52:23 +09:00
|
|
|
/** @type {OverlayManager} */
|
|
|
|
overlayManager: null,
|
2017-04-17 20:21:11 +09:00
|
|
|
/** @type {Preferences} */
|
|
|
|
preferences: null,
|
2016-11-19 03:50:29 +09:00
|
|
|
/** @type {Toolbar} */
|
|
|
|
toolbar: null,
|
|
|
|
/** @type {SecondaryToolbar} */
|
|
|
|
secondaryToolbar: null,
|
2016-04-26 07:57:15 +09:00
|
|
|
/** @type {EventBus} */
|
|
|
|
eventBus: null,
|
2017-05-04 10:05:53 +09:00
|
|
|
/** @type {IL10n} */
|
|
|
|
l10n: null,
|
2014-09-22 20:41:17 +09:00
|
|
|
isInitialViewSet: false,
|
2017-06-17 20:14:36 +09:00
|
|
|
downloadComplete: false,
|
2013-07-20 23:33:40 +09:00
|
|
|
isViewerEmbedded: (window.parent !== window),
|
2014-07-25 06:37:31 +09:00
|
|
|
url: '',
|
2016-10-01 19:05:07 +09:00
|
|
|
baseUrl: '',
|
2017-03-28 06:37:14 +09:00
|
|
|
externalServices: DefaultExternalServices,
|
2017-06-14 04:11:29 +09:00
|
|
|
_boundEvents: {},
|
2018-01-17 00:24:36 +09:00
|
|
|
contentDispositionFilename: null,
|
2012-06-19 01:48:47 +09:00
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
// Called once when the document is loaded.
|
|
|
|
initialize(appConfig) {
|
2017-04-17 20:21:11 +09:00
|
|
|
this.preferences = this.externalServices.createPreferences();
|
2016-12-08 21:30:21 +09:00
|
|
|
this.appConfig = appConfig;
|
2016-12-11 07:10:08 +09:00
|
|
|
|
2017-04-17 20:21:11 +09:00
|
|
|
return this._readPreferences().then(() => {
|
2017-11-13 18:17:25 +09:00
|
|
|
return this._parseHashParameters();
|
|
|
|
}).then(() => {
|
2017-05-04 10:05:53 +09:00
|
|
|
return this._initializeL10n();
|
|
|
|
}).then(() => {
|
2017-04-17 20:21:11 +09:00
|
|
|
return this._initializeViewerComponents();
|
|
|
|
}).then(() => {
|
2016-12-09 00:28:40 +09:00
|
|
|
// Bind the various event handlers *after* the viewer has been
|
|
|
|
// initialized, to prevent errors if an event arrives too soon.
|
2017-04-17 20:21:11 +09:00
|
|
|
this.bindEvents();
|
|
|
|
this.bindWindowEvents();
|
2016-12-09 00:28:40 +09:00
|
|
|
|
2017-05-04 10:05:53 +09:00
|
|
|
// We can start UI localization now.
|
2017-06-29 19:14:26 +09:00
|
|
|
let appContainer = appConfig.appContainer || document.documentElement;
|
2017-05-04 10:05:53 +09:00
|
|
|
this.l10n.translate(appContainer).then(() => {
|
|
|
|
// Dispatch the 'localized' event on the `eventBus` once the viewer
|
|
|
|
// has been fully initialized and translated.
|
|
|
|
this.eventBus.dispatch('localized');
|
|
|
|
});
|
2016-12-08 22:44:12 +09:00
|
|
|
|
2018-02-13 22:03:52 +09:00
|
|
|
if (this.isViewerEmbedded &&
|
2018-02-17 23:08:28 +09:00
|
|
|
AppOptions.get('externalLinkTarget') === LinkTarget.NONE) {
|
2016-12-11 07:10:08 +09:00
|
|
|
// Prevent external links from "replacing" the viewer,
|
|
|
|
// when it's embedded in e.g. an iframe or an object.
|
2018-02-17 23:08:28 +09:00
|
|
|
AppOptions.set('externalLinkTarget', LinkTarget.TOP);
|
2016-12-11 07:10:08 +09:00
|
|
|
}
|
|
|
|
|
2017-04-17 20:21:11 +09:00
|
|
|
this.initialized = true;
|
2016-12-11 07:10:08 +09:00
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @private
|
|
|
|
*/
|
2017-04-28 19:02:42 +09:00
|
|
|
_readPreferences() {
|
2018-02-17 23:08:28 +09:00
|
|
|
let { preferences, } = this;
|
2016-12-11 07:10:08 +09:00
|
|
|
|
|
|
|
return Promise.all([
|
2017-04-17 20:21:11 +09:00
|
|
|
preferences.get('enableWebGL').then(function resolved(value) {
|
2018-02-17 23:08:28 +09:00
|
|
|
AppOptions.set('enableWebGL', value);
|
2016-12-11 07:10:08 +09:00
|
|
|
}),
|
2017-04-17 20:21:11 +09:00
|
|
|
preferences.get('sidebarViewOnLoad').then(function resolved(value) {
|
2018-02-17 23:08:28 +09:00
|
|
|
AppOptions.set('sidebarViewOnLoad', value);
|
2016-12-11 07:10:08 +09:00
|
|
|
}),
|
2018-03-20 07:24:56 +09:00
|
|
|
preferences.get('cursorToolOnLoad').then(function resolved(value) {
|
|
|
|
AppOptions.set('cursorToolOnLoad', value);
|
|
|
|
}),
|
2017-04-17 20:21:11 +09:00
|
|
|
preferences.get('pdfBugEnabled').then(function resolved(value) {
|
2018-02-17 23:08:28 +09:00
|
|
|
AppOptions.set('pdfBugEnabled', value);
|
2016-12-11 07:10:08 +09:00
|
|
|
}),
|
2017-04-17 20:21:11 +09:00
|
|
|
preferences.get('showPreviousViewOnLoad').then(function resolved(value) {
|
2018-02-17 23:08:28 +09:00
|
|
|
AppOptions.set('showPreviousViewOnLoad', value);
|
2016-12-11 07:10:08 +09:00
|
|
|
}),
|
2017-04-17 20:21:11 +09:00
|
|
|
preferences.get('defaultZoomValue').then(function resolved(value) {
|
2018-02-17 23:08:28 +09:00
|
|
|
AppOptions.set('defaultZoomValue', value);
|
2016-12-11 07:10:08 +09:00
|
|
|
}),
|
2018-02-13 23:01:55 +09:00
|
|
|
preferences.get('textLayerMode').then(function resolved(value) {
|
2018-02-17 23:08:28 +09:00
|
|
|
if (AppOptions.get('textLayerMode') === TextLayerMode.DISABLE) {
|
2016-12-11 07:10:08 +09:00
|
|
|
return;
|
|
|
|
}
|
2018-02-17 23:08:28 +09:00
|
|
|
AppOptions.set('textLayerMode', value);
|
2016-12-11 07:10:08 +09:00
|
|
|
}),
|
2017-04-17 20:21:11 +09:00
|
|
|
preferences.get('disableRange').then(function resolved(value) {
|
2018-02-18 06:22:10 +09:00
|
|
|
if (AppOptions.get('disableRange') === true) {
|
2016-12-11 07:10:08 +09:00
|
|
|
return;
|
|
|
|
}
|
2018-02-18 06:22:10 +09:00
|
|
|
AppOptions.set('disableRange', value);
|
2016-12-11 07:10:08 +09:00
|
|
|
}),
|
2017-04-17 20:21:11 +09:00
|
|
|
preferences.get('disableStream').then(function resolved(value) {
|
2018-02-18 06:28:08 +09:00
|
|
|
if (AppOptions.get('disableStream') === true) {
|
2016-12-11 07:10:08 +09:00
|
|
|
return;
|
|
|
|
}
|
2018-02-18 06:28:08 +09:00
|
|
|
AppOptions.set('disableStream', value);
|
2016-12-11 07:10:08 +09:00
|
|
|
}),
|
2017-04-17 20:21:11 +09:00
|
|
|
preferences.get('disableAutoFetch').then(function resolved(value) {
|
2018-02-18 06:08:45 +09:00
|
|
|
AppOptions.set('disableAutoFetch', value);
|
2016-12-11 07:10:08 +09:00
|
|
|
}),
|
2017-04-17 20:21:11 +09:00
|
|
|
preferences.get('disableFontFace').then(function resolved(value) {
|
2018-02-18 05:57:20 +09:00
|
|
|
if (AppOptions.get('disableFontFace') === true) {
|
2016-12-11 07:10:08 +09:00
|
|
|
return;
|
|
|
|
}
|
2018-02-18 05:57:20 +09:00
|
|
|
AppOptions.set('disableFontFace', value);
|
2016-12-11 07:10:08 +09:00
|
|
|
}),
|
2017-04-17 20:21:11 +09:00
|
|
|
preferences.get('useOnlyCssZoom').then(function resolved(value) {
|
2018-02-17 23:08:28 +09:00
|
|
|
AppOptions.set('useOnlyCssZoom', value);
|
2016-12-11 07:10:08 +09:00
|
|
|
}),
|
2017-04-17 20:21:11 +09:00
|
|
|
preferences.get('externalLinkTarget').then(function resolved(value) {
|
2018-02-17 23:08:28 +09:00
|
|
|
if (AppOptions.get('externalLinkTarget') !== LinkTarget.NONE) {
|
2016-12-11 07:10:08 +09:00
|
|
|
return;
|
|
|
|
}
|
2018-02-17 23:08:28 +09:00
|
|
|
AppOptions.set('externalLinkTarget', value);
|
2016-12-11 07:10:08 +09:00
|
|
|
}),
|
2017-04-17 20:21:11 +09:00
|
|
|
preferences.get('renderer').then(function resolved(value) {
|
2018-02-17 23:08:28 +09:00
|
|
|
AppOptions.set('renderer', value);
|
2016-12-11 07:10:08 +09:00
|
|
|
}),
|
2017-04-17 20:21:11 +09:00
|
|
|
preferences.get('renderInteractiveForms').then(function resolved(value) {
|
2018-02-17 23:08:28 +09:00
|
|
|
AppOptions.set('renderInteractiveForms', value);
|
2016-12-11 07:10:08 +09:00
|
|
|
}),
|
2017-07-19 23:26:17 +09:00
|
|
|
preferences.get('disablePageMode').then(function resolved(value) {
|
2018-02-17 23:08:28 +09:00
|
|
|
AppOptions.set('disablePageMode', value);
|
2017-07-19 23:26:17 +09:00
|
|
|
}),
|
2017-04-17 20:21:11 +09:00
|
|
|
preferences.get('disablePageLabels').then(function resolved(value) {
|
2018-02-17 23:08:28 +09:00
|
|
|
AppOptions.set('disablePageLabels', value);
|
2016-12-11 07:10:08 +09:00
|
|
|
}),
|
2017-04-17 20:21:11 +09:00
|
|
|
preferences.get('enablePrintAutoRotate').then(function resolved(value) {
|
2018-02-17 23:08:28 +09:00
|
|
|
AppOptions.set('enablePrintAutoRotate', value);
|
2017-02-08 08:15:09 +09:00
|
|
|
}),
|
2018-05-15 12:10:33 +09:00
|
|
|
preferences.get('scrollModeOnLoad').then(function resolved(value) {
|
|
|
|
AppOptions.set('scrollModeOnLoad', value);
|
|
|
|
}),
|
|
|
|
preferences.get('spreadModeOnLoad').then(function resolved(value) {
|
|
|
|
AppOptions.set('spreadModeOnLoad', value);
|
|
|
|
}),
|
2017-06-29 19:14:26 +09:00
|
|
|
]).catch(function(reason) { });
|
2016-12-11 07:10:08 +09:00
|
|
|
},
|
|
|
|
|
2017-11-13 18:17:25 +09:00
|
|
|
/**
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
_parseHashParameters() {
|
2018-02-17 23:08:28 +09:00
|
|
|
let { appConfig, } = this;
|
2017-11-13 18:17:25 +09:00
|
|
|
let waitOn = [];
|
|
|
|
|
2017-05-04 10:05:53 +09:00
|
|
|
if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION') ||
|
2018-02-17 23:08:28 +09:00
|
|
|
AppOptions.get('pdfBugEnabled')) {
|
2017-11-13 18:17:25 +09:00
|
|
|
// Special debugging flags in the hash section of the URL.
|
2017-05-04 10:05:53 +09:00
|
|
|
let hash = document.location.hash.substring(1);
|
|
|
|
let hashParams = parseQueryString(hash);
|
2017-11-13 18:17:25 +09:00
|
|
|
|
2018-01-20 02:16:17 +09:00
|
|
|
if ('disableworker' in hashParams &&
|
|
|
|
hashParams['disableworker'] === 'true') {
|
|
|
|
waitOn.push(loadFakeWorker());
|
2017-11-13 18:17:25 +09:00
|
|
|
}
|
|
|
|
if ('disablerange' in hashParams) {
|
2018-02-18 06:22:10 +09:00
|
|
|
AppOptions.set('disableRange', hashParams['disablerange'] === 'true');
|
2017-11-13 18:17:25 +09:00
|
|
|
}
|
|
|
|
if ('disablestream' in hashParams) {
|
2018-02-18 06:28:08 +09:00
|
|
|
AppOptions.set('disableStream', hashParams['disablestream'] === 'true');
|
2017-11-13 18:17:25 +09:00
|
|
|
}
|
|
|
|
if ('disableautofetch' in hashParams) {
|
2018-02-18 06:08:45 +09:00
|
|
|
AppOptions.set('disableAutoFetch',
|
|
|
|
hashParams['disableautofetch'] === 'true');
|
2017-11-13 18:17:25 +09:00
|
|
|
}
|
|
|
|
if ('disablefontface' in hashParams) {
|
2018-02-18 05:57:20 +09:00
|
|
|
AppOptions.set('disableFontFace',
|
|
|
|
hashParams['disablefontface'] === 'true');
|
2017-11-13 18:17:25 +09:00
|
|
|
}
|
|
|
|
if ('disablehistory' in hashParams) {
|
2018-02-17 23:08:28 +09:00
|
|
|
AppOptions.set('disableHistory',
|
|
|
|
hashParams['disablehistory'] === 'true');
|
2017-11-13 18:17:25 +09:00
|
|
|
}
|
|
|
|
if ('webgl' in hashParams) {
|
2018-02-17 23:08:28 +09:00
|
|
|
AppOptions.set('enableWebGL', hashParams['webgl'] === 'true');
|
2017-11-13 18:17:25 +09:00
|
|
|
}
|
|
|
|
if ('useonlycsszoom' in hashParams) {
|
2018-02-17 23:08:28 +09:00
|
|
|
AppOptions.set('useOnlyCssZoom',
|
|
|
|
hashParams['useonlycsszoom'] === 'true');
|
2017-11-13 18:17:25 +09:00
|
|
|
}
|
|
|
|
if ('verbosity' in hashParams) {
|
2018-02-17 23:33:57 +09:00
|
|
|
AppOptions.set('verbosity', hashParams['verbosity'] | 0);
|
2017-11-13 18:17:25 +09:00
|
|
|
}
|
|
|
|
if ((typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION')) &&
|
|
|
|
hashParams['disablebcmaps'] === 'true') {
|
2018-02-18 00:57:24 +09:00
|
|
|
AppOptions.set('cMapUrl', '../external/cmaps/');
|
|
|
|
AppOptions.set('cMapPacked', false);
|
2017-11-13 18:17:25 +09:00
|
|
|
}
|
|
|
|
if ('textlayer' in hashParams) {
|
|
|
|
switch (hashParams['textlayer']) {
|
|
|
|
case 'off':
|
2018-02-17 23:08:28 +09:00
|
|
|
AppOptions.set('textLayerMode', TextLayerMode.DISABLE);
|
2017-11-13 18:17:25 +09:00
|
|
|
break;
|
|
|
|
case 'visible':
|
|
|
|
case 'shadow':
|
|
|
|
case 'hover':
|
|
|
|
let viewer = appConfig.viewerContainer;
|
|
|
|
viewer.classList.add('textLayer-' + hashParams['textlayer']);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ('pdfbug' in hashParams) {
|
2018-02-18 07:13:49 +09:00
|
|
|
AppOptions.set('pdfBug', true);
|
2018-02-13 22:34:29 +09:00
|
|
|
let enabled = hashParams['pdfbug'].split(',');
|
2017-11-13 18:17:25 +09:00
|
|
|
waitOn.push(loadAndEnablePDFBug(enabled));
|
|
|
|
}
|
|
|
|
// Locale can be changed only when special debugging flags is present in
|
|
|
|
// the hash section of the URL, or development version of viewer is used.
|
|
|
|
// It is not possible to change locale for Firefox extension builds.
|
|
|
|
if ((typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION') ||
|
|
|
|
!PDFJSDev.test('FIREFOX || MOZCENTRAL')) && 'locale' in hashParams) {
|
2018-02-17 23:08:28 +09:00
|
|
|
AppOptions.set('locale', hashParams['locale']);
|
2017-05-04 10:05:53 +09:00
|
|
|
}
|
|
|
|
}
|
2017-11-13 18:17:25 +09:00
|
|
|
|
|
|
|
return Promise.all(waitOn);
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
_initializeL10n() {
|
2018-02-13 22:22:14 +09:00
|
|
|
this.l10n = this.externalServices.createL10n({
|
2018-02-17 23:08:28 +09:00
|
|
|
locale: AppOptions.get('locale'),
|
2018-02-13 22:22:14 +09:00
|
|
|
});
|
2017-05-04 10:05:53 +09:00
|
|
|
return this.l10n.getDirection().then((dir) => {
|
|
|
|
document.getElementsByTagName('html')[0].dir = dir;
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
2016-12-11 07:10:08 +09:00
|
|
|
/**
|
|
|
|
* @private
|
|
|
|
*/
|
2017-04-28 19:02:42 +09:00
|
|
|
_initializeViewerComponents() {
|
2018-02-17 23:08:28 +09:00
|
|
|
let { appConfig, } = this;
|
2016-12-11 07:10:08 +09:00
|
|
|
|
2017-04-17 20:21:11 +09:00
|
|
|
return new Promise((resolve, reject) => {
|
2017-05-26 21:52:23 +09:00
|
|
|
this.overlayManager = new OverlayManager();
|
|
|
|
|
2017-05-09 20:17:39 +09:00
|
|
|
let eventBus = appConfig.eventBus || getGlobalEventBus();
|
2017-04-28 19:02:42 +09:00
|
|
|
this.eventBus = eventBus;
|
2016-09-04 03:27:01 +09:00
|
|
|
|
2017-05-09 20:17:39 +09:00
|
|
|
let pdfRenderingQueue = new PDFRenderingQueue();
|
|
|
|
pdfRenderingQueue.onIdle = this.cleanup.bind(this);
|
|
|
|
this.pdfRenderingQueue = pdfRenderingQueue;
|
2016-09-04 03:27:01 +09:00
|
|
|
|
2017-05-09 20:17:39 +09:00
|
|
|
let pdfLinkService = new PDFLinkService({
|
2017-04-28 19:02:42 +09:00
|
|
|
eventBus,
|
2018-02-17 23:08:28 +09:00
|
|
|
externalLinkTarget: AppOptions.get('externalLinkTarget'),
|
|
|
|
externalLinkRel: AppOptions.get('externalLinkRel'),
|
2016-12-08 21:30:21 +09:00
|
|
|
});
|
2017-05-09 20:17:39 +09:00
|
|
|
this.pdfLinkService = pdfLinkService;
|
2012-06-19 01:48:47 +09:00
|
|
|
|
2018-02-18 06:51:03 +09:00
|
|
|
let downloadManager = this.externalServices.createDownloadManager({
|
|
|
|
disableCreateObjectURL: AppOptions.get('disableCreateObjectURL'),
|
|
|
|
});
|
2017-05-09 20:17:39 +09:00
|
|
|
this.downloadManager = downloadManager;
|
2016-09-04 03:27:01 +09:00
|
|
|
|
2017-05-09 20:17:39 +09:00
|
|
|
let container = appConfig.mainContainer;
|
|
|
|
let viewer = appConfig.viewerContainer;
|
|
|
|
this.pdfViewer = new PDFViewer({
|
2017-04-28 19:02:42 +09:00
|
|
|
container,
|
|
|
|
viewer,
|
|
|
|
eventBus,
|
2016-12-08 21:30:21 +09:00
|
|
|
renderingQueue: pdfRenderingQueue,
|
|
|
|
linkService: pdfLinkService,
|
2017-04-28 19:02:42 +09:00
|
|
|
downloadManager,
|
2018-02-17 23:08:28 +09:00
|
|
|
renderer: AppOptions.get('renderer'),
|
|
|
|
enableWebGL: AppOptions.get('enableWebGL'),
|
2017-05-04 10:05:53 +09:00
|
|
|
l10n: this.l10n,
|
2018-02-17 23:08:28 +09:00
|
|
|
textLayerMode: AppOptions.get('textLayerMode'),
|
|
|
|
imageResourcesPath: AppOptions.get('imageResourcesPath'),
|
|
|
|
renderInteractiveForms: AppOptions.get('renderInteractiveForms'),
|
|
|
|
enablePrintAutoRotate: AppOptions.get('enablePrintAutoRotate'),
|
|
|
|
useOnlyCssZoom: AppOptions.get('useOnlyCssZoom'),
|
|
|
|
maxCanvasPixels: AppOptions.get('maxCanvasPixels'),
|
2016-12-08 21:30:21 +09:00
|
|
|
});
|
2017-05-09 20:17:39 +09:00
|
|
|
pdfRenderingQueue.setViewer(this.pdfViewer);
|
|
|
|
pdfLinkService.setViewer(this.pdfViewer);
|
2016-12-08 21:30:21 +09:00
|
|
|
|
2017-05-09 20:17:39 +09:00
|
|
|
let thumbnailContainer = appConfig.sidebar.thumbnailView;
|
|
|
|
this.pdfThumbnailViewer = new PDFThumbnailViewer({
|
2016-12-08 21:30:21 +09:00
|
|
|
container: thumbnailContainer,
|
|
|
|
renderingQueue: pdfRenderingQueue,
|
|
|
|
linkService: pdfLinkService,
|
Fix inconsistent spacing and trailing commas in objects in `web/` files, so we can enable the `comma-dangle` and `object-curly-spacing` ESLint rules later on
http://eslint.org/docs/rules/comma-dangle
http://eslint.org/docs/rules/object-curly-spacing
Given that we currently have quite inconsistent object formatting, fixing this in in *one* big patch probably wouldn't be feasible (since I cannot imagine anyone wanting to review that); hence I've opted to try and do this piecewise instead.
*Please note:* This patch was created automatically, using the ESLint `--fix` command line option. In a couple of places this caused lines to become too long, and I've fixed those manually; please refer to the interdiff below for the only hand-edits in this patch.
```diff
diff --git a/web/pdf_thumbnail_view.js b/web/pdf_thumbnail_view.js
index 002dbf29..1de4e530 100644
--- a/web/pdf_thumbnail_view.js
+++ b/web/pdf_thumbnail_view.js
@@ -420,8 +420,8 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() {
setPageLabel: function PDFThumbnailView_setPageLabel(label) {
this.pageLabel = (typeof label === 'string' ? label : null);
- this.l10n.get('thumb_page_title', { page: this.pageId, }, 'Page {{page}}').
- then((msg) => {
+ this.l10n.get('thumb_page_title', { page: this.pageId, },
+ 'Page {{page}}').then((msg) => {
this.anchor.title = msg;
});
diff --git a/web/secondary_toolbar.js b/web/secondary_toolbar.js
index 160e0410..6495fc5e 100644
--- a/web/secondary_toolbar.js
+++ b/web/secondary_toolbar.js
@@ -65,7 +65,8 @@ class SecondaryToolbar {
{ element: options.printButton, eventName: 'print', close: true, },
{ element: options.downloadButton, eventName: 'download', close: true, },
{ element: options.viewBookmarkButton, eventName: null, close: true, },
- { element: options.firstPageButton, eventName: 'firstpage', close: true, },
+ { element: options.firstPageButton, eventName: 'firstpage',
+ close: true, },
{ element: options.lastPageButton, eventName: 'lastpage', close: true, },
{ element: options.pageRotateCwButton, eventName: 'rotatecw',
close: false, },
@@ -76,7 +77,7 @@ class SecondaryToolbar {
{ element: options.cursorHandToolButton, eventName: 'switchcursortool',
eventDetails: { tool: CursorTool.HAND, }, close: true, },
{ element: options.documentPropertiesButton,
- eventName: 'documentproperties', close: true, }
+ eventName: 'documentproperties', close: true, },
];
this.items = {
firstPage: options.firstPageButton,
```
2017-06-01 19:46:12 +09:00
|
|
|
l10n: this.l10n,
|
2016-12-08 21:30:21 +09:00
|
|
|
});
|
2017-05-09 20:17:39 +09:00
|
|
|
pdfRenderingQueue.setThumbnailViewer(this.pdfThumbnailViewer);
|
2016-09-04 03:27:01 +09:00
|
|
|
|
2017-05-09 20:17:39 +09:00
|
|
|
this.pdfHistory = new PDFHistory({
|
2016-12-08 21:30:21 +09:00
|
|
|
linkService: pdfLinkService,
|
2017-04-28 19:02:42 +09:00
|
|
|
eventBus,
|
2016-12-08 21:30:21 +09:00
|
|
|
});
|
2017-05-09 20:17:39 +09:00
|
|
|
pdfLinkService.setHistory(this.pdfHistory);
|
2016-09-04 03:27:01 +09:00
|
|
|
|
2017-05-09 20:17:39 +09:00
|
|
|
this.findController = new PDFFindController({
|
|
|
|
pdfViewer: this.pdfViewer,
|
2016-12-08 21:30:21 +09:00
|
|
|
});
|
2017-05-09 20:17:39 +09:00
|
|
|
this.findController.onUpdateResultsCount = (matchCount) => {
|
|
|
|
if (this.supportsIntegratedFind) {
|
2016-12-08 21:30:21 +09:00
|
|
|
return;
|
|
|
|
}
|
2017-05-09 20:17:39 +09:00
|
|
|
this.findBar.updateResultsCount(matchCount);
|
2016-12-08 21:30:21 +09:00
|
|
|
};
|
2017-05-09 20:17:39 +09:00
|
|
|
this.findController.onUpdateState = (state, previous, matchCount) => {
|
|
|
|
if (this.supportsIntegratedFind) {
|
|
|
|
this.externalServices.updateFindControlState({
|
|
|
|
result: state,
|
|
|
|
findPrevious: previous,
|
|
|
|
});
|
2016-12-08 21:30:21 +09:00
|
|
|
} else {
|
2017-05-09 20:17:39 +09:00
|
|
|
this.findBar.updateUIState(state, previous, matchCount);
|
2016-12-08 21:30:21 +09:00
|
|
|
}
|
|
|
|
};
|
2016-09-04 03:27:01 +09:00
|
|
|
|
2017-05-09 20:17:39 +09:00
|
|
|
this.pdfViewer.setFindController(this.findController);
|
2016-09-04 03:27:01 +09:00
|
|
|
|
2017-05-26 21:52:23 +09:00
|
|
|
// TODO: improve `PDFFindBar` constructor parameter passing
|
2017-05-09 20:17:39 +09:00
|
|
|
let findBarConfig = Object.create(appConfig.findBar);
|
|
|
|
findBarConfig.findController = this.findController;
|
2016-12-08 21:30:21 +09:00
|
|
|
findBarConfig.eventBus = eventBus;
|
2017-05-04 10:05:53 +09:00
|
|
|
this.findBar = new PDFFindBar(findBarConfig, this.l10n);
|
2016-09-04 03:27:01 +09:00
|
|
|
|
2016-09-07 20:30:26 +09:00
|
|
|
this.pdfDocumentProperties =
|
2017-05-26 21:52:23 +09:00
|
|
|
new PDFDocumentProperties(appConfig.documentProperties,
|
2018-03-18 02:50:34 +09:00
|
|
|
this.overlayManager, eventBus, this.l10n);
|
2016-09-07 20:30:26 +09:00
|
|
|
|
|
|
|
this.pdfCursorTools = new PDFCursorTools({
|
2017-04-17 20:21:11 +09:00
|
|
|
container,
|
|
|
|
eventBus,
|
2018-03-20 07:24:56 +09:00
|
|
|
cursorToolOnLoad: AppOptions.get('cursorToolOnLoad'),
|
2016-12-08 21:30:21 +09:00
|
|
|
});
|
2016-11-19 03:50:29 +09:00
|
|
|
|
2017-05-04 10:05:53 +09:00
|
|
|
this.toolbar = new Toolbar(appConfig.toolbar, container, eventBus,
|
|
|
|
this.l10n);
|
2016-12-08 21:30:21 +09:00
|
|
|
|
2017-05-09 20:17:39 +09:00
|
|
|
this.secondaryToolbar =
|
2016-12-08 21:30:21 +09:00
|
|
|
new SecondaryToolbar(appConfig.secondaryToolbar, container, eventBus);
|
|
|
|
|
2017-05-09 20:17:39 +09:00
|
|
|
if (this.supportsFullscreen) {
|
|
|
|
this.pdfPresentationMode = new PDFPresentationMode({
|
2017-04-28 19:02:42 +09:00
|
|
|
container,
|
|
|
|
viewer,
|
2017-05-09 20:17:39 +09:00
|
|
|
pdfViewer: this.pdfViewer,
|
2017-04-28 19:02:42 +09:00
|
|
|
eventBus,
|
Fix inconsistent spacing and trailing commas in objects in `web/` files, so we can enable the `comma-dangle` and `object-curly-spacing` ESLint rules later on
http://eslint.org/docs/rules/comma-dangle
http://eslint.org/docs/rules/object-curly-spacing
Given that we currently have quite inconsistent object formatting, fixing this in in *one* big patch probably wouldn't be feasible (since I cannot imagine anyone wanting to review that); hence I've opted to try and do this piecewise instead.
*Please note:* This patch was created automatically, using the ESLint `--fix` command line option. In a couple of places this caused lines to become too long, and I've fixed those manually; please refer to the interdiff below for the only hand-edits in this patch.
```diff
diff --git a/web/pdf_thumbnail_view.js b/web/pdf_thumbnail_view.js
index 002dbf29..1de4e530 100644
--- a/web/pdf_thumbnail_view.js
+++ b/web/pdf_thumbnail_view.js
@@ -420,8 +420,8 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() {
setPageLabel: function PDFThumbnailView_setPageLabel(label) {
this.pageLabel = (typeof label === 'string' ? label : null);
- this.l10n.get('thumb_page_title', { page: this.pageId, }, 'Page {{page}}').
- then((msg) => {
+ this.l10n.get('thumb_page_title', { page: this.pageId, },
+ 'Page {{page}}').then((msg) => {
this.anchor.title = msg;
});
diff --git a/web/secondary_toolbar.js b/web/secondary_toolbar.js
index 160e0410..6495fc5e 100644
--- a/web/secondary_toolbar.js
+++ b/web/secondary_toolbar.js
@@ -65,7 +65,8 @@ class SecondaryToolbar {
{ element: options.printButton, eventName: 'print', close: true, },
{ element: options.downloadButton, eventName: 'download', close: true, },
{ element: options.viewBookmarkButton, eventName: null, close: true, },
- { element: options.firstPageButton, eventName: 'firstpage', close: true, },
+ { element: options.firstPageButton, eventName: 'firstpage',
+ close: true, },
{ element: options.lastPageButton, eventName: 'lastpage', close: true, },
{ element: options.pageRotateCwButton, eventName: 'rotatecw',
close: false, },
@@ -76,7 +77,7 @@ class SecondaryToolbar {
{ element: options.cursorHandToolButton, eventName: 'switchcursortool',
eventDetails: { tool: CursorTool.HAND, }, close: true, },
{ element: options.documentPropertiesButton,
- eventName: 'documentproperties', close: true, }
+ eventName: 'documentproperties', close: true, },
];
this.items = {
firstPage: options.firstPageButton,
```
2017-06-01 19:46:12 +09:00
|
|
|
contextMenuItems: appConfig.fullscreen,
|
2016-12-08 21:30:21 +09:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-05-26 21:52:23 +09:00
|
|
|
this.passwordPrompt = new PasswordPrompt(appConfig.passwordOverlay,
|
2017-05-04 10:05:53 +09:00
|
|
|
this.overlayManager, this.l10n);
|
2016-12-08 21:30:21 +09:00
|
|
|
|
2017-05-09 20:17:39 +09:00
|
|
|
this.pdfOutlineViewer = new PDFOutlineViewer({
|
2016-12-08 21:30:21 +09:00
|
|
|
container: appConfig.sidebar.outlineView,
|
2017-04-28 19:02:42 +09:00
|
|
|
eventBus,
|
2016-12-08 21:30:21 +09:00
|
|
|
linkService: pdfLinkService,
|
2016-09-04 03:27:01 +09:00
|
|
|
});
|
|
|
|
|
2017-05-09 20:17:39 +09:00
|
|
|
this.pdfAttachmentViewer = new PDFAttachmentViewer({
|
2016-12-08 21:30:21 +09:00
|
|
|
container: appConfig.sidebar.attachmentsView,
|
2017-04-28 19:02:42 +09:00
|
|
|
eventBus,
|
|
|
|
downloadManager,
|
2016-12-08 21:30:21 +09:00
|
|
|
});
|
2016-09-04 03:27:01 +09:00
|
|
|
|
2017-05-26 21:52:23 +09:00
|
|
|
// TODO: improve `PDFSidebar` constructor parameter passing
|
2017-05-09 20:17:39 +09:00
|
|
|
let sidebarConfig = Object.create(appConfig.sidebar);
|
|
|
|
sidebarConfig.pdfViewer = this.pdfViewer;
|
|
|
|
sidebarConfig.pdfThumbnailViewer = this.pdfThumbnailViewer;
|
|
|
|
sidebarConfig.pdfOutlineViewer = this.pdfOutlineViewer;
|
2016-12-08 21:30:21 +09:00
|
|
|
sidebarConfig.eventBus = eventBus;
|
2017-05-04 10:05:53 +09:00
|
|
|
this.pdfSidebar = new PDFSidebar(sidebarConfig, this.l10n);
|
2017-05-09 20:17:39 +09:00
|
|
|
this.pdfSidebar.onToggled = this.forceRendering.bind(this);
|
2016-09-04 03:27:01 +09:00
|
|
|
|
Implement sidebar resizing for modern browsers, by utilizing CSS variables (issue 2072)
By making use of modern CSS features, in this case [CSS variables](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables), implementing sidebar resizing is actually quite simple. Not only will the amount of added code be fairly small, but it should also be easy to maintain since there's no need for complicated JavaScript hacks in order to update the CSS. Another benefit is that the JavaScript code doesn't need to make detailed assumptions about the exact structure of the HTML/CSS code.
Obviously this will not work in older browsers, such as IE, that lack support for CSS variables. In those cases sidebar resizing is simply disabled (via feature detection), and the resizing DOM element hidden, and the behaviour is thus *identical* to the current (fixed-width) sidebar.
However, considering the simplicity of the implementation, I really don't see why limiting this feature to "modern" browsers is a problem.
Finally, note that a few edge-cases meant that the patch is a bit larger than what the basic functionality would dictate. Among those is first of all proper RTL support, and secondly (automatic) resizing of the sidebar when the width of the *entire* viewer changes. Another, pre-existing, issue fixed here is the incomplete interface of `NullL10n`.
*Please note:* This patch has been successfully tested in both LTR and RTL viewer locales, in recent versions of Firefox and Chrome.
Fixes 2072.
2017-10-10 23:16:05 +09:00
|
|
|
this.pdfSidebarResizer = new PDFSidebarResizer(appConfig.sidebarResizer,
|
|
|
|
eventBus, this.l10n);
|
2016-12-08 21:30:21 +09:00
|
|
|
resolve(undefined);
|
2016-09-04 03:27:01 +09:00
|
|
|
});
|
2012-04-26 03:34:28 +09:00
|
|
|
},
|
2011-07-29 02:48:05 +09:00
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
run(config) {
|
2016-04-22 01:39:11 +09:00
|
|
|
this.initialize(config).then(webViewerInitialized);
|
2016-04-02 00:29:44 +09:00
|
|
|
},
|
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
zoomIn(ticks) {
|
|
|
|
let newScale = this.pdfViewer.currentScale;
|
2013-08-27 04:00:35 +09:00
|
|
|
do {
|
|
|
|
newScale = (newScale * DEFAULT_SCALE_DELTA).toFixed(2);
|
|
|
|
newScale = Math.ceil(newScale * 10) / 10;
|
|
|
|
newScale = Math.min(MAX_SCALE, newScale);
|
2015-05-14 12:27:56 +09:00
|
|
|
} while (--ticks > 0 && newScale < MAX_SCALE);
|
2015-07-11 18:47:45 +09:00
|
|
|
this.pdfViewer.currentScaleValue = newScale;
|
2011-09-03 10:16:52 +09:00
|
|
|
},
|
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
zoomOut(ticks) {
|
|
|
|
let newScale = this.pdfViewer.currentScale;
|
2013-08-27 04:00:35 +09:00
|
|
|
do {
|
|
|
|
newScale = (newScale / DEFAULT_SCALE_DELTA).toFixed(2);
|
|
|
|
newScale = Math.floor(newScale * 10) / 10;
|
|
|
|
newScale = Math.max(MIN_SCALE, newScale);
|
2015-05-14 12:27:56 +09:00
|
|
|
} while (--ticks > 0 && newScale > MIN_SCALE);
|
2015-07-11 18:47:45 +09:00
|
|
|
this.pdfViewer.currentScaleValue = newScale;
|
2011-09-03 10:16:52 +09:00
|
|
|
},
|
|
|
|
|
2014-09-13 11:27:45 +09:00
|
|
|
get pagesCount() {
|
2016-08-07 20:10:50 +09:00
|
|
|
return this.pdfDocument ? this.pdfDocument.numPages : 0;
|
2014-09-13 11:27:45 +09:00
|
|
|
},
|
2011-10-15 11:05:57 +09:00
|
|
|
|
2014-09-13 11:27:45 +09:00
|
|
|
set page(val) {
|
2016-08-07 20:10:50 +09:00
|
|
|
this.pdfViewer.currentPageNumber = val;
|
2011-07-29 02:48:05 +09:00
|
|
|
},
|
|
|
|
|
2016-08-07 20:10:50 +09:00
|
|
|
get page() {
|
|
|
|
return this.pdfViewer.currentPageNumber;
|
2011-07-29 02:48:05 +09:00
|
|
|
},
|
|
|
|
|
2016-10-07 06:46:30 +09:00
|
|
|
get printing() {
|
|
|
|
return !!this.printService;
|
|
|
|
},
|
2015-02-01 06:43:30 +09:00
|
|
|
|
2016-10-07 06:46:30 +09:00
|
|
|
get supportsPrinting() {
|
|
|
|
return PDFPrintServiceFactory.instance.supportsPrinting;
|
2012-06-29 01:50:25 +09:00
|
|
|
},
|
|
|
|
|
2012-07-31 00:12:49 +09:00
|
|
|
get supportsFullscreen() {
|
2017-06-29 19:14:26 +09:00
|
|
|
let support;
|
2016-10-15 00:57:53 +09:00
|
|
|
if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('MOZCENTRAL')) {
|
|
|
|
support = document.fullscreenEnabled === true ||
|
|
|
|
document.mozFullScreenEnabled === true;
|
|
|
|
} else {
|
2017-06-29 19:14:26 +09:00
|
|
|
let doc = document.documentElement;
|
2016-10-15 00:57:53 +09:00
|
|
|
support = !!(doc.requestFullscreen || doc.mozRequestFullScreen ||
|
|
|
|
doc.webkitRequestFullScreen || doc.msRequestFullscreen);
|
|
|
|
|
|
|
|
if (document.fullscreenEnabled === false ||
|
|
|
|
document.mozFullScreenEnabled === false ||
|
|
|
|
document.webkitFullscreenEnabled === false ||
|
|
|
|
document.msFullscreenEnabled === false) {
|
|
|
|
support = false;
|
|
|
|
}
|
2013-03-02 05:54:02 +09:00
|
|
|
}
|
2018-02-17 23:08:28 +09:00
|
|
|
if (support && AppOptions.get('disableFullscreen') === true) {
|
2014-12-03 23:38:25 +09:00
|
|
|
support = false;
|
|
|
|
}
|
2012-11-10 22:59:25 +09:00
|
|
|
|
2017-03-28 17:15:02 +09:00
|
|
|
return shadow(this, 'supportsFullscreen', support);
|
2012-07-31 00:12:49 +09:00
|
|
|
},
|
|
|
|
|
2012-10-06 05:59:13 +09:00
|
|
|
get supportsIntegratedFind() {
|
2016-04-14 06:21:05 +09:00
|
|
|
return this.externalServices.supportsIntegratedFind;
|
2012-10-06 05:59:13 +09:00
|
|
|
},
|
|
|
|
|
2012-12-01 07:59:51 +09:00
|
|
|
get supportsDocumentFonts() {
|
2016-04-14 06:21:05 +09:00
|
|
|
return this.externalServices.supportsDocumentFonts;
|
2012-12-01 07:59:51 +09:00
|
|
|
},
|
|
|
|
|
2013-04-04 01:49:03 +09:00
|
|
|
get supportsDocumentColors() {
|
2016-04-14 06:21:05 +09:00
|
|
|
return this.externalServices.supportsDocumentColors;
|
2013-04-04 01:49:03 +09:00
|
|
|
},
|
|
|
|
|
2013-07-19 01:28:59 +09:00
|
|
|
get loadingBar() {
|
2017-06-29 19:14:26 +09:00
|
|
|
let bar = new ProgressBar('#loadingBar');
|
2017-03-28 17:15:02 +09:00
|
|
|
return shadow(this, 'loadingBar', bar);
|
2013-07-19 01:28:59 +09:00
|
|
|
},
|
|
|
|
|
2015-06-02 20:17:02 +09:00
|
|
|
get supportedMouseWheelZoomModifierKeys() {
|
2016-04-14 06:21:05 +09:00
|
|
|
return this.externalServices.supportedMouseWheelZoomModifierKeys;
|
2015-06-02 20:17:02 +09:00
|
|
|
},
|
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
initPassiveLoading() {
|
|
|
|
if (typeof PDFJSDev === 'undefined' ||
|
|
|
|
!PDFJSDev.test('FIREFOX || MOZCENTRAL || CHROME')) {
|
2016-10-15 00:57:53 +09:00
|
|
|
throw new Error('Not implemented: initPassiveLoading');
|
|
|
|
}
|
2017-06-29 19:14:26 +09:00
|
|
|
this.externalServices.initPassiveLoading({
|
|
|
|
onOpenWithTransport(url, length, transport) {
|
|
|
|
PDFViewerApplication.open(url, { range: transport, });
|
|
|
|
|
|
|
|
if (length) {
|
|
|
|
PDFViewerApplication.pdfDocumentProperties.setFileSize(length);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
onOpenWithData(data) {
|
|
|
|
PDFViewerApplication.open(data);
|
|
|
|
},
|
|
|
|
onOpenWithURL(url, length, originalURL) {
|
|
|
|
let file = url, args = null;
|
|
|
|
if (length !== undefined) {
|
|
|
|
args = { length, };
|
|
|
|
}
|
|
|
|
if (originalURL !== undefined) {
|
|
|
|
file = { file: url, originalURL, };
|
|
|
|
}
|
|
|
|
PDFViewerApplication.open(file, args);
|
|
|
|
},
|
|
|
|
onError(err) {
|
|
|
|
PDFViewerApplication.l10n.get('loading_error', null,
|
|
|
|
'An error occurred while loading the PDF.').then((msg) => {
|
|
|
|
PDFViewerApplication.error(msg, err);
|
|
|
|
});
|
|
|
|
},
|
|
|
|
onProgress(loaded, total) {
|
|
|
|
PDFViewerApplication.progress(loaded / total);
|
|
|
|
},
|
|
|
|
});
|
2012-08-01 02:21:07 +09:00
|
|
|
},
|
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
setTitleUsingUrl(url) {
|
2012-08-01 02:21:07 +09:00
|
|
|
this.url = url;
|
2016-10-01 19:05:07 +09:00
|
|
|
this.baseUrl = url.split('#')[0];
|
2017-06-29 19:14:26 +09:00
|
|
|
let title = getPDFFileNameFromURL(url, '');
|
2017-02-06 08:46:12 +09:00
|
|
|
if (!title) {
|
|
|
|
try {
|
2017-03-28 17:15:02 +09:00
|
|
|
title = decodeURIComponent(getFilenameFromUrl(url)) || url;
|
2017-06-29 19:14:26 +09:00
|
|
|
} catch (ex) {
|
2017-02-06 08:46:12 +09:00
|
|
|
// decodeURIComponent may throw URIError,
|
|
|
|
// fall back to using the unprocessed url in that case
|
|
|
|
title = url;
|
|
|
|
}
|
2012-08-27 08:49:07 +09:00
|
|
|
}
|
2017-02-06 08:46:12 +09:00
|
|
|
this.setTitle(title);
|
2012-08-01 02:21:07 +09:00
|
|
|
},
|
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
setTitle(title) {
|
2015-03-06 12:36:08 +09:00
|
|
|
if (this.isViewerEmbedded) {
|
|
|
|
// Embedded PDF viewers should not be changing their parent page's title.
|
|
|
|
return;
|
|
|
|
}
|
2012-11-29 04:02:56 +09:00
|
|
|
document.title = title;
|
|
|
|
},
|
|
|
|
|
2015-10-23 22:49:02 +09:00
|
|
|
/**
|
|
|
|
* Closes opened PDF document.
|
|
|
|
* @returns {Promise} - Returns the promise, which is resolved when all
|
|
|
|
* destruction is completed.
|
|
|
|
*/
|
2017-06-29 19:14:26 +09:00
|
|
|
close() {
|
|
|
|
let errorWrapper = this.appConfig.errorWrapper.container;
|
2014-04-15 19:00:46 +09:00
|
|
|
errorWrapper.setAttribute('hidden', 'true');
|
|
|
|
|
2015-10-23 22:49:02 +09:00
|
|
|
if (!this.pdfLoadingTask) {
|
|
|
|
return Promise.resolve();
|
2014-03-27 05:18:53 +09:00
|
|
|
}
|
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
let promise = this.pdfLoadingTask.destroy();
|
2015-10-23 22:49:02 +09:00
|
|
|
this.pdfLoadingTask = null;
|
|
|
|
|
|
|
|
if (this.pdfDocument) {
|
|
|
|
this.pdfDocument = null;
|
2014-03-27 05:18:53 +09:00
|
|
|
|
2015-10-23 22:49:02 +09:00
|
|
|
this.pdfThumbnailViewer.setDocument(null);
|
|
|
|
this.pdfViewer.setDocument(null);
|
|
|
|
this.pdfLinkService.setDocument(null, null);
|
2017-05-05 21:04:08 +09:00
|
|
|
this.pdfDocumentProperties.setDocument(null, null);
|
2015-10-23 22:49:02 +09:00
|
|
|
}
|
2016-03-12 21:07:43 +09:00
|
|
|
this.store = null;
|
|
|
|
this.isInitialViewSet = false;
|
2017-06-17 20:14:36 +09:00
|
|
|
this.downloadComplete = false;
|
2018-01-14 12:04:29 +09:00
|
|
|
this.url = '';
|
|
|
|
this.baseUrl = '';
|
2018-01-17 00:24:36 +09:00
|
|
|
this.contentDispositionFilename = null;
|
2014-03-27 05:18:53 +09:00
|
|
|
|
2016-02-22 01:54:23 +09:00
|
|
|
this.pdfSidebar.reset();
|
2016-02-21 21:36:24 +09:00
|
|
|
this.pdfOutlineViewer.reset();
|
|
|
|
this.pdfAttachmentViewer.reset();
|
|
|
|
|
2016-02-27 02:06:59 +09:00
|
|
|
this.findController.reset();
|
2016-02-27 02:22:08 +09:00
|
|
|
this.findBar.reset();
|
2016-11-19 03:50:29 +09:00
|
|
|
this.toolbar.reset();
|
|
|
|
this.secondaryToolbar.reset();
|
2016-02-27 02:06:59 +09:00
|
|
|
|
2014-03-27 05:18:53 +09:00
|
|
|
if (typeof PDFBug !== 'undefined') {
|
|
|
|
PDFBug.cleanup();
|
|
|
|
}
|
2015-10-23 22:49:02 +09:00
|
|
|
return promise;
|
2014-03-27 05:18:53 +09:00
|
|
|
},
|
|
|
|
|
2015-10-23 22:49:02 +09:00
|
|
|
/**
|
|
|
|
* Opens PDF document specified by URL or array with additional arguments.
|
|
|
|
* @param {string|TypedArray|ArrayBuffer} file - PDF location or binary data.
|
|
|
|
* @param {Object} args - (optional) Additional arguments for the getDocument
|
|
|
|
* call, e.g. HTTP headers ('httpHeaders') or
|
|
|
|
* alternative data transport ('range').
|
|
|
|
* @returns {Promise} - Returns the promise, which is resolved when document
|
|
|
|
* is opened.
|
|
|
|
*/
|
2017-05-09 20:17:39 +09:00
|
|
|
open(file, args) {
|
2015-10-23 22:49:02 +09:00
|
|
|
if (this.pdfLoadingTask) {
|
|
|
|
// We need to destroy already opened document.
|
2017-04-17 20:21:11 +09:00
|
|
|
return this.close().then(() => {
|
2015-10-23 22:49:02 +09:00
|
|
|
// Reload the preferences if a document was previously opened.
|
2017-04-17 20:21:11 +09:00
|
|
|
this.preferences.reload();
|
2015-10-23 22:49:02 +09:00
|
|
|
// ... and repeat the open() call.
|
|
|
|
return this.open(file, args);
|
2017-04-17 20:21:11 +09:00
|
|
|
});
|
2014-03-27 05:18:53 +09:00
|
|
|
}
|
2018-02-17 23:33:57 +09:00
|
|
|
// Set the necessary global worker parameters, using the available options.
|
|
|
|
const workerParameters = AppOptions.getAll('worker');
|
|
|
|
for (let key in workerParameters) {
|
|
|
|
GlobalWorkerOptions[key] = workerParameters[key];
|
|
|
|
}
|
2014-03-27 05:18:53 +09:00
|
|
|
|
Remove the ability to pass a `scale` parameter in the (optional) `args` object parameter of `PDFViewerApplication.open(file, args)`
Since the very early days of the viewer, it's been possible to pass in a `scale` when opening a PDF file. However, most of the time it was/is actually being ignored, which limits its usefulness considerably.
In older versions of the viewer, if a document hash was present (i.e. `PDFViewerApplication.initialBookmark` being set) or if the document existed in the `ViewHistory`, the `scale` passed to `PDFViewerApplication.open` would thus always be ignored.
In addition to the above, in the current viewer there's even more cases where the `scale` parameter will be ignored: if a (valid) browser history entry exists on document load, or if the `defaultZoomValue` preference is set to a non-default value.
Hence the result is that in most situation, a `scale` passed to `PDFViewerApplication.open` will be completely ignored.
A much better, not to mention supported, way of setting the initial scale is by using the `defaultZoomLevel` preference. In comparision, this also has the advantage of being used in situations where the `scale` would be ignored.
All in all this leads to the current situation where we have code which is essentially dead, since no part of the viewer (by default) relies on it.
To clean up this code, and to avoid having to pass (basically) unused parameters around, I'd thus like to remove the ability to pass a `scale` to `PDFViewerApplication.open`.
2017-08-24 16:24:32 +09:00
|
|
|
let parameters = Object.create(null);
|
2014-09-10 15:17:19 +09:00
|
|
|
if (typeof file === 'string') { // URL
|
|
|
|
this.setTitleUsingUrl(file);
|
|
|
|
parameters.url = file;
|
|
|
|
} else if (file && 'byteLength' in file) { // ArrayBuffer
|
|
|
|
parameters.data = file;
|
|
|
|
} else if (file.url && file.originalUrl) {
|
|
|
|
this.setTitleUsingUrl(file.originalUrl);
|
|
|
|
parameters.url = file.url;
|
2012-05-15 03:45:07 +09:00
|
|
|
}
|
2017-09-06 19:52:48 +09:00
|
|
|
if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION')) {
|
|
|
|
parameters.docBaseUrl = document.URL.split('#')[0];
|
|
|
|
} else if (typeof PDFJSDev !== 'undefined' &&
|
|
|
|
PDFJSDev.test('FIREFOX || MOZCENTRAL || CHROME')) {
|
2016-10-01 19:05:07 +09:00
|
|
|
parameters.docBaseUrl = this.baseUrl;
|
|
|
|
}
|
2018-02-17 23:33:57 +09:00
|
|
|
// Set the necessary API parameters, using the available options.
|
|
|
|
const apiParameters = AppOptions.getAll('api');
|
|
|
|
for (let key in apiParameters) {
|
|
|
|
parameters[key] = apiParameters[key];
|
|
|
|
}
|
2016-10-01 19:05:07 +09:00
|
|
|
|
2013-02-07 08:19:29 +09:00
|
|
|
if (args) {
|
2017-05-09 20:17:39 +09:00
|
|
|
for (let prop in args) {
|
2017-10-15 23:57:30 +09:00
|
|
|
if (prop === 'length') {
|
Remove the ability to pass a `scale` parameter in the (optional) `args` object parameter of `PDFViewerApplication.open(file, args)`
Since the very early days of the viewer, it's been possible to pass in a `scale` when opening a PDF file. However, most of the time it was/is actually being ignored, which limits its usefulness considerably.
In older versions of the viewer, if a document hash was present (i.e. `PDFViewerApplication.initialBookmark` being set) or if the document existed in the `ViewHistory`, the `scale` passed to `PDFViewerApplication.open` would thus always be ignored.
In addition to the above, in the current viewer there's even more cases where the `scale` parameter will be ignored: if a (valid) browser history entry exists on document load, or if the `defaultZoomValue` preference is set to a non-default value.
Hence the result is that in most situation, a `scale` passed to `PDFViewerApplication.open` will be completely ignored.
A much better, not to mention supported, way of setting the initial scale is by using the `defaultZoomLevel` preference. In comparision, this also has the advantage of being used in situations where the `scale` would be ignored.
All in all this leads to the current situation where we have code which is essentially dead, since no part of the viewer (by default) relies on it.
To clean up this code, and to avoid having to pass (basically) unused parameters around, I'd thus like to remove the ability to pass a `scale` to `PDFViewerApplication.open`.
2017-08-24 16:24:32 +09:00
|
|
|
this.pdfDocumentProperties.setFileSize(args[prop]);
|
|
|
|
}
|
2013-02-07 08:19:29 +09:00
|
|
|
parameters[prop] = args[prop];
|
|
|
|
}
|
|
|
|
}
|
2011-07-29 02:48:05 +09:00
|
|
|
|
2018-01-14 12:04:29 +09:00
|
|
|
if (this.url && isFileSchema(this.url)) {
|
|
|
|
let appConfig = this.appConfig;
|
|
|
|
appConfig.toolbar.download.setAttribute('hidden', 'true');
|
|
|
|
appConfig.secondaryToolbar.downloadButton.setAttribute('hidden', 'true');
|
|
|
|
}
|
|
|
|
|
2017-05-09 20:17:39 +09:00
|
|
|
let loadingTask = getDocument(parameters);
|
2015-10-23 22:49:02 +09:00
|
|
|
this.pdfLoadingTask = loadingTask;
|
2015-10-21 22:54:31 +09:00
|
|
|
|
2017-05-09 20:17:39 +09:00
|
|
|
loadingTask.onPassword = (updateCallback, reason) => {
|
|
|
|
this.passwordPrompt.setUpdateCallback(updateCallback, reason);
|
|
|
|
this.passwordPrompt.open();
|
2013-05-10 07:35:23 +09:00
|
|
|
};
|
|
|
|
|
2017-05-09 20:17:39 +09:00
|
|
|
loadingTask.onProgress = ({ loaded, total, }) => {
|
|
|
|
this.progress(loaded / total);
|
2015-10-21 22:54:31 +09:00
|
|
|
};
|
2013-06-06 04:28:31 +09:00
|
|
|
|
2015-12-01 05:42:47 +09:00
|
|
|
// Listen for unsupported features to trigger the fallback UI.
|
|
|
|
loadingTask.onUnsupportedFeature = this.fallback.bind(this);
|
|
|
|
|
2017-05-09 20:17:39 +09:00
|
|
|
return loadingTask.promise.then((pdfDocument) => {
|
Remove the ability to pass a `scale` parameter in the (optional) `args` object parameter of `PDFViewerApplication.open(file, args)`
Since the very early days of the viewer, it's been possible to pass in a `scale` when opening a PDF file. However, most of the time it was/is actually being ignored, which limits its usefulness considerably.
In older versions of the viewer, if a document hash was present (i.e. `PDFViewerApplication.initialBookmark` being set) or if the document existed in the `ViewHistory`, the `scale` passed to `PDFViewerApplication.open` would thus always be ignored.
In addition to the above, in the current viewer there's even more cases where the `scale` parameter will be ignored: if a (valid) browser history entry exists on document load, or if the `defaultZoomValue` preference is set to a non-default value.
Hence the result is that in most situation, a `scale` passed to `PDFViewerApplication.open` will be completely ignored.
A much better, not to mention supported, way of setting the initial scale is by using the `defaultZoomLevel` preference. In comparision, this also has the advantage of being used in situations where the `scale` would be ignored.
All in all this leads to the current situation where we have code which is essentially dead, since no part of the viewer (by default) relies on it.
To clean up this code, and to avoid having to pass (basically) unused parameters around, I'd thus like to remove the ability to pass a `scale` to `PDFViewerApplication.open`.
2017-08-24 16:24:32 +09:00
|
|
|
this.load(pdfDocument);
|
2017-05-09 20:17:39 +09:00
|
|
|
}, (exception) => {
|
2017-11-23 21:44:26 +09:00
|
|
|
if (loadingTask !== this.pdfLoadingTask) {
|
|
|
|
return; // Ignore errors for previously opened PDF files.
|
|
|
|
}
|
|
|
|
|
2017-05-09 20:17:39 +09:00
|
|
|
let message = exception && exception.message;
|
2017-05-04 10:05:53 +09:00
|
|
|
let loadingErrorMessage;
|
2017-05-09 20:17:39 +09:00
|
|
|
if (exception instanceof InvalidPDFException) {
|
|
|
|
// change error message also for other builds
|
2017-05-04 10:05:53 +09:00
|
|
|
loadingErrorMessage = this.l10n.get('invalid_file_error', null,
|
|
|
|
'Invalid or corrupted PDF file.');
|
2017-05-09 20:17:39 +09:00
|
|
|
} else if (exception instanceof MissingPDFException) {
|
|
|
|
// special message for missing PDF's
|
2017-05-04 10:05:53 +09:00
|
|
|
loadingErrorMessage = this.l10n.get('missing_file_error', null,
|
|
|
|
'Missing PDF file.');
|
2017-05-09 20:17:39 +09:00
|
|
|
} else if (exception instanceof UnexpectedResponseException) {
|
2017-05-04 10:05:53 +09:00
|
|
|
loadingErrorMessage = this.l10n.get('unexpected_response_error', null,
|
|
|
|
'Unexpected server response.');
|
|
|
|
} else {
|
|
|
|
loadingErrorMessage = this.l10n.get('loading_error', null,
|
|
|
|
'An error occurred while loading the PDF.');
|
2012-04-10 14:20:57 +09:00
|
|
|
}
|
2017-05-09 20:17:39 +09:00
|
|
|
|
2017-05-04 10:05:53 +09:00
|
|
|
return loadingErrorMessage.then((msg) => {
|
|
|
|
this.error(msg, { message, });
|
|
|
|
throw new Error(msg);
|
|
|
|
});
|
2017-05-09 20:17:39 +09:00
|
|
|
});
|
2011-07-29 02:48:05 +09:00
|
|
|
},
|
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
download() {
|
2014-03-14 12:23:47 +09:00
|
|
|
function downloadByUrl() {
|
2013-07-13 03:14:13 +09:00
|
|
|
downloadManager.downloadUrl(url, filename);
|
2013-03-25 02:25:57 +09:00
|
|
|
}
|
2013-07-13 03:14:13 +09:00
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
let url = this.baseUrl;
|
2017-02-06 08:45:51 +09:00
|
|
|
// Use this.url instead of this.baseUrl to perform filename detection based
|
|
|
|
// on the reference fragment as ultimate fallback if needed.
|
2018-01-17 00:24:36 +09:00
|
|
|
let filename = this.contentDispositionFilename ||
|
2018-01-13 17:01:50 +09:00
|
|
|
getPDFFileNameFromURL(this.url);
|
2017-06-29 19:14:26 +09:00
|
|
|
let downloadManager = this.downloadManager;
|
|
|
|
downloadManager.onerror = (err) => {
|
2013-07-13 03:14:13 +09:00
|
|
|
// This error won't really be helpful because it's likely the
|
|
|
|
// fallback won't work either (or is already open).
|
2017-06-29 19:14:26 +09:00
|
|
|
this.error(`PDF failed to download: ${err}`);
|
2013-07-13 03:14:13 +09:00
|
|
|
};
|
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
// When the PDF document isn't ready, or the PDF file is still downloading,
|
|
|
|
// simply download using the URL.
|
|
|
|
if (!this.pdfDocument || !this.downloadComplete) {
|
2014-03-14 12:23:47 +09:00
|
|
|
downloadByUrl();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
this.pdfDocument.getData().then(function(data) {
|
|
|
|
let blob = createBlob(data, 'application/pdf');
|
|
|
|
downloadManager.download(blob, url, filename);
|
|
|
|
}).catch(downloadByUrl); // Error occurred, try downloading with the URL.
|
2011-10-19 13:29:14 +09:00
|
|
|
},
|
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
fallback(featureId) {
|
2016-10-15 00:57:53 +09:00
|
|
|
if (typeof PDFJSDev !== 'undefined' &&
|
|
|
|
PDFJSDev.test('FIREFOX || MOZCENTRAL')) {
|
|
|
|
// Only trigger the fallback once so we don't spam the user with messages
|
|
|
|
// for one PDF.
|
|
|
|
if (this.fellback) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.fellback = true;
|
2016-10-01 19:05:07 +09:00
|
|
|
this.externalServices.fallback({
|
2017-04-28 19:02:42 +09:00
|
|
|
featureId,
|
2016-10-01 19:05:07 +09:00
|
|
|
url: this.baseUrl,
|
|
|
|
}, function response(download) {
|
|
|
|
if (!download) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
PDFViewerApplication.download();
|
|
|
|
});
|
2015-04-26 08:49:37 +09:00
|
|
|
}
|
2012-05-11 07:54:58 +09:00
|
|
|
},
|
|
|
|
|
2011-11-30 04:28:05 +09:00
|
|
|
/**
|
|
|
|
* Show the error box.
|
|
|
|
* @param {String} message A message that is human readable.
|
|
|
|
* @param {Object} moreInfo (optional) Further information about the error
|
|
|
|
* that is more technical. Should have a 'message'
|
|
|
|
* and optionally a 'stack' property.
|
|
|
|
*/
|
2017-06-29 19:14:26 +09:00
|
|
|
error(message, moreInfo) {
|
2017-05-04 10:05:53 +09:00
|
|
|
let moreInfoText = [this.l10n.get('error_version_info',
|
Fix inconsistent spacing and trailing commas in objects in `web/` files, so we can enable the `comma-dangle` and `object-curly-spacing` ESLint rules later on
http://eslint.org/docs/rules/comma-dangle
http://eslint.org/docs/rules/object-curly-spacing
Given that we currently have quite inconsistent object formatting, fixing this in in *one* big patch probably wouldn't be feasible (since I cannot imagine anyone wanting to review that); hence I've opted to try and do this piecewise instead.
*Please note:* This patch was created automatically, using the ESLint `--fix` command line option. In a couple of places this caused lines to become too long, and I've fixed those manually; please refer to the interdiff below for the only hand-edits in this patch.
```diff
diff --git a/web/pdf_thumbnail_view.js b/web/pdf_thumbnail_view.js
index 002dbf29..1de4e530 100644
--- a/web/pdf_thumbnail_view.js
+++ b/web/pdf_thumbnail_view.js
@@ -420,8 +420,8 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() {
setPageLabel: function PDFThumbnailView_setPageLabel(label) {
this.pageLabel = (typeof label === 'string' ? label : null);
- this.l10n.get('thumb_page_title', { page: this.pageId, }, 'Page {{page}}').
- then((msg) => {
+ this.l10n.get('thumb_page_title', { page: this.pageId, },
+ 'Page {{page}}').then((msg) => {
this.anchor.title = msg;
});
diff --git a/web/secondary_toolbar.js b/web/secondary_toolbar.js
index 160e0410..6495fc5e 100644
--- a/web/secondary_toolbar.js
+++ b/web/secondary_toolbar.js
@@ -65,7 +65,8 @@ class SecondaryToolbar {
{ element: options.printButton, eventName: 'print', close: true, },
{ element: options.downloadButton, eventName: 'download', close: true, },
{ element: options.viewBookmarkButton, eventName: null, close: true, },
- { element: options.firstPageButton, eventName: 'firstpage', close: true, },
+ { element: options.firstPageButton, eventName: 'firstpage',
+ close: true, },
{ element: options.lastPageButton, eventName: 'lastpage', close: true, },
{ element: options.pageRotateCwButton, eventName: 'rotatecw',
close: false, },
@@ -76,7 +77,7 @@ class SecondaryToolbar {
{ element: options.cursorHandToolButton, eventName: 'switchcursortool',
eventDetails: { tool: CursorTool.HAND, }, close: true, },
{ element: options.documentPropertiesButton,
- eventName: 'documentproperties', close: true, }
+ eventName: 'documentproperties', close: true, },
];
this.items = {
firstPage: options.firstPageButton,
```
2017-06-01 19:46:12 +09:00
|
|
|
{ version: version || '?', build: build || '?', },
|
2017-05-04 10:05:53 +09:00
|
|
|
'PDF.js v{{version}} (build: {{build}})')];
|
2012-05-15 09:19:09 +09:00
|
|
|
if (moreInfo) {
|
2017-05-04 10:05:53 +09:00
|
|
|
moreInfoText.push(
|
Fix inconsistent spacing and trailing commas in objects in `web/` files, so we can enable the `comma-dangle` and `object-curly-spacing` ESLint rules later on
http://eslint.org/docs/rules/comma-dangle
http://eslint.org/docs/rules/object-curly-spacing
Given that we currently have quite inconsistent object formatting, fixing this in in *one* big patch probably wouldn't be feasible (since I cannot imagine anyone wanting to review that); hence I've opted to try and do this piecewise instead.
*Please note:* This patch was created automatically, using the ESLint `--fix` command line option. In a couple of places this caused lines to become too long, and I've fixed those manually; please refer to the interdiff below for the only hand-edits in this patch.
```diff
diff --git a/web/pdf_thumbnail_view.js b/web/pdf_thumbnail_view.js
index 002dbf29..1de4e530 100644
--- a/web/pdf_thumbnail_view.js
+++ b/web/pdf_thumbnail_view.js
@@ -420,8 +420,8 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() {
setPageLabel: function PDFThumbnailView_setPageLabel(label) {
this.pageLabel = (typeof label === 'string' ? label : null);
- this.l10n.get('thumb_page_title', { page: this.pageId, }, 'Page {{page}}').
- then((msg) => {
+ this.l10n.get('thumb_page_title', { page: this.pageId, },
+ 'Page {{page}}').then((msg) => {
this.anchor.title = msg;
});
diff --git a/web/secondary_toolbar.js b/web/secondary_toolbar.js
index 160e0410..6495fc5e 100644
--- a/web/secondary_toolbar.js
+++ b/web/secondary_toolbar.js
@@ -65,7 +65,8 @@ class SecondaryToolbar {
{ element: options.printButton, eventName: 'print', close: true, },
{ element: options.downloadButton, eventName: 'download', close: true, },
{ element: options.viewBookmarkButton, eventName: null, close: true, },
- { element: options.firstPageButton, eventName: 'firstpage', close: true, },
+ { element: options.firstPageButton, eventName: 'firstpage',
+ close: true, },
{ element: options.lastPageButton, eventName: 'lastpage', close: true, },
{ element: options.pageRotateCwButton, eventName: 'rotatecw',
close: false, },
@@ -76,7 +77,7 @@ class SecondaryToolbar {
{ element: options.cursorHandToolButton, eventName: 'switchcursortool',
eventDetails: { tool: CursorTool.HAND, }, close: true, },
{ element: options.documentPropertiesButton,
- eventName: 'documentproperties', close: true, }
+ eventName: 'documentproperties', close: true, },
];
this.items = {
firstPage: options.firstPageButton,
```
2017-06-01 19:46:12 +09:00
|
|
|
this.l10n.get('error_message', { message: moreInfo.message, },
|
2017-05-04 10:05:53 +09:00
|
|
|
'Message: {{message}}'));
|
2012-05-15 09:19:09 +09:00
|
|
|
if (moreInfo.stack) {
|
2017-05-04 10:05:53 +09:00
|
|
|
moreInfoText.push(
|
Fix inconsistent spacing and trailing commas in objects in `web/` files, so we can enable the `comma-dangle` and `object-curly-spacing` ESLint rules later on
http://eslint.org/docs/rules/comma-dangle
http://eslint.org/docs/rules/object-curly-spacing
Given that we currently have quite inconsistent object formatting, fixing this in in *one* big patch probably wouldn't be feasible (since I cannot imagine anyone wanting to review that); hence I've opted to try and do this piecewise instead.
*Please note:* This patch was created automatically, using the ESLint `--fix` command line option. In a couple of places this caused lines to become too long, and I've fixed those manually; please refer to the interdiff below for the only hand-edits in this patch.
```diff
diff --git a/web/pdf_thumbnail_view.js b/web/pdf_thumbnail_view.js
index 002dbf29..1de4e530 100644
--- a/web/pdf_thumbnail_view.js
+++ b/web/pdf_thumbnail_view.js
@@ -420,8 +420,8 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() {
setPageLabel: function PDFThumbnailView_setPageLabel(label) {
this.pageLabel = (typeof label === 'string' ? label : null);
- this.l10n.get('thumb_page_title', { page: this.pageId, }, 'Page {{page}}').
- then((msg) => {
+ this.l10n.get('thumb_page_title', { page: this.pageId, },
+ 'Page {{page}}').then((msg) => {
this.anchor.title = msg;
});
diff --git a/web/secondary_toolbar.js b/web/secondary_toolbar.js
index 160e0410..6495fc5e 100644
--- a/web/secondary_toolbar.js
+++ b/web/secondary_toolbar.js
@@ -65,7 +65,8 @@ class SecondaryToolbar {
{ element: options.printButton, eventName: 'print', close: true, },
{ element: options.downloadButton, eventName: 'download', close: true, },
{ element: options.viewBookmarkButton, eventName: null, close: true, },
- { element: options.firstPageButton, eventName: 'firstpage', close: true, },
+ { element: options.firstPageButton, eventName: 'firstpage',
+ close: true, },
{ element: options.lastPageButton, eventName: 'lastpage', close: true, },
{ element: options.pageRotateCwButton, eventName: 'rotatecw',
close: false, },
@@ -76,7 +77,7 @@ class SecondaryToolbar {
{ element: options.cursorHandToolButton, eventName: 'switchcursortool',
eventDetails: { tool: CursorTool.HAND, }, close: true, },
{ element: options.documentPropertiesButton,
- eventName: 'documentproperties', close: true, }
+ eventName: 'documentproperties', close: true, },
];
this.items = {
firstPage: options.firstPageButton,
```
2017-06-01 19:46:12 +09:00
|
|
|
this.l10n.get('error_stack', { stack: moreInfo.stack, },
|
2017-05-04 10:05:53 +09:00
|
|
|
'Stack: {{stack}}'));
|
2012-05-15 09:19:09 +09:00
|
|
|
} else {
|
|
|
|
if (moreInfo.filename) {
|
2017-05-04 10:05:53 +09:00
|
|
|
moreInfoText.push(
|
Fix inconsistent spacing and trailing commas in objects in `web/` files, so we can enable the `comma-dangle` and `object-curly-spacing` ESLint rules later on
http://eslint.org/docs/rules/comma-dangle
http://eslint.org/docs/rules/object-curly-spacing
Given that we currently have quite inconsistent object formatting, fixing this in in *one* big patch probably wouldn't be feasible (since I cannot imagine anyone wanting to review that); hence I've opted to try and do this piecewise instead.
*Please note:* This patch was created automatically, using the ESLint `--fix` command line option. In a couple of places this caused lines to become too long, and I've fixed those manually; please refer to the interdiff below for the only hand-edits in this patch.
```diff
diff --git a/web/pdf_thumbnail_view.js b/web/pdf_thumbnail_view.js
index 002dbf29..1de4e530 100644
--- a/web/pdf_thumbnail_view.js
+++ b/web/pdf_thumbnail_view.js
@@ -420,8 +420,8 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() {
setPageLabel: function PDFThumbnailView_setPageLabel(label) {
this.pageLabel = (typeof label === 'string' ? label : null);
- this.l10n.get('thumb_page_title', { page: this.pageId, }, 'Page {{page}}').
- then((msg) => {
+ this.l10n.get('thumb_page_title', { page: this.pageId, },
+ 'Page {{page}}').then((msg) => {
this.anchor.title = msg;
});
diff --git a/web/secondary_toolbar.js b/web/secondary_toolbar.js
index 160e0410..6495fc5e 100644
--- a/web/secondary_toolbar.js
+++ b/web/secondary_toolbar.js
@@ -65,7 +65,8 @@ class SecondaryToolbar {
{ element: options.printButton, eventName: 'print', close: true, },
{ element: options.downloadButton, eventName: 'download', close: true, },
{ element: options.viewBookmarkButton, eventName: null, close: true, },
- { element: options.firstPageButton, eventName: 'firstpage', close: true, },
+ { element: options.firstPageButton, eventName: 'firstpage',
+ close: true, },
{ element: options.lastPageButton, eventName: 'lastpage', close: true, },
{ element: options.pageRotateCwButton, eventName: 'rotatecw',
close: false, },
@@ -76,7 +77,7 @@ class SecondaryToolbar {
{ element: options.cursorHandToolButton, eventName: 'switchcursortool',
eventDetails: { tool: CursorTool.HAND, }, close: true, },
{ element: options.documentPropertiesButton,
- eventName: 'documentproperties', close: true, }
+ eventName: 'documentproperties', close: true, },
];
this.items = {
firstPage: options.firstPageButton,
```
2017-06-01 19:46:12 +09:00
|
|
|
this.l10n.get('error_file', { file: moreInfo.filename, },
|
2017-05-04 10:05:53 +09:00
|
|
|
'File: {{file}}'));
|
2012-05-15 09:19:09 +09:00
|
|
|
}
|
|
|
|
if (moreInfo.lineNumber) {
|
2017-05-04 10:05:53 +09:00
|
|
|
moreInfoText.push(
|
Fix inconsistent spacing and trailing commas in objects in `web/` files, so we can enable the `comma-dangle` and `object-curly-spacing` ESLint rules later on
http://eslint.org/docs/rules/comma-dangle
http://eslint.org/docs/rules/object-curly-spacing
Given that we currently have quite inconsistent object formatting, fixing this in in *one* big patch probably wouldn't be feasible (since I cannot imagine anyone wanting to review that); hence I've opted to try and do this piecewise instead.
*Please note:* This patch was created automatically, using the ESLint `--fix` command line option. In a couple of places this caused lines to become too long, and I've fixed those manually; please refer to the interdiff below for the only hand-edits in this patch.
```diff
diff --git a/web/pdf_thumbnail_view.js b/web/pdf_thumbnail_view.js
index 002dbf29..1de4e530 100644
--- a/web/pdf_thumbnail_view.js
+++ b/web/pdf_thumbnail_view.js
@@ -420,8 +420,8 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() {
setPageLabel: function PDFThumbnailView_setPageLabel(label) {
this.pageLabel = (typeof label === 'string' ? label : null);
- this.l10n.get('thumb_page_title', { page: this.pageId, }, 'Page {{page}}').
- then((msg) => {
+ this.l10n.get('thumb_page_title', { page: this.pageId, },
+ 'Page {{page}}').then((msg) => {
this.anchor.title = msg;
});
diff --git a/web/secondary_toolbar.js b/web/secondary_toolbar.js
index 160e0410..6495fc5e 100644
--- a/web/secondary_toolbar.js
+++ b/web/secondary_toolbar.js
@@ -65,7 +65,8 @@ class SecondaryToolbar {
{ element: options.printButton, eventName: 'print', close: true, },
{ element: options.downloadButton, eventName: 'download', close: true, },
{ element: options.viewBookmarkButton, eventName: null, close: true, },
- { element: options.firstPageButton, eventName: 'firstpage', close: true, },
+ { element: options.firstPageButton, eventName: 'firstpage',
+ close: true, },
{ element: options.lastPageButton, eventName: 'lastpage', close: true, },
{ element: options.pageRotateCwButton, eventName: 'rotatecw',
close: false, },
@@ -76,7 +77,7 @@ class SecondaryToolbar {
{ element: options.cursorHandToolButton, eventName: 'switchcursortool',
eventDetails: { tool: CursorTool.HAND, }, close: true, },
{ element: options.documentPropertiesButton,
- eventName: 'documentproperties', close: true, }
+ eventName: 'documentproperties', close: true, },
];
this.items = {
firstPage: options.firstPageButton,
```
2017-06-01 19:46:12 +09:00
|
|
|
this.l10n.get('error_line', { line: moreInfo.lineNumber, },
|
2017-05-04 10:05:53 +09:00
|
|
|
'Line: {{line}}'));
|
2012-05-15 09:19:09 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-08-23 00:48:56 +09:00
|
|
|
|
2016-10-15 00:57:53 +09:00
|
|
|
if (typeof PDFJSDev === 'undefined' ||
|
|
|
|
!PDFJSDev.test('FIREFOX || MOZCENTRAL')) {
|
2017-06-29 19:14:26 +09:00
|
|
|
let errorWrapperConfig = this.appConfig.errorWrapper;
|
|
|
|
let errorWrapper = errorWrapperConfig.container;
|
2016-10-15 00:57:53 +09:00
|
|
|
errorWrapper.removeAttribute('hidden');
|
2011-11-29 09:55:09 +09:00
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
let errorMessage = errorWrapperConfig.errorMessage;
|
2016-10-15 00:57:53 +09:00
|
|
|
errorMessage.textContent = message;
|
2011-11-29 09:55:09 +09:00
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
let closeButton = errorWrapperConfig.closeButton;
|
2016-10-15 00:57:53 +09:00
|
|
|
closeButton.onclick = function() {
|
|
|
|
errorWrapper.setAttribute('hidden', 'true');
|
|
|
|
};
|
2011-11-30 04:28:05 +09:00
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
let errorMoreInfo = errorWrapperConfig.errorMoreInfo;
|
|
|
|
let moreInfoButton = errorWrapperConfig.moreInfoButton;
|
|
|
|
let lessInfoButton = errorWrapperConfig.lessInfoButton;
|
2016-10-15 00:57:53 +09:00
|
|
|
moreInfoButton.onclick = function() {
|
|
|
|
errorMoreInfo.removeAttribute('hidden');
|
|
|
|
moreInfoButton.setAttribute('hidden', 'true');
|
|
|
|
lessInfoButton.removeAttribute('hidden');
|
|
|
|
errorMoreInfo.style.height = errorMoreInfo.scrollHeight + 'px';
|
|
|
|
};
|
|
|
|
lessInfoButton.onclick = function() {
|
|
|
|
errorMoreInfo.setAttribute('hidden', 'true');
|
|
|
|
moreInfoButton.removeAttribute('hidden');
|
|
|
|
lessInfoButton.setAttribute('hidden', 'true');
|
|
|
|
};
|
|
|
|
moreInfoButton.oncontextmenu = noContextMenuHandler;
|
|
|
|
lessInfoButton.oncontextmenu = noContextMenuHandler;
|
|
|
|
closeButton.oncontextmenu = noContextMenuHandler;
|
2011-11-29 09:55:09 +09:00
|
|
|
moreInfoButton.removeAttribute('hidden');
|
2011-11-30 04:28:05 +09:00
|
|
|
lessInfoButton.setAttribute('hidden', 'true');
|
2017-05-04 10:05:53 +09:00
|
|
|
Promise.all(moreInfoText).then((parts) => {
|
|
|
|
errorMoreInfo.value = parts.join('\n');
|
|
|
|
});
|
2016-10-15 00:57:53 +09:00
|
|
|
} else {
|
2017-08-28 20:49:40 +09:00
|
|
|
Promise.all(moreInfoText).then((parts) => {
|
|
|
|
console.error(message + '\n' + parts.join('\n'));
|
|
|
|
});
|
2016-10-15 00:57:53 +09:00
|
|
|
this.fallback();
|
|
|
|
}
|
2011-09-28 19:53:53 +09:00
|
|
|
},
|
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
progress(level) {
|
2017-07-29 18:36:45 +09:00
|
|
|
if (this.downloadComplete) {
|
|
|
|
// Don't accidentally show the loading bar again when the entire file has
|
|
|
|
// already been fetched (only an issue when disableAutoFetch is enabled).
|
|
|
|
return;
|
|
|
|
}
|
2017-06-29 19:14:26 +09:00
|
|
|
let percent = Math.round(level * 100);
|
2013-04-24 02:00:31 +09:00
|
|
|
// When we transition from full request to range requests, it's possible
|
|
|
|
// that we discard some of the loaded data. This can cause the loading
|
|
|
|
// bar to move backwards. So prevent this by only updating the bar if it
|
|
|
|
// increases.
|
2014-09-22 20:41:17 +09:00
|
|
|
if (percent > this.loadingBar.percent || isNaN(percent)) {
|
|
|
|
this.loadingBar.percent = percent;
|
2014-08-17 08:06:03 +09:00
|
|
|
|
|
|
|
// When disableAutoFetch is enabled, it's not uncommon for the entire file
|
|
|
|
// to never be fetched (depends on e.g. the file structure). In this case
|
|
|
|
// the loading bar will not be completely filled, nor will it be hidden.
|
|
|
|
// To prevent displaying a partially filled loading bar permanently, we
|
|
|
|
// hide it when no data has been loaded during a certain amount of time.
|
2018-02-18 06:08:45 +09:00
|
|
|
const disableAutoFetch = this.pdfDocument ?
|
|
|
|
this.pdfDocument.loadingParams['disableAutoFetch'] :
|
|
|
|
AppOptions.get('disableAutoFetch');
|
|
|
|
|
|
|
|
if (disableAutoFetch && percent) {
|
2014-08-17 08:06:03 +09:00
|
|
|
if (this.disableAutoFetchLoadingBarTimeout) {
|
|
|
|
clearTimeout(this.disableAutoFetchLoadingBarTimeout);
|
|
|
|
this.disableAutoFetchLoadingBarTimeout = null;
|
|
|
|
}
|
|
|
|
this.loadingBar.show();
|
|
|
|
|
2017-05-05 00:09:50 +09:00
|
|
|
this.disableAutoFetchLoadingBarTimeout = setTimeout(() => {
|
2014-08-17 08:06:03 +09:00
|
|
|
this.loadingBar.hide();
|
|
|
|
this.disableAutoFetchLoadingBarTimeout = null;
|
2017-05-05 00:09:50 +09:00
|
|
|
}, DISABLE_AUTO_FETCH_LOADING_BAR_TIMEOUT);
|
2014-08-17 08:06:03 +09:00
|
|
|
}
|
2013-04-24 02:00:31 +09:00
|
|
|
}
|
2011-09-28 19:53:53 +09:00
|
|
|
},
|
|
|
|
|
Remove the ability to pass a `scale` parameter in the (optional) `args` object parameter of `PDFViewerApplication.open(file, args)`
Since the very early days of the viewer, it's been possible to pass in a `scale` when opening a PDF file. However, most of the time it was/is actually being ignored, which limits its usefulness considerably.
In older versions of the viewer, if a document hash was present (i.e. `PDFViewerApplication.initialBookmark` being set) or if the document existed in the `ViewHistory`, the `scale` passed to `PDFViewerApplication.open` would thus always be ignored.
In addition to the above, in the current viewer there's even more cases where the `scale` parameter will be ignored: if a (valid) browser history entry exists on document load, or if the `defaultZoomValue` preference is set to a non-default value.
Hence the result is that in most situation, a `scale` passed to `PDFViewerApplication.open` will be completely ignored.
A much better, not to mention supported, way of setting the initial scale is by using the `defaultZoomLevel` preference. In comparision, this also has the advantage of being used in situations where the `scale` would be ignored.
All in all this leads to the current situation where we have code which is essentially dead, since no part of the viewer (by default) relies on it.
To clean up this code, and to avoid having to pass (basically) unused parameters around, I'd thus like to remove the ability to pass a `scale` to `PDFViewerApplication.open`.
2017-08-24 16:24:32 +09:00
|
|
|
load(pdfDocument) {
|
2012-06-02 06:17:09 +09:00
|
|
|
this.pdfDocument = pdfDocument;
|
|
|
|
|
2017-05-09 20:17:39 +09:00
|
|
|
pdfDocument.getDownloadInfo().then(() => {
|
|
|
|
this.downloadComplete = true;
|
|
|
|
this.loadingBar.hide();
|
|
|
|
|
|
|
|
firstPagePromise.then(() => {
|
|
|
|
this.eventBus.dispatch('documentload', { source: this, });
|
|
|
|
});
|
2013-02-07 08:19:29 +09:00
|
|
|
});
|
2011-09-28 19:53:53 +09:00
|
|
|
|
2017-07-19 23:26:17 +09:00
|
|
|
// Since the `setInitialView` call below depends on this being resolved,
|
|
|
|
// fetch it early to avoid delaying initial rendering of the PDF document.
|
|
|
|
let pageModePromise = pdfDocument.getPageMode().catch(
|
|
|
|
function() { /* Avoid breaking initial rendering; ignoring errors. */ });
|
|
|
|
|
2016-11-19 03:50:29 +09:00
|
|
|
this.toolbar.setPagesCount(pdfDocument.numPages, false);
|
|
|
|
this.secondaryToolbar.setPagesCount(pdfDocument.numPages);
|
2012-10-11 02:26:41 +09:00
|
|
|
|
2017-05-09 20:17:39 +09:00
|
|
|
let id = this.documentFingerprint = pdfDocument.fingerprint;
|
|
|
|
let store = this.store = new ViewHistory(id);
|
2011-07-29 02:48:05 +09:00
|
|
|
|
2017-05-09 20:17:39 +09:00
|
|
|
let baseDocumentUrl;
|
2016-10-15 00:57:53 +09:00
|
|
|
if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {
|
|
|
|
baseDocumentUrl = null;
|
|
|
|
} else if (PDFJSDev.test('FIREFOX || MOZCENTRAL')) {
|
2016-10-01 19:05:07 +09:00
|
|
|
baseDocumentUrl = this.baseUrl;
|
2016-10-15 00:57:53 +09:00
|
|
|
} else if (PDFJSDev.test('CHROME')) {
|
|
|
|
baseDocumentUrl = location.href.split('#')[0];
|
|
|
|
}
|
2015-04-28 00:25:32 +09:00
|
|
|
this.pdfLinkService.setDocument(pdfDocument, baseDocumentUrl);
|
2017-05-05 21:04:08 +09:00
|
|
|
this.pdfDocumentProperties.setDocument(pdfDocument, this.url);
|
2015-04-28 00:25:32 +09:00
|
|
|
|
2017-05-09 20:17:39 +09:00
|
|
|
let pdfViewer = this.pdfViewer;
|
2014-09-15 23:49:24 +09:00
|
|
|
pdfViewer.setDocument(pdfDocument);
|
2017-05-09 20:17:39 +09:00
|
|
|
let firstPagePromise = pdfViewer.firstPagePromise;
|
|
|
|
let pagesPromise = pdfViewer.pagesPromise;
|
|
|
|
let onePageRendered = pdfViewer.onePageRendered;
|
2012-09-08 08:05:14 +09:00
|
|
|
|
2017-05-09 20:17:39 +09:00
|
|
|
let pdfThumbnailViewer = this.pdfThumbnailViewer;
|
2016-01-23 21:56:56 +09:00
|
|
|
pdfThumbnailViewer.setDocument(pdfDocument);
|
2012-04-10 14:20:57 +09:00
|
|
|
|
2017-04-22 20:42:41 +09:00
|
|
|
firstPagePromise.then((pdfPage) => {
|
2017-05-09 20:17:39 +09:00
|
|
|
this.loadingBar.setWidth(this.appConfig.viewerContainer);
|
2013-07-19 01:28:59 +09:00
|
|
|
|
2018-02-17 23:08:28 +09:00
|
|
|
if (!AppOptions.get('disableHistory') && !this.isViewerEmbedded) {
|
2014-09-22 20:41:17 +09:00
|
|
|
// The browsing history is only enabled when the viewer is standalone,
|
|
|
|
// i.e. not when it is embedded in a web page.
|
2018-02-17 23:08:28 +09:00
|
|
|
let resetHistory = !AppOptions.get('showPreviousViewOnLoad');
|
2017-07-14 21:24:32 +09:00
|
|
|
this.pdfHistory.initialize(id, resetHistory);
|
Re-write `PDFHistory` from scratch
This patch completely re-implements `PDFHistory` to get rid of various bugs currently present, and to hopefully make maintenance slightly easier. Most of the interface is similar to the existing one, but it should be somewhat simplified.
The new implementation should be more robust against failure, compared to the old one. Previously, it was too easy to end up in a state which basically caused the browser history to lock-up, preventing the user from navigating back/forward. (In the new implementation, the browser history should not be updated rather than breaking if things go wrong.)
Given that the code has to deal with various edge-cases, it's still not as simple as I would have liked, but it should now be somewhat easier to deal with.
The main source of complication in the code is actually that we allow the user to change the hash of a already loaded document (we'll no longer try to navigate back-and-forth in this case, since the next commit contains a workaround).
In the new code, there's also *a lot* more comments (perhaps too many?) to attempt to explain the logic. This is something that the old implementation was serverly lacking, which is a one of the reasons why it was so difficult to maintain.
One particular thing to note is that the new code uses the `pagehide` event rather than `beforeunload`, since the latter seems to be a bad idea based on https://bugzilla.mozilla.org/show_bug.cgi?id=1336763.
2017-07-16 20:39:39 +09:00
|
|
|
|
|
|
|
if (this.pdfHistory.initialBookmark) {
|
|
|
|
this.initialBookmark = this.pdfHistory.initialBookmark;
|
2017-08-21 18:56:49 +09:00
|
|
|
|
|
|
|
this.initialRotation = this.pdfHistory.initialRotation;
|
Re-write `PDFHistory` from scratch
This patch completely re-implements `PDFHistory` to get rid of various bugs currently present, and to hopefully make maintenance slightly easier. Most of the interface is similar to the existing one, but it should be somewhat simplified.
The new implementation should be more robust against failure, compared to the old one. Previously, it was too easy to end up in a state which basically caused the browser history to lock-up, preventing the user from navigating back/forward. (In the new implementation, the browser history should not be updated rather than breaking if things go wrong.)
Given that the code has to deal with various edge-cases, it's still not as simple as I would have liked, but it should now be somewhat easier to deal with.
The main source of complication in the code is actually that we allow the user to change the hash of a already loaded document (we'll no longer try to navigate back-and-forth in this case, since the next commit contains a workaround).
In the new code, there's also *a lot* more comments (perhaps too many?) to attempt to explain the logic. This is something that the old implementation was serverly lacking, which is a one of the reasons why it was so difficult to maintain.
One particular thing to note is that the new code uses the `pagehide` event rather than `beforeunload`, since the latter seems to be a bad idea based on https://bugzilla.mozilla.org/show_bug.cgi?id=1336763.
2017-07-16 20:39:39 +09:00
|
|
|
}
|
2014-09-22 20:41:17 +09:00
|
|
|
}
|
2013-03-09 11:08:37 +09:00
|
|
|
|
2017-05-09 20:17:39 +09:00
|
|
|
let initialParams = {
|
Re-write `PDFHistory` from scratch
This patch completely re-implements `PDFHistory` to get rid of various bugs currently present, and to hopefully make maintenance slightly easier. Most of the interface is similar to the existing one, but it should be somewhat simplified.
The new implementation should be more robust against failure, compared to the old one. Previously, it was too easy to end up in a state which basically caused the browser history to lock-up, preventing the user from navigating back/forward. (In the new implementation, the browser history should not be updated rather than breaking if things go wrong.)
Given that the code has to deal with various edge-cases, it's still not as simple as I would have liked, but it should now be somewhat easier to deal with.
The main source of complication in the code is actually that we allow the user to change the hash of a already loaded document (we'll no longer try to navigate back-and-forth in this case, since the next commit contains a workaround).
In the new code, there's also *a lot* more comments (perhaps too many?) to attempt to explain the logic. This is something that the old implementation was serverly lacking, which is a one of the reasons why it was so difficult to maintain.
One particular thing to note is that the new code uses the `pagehide` event rather than `beforeunload`, since the latter seems to be a bad idea based on https://bugzilla.mozilla.org/show_bug.cgi?id=1336763.
2017-07-16 20:39:39 +09:00
|
|
|
bookmark: null,
|
For documents with different page sizes, ensure that the correct page becomes visible on load when e.g. the 'page' hash parameter was provided (bug 1191279, issue 6393)
This issue is actually, in a sense, "caused" by the fact that the API/viewer supports partial loading/rendering. Previously when the *entire* document was always fetched before rendering begun, we knew all page sizes in advance and this issue didn't exist.
Now we use the size of *one* page in order to set the initial size of every page, until we've fetched the pages and thus know their correct sizes.
This means that during loading the size of the pages can change, which may cause the initial position to become scrolled out of view.
The most naive solution to this problem would perhaps be to delay setting the initial position on load for all documents, until all pages are fetched. However I think that would be a *really* bad idea, since doing so would make the initial rendering slower and make it feel sluggish for most documents.
Since there is generally no way of knowing if a document has different sized pages prior to loading it, we can only check once the pages are available.
Hence this patch, which treats documents with different sized pages as a special case, by re-applying the initial position when all pages have become available.
2015-08-06 00:35:41 +09:00
|
|
|
hash: null,
|
|
|
|
};
|
2017-07-19 23:04:56 +09:00
|
|
|
let storePromise = store.getMultiple({
|
|
|
|
exists: false,
|
|
|
|
page: '1',
|
|
|
|
zoom: DEFAULT_SCALE_VALUE,
|
|
|
|
scrollLeft: '0',
|
|
|
|
scrollTop: '0',
|
2017-08-21 18:22:07 +09:00
|
|
|
rotation: null,
|
2017-07-19 23:04:56 +09:00
|
|
|
sidebarView: SidebarView.NONE,
|
2018-05-15 12:10:33 +09:00
|
|
|
scrollMode: null,
|
|
|
|
spreadMode: null,
|
2017-07-19 23:26:17 +09:00
|
|
|
}).catch(() => { /* Unable to read from storage; ignoring errors. */ });
|
2017-07-19 23:04:56 +09:00
|
|
|
|
2017-07-19 23:26:17 +09:00
|
|
|
Promise.all([storePromise, pageModePromise]).then(
|
|
|
|
([values = {}, pageMode]) => {
|
2017-07-19 23:04:56 +09:00
|
|
|
// Initialize the default values, from user preferences.
|
2018-02-17 23:08:28 +09:00
|
|
|
let hash = AppOptions.get('defaultZoomValue') ?
|
|
|
|
('zoom=' + AppOptions.get('defaultZoomValue')) : null;
|
2017-08-21 18:22:07 +09:00
|
|
|
let rotation = null;
|
2018-02-17 23:08:28 +09:00
|
|
|
let sidebarView = AppOptions.get('sidebarViewOnLoad');
|
2018-05-15 12:10:33 +09:00
|
|
|
let scrollMode = AppOptions.get('scrollModeOnLoad');
|
|
|
|
let spreadMode = AppOptions.get('spreadModeOnLoad');
|
2017-07-19 23:04:56 +09:00
|
|
|
|
2018-02-17 23:08:28 +09:00
|
|
|
if (values.exists && AppOptions.get('showPreviousViewOnLoad')) {
|
2017-07-19 23:04:56 +09:00
|
|
|
hash = 'page=' + values.page +
|
2018-02-17 23:08:28 +09:00
|
|
|
'&zoom=' + (AppOptions.get('defaultZoomValue') || values.zoom) +
|
2017-04-22 20:42:41 +09:00
|
|
|
',' + values.scrollLeft + ',' + values.scrollTop;
|
2017-08-21 18:22:07 +09:00
|
|
|
rotation = parseInt(values.rotation, 10);
|
2017-07-19 23:04:56 +09:00
|
|
|
sidebarView = sidebarView || (values.sidebarView | 0);
|
2018-05-15 12:10:33 +09:00
|
|
|
if (values.scrollMode !== null) {
|
|
|
|
scrollMode = values.scrollMode;
|
|
|
|
}
|
|
|
|
if (values.spreadMode !== null) {
|
|
|
|
spreadMode = values.spreadMode;
|
|
|
|
}
|
2017-07-19 23:04:56 +09:00
|
|
|
}
|
2018-02-17 23:08:28 +09:00
|
|
|
if (pageMode && !AppOptions.get('disablePageMode')) {
|
2017-07-19 23:26:17 +09:00
|
|
|
// Always let the user preference/history take precedence.
|
|
|
|
sidebarView = sidebarView || apiPageModeToSidebarView(pageMode);
|
|
|
|
}
|
2017-07-19 23:04:56 +09:00
|
|
|
return {
|
|
|
|
hash,
|
2017-08-21 18:22:07 +09:00
|
|
|
rotation,
|
2017-07-19 23:04:56 +09:00
|
|
|
sidebarView,
|
2018-05-15 12:10:33 +09:00
|
|
|
scrollMode,
|
|
|
|
spreadMode,
|
2017-07-19 23:04:56 +09:00
|
|
|
};
|
2018-05-15 12:10:33 +09:00
|
|
|
}).then(({ hash, rotation, sidebarView, scrollMode, spreadMode, }) => {
|
Re-write `PDFHistory` from scratch
This patch completely re-implements `PDFHistory` to get rid of various bugs currently present, and to hopefully make maintenance slightly easier. Most of the interface is similar to the existing one, but it should be somewhat simplified.
The new implementation should be more robust against failure, compared to the old one. Previously, it was too easy to end up in a state which basically caused the browser history to lock-up, preventing the user from navigating back/forward. (In the new implementation, the browser history should not be updated rather than breaking if things go wrong.)
Given that the code has to deal with various edge-cases, it's still not as simple as I would have liked, but it should now be somewhat easier to deal with.
The main source of complication in the code is actually that we allow the user to change the hash of a already loaded document (we'll no longer try to navigate back-and-forth in this case, since the next commit contains a workaround).
In the new code, there's also *a lot* more comments (perhaps too many?) to attempt to explain the logic. This is something that the old implementation was serverly lacking, which is a one of the reasons why it was so difficult to maintain.
One particular thing to note is that the new code uses the `pagehide` event rather than `beforeunload`, since the latter seems to be a bad idea based on https://bugzilla.mozilla.org/show_bug.cgi?id=1336763.
2017-07-16 20:39:39 +09:00
|
|
|
initialParams.bookmark = this.initialBookmark;
|
2017-07-19 23:04:56 +09:00
|
|
|
initialParams.hash = hash;
|
For documents with different page sizes, ensure that the correct page becomes visible on load when e.g. the 'page' hash parameter was provided (bug 1191279, issue 6393)
This issue is actually, in a sense, "caused" by the fact that the API/viewer supports partial loading/rendering. Previously when the *entire* document was always fetched before rendering begun, we knew all page sizes in advance and this issue didn't exist.
Now we use the size of *one* page in order to set the initial size of every page, until we've fetched the pages and thus know their correct sizes.
This means that during loading the size of the pages can change, which may cause the initial position to become scrolled out of view.
The most naive solution to this problem would perhaps be to delay setting the initial position on load for all documents, until all pages are fetched. However I think that would be a *really* bad idea, since doing so would make the initial rendering slower and make it feel sluggish for most documents.
Since there is generally no way of knowing if a document has different sized pages prior to loading it, we can only check once the pages are available.
Hence this patch, which treats documents with different sized pages as a special case, by re-applying the initial position when all pages have become available.
2015-08-06 00:35:41 +09:00
|
|
|
|
2018-05-15 12:10:33 +09:00
|
|
|
this.setInitialView(hash, {
|
|
|
|
rotation, sidebarView, scrollMode, spreadMode,
|
|
|
|
});
|
Re-write `PDFHistory` from scratch
This patch completely re-implements `PDFHistory` to get rid of various bugs currently present, and to hopefully make maintenance slightly easier. Most of the interface is similar to the existing one, but it should be somewhat simplified.
The new implementation should be more robust against failure, compared to the old one. Previously, it was too easy to end up in a state which basically caused the browser history to lock-up, preventing the user from navigating back/forward. (In the new implementation, the browser history should not be updated rather than breaking if things go wrong.)
Given that the code has to deal with various edge-cases, it's still not as simple as I would have liked, but it should now be somewhat easier to deal with.
The main source of complication in the code is actually that we allow the user to change the hash of a already loaded document (we'll no longer try to navigate back-and-forth in this case, since the next commit contains a workaround).
In the new code, there's also *a lot* more comments (perhaps too many?) to attempt to explain the logic. This is something that the old implementation was serverly lacking, which is a one of the reasons why it was so difficult to maintain.
One particular thing to note is that the new code uses the `pagehide` event rather than `beforeunload`, since the latter seems to be a bad idea based on https://bugzilla.mozilla.org/show_bug.cgi?id=1336763.
2017-07-16 20:39:39 +09:00
|
|
|
|
2015-04-01 01:17:56 +09:00
|
|
|
// Make all navigation keys work on document load,
|
|
|
|
// unless the viewer is embedded in a web page.
|
2017-04-22 20:42:41 +09:00
|
|
|
if (!this.isViewerEmbedded) {
|
2017-06-29 19:14:26 +09:00
|
|
|
pdfViewer.focus();
|
2015-04-01 01:17:56 +09:00
|
|
|
}
|
2017-04-22 20:42:41 +09:00
|
|
|
return pagesPromise;
|
|
|
|
}).then(() => {
|
|
|
|
// For documents with different page sizes, once all pages are resolved,
|
|
|
|
// ensure that the correct location becomes visible on load.
|
2017-07-14 21:24:32 +09:00
|
|
|
if (!initialParams.bookmark && !initialParams.hash) {
|
For documents with different page sizes, ensure that the correct page becomes visible on load when e.g. the 'page' hash parameter was provided (bug 1191279, issue 6393)
This issue is actually, in a sense, "caused" by the fact that the API/viewer supports partial loading/rendering. Previously when the *entire* document was always fetched before rendering begun, we knew all page sizes in advance and this issue didn't exist.
Now we use the size of *one* page in order to set the initial size of every page, until we've fetched the pages and thus know their correct sizes.
This means that during loading the size of the pages can change, which may cause the initial position to become scrolled out of view.
The most naive solution to this problem would perhaps be to delay setting the initial position on load for all documents, until all pages are fetched. However I think that would be a *really* bad idea, since doing so would make the initial rendering slower and make it feel sluggish for most documents.
Since there is generally no way of knowing if a document has different sized pages prior to loading it, we can only check once the pages are available.
Hence this patch, which treats documents with different sized pages as a special case, by re-applying the initial position when all pages have become available.
2015-08-06 00:35:41 +09:00
|
|
|
return;
|
|
|
|
}
|
2017-07-09 19:43:57 +09:00
|
|
|
if (pdfViewer.hasEqualPageSizes) {
|
For documents with different page sizes, ensure that the correct page becomes visible on load when e.g. the 'page' hash parameter was provided (bug 1191279, issue 6393)
This issue is actually, in a sense, "caused" by the fact that the API/viewer supports partial loading/rendering. Previously when the *entire* document was always fetched before rendering begun, we knew all page sizes in advance and this issue didn't exist.
Now we use the size of *one* page in order to set the initial size of every page, until we've fetched the pages and thus know their correct sizes.
This means that during loading the size of the pages can change, which may cause the initial position to become scrolled out of view.
The most naive solution to this problem would perhaps be to delay setting the initial position on load for all documents, until all pages are fetched. However I think that would be a *really* bad idea, since doing so would make the initial rendering slower and make it feel sluggish for most documents.
Since there is generally no way of knowing if a document has different sized pages prior to loading it, we can only check once the pages are available.
Hence this patch, which treats documents with different sized pages as a special case, by re-applying the initial position when all pages have become available.
2015-08-06 00:35:41 +09:00
|
|
|
return;
|
|
|
|
}
|
2017-04-22 20:42:41 +09:00
|
|
|
this.initialBookmark = initialParams.bookmark;
|
For documents with different page sizes, ensure that the correct page becomes visible on load when e.g. the 'page' hash parameter was provided (bug 1191279, issue 6393)
This issue is actually, in a sense, "caused" by the fact that the API/viewer supports partial loading/rendering. Previously when the *entire* document was always fetched before rendering begun, we knew all page sizes in advance and this issue didn't exist.
Now we use the size of *one* page in order to set the initial size of every page, until we've fetched the pages and thus know their correct sizes.
This means that during loading the size of the pages can change, which may cause the initial position to become scrolled out of view.
The most naive solution to this problem would perhaps be to delay setting the initial position on load for all documents, until all pages are fetched. However I think that would be a *really* bad idea, since doing so would make the initial rendering slower and make it feel sluggish for most documents.
Since there is generally no way of knowing if a document has different sized pages prior to loading it, we can only check once the pages are available.
Hence this patch, which treats documents with different sized pages as a special case, by re-applying the initial position when all pages have become available.
2015-08-06 00:35:41 +09:00
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
pdfViewer.currentScaleValue = pdfViewer.currentScaleValue;
|
2017-04-22 20:42:41 +09:00
|
|
|
this.setInitialView(initialParams.hash);
|
2017-07-06 20:44:01 +09:00
|
|
|
}).then(function() {
|
|
|
|
// At this point, rendering of the initial page(s) should always have
|
|
|
|
// started (and may even have completed).
|
|
|
|
// To prevent any future issues, e.g. the document being completely
|
|
|
|
// blank on load, always trigger rendering here.
|
|
|
|
pdfViewer.update();
|
For documents with different page sizes, ensure that the correct page becomes visible on load when e.g. the 'page' hash parameter was provided (bug 1191279, issue 6393)
This issue is actually, in a sense, "caused" by the fact that the API/viewer supports partial loading/rendering. Previously when the *entire* document was always fetched before rendering begun, we knew all page sizes in advance and this issue didn't exist.
Now we use the size of *one* page in order to set the initial size of every page, until we've fetched the pages and thus know their correct sizes.
This means that during loading the size of the pages can change, which may cause the initial position to become scrolled out of view.
The most naive solution to this problem would perhaps be to delay setting the initial position on load for all documents, until all pages are fetched. However I think that would be a *really* bad idea, since doing so would make the initial rendering slower and make it feel sluggish for most documents.
Since there is generally no way of knowing if a document has different sized pages prior to loading it, we can only check once the pages are available.
Hence this patch, which treats documents with different sized pages as a special case, by re-applying the initial position when all pages have become available.
2015-08-06 00:35:41 +09:00
|
|
|
});
|
2013-03-09 11:08:37 +09:00
|
|
|
});
|
|
|
|
|
2017-05-09 20:17:39 +09:00
|
|
|
pdfDocument.getPageLabels().then((labels) => {
|
2018-02-17 23:08:28 +09:00
|
|
|
if (!labels || AppOptions.get('disablePageLabels')) {
|
2016-01-23 21:56:56 +09:00
|
|
|
return;
|
|
|
|
}
|
2017-05-09 20:17:39 +09:00
|
|
|
let i = 0, numLabels = labels.length;
|
|
|
|
if (numLabels !== this.pagesCount) {
|
2016-01-23 21:56:56 +09:00
|
|
|
console.error('The number of Page Labels does not match ' +
|
|
|
|
'the number of pages in the document.');
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Ignore page labels that correspond to standard page numbering.
|
|
|
|
while (i < numLabels && labels[i] === (i + 1).toString()) {
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
if (i === numLabels) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
pdfViewer.setPageLabels(labels);
|
|
|
|
pdfThumbnailViewer.setPageLabels(labels);
|
|
|
|
|
2016-11-19 03:50:29 +09:00
|
|
|
// Changing toolbar page display to use labels and we need to set
|
|
|
|
// the label of the current page.
|
2017-05-09 20:17:39 +09:00
|
|
|
this.toolbar.setPagesCount(pdfDocument.numPages, true);
|
|
|
|
this.toolbar.setPageNumber(pdfViewer.currentPageNumber,
|
2016-11-19 03:50:29 +09:00
|
|
|
pdfViewer.currentPageLabel);
|
2016-01-23 21:56:56 +09:00
|
|
|
});
|
|
|
|
|
2017-05-09 20:17:39 +09:00
|
|
|
pagesPromise.then(() => {
|
|
|
|
if (!this.supportsPrinting) {
|
|
|
|
return;
|
2013-03-01 08:29:07 +09:00
|
|
|
}
|
2017-05-09 20:17:39 +09:00
|
|
|
pdfDocument.getJavaScript().then((javaScript) => {
|
2017-10-16 05:13:58 +09:00
|
|
|
if (!javaScript) {
|
Only warn about unsupported JavaScript, in the viewer, when non-empty actions exist (issue 5767)
Some PDF files contain JavaScript actions that consist of nothing more that one, or possibly several, empty string(s). At least to me, printing a warning/showing the fallback seems completely unnecessary in that case.
Furthermore, this patch also makes use of an early `return`, so that we no longer will attempt to check for printing instructions when no JavaScript is present in the PDF file.
*Note:* It would perhaps make sense to change the API/core code, such that we ignore empty entries there instead. However, that would probably be considered a breaking changing with respect to backwards compatibility, hence this simple viewer only solution.
Fixes 5767.
2017-10-08 21:06:33 +09:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
javaScript.some((js) => {
|
|
|
|
if (!js) { // Don't warn/fallback for empty JavaScript actions.
|
|
|
|
return false;
|
|
|
|
}
|
2017-05-09 20:17:39 +09:00
|
|
|
console.warn('Warning: JavaScript is not supported');
|
|
|
|
this.fallback(UNSUPPORTED_FEATURES.javaScript);
|
Only warn about unsupported JavaScript, in the viewer, when non-empty actions exist (issue 5767)
Some PDF files contain JavaScript actions that consist of nothing more that one, or possibly several, empty string(s). At least to me, printing a warning/showing the fallback seems completely unnecessary in that case.
Furthermore, this patch also makes use of an early `return`, so that we no longer will attempt to check for printing instructions when no JavaScript is present in the PDF file.
*Note:* It would perhaps make sense to change the API/core code, such that we ignore empty entries there instead. However, that would probably be considered a breaking changing with respect to backwards compatibility, hence this simple viewer only solution.
Fixes 5767.
2017-10-08 21:06:33 +09:00
|
|
|
return true;
|
|
|
|
});
|
|
|
|
|
2017-05-09 20:17:39 +09:00
|
|
|
// Hack to support auto printing.
|
|
|
|
let regex = /\bprint\s*\(/;
|
|
|
|
for (let i = 0, ii = javaScript.length; i < ii; i++) {
|
|
|
|
let js = javaScript[i];
|
|
|
|
if (js && regex.test(js)) {
|
|
|
|
setTimeout(function() {
|
|
|
|
window.print();
|
|
|
|
});
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2012-04-10 14:20:57 +09:00
|
|
|
});
|
2011-12-01 10:04:45 +09:00
|
|
|
|
2017-05-09 20:17:39 +09:00
|
|
|
Promise.all([onePageRendered, animationStarted]).then(() => {
|
|
|
|
pdfDocument.getOutline().then((outline) => {
|
|
|
|
this.pdfOutlineViewer.render({ outline, });
|
2012-04-10 14:20:57 +09:00
|
|
|
});
|
2017-05-09 20:17:39 +09:00
|
|
|
pdfDocument.getAttachments().then((attachments) => {
|
|
|
|
this.pdfAttachmentViewer.render({ attachments, });
|
2014-03-19 05:32:47 +09:00
|
|
|
});
|
2012-04-10 14:20:57 +09:00
|
|
|
});
|
|
|
|
|
2018-01-13 17:01:50 +09:00
|
|
|
pdfDocument.getMetadata().then(
|
2018-01-17 00:24:36 +09:00
|
|
|
({ info, metadata, contentDispositionFilename, }) => {
|
2017-05-09 20:17:39 +09:00
|
|
|
this.documentInfo = info;
|
|
|
|
this.metadata = metadata;
|
2018-01-17 00:24:36 +09:00
|
|
|
this.contentDispositionFilename = contentDispositionFilename;
|
2012-04-10 14:20:57 +09:00
|
|
|
|
2012-11-06 02:12:17 +09:00
|
|
|
// Provides some basic debug information
|
|
|
|
console.log('PDF ' + pdfDocument.fingerprint + ' [' +
|
2014-04-10 19:20:39 +09:00
|
|
|
info.PDFFormatVersion + ' ' + (info.Producer || '-').trim() +
|
|
|
|
' / ' + (info.Creator || '-').trim() + ']' +
|
2017-03-28 17:15:02 +09:00
|
|
|
' (PDF.js: ' + (version || '-') +
|
2018-02-17 23:08:28 +09:00
|
|
|
(AppOptions.get('enableWebGL') ? ' [WebGL]' : '') + ')');
|
2012-11-06 02:12:17 +09:00
|
|
|
|
2017-05-09 20:17:39 +09:00
|
|
|
let pdfTitle;
|
2014-03-09 20:20:32 +09:00
|
|
|
if (metadata && metadata.has('dc:title')) {
|
2017-05-09 20:17:39 +09:00
|
|
|
let title = metadata.get('dc:title');
|
2014-09-11 10:05:04 +09:00
|
|
|
// Ghostscript sometimes return 'Untitled', sets the title to 'Untitled'
|
|
|
|
if (title !== 'Untitled') {
|
|
|
|
pdfTitle = title;
|
|
|
|
}
|
2012-04-10 14:20:57 +09:00
|
|
|
}
|
2011-10-02 03:54:37 +09:00
|
|
|
|
2014-03-09 20:20:32 +09:00
|
|
|
if (!pdfTitle && info && info['Title']) {
|
2012-04-10 14:20:57 +09:00
|
|
|
pdfTitle = info['Title'];
|
2014-03-09 20:20:32 +09:00
|
|
|
}
|
2012-04-10 14:20:57 +09:00
|
|
|
|
2014-03-09 20:20:32 +09:00
|
|
|
if (pdfTitle) {
|
2018-01-17 00:24:36 +09:00
|
|
|
this.setTitle(
|
|
|
|
`${pdfTitle} - ${contentDispositionFilename || document.title}`);
|
|
|
|
} else if (contentDispositionFilename) {
|
|
|
|
this.setTitle(contentDispositionFilename);
|
2018-01-13 17:01:50 +09:00
|
|
|
}
|
|
|
|
|
2013-02-01 06:46:44 +09:00
|
|
|
if (info.IsAcroFormPresent) {
|
2013-03-17 00:13:08 +09:00
|
|
|
console.warn('Warning: AcroForm/XFA is not supported');
|
2017-05-09 20:17:39 +09:00
|
|
|
this.fallback(UNSUPPORTED_FEATURES.forms);
|
2013-02-01 06:46:44 +09:00
|
|
|
}
|
2013-08-16 23:53:05 +09:00
|
|
|
|
2016-10-15 00:57:53 +09:00
|
|
|
if (typeof PDFJSDev !== 'undefined' &&
|
|
|
|
PDFJSDev.test('FIREFOX || MOZCENTRAL')) {
|
2017-05-09 20:17:39 +09:00
|
|
|
let versionId = String(info.PDFFormatVersion).slice(-1) | 0;
|
|
|
|
let generatorId = 0;
|
|
|
|
const KNOWN_GENERATORS = [
|
2016-10-15 00:57:53 +09:00
|
|
|
'acrobat distiller', 'acrobat pdfwriter', 'adobe livecycle',
|
|
|
|
'adobe pdf library', 'adobe photoshop', 'ghostscript', 'tcpdf',
|
|
|
|
'cairo', 'dvipdfm', 'dvips', 'pdftex', 'pdfkit', 'itext', 'prince',
|
|
|
|
'quarkxpress', 'mac os x', 'microsoft', 'openoffice', 'oracle',
|
|
|
|
'luradocument', 'pdf-xchange', 'antenna house', 'aspose.cells', 'fpdf'
|
|
|
|
];
|
|
|
|
if (info.Producer) {
|
|
|
|
KNOWN_GENERATORS.some(function (generator, s, i) {
|
2018-02-11 01:06:03 +09:00
|
|
|
if (!generator.includes(s)) {
|
2016-10-15 00:57:53 +09:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
generatorId = i + 1;
|
|
|
|
return true;
|
|
|
|
}.bind(null, info.Producer.toLowerCase()));
|
|
|
|
}
|
2017-05-09 20:17:39 +09:00
|
|
|
let formType = !info.IsAcroFormPresent ? null : info.IsXFAPresent ?
|
2016-10-15 00:57:53 +09:00
|
|
|
'xfa' : 'acroform';
|
2017-05-09 20:17:39 +09:00
|
|
|
this.externalServices.reportTelemetry({
|
2016-10-15 00:57:53 +09:00
|
|
|
type: 'documentInfo',
|
|
|
|
version: versionId,
|
|
|
|
generator: generatorId,
|
2017-04-28 19:02:42 +09:00
|
|
|
formType,
|
2016-10-15 00:57:53 +09:00
|
|
|
});
|
2015-04-26 08:49:37 +09:00
|
|
|
}
|
2012-04-10 14:20:57 +09:00
|
|
|
});
|
|
|
|
},
|
|
|
|
|
2018-05-15 12:10:33 +09:00
|
|
|
setInitialView(storedHash, values = {}) {
|
|
|
|
let { rotation, sidebarView, scrollMode, spreadMode, } = values;
|
2017-08-21 18:22:07 +09:00
|
|
|
let setRotation = (angle) => {
|
|
|
|
if (isValidRotation(angle)) {
|
|
|
|
this.pdfViewer.pagesRotation = angle;
|
|
|
|
}
|
|
|
|
};
|
2018-05-15 12:10:33 +09:00
|
|
|
|
|
|
|
// Putting these before isInitialViewSet = true prevents these values from
|
|
|
|
// being stored in the document history (and overriding any future changes
|
|
|
|
// made to the corresponding global preferences), just this once.
|
2018-05-15 12:10:33 +09:00
|
|
|
if (Number.isInteger(scrollMode)) {
|
|
|
|
this.pdfViewer.setScrollMode(scrollMode);
|
|
|
|
}
|
|
|
|
if (Number.isInteger(spreadMode)) {
|
|
|
|
this.pdfViewer.setSpreadMode(spreadMode);
|
|
|
|
}
|
|
|
|
|
2014-09-22 20:41:17 +09:00
|
|
|
this.isInitialViewSet = true;
|
2017-04-22 20:42:41 +09:00
|
|
|
this.pdfSidebar.setInitialView(sidebarView);
|
2016-02-22 01:54:23 +09:00
|
|
|
|
2017-07-14 21:24:32 +09:00
|
|
|
if (this.initialBookmark) {
|
2017-08-21 18:56:49 +09:00
|
|
|
setRotation(this.initialRotation);
|
|
|
|
delete this.initialRotation;
|
|
|
|
|
2015-04-28 00:25:32 +09:00
|
|
|
this.pdfLinkService.setHash(this.initialBookmark);
|
2011-10-02 03:54:37 +09:00
|
|
|
this.initialBookmark = null;
|
2013-05-16 07:31:17 +09:00
|
|
|
} else if (storedHash) {
|
2017-08-21 18:22:07 +09:00
|
|
|
setRotation(rotation);
|
|
|
|
|
2015-04-28 00:25:32 +09:00
|
|
|
this.pdfLinkService.setHash(storedHash);
|
2011-12-29 10:18:55 +09:00
|
|
|
}
|
2012-01-26 12:52:10 +09:00
|
|
|
|
2016-11-19 03:50:29 +09:00
|
|
|
// Ensure that the correct page number is displayed in the UI,
|
|
|
|
// even if the active page didn't change during document load.
|
|
|
|
this.toolbar.setPageNumber(this.pdfViewer.currentPageNumber,
|
|
|
|
this.pdfViewer.currentPageLabel);
|
|
|
|
this.secondaryToolbar.setPageNumber(this.pdfViewer.currentPageNumber);
|
|
|
|
|
2015-03-15 04:07:17 +09:00
|
|
|
if (!this.pdfViewer.currentScaleValue) {
|
2012-01-26 12:52:10 +09:00
|
|
|
// Scale was not initialized: invalid bookmark or scale was not specified.
|
|
|
|
// Setting the default one.
|
2015-07-11 18:47:45 +09:00
|
|
|
this.pdfViewer.currentScaleValue = DEFAULT_SCALE_VALUE;
|
2012-01-26 12:52:10 +09:00
|
|
|
}
|
2011-10-02 03:54:37 +09:00
|
|
|
},
|
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
cleanup() {
|
2015-10-23 22:49:02 +09:00
|
|
|
if (!this.pdfDocument) {
|
|
|
|
return; // run cleanup when document is loaded
|
|
|
|
}
|
2014-09-13 11:27:45 +09:00
|
|
|
this.pdfViewer.cleanup();
|
2014-09-13 04:48:44 +09:00
|
|
|
this.pdfThumbnailViewer.cleanup();
|
2016-11-19 04:03:49 +09:00
|
|
|
|
|
|
|
// We don't want to remove fonts used by active page SVGs.
|
|
|
|
if (this.pdfViewer.renderer !== RendererType.SVG) {
|
|
|
|
this.pdfDocument.cleanup();
|
|
|
|
}
|
2012-06-19 01:48:47 +09:00
|
|
|
},
|
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
forceRendering() {
|
2014-09-16 01:18:28 +09:00
|
|
|
this.pdfRenderingQueue.printing = this.printing;
|
2016-02-22 01:54:23 +09:00
|
|
|
this.pdfRenderingQueue.isThumbnailViewEnabled =
|
|
|
|
this.pdfSidebar.isThumbnailViewVisible;
|
2014-09-16 01:18:28 +09:00
|
|
|
this.pdfRenderingQueue.renderHighestPriority();
|
2012-06-19 01:48:47 +09:00
|
|
|
},
|
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
beforePrint() {
|
2016-10-08 21:36:55 +09:00
|
|
|
if (this.printService) {
|
|
|
|
// There is no way to suppress beforePrint/afterPrint events,
|
|
|
|
// but PDFPrintService may generate double events -- this will ignore
|
|
|
|
// the second event that will be coming from native window.print().
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-06-29 01:50:25 +09:00
|
|
|
if (!this.supportsPrinting) {
|
2017-05-04 10:05:53 +09:00
|
|
|
this.l10n.get('printing_not_supported', null,
|
|
|
|
'Warning: Printing is not fully supported by ' +
|
|
|
|
'this browser.').then((printMessage) => {
|
|
|
|
this.error(printMessage);
|
|
|
|
});
|
2012-06-29 01:50:25 +09:00
|
|
|
return;
|
|
|
|
}
|
2013-03-09 11:08:37 +09:00
|
|
|
|
2016-10-07 06:46:30 +09:00
|
|
|
// The beforePrint is a sync method and we need to know layout before
|
|
|
|
// returning from this method. Ensure that we can get sizes of the pages.
|
|
|
|
if (!this.pdfViewer.pageViewsReady) {
|
2017-05-04 10:05:53 +09:00
|
|
|
this.l10n.get('printing_not_ready', null,
|
|
|
|
'Warning: The PDF is not fully loaded for printing.').
|
|
|
|
then((notReadyMessage) => {
|
|
|
|
window.alert(notReadyMessage);
|
|
|
|
});
|
2013-03-09 11:08:37 +09:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
let pagesOverview = this.pdfViewer.getPagesOverview();
|
|
|
|
let printContainer = this.appConfig.printContainer;
|
|
|
|
let printService = PDFPrintServiceFactory.instance.createPrintService(
|
2017-05-04 10:05:53 +09:00
|
|
|
this.pdfDocument, pagesOverview, printContainer, this.l10n);
|
2016-10-07 06:46:30 +09:00
|
|
|
this.printService = printService;
|
2014-09-16 01:18:28 +09:00
|
|
|
this.forceRendering();
|
2014-06-25 07:23:42 +09:00
|
|
|
|
2016-10-07 06:46:30 +09:00
|
|
|
printService.layout();
|
2014-06-15 05:55:21 +09:00
|
|
|
|
2016-10-15 00:57:53 +09:00
|
|
|
if (typeof PDFJSDev !== 'undefined' &&
|
|
|
|
PDFJSDev.test('FIREFOX || MOZCENTRAL')) {
|
|
|
|
this.externalServices.reportTelemetry({
|
Fix inconsistent spacing and trailing commas in objects in `web/` files, so we can enable the `comma-dangle` and `object-curly-spacing` ESLint rules later on
http://eslint.org/docs/rules/comma-dangle
http://eslint.org/docs/rules/object-curly-spacing
Given that we currently have quite inconsistent object formatting, fixing this in in *one* big patch probably wouldn't be feasible (since I cannot imagine anyone wanting to review that); hence I've opted to try and do this piecewise instead.
*Please note:* This patch was created automatically, using the ESLint `--fix` command line option. In a couple of places this caused lines to become too long, and I've fixed those manually; please refer to the interdiff below for the only hand-edits in this patch.
```diff
diff --git a/web/pdf_thumbnail_view.js b/web/pdf_thumbnail_view.js
index 002dbf29..1de4e530 100644
--- a/web/pdf_thumbnail_view.js
+++ b/web/pdf_thumbnail_view.js
@@ -420,8 +420,8 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() {
setPageLabel: function PDFThumbnailView_setPageLabel(label) {
this.pageLabel = (typeof label === 'string' ? label : null);
- this.l10n.get('thumb_page_title', { page: this.pageId, }, 'Page {{page}}').
- then((msg) => {
+ this.l10n.get('thumb_page_title', { page: this.pageId, },
+ 'Page {{page}}').then((msg) => {
this.anchor.title = msg;
});
diff --git a/web/secondary_toolbar.js b/web/secondary_toolbar.js
index 160e0410..6495fc5e 100644
--- a/web/secondary_toolbar.js
+++ b/web/secondary_toolbar.js
@@ -65,7 +65,8 @@ class SecondaryToolbar {
{ element: options.printButton, eventName: 'print', close: true, },
{ element: options.downloadButton, eventName: 'download', close: true, },
{ element: options.viewBookmarkButton, eventName: null, close: true, },
- { element: options.firstPageButton, eventName: 'firstpage', close: true, },
+ { element: options.firstPageButton, eventName: 'firstpage',
+ close: true, },
{ element: options.lastPageButton, eventName: 'lastpage', close: true, },
{ element: options.pageRotateCwButton, eventName: 'rotatecw',
close: false, },
@@ -76,7 +77,7 @@ class SecondaryToolbar {
{ element: options.cursorHandToolButton, eventName: 'switchcursortool',
eventDetails: { tool: CursorTool.HAND, }, close: true, },
{ element: options.documentPropertiesButton,
- eventName: 'documentproperties', close: true, }
+ eventName: 'documentproperties', close: true, },
];
this.items = {
firstPage: options.firstPageButton,
```
2017-06-01 19:46:12 +09:00
|
|
|
type: 'print',
|
2016-10-15 00:57:53 +09:00
|
|
|
});
|
2015-04-30 02:09:58 +09:00
|
|
|
}
|
2012-06-29 01:50:25 +09:00
|
|
|
},
|
|
|
|
|
|
|
|
afterPrint: function pdfViewSetupAfterPrint() {
|
2016-10-07 06:46:30 +09:00
|
|
|
if (this.printService) {
|
|
|
|
this.printService.destroy();
|
|
|
|
this.printService = null;
|
2014-03-09 20:20:32 +09:00
|
|
|
}
|
2014-09-16 01:18:28 +09:00
|
|
|
this.forceRendering();
|
2012-07-31 00:12:49 +09:00
|
|
|
},
|
|
|
|
|
2017-06-17 20:14:36 +09:00
|
|
|
rotatePages(delta) {
|
|
|
|
if (!this.pdfDocument) {
|
|
|
|
return;
|
|
|
|
}
|
2017-08-19 21:23:40 +09:00
|
|
|
let newRotation = (this.pdfViewer.pagesRotation + 360 + delta) % 360;
|
|
|
|
this.pdfViewer.pagesRotation = newRotation;
|
|
|
|
// Note that the thumbnail viewer is updated, and rendering is triggered,
|
|
|
|
// in the 'rotationchanging' event handler.
|
2012-09-14 05:23:44 +09:00
|
|
|
},
|
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
requestPresentationMode() {
|
2015-02-04 02:09:11 +09:00
|
|
|
if (!this.pdfPresentationMode) {
|
2015-01-29 21:37:49 +09:00
|
|
|
return;
|
|
|
|
}
|
2015-02-04 02:09:11 +09:00
|
|
|
this.pdfPresentationMode.request();
|
2015-01-29 21:37:49 +09:00
|
|
|
},
|
|
|
|
|
2017-06-14 04:11:29 +09:00
|
|
|
bindEvents() {
|
2017-06-29 19:14:26 +09:00
|
|
|
let { eventBus, _boundEvents, } = this;
|
2017-06-14 04:11:29 +09:00
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
_boundEvents.beforePrint = this.beforePrint.bind(this);
|
|
|
|
_boundEvents.afterPrint = this.afterPrint.bind(this);
|
2016-04-26 07:57:15 +09:00
|
|
|
|
|
|
|
eventBus.on('resize', webViewerResize);
|
|
|
|
eventBus.on('hashchange', webViewerHashchange);
|
2017-06-29 19:14:26 +09:00
|
|
|
eventBus.on('beforeprint', _boundEvents.beforePrint);
|
|
|
|
eventBus.on('afterprint', _boundEvents.afterPrint);
|
2016-04-26 07:57:15 +09:00
|
|
|
eventBus.on('pagerendered', webViewerPageRendered);
|
|
|
|
eventBus.on('textlayerrendered', webViewerTextLayerRendered);
|
|
|
|
eventBus.on('updateviewarea', webViewerUpdateViewarea);
|
2016-04-30 00:05:04 +09:00
|
|
|
eventBus.on('pagechanging', webViewerPageChanging);
|
|
|
|
eventBus.on('scalechanging', webViewerScaleChanging);
|
2017-08-19 21:23:40 +09:00
|
|
|
eventBus.on('rotationchanging', webViewerRotationChanging);
|
2016-04-26 07:57:15 +09:00
|
|
|
eventBus.on('sidebarviewchanged', webViewerSidebarViewChanged);
|
|
|
|
eventBus.on('pagemode', webViewerPageMode);
|
|
|
|
eventBus.on('namedaction', webViewerNamedAction);
|
|
|
|
eventBus.on('presentationmodechanged', webViewerPresentationModeChanged);
|
2016-04-29 05:04:09 +09:00
|
|
|
eventBus.on('presentationmode', webViewerPresentationMode);
|
|
|
|
eventBus.on('openfile', webViewerOpenFile);
|
|
|
|
eventBus.on('print', webViewerPrint);
|
|
|
|
eventBus.on('download', webViewerDownload);
|
|
|
|
eventBus.on('firstpage', webViewerFirstPage);
|
|
|
|
eventBus.on('lastpage', webViewerLastPage);
|
2016-11-19 03:50:29 +09:00
|
|
|
eventBus.on('nextpage', webViewerNextPage);
|
|
|
|
eventBus.on('previouspage', webViewerPreviousPage);
|
|
|
|
eventBus.on('zoomin', webViewerZoomIn);
|
|
|
|
eventBus.on('zoomout', webViewerZoomOut);
|
|
|
|
eventBus.on('pagenumberchanged', webViewerPageNumberChanged);
|
|
|
|
eventBus.on('scalechanged', webViewerScaleChanged);
|
2016-04-29 05:04:09 +09:00
|
|
|
eventBus.on('rotatecw', webViewerRotateCw);
|
|
|
|
eventBus.on('rotateccw', webViewerRotateCcw);
|
2018-05-15 12:10:32 +09:00
|
|
|
eventBus.on('switchscrollmode', webViewerSwitchScrollMode);
|
2018-05-15 12:10:33 +09:00
|
|
|
eventBus.on('scrollmodechanged', webViewerScrollModeChanged);
|
2018-05-15 12:10:32 +09:00
|
|
|
eventBus.on('switchspreadmode', webViewerSwitchSpreadMode);
|
2018-05-15 12:10:33 +09:00
|
|
|
eventBus.on('spreadmodechanged', webViewerSpreadModeChanged);
|
2016-04-29 05:04:09 +09:00
|
|
|
eventBus.on('documentproperties', webViewerDocumentProperties);
|
2016-04-28 21:11:40 +09:00
|
|
|
eventBus.on('find', webViewerFind);
|
2016-05-26 22:24:58 +09:00
|
|
|
eventBus.on('findfromurlhash', webViewerFindFromUrlHash);
|
2016-10-15 00:57:53 +09:00
|
|
|
if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {
|
|
|
|
eventBus.on('fileinputchange', webViewerFileInputChange);
|
|
|
|
}
|
2016-12-09 00:28:40 +09:00
|
|
|
},
|
|
|
|
|
2017-06-14 04:11:29 +09:00
|
|
|
bindWindowEvents() {
|
2017-06-29 19:14:26 +09:00
|
|
|
let { eventBus, _boundEvents, } = this;
|
2016-12-09 00:28:40 +09:00
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
_boundEvents.windowResize = () => {
|
Implement sidebar resizing for modern browsers, by utilizing CSS variables (issue 2072)
By making use of modern CSS features, in this case [CSS variables](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables), implementing sidebar resizing is actually quite simple. Not only will the amount of added code be fairly small, but it should also be easy to maintain since there's no need for complicated JavaScript hacks in order to update the CSS. Another benefit is that the JavaScript code doesn't need to make detailed assumptions about the exact structure of the HTML/CSS code.
Obviously this will not work in older browsers, such as IE, that lack support for CSS variables. In those cases sidebar resizing is simply disabled (via feature detection), and the resizing DOM element hidden, and the behaviour is thus *identical* to the current (fixed-width) sidebar.
However, considering the simplicity of the implementation, I really don't see why limiting this feature to "modern" browsers is a problem.
Finally, note that a few edge-cases meant that the patch is a bit larger than what the basic functionality would dictate. Among those is first of all proper RTL support, and secondly (automatic) resizing of the sidebar when the width of the *entire* viewer changes. Another, pre-existing, issue fixed here is the incomplete interface of `NullL10n`.
*Please note:* This patch has been successfully tested in both LTR and RTL viewer locales, in recent versions of Firefox and Chrome.
Fixes 2072.
2017-10-10 23:16:05 +09:00
|
|
|
eventBus.dispatch('resize', { source: window, });
|
2017-06-14 04:11:29 +09:00
|
|
|
};
|
2017-06-29 19:14:26 +09:00
|
|
|
_boundEvents.windowHashChange = () => {
|
2016-12-09 00:28:40 +09:00
|
|
|
eventBus.dispatch('hashchange', {
|
|
|
|
hash: document.location.hash.substring(1),
|
|
|
|
});
|
2017-06-14 04:11:29 +09:00
|
|
|
};
|
2017-06-29 19:14:26 +09:00
|
|
|
_boundEvents.windowBeforePrint = () => {
|
2016-12-09 00:28:40 +09:00
|
|
|
eventBus.dispatch('beforeprint');
|
2017-06-14 04:11:29 +09:00
|
|
|
};
|
2017-06-29 19:14:26 +09:00
|
|
|
_boundEvents.windowAfterPrint = () => {
|
2016-12-09 00:28:40 +09:00
|
|
|
eventBus.dispatch('afterprint');
|
2017-06-14 04:11:29 +09:00
|
|
|
};
|
|
|
|
|
|
|
|
window.addEventListener('wheel', webViewerWheel);
|
|
|
|
window.addEventListener('click', webViewerClick);
|
|
|
|
window.addEventListener('keydown', webViewerKeyDown);
|
2017-06-29 19:14:26 +09:00
|
|
|
window.addEventListener('resize', _boundEvents.windowResize);
|
|
|
|
window.addEventListener('hashchange', _boundEvents.windowHashChange);
|
|
|
|
window.addEventListener('beforeprint', _boundEvents.windowBeforePrint);
|
|
|
|
window.addEventListener('afterprint', _boundEvents.windowAfterPrint);
|
2017-06-14 04:11:29 +09:00
|
|
|
},
|
|
|
|
|
|
|
|
unbindEvents() {
|
2017-06-29 19:14:26 +09:00
|
|
|
let { eventBus, _boundEvents, } = this;
|
2017-06-14 04:11:29 +09:00
|
|
|
|
|
|
|
eventBus.off('resize', webViewerResize);
|
|
|
|
eventBus.off('hashchange', webViewerHashchange);
|
2017-06-29 19:14:26 +09:00
|
|
|
eventBus.off('beforeprint', _boundEvents.beforePrint);
|
|
|
|
eventBus.off('afterprint', _boundEvents.afterPrint);
|
2017-06-14 04:11:29 +09:00
|
|
|
eventBus.off('pagerendered', webViewerPageRendered);
|
|
|
|
eventBus.off('textlayerrendered', webViewerTextLayerRendered);
|
|
|
|
eventBus.off('updateviewarea', webViewerUpdateViewarea);
|
|
|
|
eventBus.off('pagechanging', webViewerPageChanging);
|
|
|
|
eventBus.off('scalechanging', webViewerScaleChanging);
|
2017-08-19 21:23:40 +09:00
|
|
|
eventBus.off('rotationchanging', webViewerRotationChanging);
|
2017-06-14 04:11:29 +09:00
|
|
|
eventBus.off('sidebarviewchanged', webViewerSidebarViewChanged);
|
|
|
|
eventBus.off('pagemode', webViewerPageMode);
|
|
|
|
eventBus.off('namedaction', webViewerNamedAction);
|
|
|
|
eventBus.off('presentationmodechanged', webViewerPresentationModeChanged);
|
|
|
|
eventBus.off('presentationmode', webViewerPresentationMode);
|
|
|
|
eventBus.off('openfile', webViewerOpenFile);
|
|
|
|
eventBus.off('print', webViewerPrint);
|
|
|
|
eventBus.off('download', webViewerDownload);
|
|
|
|
eventBus.off('firstpage', webViewerFirstPage);
|
|
|
|
eventBus.off('lastpage', webViewerLastPage);
|
|
|
|
eventBus.off('nextpage', webViewerNextPage);
|
|
|
|
eventBus.off('previouspage', webViewerPreviousPage);
|
|
|
|
eventBus.off('zoomin', webViewerZoomIn);
|
|
|
|
eventBus.off('zoomout', webViewerZoomOut);
|
|
|
|
eventBus.off('pagenumberchanged', webViewerPageNumberChanged);
|
|
|
|
eventBus.off('scalechanged', webViewerScaleChanged);
|
|
|
|
eventBus.off('rotatecw', webViewerRotateCw);
|
|
|
|
eventBus.off('rotateccw', webViewerRotateCcw);
|
2018-05-15 12:10:32 +09:00
|
|
|
eventBus.off('switchscrollmode', webViewerSwitchScrollMode);
|
2018-05-15 12:10:33 +09:00
|
|
|
eventBus.off('scrollmodechanged', webViewerScrollModeChanged);
|
2018-05-15 12:10:32 +09:00
|
|
|
eventBus.off('switchspreadmode', webViewerSwitchSpreadMode);
|
2018-05-15 12:10:33 +09:00
|
|
|
eventBus.off('spreadmodechanged', webViewerSpreadModeChanged);
|
2017-06-14 04:11:29 +09:00
|
|
|
eventBus.off('documentproperties', webViewerDocumentProperties);
|
|
|
|
eventBus.off('find', webViewerFind);
|
|
|
|
eventBus.off('findfromurlhash', webViewerFindFromUrlHash);
|
|
|
|
if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {
|
|
|
|
eventBus.off('fileinputchange', webViewerFileInputChange);
|
2016-12-09 00:28:40 +09:00
|
|
|
}
|
2017-06-14 04:11:29 +09:00
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
_boundEvents.beforePrint = null;
|
|
|
|
_boundEvents.afterPrint = null;
|
2017-06-14 04:11:29 +09:00
|
|
|
},
|
|
|
|
|
|
|
|
unbindWindowEvents() {
|
2017-06-29 19:14:26 +09:00
|
|
|
let { _boundEvents, } = this;
|
|
|
|
|
2017-06-14 04:11:29 +09:00
|
|
|
window.removeEventListener('wheel', webViewerWheel);
|
|
|
|
window.removeEventListener('click', webViewerClick);
|
|
|
|
window.removeEventListener('keydown', webViewerKeyDown);
|
2017-06-29 19:14:26 +09:00
|
|
|
window.removeEventListener('resize', _boundEvents.windowResize);
|
|
|
|
window.removeEventListener('hashchange', _boundEvents.windowHashChange);
|
|
|
|
window.removeEventListener('beforeprint', _boundEvents.windowBeforePrint);
|
|
|
|
window.removeEventListener('afterprint', _boundEvents.windowAfterPrint);
|
2017-06-14 04:11:29 +09:00
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
_boundEvents.windowResize = null;
|
|
|
|
_boundEvents.windowHashChange = null;
|
|
|
|
_boundEvents.windowBeforePrint = null;
|
|
|
|
_boundEvents.windowAfterPrint = null;
|
2016-12-09 00:28:40 +09:00
|
|
|
},
|
2011-07-29 02:48:05 +09:00
|
|
|
};
|
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
let validateFileURL;
|
2016-10-15 00:57:53 +09:00
|
|
|
if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {
|
2017-06-29 19:14:26 +09:00
|
|
|
const HOSTED_VIEWER_ORIGINS = ['null',
|
2016-10-15 00:57:53 +09:00
|
|
|
'http://mozilla.github.io', 'https://mozilla.github.io'];
|
|
|
|
validateFileURL = function validateFileURL(file) {
|
2017-07-14 05:48:04 +09:00
|
|
|
if (file === undefined) {
|
|
|
|
return;
|
|
|
|
}
|
2016-10-15 00:57:53 +09:00
|
|
|
try {
|
2017-06-29 19:14:26 +09:00
|
|
|
let viewerOrigin = new URL(window.location.href).origin || 'null';
|
2018-02-11 01:06:03 +09:00
|
|
|
if (HOSTED_VIEWER_ORIGINS.includes(viewerOrigin)) {
|
2016-10-15 00:57:53 +09:00
|
|
|
// Hosted or local viewer, allow for any file locations
|
|
|
|
return;
|
|
|
|
}
|
2018-02-23 20:48:52 +09:00
|
|
|
let { origin, protocol, } = new URL(file, window.location.href);
|
2016-10-15 00:57:53 +09:00
|
|
|
// Removing of the following line will not guarantee that the viewer will
|
|
|
|
// start accepting URLs from foreign origin -- CORS headers on the remote
|
|
|
|
// server must be properly configured.
|
2018-02-23 20:48:52 +09:00
|
|
|
// IE10 / IE11 does not include an origin in `blob:`-URLs. So don't block
|
|
|
|
// any blob:-URL. The browser's same-origin policy will block requests to
|
|
|
|
// blob:-URLs from other origins, so this is safe.
|
|
|
|
if (origin !== viewerOrigin && protocol !== 'blob:') {
|
2016-10-15 00:57:53 +09:00
|
|
|
throw new Error('file origin does not match viewer\'s');
|
|
|
|
}
|
2017-06-29 19:14:26 +09:00
|
|
|
} catch (ex) {
|
|
|
|
let message = ex && ex.message;
|
2017-05-04 10:05:53 +09:00
|
|
|
PDFViewerApplication.l10n.get('loading_error', null,
|
|
|
|
'An error occurred while loading the PDF.').
|
|
|
|
then((loadingErrorMessage) => {
|
|
|
|
PDFViewerApplication.error(loadingErrorMessage, { message, });
|
|
|
|
});
|
2017-06-29 19:14:26 +09:00
|
|
|
throw ex;
|
2016-10-15 00:57:53 +09:00
|
|
|
}
|
|
|
|
};
|
2016-01-23 02:54:19 +09:00
|
|
|
}
|
|
|
|
|
2018-01-20 02:16:17 +09:00
|
|
|
function loadFakeWorker() {
|
|
|
|
return new Promise(function(resolve, reject) {
|
2018-02-17 23:33:57 +09:00
|
|
|
if (!GlobalWorkerOptions.workerSrc) {
|
|
|
|
GlobalWorkerOptions.workerSrc = AppOptions.get('workerSrc');
|
|
|
|
}
|
2018-01-20 02:16:17 +09:00
|
|
|
if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION')) {
|
|
|
|
if (typeof SystemJS === 'object') {
|
|
|
|
SystemJS.import('pdfjs/core/worker').then((worker) => {
|
2018-03-29 17:50:52 +09:00
|
|
|
window.pdfjsWorker = worker;
|
2018-01-20 02:16:17 +09:00
|
|
|
resolve();
|
|
|
|
});
|
|
|
|
} else if (typeof require === 'function') {
|
2018-03-29 17:50:52 +09:00
|
|
|
window.pdfjsWorker = require('../src/core/worker.js');
|
2018-01-20 02:16:17 +09:00
|
|
|
resolve();
|
|
|
|
} else {
|
|
|
|
reject(new Error(
|
|
|
|
'SystemJS or CommonJS must be used to load fake worker.'));
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
let script = document.createElement('script');
|
|
|
|
script.src = PDFWorker.getWorkerSrc();
|
|
|
|
script.onload = function() {
|
|
|
|
resolve();
|
|
|
|
};
|
|
|
|
script.onerror = function() {
|
|
|
|
reject(new Error(`Cannot load fake worker at: ${script.src}`));
|
|
|
|
};
|
|
|
|
(document.head || document.documentElement).appendChild(script);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2016-05-10 08:18:43 +09:00
|
|
|
function loadAndEnablePDFBug(enabledTabs) {
|
|
|
|
return new Promise(function (resolve, reject) {
|
2017-06-29 19:14:26 +09:00
|
|
|
let appConfig = PDFViewerApplication.appConfig;
|
|
|
|
let script = document.createElement('script');
|
2016-05-10 08:18:43 +09:00
|
|
|
script.src = appConfig.debuggerScriptPath;
|
|
|
|
script.onload = function () {
|
|
|
|
PDFBug.enable(enabledTabs);
|
2017-03-28 17:15:02 +09:00
|
|
|
PDFBug.init({
|
|
|
|
OPS,
|
|
|
|
}, appConfig.mainContainer);
|
2016-05-10 08:18:43 +09:00
|
|
|
resolve();
|
|
|
|
};
|
|
|
|
script.onerror = function () {
|
|
|
|
reject(new Error('Cannot load debugger at ' + script.src));
|
|
|
|
};
|
|
|
|
(document.getElementsByTagName('head')[0] || document.body).
|
|
|
|
appendChild(script);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2014-04-04 02:20:53 +09:00
|
|
|
function webViewerInitialized() {
|
2017-06-29 19:14:26 +09:00
|
|
|
let appConfig = PDFViewerApplication.appConfig;
|
|
|
|
let file;
|
2016-10-15 00:57:53 +09:00
|
|
|
if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {
|
2017-06-29 19:14:26 +09:00
|
|
|
let queryString = document.location.search.substring(1);
|
|
|
|
let params = parseQueryString(queryString);
|
2018-02-18 07:25:23 +09:00
|
|
|
file = 'file' in params ? params.file : AppOptions.get('defaultUrl');
|
2016-10-15 00:57:53 +09:00
|
|
|
validateFileURL(file);
|
|
|
|
} else if (PDFJSDev.test('FIREFOX || MOZCENTRAL')) {
|
|
|
|
file = window.location.href.split('#')[0];
|
|
|
|
} else if (PDFJSDev.test('CHROME')) {
|
2018-02-18 07:25:23 +09:00
|
|
|
file = AppOptions.get('defaultUrl');
|
2016-10-15 00:57:53 +09:00
|
|
|
}
|
2013-08-15 06:36:40 +09:00
|
|
|
|
2016-10-15 00:57:53 +09:00
|
|
|
if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {
|
2017-06-29 19:14:26 +09:00
|
|
|
let fileInput = document.createElement('input');
|
2016-10-15 00:57:53 +09:00
|
|
|
fileInput.id = appConfig.openFileInputName;
|
|
|
|
fileInput.className = 'fileInput';
|
|
|
|
fileInput.setAttribute('type', 'file');
|
|
|
|
fileInput.oncontextmenu = noContextMenuHandler;
|
|
|
|
document.body.appendChild(fileInput);
|
|
|
|
|
|
|
|
if (!window.File || !window.FileReader ||
|
|
|
|
!window.FileList || !window.Blob) {
|
|
|
|
appConfig.toolbar.openFile.setAttribute('hidden', 'true');
|
|
|
|
appConfig.secondaryToolbar.openFileButton.setAttribute('hidden', 'true');
|
|
|
|
} else {
|
|
|
|
fileInput.value = null;
|
|
|
|
}
|
2017-09-16 20:05:01 +09:00
|
|
|
|
|
|
|
fileInput.addEventListener('change', function(evt) {
|
|
|
|
let files = evt.target.files;
|
|
|
|
if (!files || files.length === 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
PDFViewerApplication.eventBus.dispatch('fileinputchange', {
|
|
|
|
fileInput: evt.target,
|
|
|
|
});
|
|
|
|
});
|
2016-10-15 00:57:53 +09:00
|
|
|
} else {
|
2016-04-22 01:39:11 +09:00
|
|
|
appConfig.toolbar.openFile.setAttribute('hidden', 'true');
|
2016-05-11 08:31:03 +09:00
|
|
|
appConfig.secondaryToolbar.openFileButton.setAttribute('hidden', 'true');
|
2012-01-25 08:13:50 +09:00
|
|
|
}
|
2016-04-22 01:39:11 +09:00
|
|
|
|
2017-05-04 10:05:53 +09:00
|
|
|
if (typeof PDFJSDev !== 'undefined' &&
|
|
|
|
PDFJSDev.test('FIREFOX || MOZCENTRAL') &&
|
|
|
|
!PDFViewerApplication.supportsDocumentFonts) {
|
2018-02-18 05:57:20 +09:00
|
|
|
AppOptions.set('disableFontFace', true);
|
2017-05-04 10:05:53 +09:00
|
|
|
PDFViewerApplication.l10n.get('web_fonts_disabled', null,
|
|
|
|
'Web fonts are disabled: unable to use embedded PDF fonts.').
|
|
|
|
then((msg) => {
|
|
|
|
console.warn(msg);
|
|
|
|
});
|
2015-04-26 08:49:37 +09:00
|
|
|
}
|
2012-05-01 05:29:05 +09:00
|
|
|
|
2014-09-22 20:41:17 +09:00
|
|
|
if (!PDFViewerApplication.supportsPrinting) {
|
2016-04-22 01:39:11 +09:00
|
|
|
appConfig.toolbar.print.classList.add('hidden');
|
2016-05-11 08:31:03 +09:00
|
|
|
appConfig.secondaryToolbar.printButton.classList.add('hidden');
|
2012-07-10 08:04:55 +09:00
|
|
|
}
|
|
|
|
|
2014-09-22 20:41:17 +09:00
|
|
|
if (!PDFViewerApplication.supportsFullscreen) {
|
2016-04-22 01:39:11 +09:00
|
|
|
appConfig.toolbar.presentationModeButton.classList.add('hidden');
|
|
|
|
appConfig.secondaryToolbar.presentationModeButton.classList.add('hidden');
|
2012-07-31 00:12:49 +09:00
|
|
|
}
|
|
|
|
|
2014-09-22 20:41:17 +09:00
|
|
|
if (PDFViewerApplication.supportsIntegratedFind) {
|
2016-04-22 01:39:11 +09:00
|
|
|
appConfig.toolbar.viewFind.classList.add('hidden');
|
2012-10-06 05:59:13 +09:00
|
|
|
}
|
|
|
|
|
2017-09-30 23:41:46 +09:00
|
|
|
appConfig.mainContainer.addEventListener('transitionend', function(evt) {
|
|
|
|
if (evt.target === /* mainContainer */ this) {
|
Implement sidebar resizing for modern browsers, by utilizing CSS variables (issue 2072)
By making use of modern CSS features, in this case [CSS variables](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables), implementing sidebar resizing is actually quite simple. Not only will the amount of added code be fairly small, but it should also be easy to maintain since there's no need for complicated JavaScript hacks in order to update the CSS. Another benefit is that the JavaScript code doesn't need to make detailed assumptions about the exact structure of the HTML/CSS code.
Obviously this will not work in older browsers, such as IE, that lack support for CSS variables. In those cases sidebar resizing is simply disabled (via feature detection), and the resizing DOM element hidden, and the behaviour is thus *identical* to the current (fixed-width) sidebar.
However, considering the simplicity of the implementation, I really don't see why limiting this feature to "modern" browsers is a problem.
Finally, note that a few edge-cases meant that the patch is a bit larger than what the basic functionality would dictate. Among those is first of all proper RTL support, and secondly (automatic) resizing of the sidebar when the width of the *entire* viewer changes. Another, pre-existing, issue fixed here is the incomplete interface of `NullL10n`.
*Please note:* This patch has been successfully tested in both LTR and RTL viewer locales, in recent versions of Firefox and Chrome.
Fixes 2072.
2017-10-10 23:16:05 +09:00
|
|
|
PDFViewerApplication.eventBus.dispatch('resize', { source: this, });
|
2017-09-30 23:41:46 +09:00
|
|
|
}
|
|
|
|
}, true);
|
2012-09-07 00:33:07 +09:00
|
|
|
|
2016-08-07 20:10:50 +09:00
|
|
|
appConfig.sidebar.toggleButton.addEventListener('click', function() {
|
|
|
|
PDFViewerApplication.pdfSidebar.toggle();
|
|
|
|
});
|
2014-03-19 05:32:47 +09:00
|
|
|
|
2017-11-13 18:17:25 +09:00
|
|
|
Promise.resolve().then(function() {
|
2016-05-10 08:18:43 +09:00
|
|
|
webViewerOpenFileViaURL(file);
|
2017-11-13 18:17:25 +09:00
|
|
|
}).catch(function(reason) {
|
2017-05-04 10:05:53 +09:00
|
|
|
PDFViewerApplication.l10n.get('loading_error', null,
|
2017-11-13 18:17:25 +09:00
|
|
|
'An error occurred while loading the PDF.').then((msg) => {
|
2017-05-04 10:05:53 +09:00
|
|
|
PDFViewerApplication.error(msg, reason);
|
|
|
|
});
|
2016-05-10 08:18:43 +09:00
|
|
|
});
|
|
|
|
}
|
2012-08-16 00:17:30 +09:00
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
let webViewerOpenFileViaURL;
|
2016-10-15 00:57:53 +09:00
|
|
|
if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {
|
|
|
|
webViewerOpenFileViaURL = function webViewerOpenFileViaURL(file) {
|
|
|
|
if (file && file.lastIndexOf('file:', 0) === 0) {
|
|
|
|
// file:-scheme. Load the contents in the main thread because QtWebKit
|
|
|
|
// cannot load file:-URLs in a Web Worker. file:-URLs are usually loaded
|
|
|
|
// very quickly, so there is no need to set up progress event listeners.
|
|
|
|
PDFViewerApplication.setTitleUsingUrl(file);
|
2017-06-29 19:14:26 +09:00
|
|
|
let xhr = new XMLHttpRequest();
|
2016-10-15 00:57:53 +09:00
|
|
|
xhr.onload = function() {
|
|
|
|
PDFViewerApplication.open(new Uint8Array(xhr.response));
|
|
|
|
};
|
|
|
|
try {
|
|
|
|
xhr.open('GET', file);
|
|
|
|
xhr.responseType = 'arraybuffer';
|
|
|
|
xhr.send();
|
2017-06-29 19:14:26 +09:00
|
|
|
} catch (ex) {
|
2017-11-13 18:17:25 +09:00
|
|
|
throw ex;
|
2016-10-15 00:57:53 +09:00
|
|
|
}
|
|
|
|
return;
|
2014-07-30 08:28:41 +09:00
|
|
|
}
|
|
|
|
|
2016-10-15 00:57:53 +09:00
|
|
|
if (file) {
|
|
|
|
PDFViewerApplication.open(file);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
} else if (PDFJSDev.test('FIREFOX || MOZCENTRAL || CHROME')) {
|
|
|
|
webViewerOpenFileViaURL = function webViewerOpenFileViaURL(file) {
|
|
|
|
PDFViewerApplication.setTitleUsingUrl(file);
|
|
|
|
PDFViewerApplication.initPassiveLoading();
|
|
|
|
};
|
|
|
|
} else {
|
2017-11-13 18:17:25 +09:00
|
|
|
webViewerOpenFileViaURL = function webViewerOpenFileViaURL(file) {
|
2016-10-15 00:57:53 +09:00
|
|
|
if (file) {
|
2017-11-13 18:17:25 +09:00
|
|
|
throw new Error('Not implemented: webViewerOpenFileViaURL');
|
2016-10-15 00:57:53 +09:00
|
|
|
}
|
|
|
|
};
|
2014-02-28 02:45:02 +09:00
|
|
|
}
|
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
function webViewerPageRendered(evt) {
|
|
|
|
let pageNumber = evt.pageNumber;
|
|
|
|
let pageIndex = pageNumber - 1;
|
|
|
|
let pageView = PDFViewerApplication.pdfViewer.getPageView(pageIndex);
|
2015-01-28 05:13:34 +09:00
|
|
|
|
2016-07-30 03:39:22 +09:00
|
|
|
// If the page is still visible when it has finished rendering,
|
|
|
|
// ensure that the page number input loading indicator is hidden.
|
|
|
|
if (pageNumber === PDFViewerApplication.page) {
|
2016-11-19 03:50:29 +09:00
|
|
|
PDFViewerApplication.toolbar.updateLoadingIndicatorState(false);
|
2016-07-30 03:39:22 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
// Prevent errors in the edge-case where the PDF document is removed *before*
|
|
|
|
// the 'pagerendered' event handler is invoked.
|
|
|
|
if (!pageView) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-02-22 01:54:23 +09:00
|
|
|
// Use the rendered page to set the corresponding thumbnail image.
|
|
|
|
if (PDFViewerApplication.pdfSidebar.isThumbnailViewVisible) {
|
2017-06-29 19:14:26 +09:00
|
|
|
let thumbnailView = PDFViewerApplication.pdfThumbnailViewer.
|
2015-01-28 05:13:34 +09:00
|
|
|
getThumbnail(pageIndex);
|
|
|
|
thumbnailView.setImage(pageView);
|
|
|
|
}
|
2012-08-08 08:52:22 +09:00
|
|
|
|
2018-02-13 22:34:29 +09:00
|
|
|
if (typeof Stats !== 'undefined' && Stats.enabled && pageView.stats) {
|
2014-09-30 01:15:06 +09:00
|
|
|
Stats.add(pageNumber, pageView.stats);
|
|
|
|
}
|
|
|
|
|
2014-09-16 04:57:12 +09:00
|
|
|
if (pageView.error) {
|
2017-05-04 10:05:53 +09:00
|
|
|
PDFViewerApplication.l10n.get('rendering_error', null,
|
|
|
|
'An error occurred while rendering the page.').then((msg) => {
|
|
|
|
PDFViewerApplication.error(msg, pageView.error);
|
|
|
|
});
|
2014-09-16 04:57:12 +09:00
|
|
|
}
|
2012-08-08 08:52:22 +09:00
|
|
|
|
2016-10-15 00:57:53 +09:00
|
|
|
if (typeof PDFJSDev !== 'undefined' &&
|
|
|
|
PDFJSDev.test('FIREFOX || MOZCENTRAL')) {
|
2016-04-14 06:21:05 +09:00
|
|
|
PDFViewerApplication.externalServices.reportTelemetry({
|
Fix inconsistent spacing and trailing commas in objects in `web/` files, so we can enable the `comma-dangle` and `object-curly-spacing` ESLint rules later on
http://eslint.org/docs/rules/comma-dangle
http://eslint.org/docs/rules/object-curly-spacing
Given that we currently have quite inconsistent object formatting, fixing this in in *one* big patch probably wouldn't be feasible (since I cannot imagine anyone wanting to review that); hence I've opted to try and do this piecewise instead.
*Please note:* This patch was created automatically, using the ESLint `--fix` command line option. In a couple of places this caused lines to become too long, and I've fixed those manually; please refer to the interdiff below for the only hand-edits in this patch.
```diff
diff --git a/web/pdf_thumbnail_view.js b/web/pdf_thumbnail_view.js
index 002dbf29..1de4e530 100644
--- a/web/pdf_thumbnail_view.js
+++ b/web/pdf_thumbnail_view.js
@@ -420,8 +420,8 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() {
setPageLabel: function PDFThumbnailView_setPageLabel(label) {
this.pageLabel = (typeof label === 'string' ? label : null);
- this.l10n.get('thumb_page_title', { page: this.pageId, }, 'Page {{page}}').
- then((msg) => {
+ this.l10n.get('thumb_page_title', { page: this.pageId, },
+ 'Page {{page}}').then((msg) => {
this.anchor.title = msg;
});
diff --git a/web/secondary_toolbar.js b/web/secondary_toolbar.js
index 160e0410..6495fc5e 100644
--- a/web/secondary_toolbar.js
+++ b/web/secondary_toolbar.js
@@ -65,7 +65,8 @@ class SecondaryToolbar {
{ element: options.printButton, eventName: 'print', close: true, },
{ element: options.downloadButton, eventName: 'download', close: true, },
{ element: options.viewBookmarkButton, eventName: null, close: true, },
- { element: options.firstPageButton, eventName: 'firstpage', close: true, },
+ { element: options.firstPageButton, eventName: 'firstpage',
+ close: true, },
{ element: options.lastPageButton, eventName: 'lastpage', close: true, },
{ element: options.pageRotateCwButton, eventName: 'rotatecw',
close: false, },
@@ -76,7 +77,7 @@ class SecondaryToolbar {
{ element: options.cursorHandToolButton, eventName: 'switchcursortool',
eventDetails: { tool: CursorTool.HAND, }, close: true, },
{ element: options.documentPropertiesButton,
- eventName: 'documentproperties', close: true, }
+ eventName: 'documentproperties', close: true, },
];
this.items = {
firstPage: options.firstPageButton,
```
2017-06-01 19:46:12 +09:00
|
|
|
type: 'pageInfo',
|
2016-04-14 06:21:05 +09:00
|
|
|
});
|
2016-10-15 00:57:53 +09:00
|
|
|
// It is a good time to report stream and font types.
|
|
|
|
PDFViewerApplication.pdfDocument.getStats().then(function (stats) {
|
|
|
|
PDFViewerApplication.externalServices.reportTelemetry({
|
|
|
|
type: 'documentStats',
|
2017-04-28 19:02:42 +09:00
|
|
|
stats,
|
2016-10-15 00:57:53 +09:00
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
2016-04-26 07:57:15 +09:00
|
|
|
}
|
2012-08-08 08:52:22 +09:00
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
function webViewerTextLayerRendered(evt) {
|
2016-10-15 00:57:53 +09:00
|
|
|
if (typeof PDFJSDev !== 'undefined' &&
|
|
|
|
PDFJSDev.test('FIREFOX || MOZCENTRAL') &&
|
2017-06-29 19:14:26 +09:00
|
|
|
evt.numTextDivs > 0 && !PDFViewerApplication.supportsDocumentColors) {
|
2017-05-04 10:05:53 +09:00
|
|
|
PDFViewerApplication.l10n.get('document_colors_not_allowed', null,
|
2015-04-26 08:49:37 +09:00
|
|
|
'PDF documents are not allowed to use their own colors: ' +
|
|
|
|
'\'Allow pages to choose their own colors\' ' +
|
2017-05-04 10:05:53 +09:00
|
|
|
'is deactivated in the browser.').
|
|
|
|
then((msg) => {
|
|
|
|
console.error(msg);
|
|
|
|
});
|
2015-04-26 08:49:37 +09:00
|
|
|
PDFViewerApplication.fallback();
|
|
|
|
}
|
2016-04-26 07:57:15 +09:00
|
|
|
}
|
2014-12-31 21:10:59 +09:00
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
function webViewerPageMode(evt) {
|
2015-08-05 05:57:51 +09:00
|
|
|
// Handle the 'pagemode' hash parameter, see also `PDFLinkService_setHash`.
|
2017-06-29 19:14:26 +09:00
|
|
|
let mode = evt.mode, view;
|
2015-08-05 05:57:51 +09:00
|
|
|
switch (mode) {
|
|
|
|
case 'thumbs':
|
2016-02-22 01:54:23 +09:00
|
|
|
view = SidebarView.THUMBS;
|
|
|
|
break;
|
|
|
|
case 'bookmarks':
|
|
|
|
case 'outline':
|
|
|
|
view = SidebarView.OUTLINE;
|
|
|
|
break;
|
2015-08-05 05:57:51 +09:00
|
|
|
case 'attachments':
|
2016-02-22 01:54:23 +09:00
|
|
|
view = SidebarView.ATTACHMENTS;
|
2015-08-05 05:57:51 +09:00
|
|
|
break;
|
|
|
|
case 'none':
|
2016-02-22 01:54:23 +09:00
|
|
|
view = SidebarView.NONE;
|
2015-08-05 05:57:51 +09:00
|
|
|
break;
|
2016-02-22 01:54:23 +09:00
|
|
|
default:
|
|
|
|
console.error('Invalid "pagemode" hash parameter: ' + mode);
|
|
|
|
return;
|
2015-08-05 05:57:51 +09:00
|
|
|
}
|
2016-02-22 01:54:23 +09:00
|
|
|
PDFViewerApplication.pdfSidebar.switchView(view, /* forceOpen = */ true);
|
2016-04-26 07:57:15 +09:00
|
|
|
}
|
2015-08-05 05:57:51 +09:00
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
function webViewerNamedAction(evt) {
|
2015-04-28 00:25:32 +09:00
|
|
|
// Processing couple of named actions that might be useful.
|
|
|
|
// See also PDFLinkService.executeNamedAction
|
2017-06-29 19:14:26 +09:00
|
|
|
let action = evt.action;
|
2015-04-28 00:25:32 +09:00
|
|
|
switch (action) {
|
|
|
|
case 'GoToPage':
|
2016-09-01 20:23:18 +09:00
|
|
|
PDFViewerApplication.appConfig.toolbar.pageNumber.select();
|
2015-04-28 00:25:32 +09:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 'Find':
|
2015-08-05 06:07:44 +09:00
|
|
|
if (!PDFViewerApplication.supportsIntegratedFind) {
|
|
|
|
PDFViewerApplication.findBar.toggle();
|
2015-04-28 00:25:32 +09:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2016-04-26 07:57:15 +09:00
|
|
|
}
|
2015-04-28 00:25:32 +09:00
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
function webViewerPresentationModeChanged(evt) {
|
|
|
|
let { active, switchInProgress, } = evt;
|
2014-09-22 20:41:17 +09:00
|
|
|
PDFViewerApplication.pdfViewer.presentationModeState =
|
2014-09-16 02:37:03 +09:00
|
|
|
switchInProgress ? PresentationModeState.CHANGING :
|
|
|
|
active ? PresentationModeState.FULLSCREEN : PresentationModeState.NORMAL;
|
2016-04-26 07:57:15 +09:00
|
|
|
}
|
2012-08-08 08:52:22 +09:00
|
|
|
|
2017-04-22 20:42:41 +09:00
|
|
|
function webViewerSidebarViewChanged(evt) {
|
2016-03-12 21:07:43 +09:00
|
|
|
PDFViewerApplication.pdfRenderingQueue.isThumbnailViewEnabled =
|
|
|
|
PDFViewerApplication.pdfSidebar.isThumbnailViewVisible;
|
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
let store = PDFViewerApplication.store;
|
2017-04-22 20:42:41 +09:00
|
|
|
if (store && PDFViewerApplication.isInitialViewSet) {
|
2016-03-12 21:07:43 +09:00
|
|
|
// Only update the storage when the document has been loaded *and* rendered.
|
2017-04-22 20:42:41 +09:00
|
|
|
store.set('sidebarView', evt.view).catch(function() { });
|
2016-03-12 21:07:43 +09:00
|
|
|
}
|
2016-04-26 07:57:15 +09:00
|
|
|
}
|
2016-03-12 21:07:43 +09:00
|
|
|
|
2017-04-22 20:42:41 +09:00
|
|
|
function webViewerUpdateViewarea(evt) {
|
2017-06-29 19:14:26 +09:00
|
|
|
let location = evt.location, store = PDFViewerApplication.store;
|
2017-04-22 20:42:41 +09:00
|
|
|
|
|
|
|
if (store && PDFViewerApplication.isInitialViewSet) {
|
|
|
|
store.setMultiple({
|
|
|
|
'exists': true,
|
|
|
|
'page': location.pageNumber,
|
|
|
|
'zoom': location.scale,
|
|
|
|
'scrollLeft': location.left,
|
|
|
|
'scrollTop': location.top,
|
2017-08-21 18:22:07 +09:00
|
|
|
'rotation': location.rotation,
|
2017-04-22 20:42:41 +09:00
|
|
|
}).catch(function() { /* unable to write to storage */ });
|
2016-03-12 21:07:43 +09:00
|
|
|
}
|
2017-06-29 19:14:26 +09:00
|
|
|
let href =
|
2015-04-28 00:25:32 +09:00
|
|
|
PDFViewerApplication.pdfLinkService.getAnchorUrl(location.pdfOpenParams);
|
2016-04-22 01:39:11 +09:00
|
|
|
PDFViewerApplication.appConfig.toolbar.viewBookmark.href = href;
|
2016-05-11 08:31:03 +09:00
|
|
|
PDFViewerApplication.appConfig.secondaryToolbar.viewBookmarkButton.href =
|
|
|
|
href;
|
2013-05-16 07:31:17 +09:00
|
|
|
|
2014-07-18 20:53:04 +09:00
|
|
|
// Show/hide the loading indicator in the page number input element.
|
2017-06-29 19:14:26 +09:00
|
|
|
let currentPage =
|
2014-07-18 20:53:04 +09:00
|
|
|
PDFViewerApplication.pdfViewer.getPageView(PDFViewerApplication.page - 1);
|
2017-06-29 19:14:26 +09:00
|
|
|
let loading = currentPage.renderingState !== RenderingStates.FINISHED;
|
2016-11-19 03:50:29 +09:00
|
|
|
PDFViewerApplication.toolbar.updateLoadingIndicatorState(loading);
|
2016-04-26 07:57:15 +09:00
|
|
|
}
|
2011-09-03 10:16:52 +09:00
|
|
|
|
2018-05-15 12:10:33 +09:00
|
|
|
function webViewerScrollModeChanged(evt) {
|
|
|
|
let store = PDFViewerApplication.store;
|
|
|
|
if (store && PDFViewerApplication.isInitialViewSet) {
|
|
|
|
// Only update the storage when the document has been loaded *and* rendered.
|
|
|
|
store.set('scrollMode', evt.mode).catch(function() { });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function webViewerSpreadModeChanged(evt) {
|
|
|
|
let store = PDFViewerApplication.store;
|
|
|
|
if (store && PDFViewerApplication.isInitialViewSet) {
|
|
|
|
// Only update the storage when the document has been loaded *and* rendered.
|
|
|
|
store.set('spreadMode', evt.mode).catch(function() { });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-26 07:57:15 +09:00
|
|
|
function webViewerResize() {
|
2017-07-06 20:13:22 +09:00
|
|
|
let { pdfDocument, pdfViewer, } = PDFViewerApplication;
|
|
|
|
if (!pdfDocument) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
let currentScaleValue = pdfViewer.currentScaleValue;
|
2016-12-09 00:28:40 +09:00
|
|
|
if (currentScaleValue === 'auto' ||
|
|
|
|
currentScaleValue === 'page-fit' ||
|
|
|
|
currentScaleValue === 'page-width') {
|
|
|
|
// Note: the scale is constant for 'page-actual'.
|
2017-07-06 20:13:22 +09:00
|
|
|
pdfViewer.currentScaleValue = currentScaleValue;
|
2013-08-01 02:43:03 +09:00
|
|
|
}
|
2017-07-06 20:13:22 +09:00
|
|
|
pdfViewer.update();
|
2016-04-26 07:57:15 +09:00
|
|
|
}
|
2011-09-03 10:16:52 +09:00
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
function webViewerHashchange(evt) {
|
2017-07-14 21:24:32 +09:00
|
|
|
let hash = evt.hash;
|
|
|
|
if (!hash) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!PDFViewerApplication.isInitialViewSet) {
|
|
|
|
PDFViewerApplication.initialBookmark = hash;
|
Re-write `PDFHistory` from scratch
This patch completely re-implements `PDFHistory` to get rid of various bugs currently present, and to hopefully make maintenance slightly easier. Most of the interface is similar to the existing one, but it should be somewhat simplified.
The new implementation should be more robust against failure, compared to the old one. Previously, it was too easy to end up in a state which basically caused the browser history to lock-up, preventing the user from navigating back/forward. (In the new implementation, the browser history should not be updated rather than breaking if things go wrong.)
Given that the code has to deal with various edge-cases, it's still not as simple as I would have liked, but it should now be somewhat easier to deal with.
The main source of complication in the code is actually that we allow the user to change the hash of a already loaded document (we'll no longer try to navigate back-and-forth in this case, since the next commit contains a workaround).
In the new code, there's also *a lot* more comments (perhaps too many?) to attempt to explain the logic. This is something that the old implementation was serverly lacking, which is a one of the reasons why it was so difficult to maintain.
One particular thing to note is that the new code uses the `pagehide` event rather than `beforeunload`, since the latter seems to be a bad idea based on https://bugzilla.mozilla.org/show_bug.cgi?id=1336763.
2017-07-16 20:39:39 +09:00
|
|
|
} else if (!PDFViewerApplication.pdfHistory.popStateInProgress) {
|
2017-07-14 21:24:32 +09:00
|
|
|
PDFViewerApplication.pdfLinkService.setHash(hash);
|
2013-05-16 07:31:17 +09:00
|
|
|
}
|
2016-04-26 07:57:15 +09:00
|
|
|
}
|
2011-07-29 02:48:05 +09:00
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
let webViewerFileInputChange;
|
2016-10-15 00:57:53 +09:00
|
|
|
if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {
|
2017-06-29 19:14:26 +09:00
|
|
|
webViewerFileInputChange = function webViewerFileInputChange(evt) {
|
|
|
|
let file = evt.fileInput.files[0];
|
2014-01-28 04:11:02 +09:00
|
|
|
|
2018-02-18 06:51:03 +09:00
|
|
|
if (URL.createObjectURL && !AppOptions.get('disableCreateObjectURL')) {
|
2016-10-15 00:57:53 +09:00
|
|
|
PDFViewerApplication.open(URL.createObjectURL(file));
|
|
|
|
} else {
|
|
|
|
// Read the local file into a Uint8Array.
|
2017-06-29 19:14:26 +09:00
|
|
|
let fileReader = new FileReader();
|
2016-10-15 00:57:53 +09:00
|
|
|
fileReader.onload = function webViewerChangeFileReaderOnload(evt) {
|
2017-06-29 19:14:26 +09:00
|
|
|
let buffer = evt.target.result;
|
|
|
|
PDFViewerApplication.open(new Uint8Array(buffer));
|
2016-10-15 00:57:53 +09:00
|
|
|
};
|
|
|
|
fileReader.readAsArrayBuffer(file);
|
|
|
|
}
|
2014-01-28 04:11:02 +09:00
|
|
|
|
2016-10-15 00:57:53 +09:00
|
|
|
PDFViewerApplication.setTitleUsingUrl(file.name);
|
2011-10-15 11:05:57 +09:00
|
|
|
|
2016-10-15 00:57:53 +09:00
|
|
|
// URL does not reflect proper document location - hiding some icons.
|
2017-06-29 19:14:26 +09:00
|
|
|
let appConfig = PDFViewerApplication.appConfig;
|
2016-10-15 00:57:53 +09:00
|
|
|
appConfig.toolbar.viewBookmark.setAttribute('hidden', 'true');
|
|
|
|
appConfig.secondaryToolbar.viewBookmarkButton.setAttribute('hidden',
|
|
|
|
'true');
|
|
|
|
appConfig.toolbar.download.setAttribute('hidden', 'true');
|
|
|
|
appConfig.secondaryToolbar.downloadButton.setAttribute('hidden', 'true');
|
|
|
|
};
|
2016-04-26 07:57:15 +09:00
|
|
|
}
|
2011-07-29 02:48:05 +09:00
|
|
|
|
2016-04-29 05:04:09 +09:00
|
|
|
function webViewerPresentationMode() {
|
|
|
|
PDFViewerApplication.requestPresentationMode();
|
|
|
|
}
|
|
|
|
function webViewerOpenFile() {
|
2017-09-16 20:05:01 +09:00
|
|
|
if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {
|
|
|
|
let openFileInputName = PDFViewerApplication.appConfig.openFileInputName;
|
|
|
|
document.getElementById(openFileInputName).click();
|
|
|
|
}
|
2016-04-29 05:04:09 +09:00
|
|
|
}
|
|
|
|
function webViewerPrint() {
|
|
|
|
window.print();
|
|
|
|
}
|
|
|
|
function webViewerDownload() {
|
|
|
|
PDFViewerApplication.download();
|
|
|
|
}
|
|
|
|
function webViewerFirstPage() {
|
|
|
|
if (PDFViewerApplication.pdfDocument) {
|
|
|
|
PDFViewerApplication.page = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function webViewerLastPage() {
|
|
|
|
if (PDFViewerApplication.pdfDocument) {
|
|
|
|
PDFViewerApplication.page = PDFViewerApplication.pagesCount;
|
|
|
|
}
|
|
|
|
}
|
2016-11-19 03:50:29 +09:00
|
|
|
function webViewerNextPage() {
|
|
|
|
PDFViewerApplication.page++;
|
|
|
|
}
|
|
|
|
function webViewerPreviousPage() {
|
|
|
|
PDFViewerApplication.page--;
|
|
|
|
}
|
|
|
|
function webViewerZoomIn() {
|
|
|
|
PDFViewerApplication.zoomIn();
|
|
|
|
}
|
|
|
|
function webViewerZoomOut() {
|
|
|
|
PDFViewerApplication.zoomOut();
|
|
|
|
}
|
2017-06-29 19:14:26 +09:00
|
|
|
function webViewerPageNumberChanged(evt) {
|
|
|
|
let pdfViewer = PDFViewerApplication.pdfViewer;
|
|
|
|
pdfViewer.currentPageLabel = evt.value;
|
2016-11-19 03:50:29 +09:00
|
|
|
|
|
|
|
// Ensure that the page number input displays the correct value, even if the
|
|
|
|
// value entered by the user was invalid (e.g. a floating point number).
|
2017-06-29 19:14:26 +09:00
|
|
|
if (evt.value !== pdfViewer.currentPageNumber.toString() &&
|
|
|
|
evt.value !== pdfViewer.currentPageLabel) {
|
2016-11-19 03:50:29 +09:00
|
|
|
PDFViewerApplication.toolbar.setPageNumber(
|
|
|
|
pdfViewer.currentPageNumber, pdfViewer.currentPageLabel);
|
|
|
|
}
|
|
|
|
}
|
2017-06-29 19:14:26 +09:00
|
|
|
function webViewerScaleChanged(evt) {
|
|
|
|
PDFViewerApplication.pdfViewer.currentScaleValue = evt.value;
|
2016-11-19 03:50:29 +09:00
|
|
|
}
|
2016-04-29 05:04:09 +09:00
|
|
|
function webViewerRotateCw() {
|
|
|
|
PDFViewerApplication.rotatePages(90);
|
|
|
|
}
|
|
|
|
function webViewerRotateCcw() {
|
|
|
|
PDFViewerApplication.rotatePages(-90);
|
|
|
|
}
|
2018-05-15 12:10:32 +09:00
|
|
|
function webViewerSwitchScrollMode(evt) {
|
|
|
|
PDFViewerApplication.pdfViewer.setScrollMode(evt.mode);
|
|
|
|
}
|
2018-05-15 12:10:32 +09:00
|
|
|
function webViewerSwitchSpreadMode(evt) {
|
|
|
|
PDFViewerApplication.pdfViewer.setSpreadMode(evt.mode);
|
|
|
|
}
|
2016-04-29 05:04:09 +09:00
|
|
|
function webViewerDocumentProperties() {
|
|
|
|
PDFViewerApplication.pdfDocumentProperties.open();
|
|
|
|
}
|
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
function webViewerFind(evt) {
|
|
|
|
PDFViewerApplication.findController.executeCommand('find' + evt.type, {
|
|
|
|
query: evt.query,
|
|
|
|
phraseSearch: evt.phraseSearch,
|
|
|
|
caseSensitive: evt.caseSensitive,
|
|
|
|
highlightAll: evt.highlightAll,
|
|
|
|
findPrevious: evt.findPrevious,
|
2016-04-28 21:11:40 +09:00
|
|
|
});
|
|
|
|
}
|
2012-05-02 07:08:30 +09:00
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
function webViewerFindFromUrlHash(evt) {
|
2016-05-26 22:24:58 +09:00
|
|
|
PDFViewerApplication.findController.executeCommand('find', {
|
2017-06-29 19:14:26 +09:00
|
|
|
query: evt.query,
|
|
|
|
phraseSearch: evt.phraseSearch,
|
2016-05-26 22:24:58 +09:00
|
|
|
caseSensitive: false,
|
|
|
|
highlightAll: true,
|
Fix inconsistent spacing and trailing commas in objects in `web/` files, so we can enable the `comma-dangle` and `object-curly-spacing` ESLint rules later on
http://eslint.org/docs/rules/comma-dangle
http://eslint.org/docs/rules/object-curly-spacing
Given that we currently have quite inconsistent object formatting, fixing this in in *one* big patch probably wouldn't be feasible (since I cannot imagine anyone wanting to review that); hence I've opted to try and do this piecewise instead.
*Please note:* This patch was created automatically, using the ESLint `--fix` command line option. In a couple of places this caused lines to become too long, and I've fixed those manually; please refer to the interdiff below for the only hand-edits in this patch.
```diff
diff --git a/web/pdf_thumbnail_view.js b/web/pdf_thumbnail_view.js
index 002dbf29..1de4e530 100644
--- a/web/pdf_thumbnail_view.js
+++ b/web/pdf_thumbnail_view.js
@@ -420,8 +420,8 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() {
setPageLabel: function PDFThumbnailView_setPageLabel(label) {
this.pageLabel = (typeof label === 'string' ? label : null);
- this.l10n.get('thumb_page_title', { page: this.pageId, }, 'Page {{page}}').
- then((msg) => {
+ this.l10n.get('thumb_page_title', { page: this.pageId, },
+ 'Page {{page}}').then((msg) => {
this.anchor.title = msg;
});
diff --git a/web/secondary_toolbar.js b/web/secondary_toolbar.js
index 160e0410..6495fc5e 100644
--- a/web/secondary_toolbar.js
+++ b/web/secondary_toolbar.js
@@ -65,7 +65,8 @@ class SecondaryToolbar {
{ element: options.printButton, eventName: 'print', close: true, },
{ element: options.downloadButton, eventName: 'download', close: true, },
{ element: options.viewBookmarkButton, eventName: null, close: true, },
- { element: options.firstPageButton, eventName: 'firstpage', close: true, },
+ { element: options.firstPageButton, eventName: 'firstpage',
+ close: true, },
{ element: options.lastPageButton, eventName: 'lastpage', close: true, },
{ element: options.pageRotateCwButton, eventName: 'rotatecw',
close: false, },
@@ -76,7 +77,7 @@ class SecondaryToolbar {
{ element: options.cursorHandToolButton, eventName: 'switchcursortool',
eventDetails: { tool: CursorTool.HAND, }, close: true, },
{ element: options.documentPropertiesButton,
- eventName: 'documentproperties', close: true, }
+ eventName: 'documentproperties', close: true, },
];
this.items = {
firstPage: options.firstPageButton,
```
2017-06-01 19:46:12 +09:00
|
|
|
findPrevious: false,
|
2016-05-26 22:24:58 +09:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
function webViewerScaleChanging(evt) {
|
|
|
|
PDFViewerApplication.toolbar.setPageScale(evt.presetValue, evt.scale);
|
2016-06-27 19:32:28 +09:00
|
|
|
|
2015-07-23 23:02:39 +09:00
|
|
|
PDFViewerApplication.pdfViewer.update();
|
2016-04-26 07:57:15 +09:00
|
|
|
}
|
2011-07-30 01:17:04 +09:00
|
|
|
|
2017-08-19 21:23:40 +09:00
|
|
|
function webViewerRotationChanging(evt) {
|
|
|
|
PDFViewerApplication.pdfThumbnailViewer.pagesRotation = evt.pagesRotation;
|
|
|
|
|
|
|
|
PDFViewerApplication.forceRendering();
|
|
|
|
// Ensure that the active page doesn't change during rotation.
|
|
|
|
PDFViewerApplication.pdfViewer.currentPageNumber = evt.pageNumber;
|
|
|
|
}
|
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
function webViewerPageChanging(evt) {
|
|
|
|
let page = evt.pageNumber;
|
2016-02-22 01:54:23 +09:00
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
PDFViewerApplication.toolbar.setPageNumber(page, evt.pageLabel || null);
|
2016-11-19 03:50:29 +09:00
|
|
|
PDFViewerApplication.secondaryToolbar.setPageNumber(page);
|
Remove the `previousPageNumber` parameter from the `pagechanging`/pagechange` events, and stop dispatching the events if the input is out of bounds
This patch attempts to cleanup a couple of things:
- Remove the `previousPageNumber` paramater. Prior to PR 7289, when the events were dispatched even when the active page didn't change, it made sense to be able to detect that in an event listener. However, now that's no longer the case, and furthermore other similar events (e.g. `scalechanging`/`scalechange`) don't include information about the previous state.
- Don't dispatch the events when the value passed to `set currentPageNumber` is out of bounds. Given that the active page doesn't change in this case, again similar to PR 7289, I don't think that the events should actually be dispatched in this case.
- Ensure that the value passed to `set currentPageNumber` is actually an integer, to avoid any issues (note how e.g. `set currentScale` has similar validation code).
Given that these changes could possibly affect the PDF.js `mochitest` integration tests in mozilla-central, in particular https://dxr.mozilla.org/mozilla-central/source/browser/extensions/pdfjs/test/browser_pdfjs_navigation.js, I ran the tests locally with this patch applied to ensure that they still pass.
2016-07-22 22:32:14 +09:00
|
|
|
|
|
|
|
if (PDFViewerApplication.pdfSidebar.isThumbnailViewVisible) {
|
2016-06-27 19:32:28 +09:00
|
|
|
PDFViewerApplication.pdfThumbnailViewer.scrollThumbnailIntoView(page);
|
2012-04-14 06:14:05 +09:00
|
|
|
}
|
2014-09-13 11:27:45 +09:00
|
|
|
|
2018-02-18 07:13:49 +09:00
|
|
|
// We need to update stats.
|
2018-02-13 22:34:29 +09:00
|
|
|
if (typeof Stats !== 'undefined' && Stats.enabled) {
|
2017-06-29 19:14:26 +09:00
|
|
|
let pageView = PDFViewerApplication.pdfViewer.getPageView(page - 1);
|
[api-major] Only create a `StatTimer` for pages when `enableStats == true` (issue 5215)
Unless the debugging tools (i.e. `PDFBug`) are enabled, or the `browsertest` is running, the `PDFPageProxy.stats` aren't actually used for anything.
Rather than initializing unnecessary `StatTimer` instances, we can simply re-use *one* dummy class (with static methods) for every page. Note that by using a dummy `StatTimer` in this way, rather than letting `PDFPageProxy.stats` be undefined, we don't need to guard *every* single stats collection callsite.
Since it wouldn't make much sense to attempt to use `PDFPageProxy.stats` when stat collection is disabled, it was instead changed to a "private" property (i.e. `PDFPageProxy._stats`) and a getter was added for accessing `PDFPageProxy.stats`. This getter will now return `null` when stat collection is disabled, making that case easy to handle.
For benchmarking purposes, the test-suite used to re-create the `StatTimer` after loading/rendering each page. However, modifying properties on various API code from the outside in this way seems very error-prone, and is an anti-pattern that we really should avoid at all cost. Hence the `PDFPageProxy.cleanup` method was modified to accept an optional parameter, which will take care of resetting `this.stats` when necessary, and `test/driver.js` was updated accordingly.
Finally, a tiny bit more validation was added on the viewer side, to ensure that all the code we're attempting to access is defined when handling `PDFPageProxy` stats.
2017-12-07 00:30:04 +09:00
|
|
|
if (pageView && pageView.stats) {
|
2014-09-30 01:15:06 +09:00
|
|
|
Stats.add(page, pageView.stats);
|
|
|
|
}
|
|
|
|
}
|
2016-04-26 07:57:15 +09:00
|
|
|
}
|
2011-09-03 10:16:52 +09:00
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
let zoomDisabled = false, zoomDisabledTimeout;
|
2016-12-09 00:28:40 +09:00
|
|
|
function webViewerWheel(evt) {
|
2017-06-29 19:14:26 +09:00
|
|
|
let pdfViewer = PDFViewerApplication.pdfViewer;
|
2016-12-09 00:28:40 +09:00
|
|
|
if (pdfViewer.isInPresentationMode) {
|
2016-09-28 05:27:42 +09:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (evt.ctrlKey || evt.metaKey) {
|
2017-06-29 19:14:26 +09:00
|
|
|
let support = PDFViewerApplication.supportedMouseWheelZoomModifierKeys;
|
2015-06-02 20:17:02 +09:00
|
|
|
if ((evt.ctrlKey && !support.ctrlKey) ||
|
2016-04-08 04:03:04 +09:00
|
|
|
(evt.metaKey && !support.metaKey)) {
|
2015-06-02 20:17:02 +09:00
|
|
|
return;
|
|
|
|
}
|
2015-02-01 00:46:23 +09:00
|
|
|
// Only zoom the pages, not the entire viewer.
|
2014-10-16 05:03:13 +09:00
|
|
|
evt.preventDefault();
|
2016-04-08 04:03:04 +09:00
|
|
|
// NOTE: this check must be placed *after* preventDefault.
|
|
|
|
if (zoomDisabled) {
|
|
|
|
return;
|
|
|
|
}
|
2015-07-03 06:20:37 +09:00
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
let previousScale = pdfViewer.currentScale;
|
2015-07-03 06:20:37 +09:00
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
let delta = normalizeWheelEventDelta(evt);
|
2016-09-28 05:27:42 +09:00
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
const MOUSE_WHEEL_DELTA_PER_PAGE_SCALE = 3.0;
|
|
|
|
let ticks = delta * MOUSE_WHEEL_DELTA_PER_PAGE_SCALE;
|
2016-09-28 05:27:42 +09:00
|
|
|
if (ticks < 0) {
|
|
|
|
PDFViewerApplication.zoomOut(-ticks);
|
|
|
|
} else {
|
|
|
|
PDFViewerApplication.zoomIn(ticks);
|
|
|
|
}
|
2015-07-03 06:20:37 +09:00
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
let currentScale = pdfViewer.currentScale;
|
2015-07-03 06:20:37 +09:00
|
|
|
if (previousScale !== currentScale) {
|
|
|
|
// After scaling the page via zoomIn/zoomOut, the position of the upper-
|
|
|
|
// left corner is restored. When the mouse wheel is used, the position
|
|
|
|
// under the cursor should be restored instead.
|
2017-06-29 19:14:26 +09:00
|
|
|
let scaleCorrectionFactor = currentScale / previousScale - 1;
|
|
|
|
let rect = pdfViewer.container.getBoundingClientRect();
|
|
|
|
let dx = evt.clientX - rect.left;
|
|
|
|
let dy = evt.clientY - rect.top;
|
2015-07-03 06:20:37 +09:00
|
|
|
pdfViewer.container.scrollLeft += dx * scaleCorrectionFactor;
|
|
|
|
pdfViewer.container.scrollTop += dy * scaleCorrectionFactor;
|
|
|
|
}
|
2016-04-08 01:48:46 +09:00
|
|
|
} else {
|
|
|
|
zoomDisabled = true;
|
|
|
|
clearTimeout(zoomDisabledTimeout);
|
|
|
|
zoomDisabledTimeout = setTimeout(function () {
|
|
|
|
zoomDisabled = false;
|
|
|
|
}, 1000);
|
2012-06-08 04:27:26 +09:00
|
|
|
}
|
2014-01-29 04:52:25 +09:00
|
|
|
}
|
|
|
|
|
2016-12-09 00:28:40 +09:00
|
|
|
function webViewerClick(evt) {
|
2016-05-11 08:31:03 +09:00
|
|
|
if (!PDFViewerApplication.secondaryToolbar.isOpen) {
|
2016-04-29 05:04:09 +09:00
|
|
|
return;
|
|
|
|
}
|
2017-06-29 19:14:26 +09:00
|
|
|
let appConfig = PDFViewerApplication.appConfig;
|
2016-04-29 05:04:09 +09:00
|
|
|
if (PDFViewerApplication.pdfViewer.containsElement(evt.target) ||
|
|
|
|
(appConfig.toolbar.container.contains(evt.target) &&
|
|
|
|
evt.target !== appConfig.secondaryToolbar.toggleButton)) {
|
2016-05-11 08:31:03 +09:00
|
|
|
PDFViewerApplication.secondaryToolbar.close();
|
2012-10-06 11:55:47 +09:00
|
|
|
}
|
2016-12-09 00:28:40 +09:00
|
|
|
}
|
2012-10-06 11:55:47 +09:00
|
|
|
|
2016-12-09 00:28:40 +09:00
|
|
|
function webViewerKeyDown(evt) {
|
2017-05-26 21:52:23 +09:00
|
|
|
if (PDFViewerApplication.overlayManager.active) {
|
2013-09-25 00:46:54 +09:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
let handled = false, ensureViewerFocused = false;
|
|
|
|
let cmd = (evt.ctrlKey ? 1 : 0) |
|
2012-04-20 03:13:56 +09:00
|
|
|
(evt.altKey ? 2 : 0) |
|
|
|
|
(evt.shiftKey ? 4 : 0) |
|
|
|
|
(evt.metaKey ? 8 : 0);
|
2012-04-12 07:47:11 +09:00
|
|
|
|
2017-06-29 19:14:26 +09:00
|
|
|
let pdfViewer = PDFViewerApplication.pdfViewer;
|
|
|
|
let isViewerInPresentationMode = pdfViewer && pdfViewer.isInPresentationMode;
|
2015-01-29 21:37:49 +09:00
|
|
|
|
2012-04-12 07:47:11 +09:00
|
|
|
// First, handle the key bindings that are independent whether an input
|
|
|
|
// control is selected or not.
|
2013-03-12 01:04:43 +09:00
|
|
|
if (cmd === 1 || cmd === 8 || cmd === 5 || cmd === 12) {
|
|
|
|
// either CTRL or META key with optional SHIFT.
|
2012-04-12 07:47:11 +09:00
|
|
|
switch (evt.keyCode) {
|
2013-07-18 20:37:55 +09:00
|
|
|
case 70: // f
|
2014-09-22 20:41:17 +09:00
|
|
|
if (!PDFViewerApplication.supportsIntegratedFind) {
|
|
|
|
PDFViewerApplication.findBar.open();
|
2012-10-06 05:59:13 +09:00
|
|
|
handled = true;
|
|
|
|
}
|
2012-09-12 01:30:44 +09:00
|
|
|
break;
|
2013-07-18 20:37:55 +09:00
|
|
|
case 71: // g
|
2014-09-22 20:41:17 +09:00
|
|
|
if (!PDFViewerApplication.supportsIntegratedFind) {
|
2017-06-29 19:14:26 +09:00
|
|
|
let findState = PDFViewerApplication.findController.state;
|
2016-04-28 21:11:40 +09:00
|
|
|
if (findState) {
|
|
|
|
PDFViewerApplication.findController.executeCommand('findagain', {
|
|
|
|
query: findState.query,
|
2016-05-26 22:24:58 +09:00
|
|
|
phraseSearch: findState.phraseSearch,
|
2016-04-28 21:11:40 +09:00
|
|
|
caseSensitive: findState.caseSensitive,
|
|
|
|
highlightAll: findState.highlightAll,
|
Fix inconsistent spacing and trailing commas in objects in `web/` files, so we can enable the `comma-dangle` and `object-curly-spacing` ESLint rules later on
http://eslint.org/docs/rules/comma-dangle
http://eslint.org/docs/rules/object-curly-spacing
Given that we currently have quite inconsistent object formatting, fixing this in in *one* big patch probably wouldn't be feasible (since I cannot imagine anyone wanting to review that); hence I've opted to try and do this piecewise instead.
*Please note:* This patch was created automatically, using the ESLint `--fix` command line option. In a couple of places this caused lines to become too long, and I've fixed those manually; please refer to the interdiff below for the only hand-edits in this patch.
```diff
diff --git a/web/pdf_thumbnail_view.js b/web/pdf_thumbnail_view.js
index 002dbf29..1de4e530 100644
--- a/web/pdf_thumbnail_view.js
+++ b/web/pdf_thumbnail_view.js
@@ -420,8 +420,8 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() {
setPageLabel: function PDFThumbnailView_setPageLabel(label) {
this.pageLabel = (typeof label === 'string' ? label : null);
- this.l10n.get('thumb_page_title', { page: this.pageId, }, 'Page {{page}}').
- then((msg) => {
+ this.l10n.get('thumb_page_title', { page: this.pageId, },
+ 'Page {{page}}').then((msg) => {
this.anchor.title = msg;
});
diff --git a/web/secondary_toolbar.js b/web/secondary_toolbar.js
index 160e0410..6495fc5e 100644
--- a/web/secondary_toolbar.js
+++ b/web/secondary_toolbar.js
@@ -65,7 +65,8 @@ class SecondaryToolbar {
{ element: options.printButton, eventName: 'print', close: true, },
{ element: options.downloadButton, eventName: 'download', close: true, },
{ element: options.viewBookmarkButton, eventName: null, close: true, },
- { element: options.firstPageButton, eventName: 'firstpage', close: true, },
+ { element: options.firstPageButton, eventName: 'firstpage',
+ close: true, },
{ element: options.lastPageButton, eventName: 'lastpage', close: true, },
{ element: options.pageRotateCwButton, eventName: 'rotatecw',
close: false, },
@@ -76,7 +77,7 @@ class SecondaryToolbar {
{ element: options.cursorHandToolButton, eventName: 'switchcursortool',
eventDetails: { tool: CursorTool.HAND, }, close: true, },
{ element: options.documentPropertiesButton,
- eventName: 'documentproperties', close: true, }
+ eventName: 'documentproperties', close: true, },
];
this.items = {
firstPage: options.firstPageButton,
```
2017-06-01 19:46:12 +09:00
|
|
|
findPrevious: cmd === 5 || cmd === 12,
|
2016-04-28 21:11:40 +09:00
|
|
|
});
|
|
|
|
}
|
2013-07-18 20:37:55 +09:00
|
|
|
handled = true;
|
|
|
|
}
|
|
|
|
break;
|
2012-04-12 07:47:11 +09:00
|
|
|
case 61: // FF/Mac '='
|
|
|
|
case 107: // FF '+' and '='
|
|
|
|
case 187: // Chrome '+'
|
2012-12-11 06:39:35 +09:00
|
|
|
case 171: // FF with German keyboard
|
2015-01-29 21:37:49 +09:00
|
|
|
if (!isViewerInPresentationMode) {
|
2014-10-16 05:03:13 +09:00
|
|
|
PDFViewerApplication.zoomIn();
|
|
|
|
}
|
2012-04-12 07:47:11 +09:00
|
|
|
handled = true;
|
|
|
|
break;
|
2012-09-11 01:28:45 +09:00
|
|
|
case 173: // FF/Mac '-'
|
2012-04-12 07:47:11 +09:00
|
|
|
case 109: // FF '-'
|
|
|
|
case 189: // Chrome '-'
|
2015-01-29 21:37:49 +09:00
|
|
|
if (!isViewerInPresentationMode) {
|
2014-10-16 05:03:13 +09:00
|
|
|
PDFViewerApplication.zoomOut();
|
|
|
|
}
|
2012-04-12 07:47:11 +09:00
|
|
|
handled = true;
|
|
|
|
break;
|
|
|
|
case 48: // '0'
|
2012-12-12 07:59:33 +09:00
|
|
|
case 96: // '0' on Numpad of Swedish keyboard
|
2015-01-29 21:37:49 +09:00
|
|
|
if (!isViewerInPresentationMode) {
|
2014-10-16 05:03:13 +09:00
|
|
|
// keeping it unhandled (to restore page zoom to 100%)
|
|
|
|
setTimeout(function () {
|
|
|
|
// ... and resetting the scale after browser adjusts its scale
|
2015-07-11 18:47:45 +09:00
|
|
|
pdfViewer.currentScaleValue = DEFAULT_SCALE_VALUE;
|
2014-10-16 05:03:13 +09:00
|
|
|
});
|
|
|
|
handled = false;
|
|
|
|
}
|
2012-04-12 07:47:11 +09:00
|
|
|
break;
|
2016-12-01 01:19:11 +09:00
|
|
|
|
|
|
|
case 38: // up arrow
|
|
|
|
if (isViewerInPresentationMode || PDFViewerApplication.page > 1) {
|
|
|
|
PDFViewerApplication.page = 1;
|
|
|
|
handled = true;
|
|
|
|
ensureViewerFocused = true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 40: // down arrow
|
|
|
|
if (isViewerInPresentationMode ||
|
|
|
|
PDFViewerApplication.page < PDFViewerApplication.pagesCount) {
|
|
|
|
PDFViewerApplication.page = PDFViewerApplication.pagesCount;
|
|
|
|
handled = true;
|
|
|
|
ensureViewerFocused = true;
|
|
|
|
}
|
|
|
|
break;
|
2012-04-12 07:47:11 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-15 00:57:53 +09:00
|
|
|
if (typeof PDFJSDev === 'undefined' ||
|
|
|
|
!PDFJSDev.test('FIREFOX || MOZCENTRAL')) {
|
|
|
|
// CTRL or META without shift
|
|
|
|
if (cmd === 1 || cmd === 8) {
|
|
|
|
switch (evt.keyCode) {
|
|
|
|
case 83: // s
|
|
|
|
PDFViewerApplication.download();
|
|
|
|
handled = true;
|
|
|
|
break;
|
|
|
|
}
|
2014-02-28 00:08:43 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-18 23:28:06 +09:00
|
|
|
// CTRL+ALT or Option+Command
|
|
|
|
if (cmd === 3 || cmd === 10) {
|
|
|
|
switch (evt.keyCode) {
|
|
|
|
case 80: // p
|
2015-01-29 21:37:49 +09:00
|
|
|
PDFViewerApplication.requestPresentationMode();
|
2013-07-18 23:28:06 +09:00
|
|
|
handled = true;
|
|
|
|
break;
|
2013-11-12 13:47:03 +09:00
|
|
|
case 71: // g
|
|
|
|
// focuses input#pageNumber field
|
2016-04-22 01:39:11 +09:00
|
|
|
PDFViewerApplication.appConfig.toolbar.pageNumber.select();
|
2013-11-12 13:47:03 +09:00
|
|
|
handled = true;
|
|
|
|
break;
|
2013-07-18 23:28:06 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-12 07:47:11 +09:00
|
|
|
if (handled) {
|
2016-12-01 01:19:11 +09:00
|
|
|
if (ensureViewerFocused && !isViewerInPresentationMode) {
|
|
|
|
pdfViewer.focus();
|
|
|
|
}
|
2012-04-12 07:47:11 +09:00
|
|
|
evt.preventDefault();
|
2011-12-26 06:18:52 +09:00
|
|
|
return;
|
2012-04-12 07:47:11 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
// Some shortcuts should not get handled if a control/input element
|
|
|
|
// is selected.
|
2017-06-29 19:14:26 +09:00
|
|
|
let curElement = document.activeElement || document.querySelector(':focus');
|
|
|
|
let curElementTagName = curElement && curElement.tagName.toUpperCase();
|
2014-01-31 00:54:12 +09:00
|
|
|
if (curElementTagName === 'INPUT' ||
|
|
|
|
curElementTagName === 'TEXTAREA' ||
|
|
|
|
curElementTagName === 'SELECT') {
|
2013-09-05 06:48:31 +09:00
|
|
|
// Make sure that the secondary toolbar is closed when Escape is pressed.
|
|
|
|
if (evt.keyCode !== 27) { // 'Esc'
|
|
|
|
return;
|
|
|
|
}
|
2012-10-02 06:32:02 +09:00
|
|
|
}
|
2012-04-11 01:55:52 +09:00
|
|
|
|
2013-02-05 03:01:19 +09:00
|
|
|
if (cmd === 0) { // no control key pressed at all.
|
2018-05-15 12:10:32 +09:00
|
|
|
let turnPage = 0, turnOnlyIfPageFit = false;
|
2012-04-11 01:55:52 +09:00
|
|
|
switch (evt.keyCode) {
|
2012-10-06 11:55:47 +09:00
|
|
|
case 38: // up arrow
|
|
|
|
case 33: // pg up
|
2018-05-15 12:10:32 +09:00
|
|
|
// vertical scrolling using arrow/pg keys
|
|
|
|
if (pdfViewer.isVerticalScrollbarEnabled) {
|
|
|
|
turnOnlyIfPageFit = true;
|
|
|
|
}
|
|
|
|
turnPage = -1;
|
|
|
|
break;
|
2012-10-06 11:55:47 +09:00
|
|
|
case 8: // backspace
|
2018-05-15 12:10:32 +09:00
|
|
|
if (!isViewerInPresentationMode) {
|
|
|
|
turnOnlyIfPageFit = true;
|
2012-10-06 11:55:47 +09:00
|
|
|
}
|
2018-05-15 12:10:32 +09:00
|
|
|
turnPage = -1;
|
|
|
|
break;
|
2012-04-11 01:55:52 +09:00
|
|
|
case 37: // left arrow
|
2012-12-14 05:10:21 +09:00
|
|
|
// horizontal scrolling using arrow keys
|
2015-01-29 21:37:49 +09:00
|
|
|
if (pdfViewer.isHorizontalScrollbarEnabled) {
|
2018-05-15 12:10:32 +09:00
|
|
|
turnOnlyIfPageFit = true;
|
2012-12-14 05:10:21 +09:00
|
|
|
}
|
2013-02-05 03:01:19 +09:00
|
|
|
/* falls through */
|
2012-04-11 01:55:52 +09:00
|
|
|
case 75: // 'k'
|
|
|
|
case 80: // 'p'
|
2018-05-15 12:10:32 +09:00
|
|
|
turnPage = -1;
|
2012-04-11 01:55:52 +09:00
|
|
|
break;
|
2013-02-11 00:14:17 +09:00
|
|
|
case 27: // esc key
|
2016-05-11 08:31:03 +09:00
|
|
|
if (PDFViewerApplication.secondaryToolbar.isOpen) {
|
|
|
|
PDFViewerApplication.secondaryToolbar.close();
|
2013-09-05 06:48:31 +09:00
|
|
|
handled = true;
|
|
|
|
}
|
2014-09-22 20:41:17 +09:00
|
|
|
if (!PDFViewerApplication.supportsIntegratedFind &&
|
|
|
|
PDFViewerApplication.findBar.opened) {
|
|
|
|
PDFViewerApplication.findBar.close();
|
2013-02-11 00:14:17 +09:00
|
|
|
handled = true;
|
|
|
|
}
|
|
|
|
break;
|
2012-10-06 11:55:47 +09:00
|
|
|
case 40: // down arrow
|
|
|
|
case 34: // pg down
|
2018-05-15 12:10:32 +09:00
|
|
|
// vertical scrolling using arrow/pg keys
|
|
|
|
if (pdfViewer.isVerticalScrollbarEnabled) {
|
|
|
|
turnOnlyIfPageFit = true;
|
|
|
|
}
|
|
|
|
turnPage = 1;
|
|
|
|
break;
|
|
|
|
case 13: // enter key
|
2012-10-06 11:55:47 +09:00
|
|
|
case 32: // spacebar
|
2018-05-15 12:10:32 +09:00
|
|
|
if (!isViewerInPresentationMode) {
|
|
|
|
turnOnlyIfPageFit = true;
|
2012-10-06 11:55:47 +09:00
|
|
|
}
|
2018-05-15 12:10:32 +09:00
|
|
|
turnPage = 1;
|
|
|
|
break;
|
2012-04-11 01:55:52 +09:00
|
|
|
case 39: // right arrow
|
2012-12-14 05:10:21 +09:00
|
|
|
// horizontal scrolling using arrow keys
|
2015-01-29 21:37:49 +09:00
|
|
|
if (pdfViewer.isHorizontalScrollbarEnabled) {
|
2018-05-15 12:10:32 +09:00
|
|
|
turnOnlyIfPageFit = true;
|
2012-12-14 05:10:21 +09:00
|
|
|
}
|
2013-02-05 03:01:19 +09:00
|
|
|
/* falls through */
|
2012-04-11 01:55:52 +09:00
|
|
|
case 74: // 'j'
|
|
|
|
case 78: // 'n'
|
2018-05-15 12:10:32 +09:00
|
|
|
turnPage = 1;
|
2012-04-11 01:55:52 +09:00
|
|
|
break;
|
2012-07-31 00:12:49 +09:00
|
|
|
|
2012-10-06 11:55:47 +09:00
|
|
|
case 36: // home
|
2015-01-29 21:37:49 +09:00
|
|
|
if (isViewerInPresentationMode || PDFViewerApplication.page > 1) {
|
2014-09-22 20:41:17 +09:00
|
|
|
PDFViewerApplication.page = 1;
|
2012-10-06 11:55:47 +09:00
|
|
|
handled = true;
|
2015-07-23 19:25:19 +09:00
|
|
|
ensureViewerFocused = true;
|
2012-10-06 11:55:47 +09:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 35: // end
|
2016-08-07 20:10:50 +09:00
|
|
|
if (isViewerInPresentationMode ||
|
|
|
|
PDFViewerApplication.page < PDFViewerApplication.pagesCount) {
|
2014-09-22 20:41:17 +09:00
|
|
|
PDFViewerApplication.page = PDFViewerApplication.pagesCount;
|
2012-07-31 00:12:49 +09:00
|
|
|
handled = true;
|
2015-07-23 19:25:19 +09:00
|
|
|
ensureViewerFocused = true;
|
2012-07-31 00:12:49 +09:00
|
|
|
}
|
|
|
|
break;
|
2012-09-08 08:05:14 +09:00
|
|
|
|
2016-09-07 20:30:26 +09:00
|
|
|
case 83: // 's'
|
|
|
|
PDFViewerApplication.pdfCursorTools.switchTool(CursorTool.SELECT);
|
|
|
|
break;
|
2013-10-03 05:09:43 +09:00
|
|
|
case 72: // 'h'
|
2016-09-07 20:30:26 +09:00
|
|
|
PDFViewerApplication.pdfCursorTools.switchTool(CursorTool.HAND);
|
2013-10-03 05:09:43 +09:00
|
|
|
break;
|
2016-09-07 20:30:26 +09:00
|
|
|
|
2012-09-08 08:05:14 +09:00
|
|
|
case 82: // 'r'
|
2014-09-22 20:41:17 +09:00
|
|
|
PDFViewerApplication.rotatePages(90);
|
2012-09-08 08:05:14 +09:00
|
|
|
break;
|
|
|
|
}
|
2018-05-15 12:10:32 +09:00
|
|
|
|
|
|
|
if (turnPage !== 0 &&
|
|
|
|
(!turnOnlyIfPageFit || pdfViewer.currentScaleValue === 'page-fit')) {
|
|
|
|
if (turnPage > 0) {
|
|
|
|
if (PDFViewerApplication.page < PDFViewerApplication.pagesCount) {
|
|
|
|
PDFViewerApplication.page++;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (PDFViewerApplication.page > 1) {
|
|
|
|
PDFViewerApplication.page--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
handled = true;
|
|
|
|
}
|
2012-09-08 08:05:14 +09:00
|
|
|
}
|
|
|
|
|
2013-05-16 07:31:17 +09:00
|
|
|
if (cmd === 4) { // shift-key
|
2012-09-08 08:05:14 +09:00
|
|
|
switch (evt.keyCode) {
|
2018-01-05 03:54:19 +09:00
|
|
|
case 13: // enter key
|
2013-06-27 05:25:47 +09:00
|
|
|
case 32: // spacebar
|
2015-01-29 21:37:49 +09:00
|
|
|
if (!isViewerInPresentationMode &&
|
2015-07-07 16:17:05 +09:00
|
|
|
pdfViewer.currentScaleValue !== 'page-fit') {
|
2013-06-27 05:25:47 +09:00
|
|
|
break;
|
|
|
|
}
|
2016-08-07 20:10:50 +09:00
|
|
|
if (PDFViewerApplication.page > 1) {
|
|
|
|
PDFViewerApplication.page--;
|
|
|
|
}
|
2013-06-27 05:25:47 +09:00
|
|
|
handled = true;
|
|
|
|
break;
|
|
|
|
|
2012-09-08 08:05:14 +09:00
|
|
|
case 82: // 'r'
|
2014-09-22 20:41:17 +09:00
|
|
|
PDFViewerApplication.rotatePages(-90);
|
2012-09-08 08:05:14 +09:00
|
|
|
break;
|
2012-04-11 01:55:52 +09:00
|
|
|
}
|
2011-09-03 10:16:52 +09:00
|
|
|
}
|
2011-12-19 04:42:06 +09:00
|
|
|
|
2015-01-29 21:37:49 +09:00
|
|
|
if (!handled && !isViewerInPresentationMode) {
|
2014-02-27 21:33:35 +09:00
|
|
|
// 33=Page Up 34=Page Down 35=End 36=Home
|
|
|
|
// 37=Left 38=Up 39=Right 40=Down
|
|
|
|
// 32=Spacebar
|
2015-07-23 19:25:19 +09:00
|
|
|
if ((evt.keyCode >= 33 && evt.keyCode <= 40) ||
|
|
|
|
(evt.keyCode === 32 && curElementTagName !== 'BUTTON')) {
|
|
|
|
ensureViewerFocused = true;
|
2014-02-27 21:33:35 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-23 19:25:19 +09:00
|
|
|
if (ensureViewerFocused && !pdfViewer.containsElement(curElement)) {
|
|
|
|
// The page container is not focused, but a page navigation key has been
|
|
|
|
// pressed. Change the focus to the viewer container to make sure that
|
|
|
|
// navigation by keyboard works as expected.
|
|
|
|
pdfViewer.focus();
|
|
|
|
}
|
|
|
|
|
2011-12-19 04:42:06 +09:00
|
|
|
if (handled) {
|
|
|
|
evt.preventDefault();
|
|
|
|
}
|
2016-12-09 00:28:40 +09:00
|
|
|
}
|
2012-07-31 00:12:49 +09:00
|
|
|
|
2017-07-19 23:26:17 +09:00
|
|
|
/**
|
|
|
|
* Converts API PageMode values to the format used by `PDFSidebar`.
|
|
|
|
* NOTE: There's also a "FullScreen" parameter which is not possible to support,
|
|
|
|
* since the Fullscreen API used in browsers requires that entering
|
|
|
|
* fullscreen mode only occurs as a result of a user-initiated event.
|
|
|
|
* @param {string} mode - The API PageMode value.
|
|
|
|
* @returns {number} A value from {SidebarView}.
|
|
|
|
*/
|
|
|
|
function apiPageModeToSidebarView(mode) {
|
|
|
|
switch (mode) {
|
|
|
|
case 'UseNone':
|
|
|
|
return SidebarView.NONE;
|
|
|
|
case 'UseThumbs':
|
|
|
|
return SidebarView.THUMBS;
|
|
|
|
case 'UseOutlines':
|
|
|
|
return SidebarView.OUTLINE;
|
|
|
|
case 'UseAttachments':
|
|
|
|
return SidebarView.ATTACHMENTS;
|
|
|
|
case 'UseOC':
|
|
|
|
// Not implemented, since we don't support Optional Content Groups yet.
|
|
|
|
}
|
|
|
|
return SidebarView.NONE; // Default value.
|
|
|
|
}
|
|
|
|
|
2016-10-07 06:46:30 +09:00
|
|
|
/* Abstract factory for the print service. */
|
2017-06-29 19:14:26 +09:00
|
|
|
let PDFPrintServiceFactory = {
|
2016-10-07 06:46:30 +09:00
|
|
|
instance: {
|
|
|
|
supportsPrinting: false,
|
2017-04-28 19:02:42 +09:00
|
|
|
createPrintService() {
|
2016-10-07 06:46:30 +09:00
|
|
|
throw new Error('Not implemented: createPrintService');
|
Fix inconsistent spacing and trailing commas in objects in `web/` files, so we can enable the `comma-dangle` and `object-curly-spacing` ESLint rules later on
http://eslint.org/docs/rules/comma-dangle
http://eslint.org/docs/rules/object-curly-spacing
Given that we currently have quite inconsistent object formatting, fixing this in in *one* big patch probably wouldn't be feasible (since I cannot imagine anyone wanting to review that); hence I've opted to try and do this piecewise instead.
*Please note:* This patch was created automatically, using the ESLint `--fix` command line option. In a couple of places this caused lines to become too long, and I've fixed those manually; please refer to the interdiff below for the only hand-edits in this patch.
```diff
diff --git a/web/pdf_thumbnail_view.js b/web/pdf_thumbnail_view.js
index 002dbf29..1de4e530 100644
--- a/web/pdf_thumbnail_view.js
+++ b/web/pdf_thumbnail_view.js
@@ -420,8 +420,8 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() {
setPageLabel: function PDFThumbnailView_setPageLabel(label) {
this.pageLabel = (typeof label === 'string' ? label : null);
- this.l10n.get('thumb_page_title', { page: this.pageId, }, 'Page {{page}}').
- then((msg) => {
+ this.l10n.get('thumb_page_title', { page: this.pageId, },
+ 'Page {{page}}').then((msg) => {
this.anchor.title = msg;
});
diff --git a/web/secondary_toolbar.js b/web/secondary_toolbar.js
index 160e0410..6495fc5e 100644
--- a/web/secondary_toolbar.js
+++ b/web/secondary_toolbar.js
@@ -65,7 +65,8 @@ class SecondaryToolbar {
{ element: options.printButton, eventName: 'print', close: true, },
{ element: options.downloadButton, eventName: 'download', close: true, },
{ element: options.viewBookmarkButton, eventName: null, close: true, },
- { element: options.firstPageButton, eventName: 'firstpage', close: true, },
+ { element: options.firstPageButton, eventName: 'firstpage',
+ close: true, },
{ element: options.lastPageButton, eventName: 'lastpage', close: true, },
{ element: options.pageRotateCwButton, eventName: 'rotatecw',
close: false, },
@@ -76,7 +77,7 @@ class SecondaryToolbar {
{ element: options.cursorHandToolButton, eventName: 'switchcursortool',
eventDetails: { tool: CursorTool.HAND, }, close: true, },
{ element: options.documentPropertiesButton,
- eventName: 'documentproperties', close: true, }
+ eventName: 'documentproperties', close: true, },
];
this.items = {
firstPage: options.firstPageButton,
```
2017-06-01 19:46:12 +09:00
|
|
|
},
|
|
|
|
},
|
2016-10-07 06:46:30 +09:00
|
|
|
};
|
|
|
|
|
2017-03-28 08:07:27 +09:00
|
|
|
export {
|
|
|
|
PDFViewerApplication,
|
|
|
|
DefaultExternalServices,
|
|
|
|
PDFPrintServiceFactory,
|
|
|
|
};
|