diff --git a/browser/extensions/pdfjs/README.mozilla b/browser/extensions/pdfjs/README.mozilla
index be7a4066618..bd5d5b3c37a 100644
--- a/browser/extensions/pdfjs/README.mozilla
+++ b/browser/extensions/pdfjs/README.mozilla
@@ -1,3 +1,3 @@
This is the pdf.js project output, https://github.com/mozilla/pdf.js
-Current extension version is: 1.1.24
+Current extension version is: 1.1.82
diff --git a/browser/extensions/pdfjs/content/PdfStreamConverter.jsm b/browser/extensions/pdfjs/content/PdfStreamConverter.jsm
index 11109f5005e..dc3e1c0ca3f 100644
--- a/browser/extensions/pdfjs/content/PdfStreamConverter.jsm
+++ b/browser/extensions/pdfjs/content/PdfStreamConverter.jsm
@@ -459,8 +459,6 @@ ChromeActions.prototype = {
var winmm = this.domWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDocShell)
- .sameTypeRootTreeItem
- .QueryInterface(Ci.nsIDocShell)
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIContentFrameMessageManager);
@@ -773,8 +771,6 @@ function FindEventManager(contentWindow) {
this.contentWindow = contentWindow;
this.winmm = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDocShell)
- .sameTypeRootTreeItem
- .QueryInterface(Ci.nsIDocShell)
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIContentFrameMessageManager);
}
diff --git a/browser/extensions/pdfjs/content/PdfjsChromeUtils.jsm b/browser/extensions/pdfjs/content/PdfjsChromeUtils.jsm
index 13ea294e519..2e0c4db56cf 100644
--- a/browser/extensions/pdfjs/content/PdfjsChromeUtils.jsm
+++ b/browser/extensions/pdfjs/content/PdfjsChromeUtils.jsm
@@ -194,9 +194,8 @@ let PdfjsChromeUtils = {
},
handleEvent: function(aEvent) {
- // We cannot just forward the message as a CPOW without setting up
- // __exposedProps__ on it. Instead, let's just create a structured
- // cloneable version of the event for performance and for the ease of usage.
+ // To avoid forwarding the message as a CPOW, create a structured cloneable
+ // version of the event for both performance, and ease of usage, reasons.
let type = aEvent.type;
let detail = {
query: aEvent.detail.query,
@@ -205,16 +204,16 @@ let PdfjsChromeUtils = {
findPrevious: aEvent.detail.findPrevious
};
- let chromeWindow = aEvent.target.ownerDocument.defaultView;
- let browser = chromeWindow.gBrowser.selectedBrowser;
- if (this._browsers.has(browser)) {
- // Only forward the events if the selected browser is a registered
- // browser.
- let mm = browser.messageManager;
- mm.sendAsyncMessage('PDFJS:Child:handleEvent',
- { type: type, detail: detail });
- aEvent.preventDefault();
+ let browser = aEvent.currentTarget.browser;
+ if (!this._browsers.has(browser)) {
+ throw new Error('FindEventManager was not bound ' +
+ 'for the current browser.');
}
+ // Only forward the events if the current browser is a registered browser.
+ let mm = browser.messageManager;
+ mm.sendAsyncMessage('PDFJS:Child:handleEvent',
+ { type: type, detail: detail });
+ aEvent.preventDefault();
},
_types: ['find',
diff --git a/browser/extensions/pdfjs/content/build/pdf.js b/browser/extensions/pdfjs/content/build/pdf.js
index acdecab72ad..a0d00c0c260 100644
--- a/browser/extensions/pdfjs/content/build/pdf.js
+++ b/browser/extensions/pdfjs/content/build/pdf.js
@@ -22,8 +22,8 @@ if (typeof PDFJS === 'undefined') {
(typeof window !== 'undefined' ? window : this).PDFJS = {};
}
-PDFJS.version = '1.1.24';
-PDFJS.build = 'f6a8110';
+PDFJS.version = '1.1.82';
+PDFJS.build = '71ab5e5';
(function pdfjsWrapper() {
// Use strict in our context only - users might not want it
@@ -239,17 +239,10 @@ function warn(msg) {
// Fatal errors that should trigger the fallback UI and halt execution by
// throwing an exception.
function error(msg) {
- // If multiple arguments were passed, pass them all to the log function.
- if (arguments.length > 1) {
- var logArguments = ['Error:'];
- logArguments.push.apply(logArguments, arguments);
- console.log.apply(console, logArguments);
- // Join the arguments into a single string for the lines below.
- msg = [].join.call(arguments, ' ');
- } else {
+ if (PDFJS.verbosity >= PDFJS.VERBOSITY_LEVELS.errors) {
console.log('Error: ' + msg);
+ console.log(backtrace());
}
- console.log(backtrace());
UnsupportedManager.notify(UNSUPPORTED_FEATURES.unknown);
throw new Error(msg);
}
diff --git a/browser/extensions/pdfjs/content/build/pdf.worker.js b/browser/extensions/pdfjs/content/build/pdf.worker.js
index 943fcc6aaeb..4e497e9a85f 100644
--- a/browser/extensions/pdfjs/content/build/pdf.worker.js
+++ b/browser/extensions/pdfjs/content/build/pdf.worker.js
@@ -22,8 +22,8 @@ if (typeof PDFJS === 'undefined') {
(typeof window !== 'undefined' ? window : this).PDFJS = {};
}
-PDFJS.version = '1.1.24';
-PDFJS.build = 'f6a8110';
+PDFJS.version = '1.1.82';
+PDFJS.build = '71ab5e5';
(function pdfjsWrapper() {
// Use strict in our context only - users might not want it
@@ -239,17 +239,10 @@ function warn(msg) {
// Fatal errors that should trigger the fallback UI and halt execution by
// throwing an exception.
function error(msg) {
- // If multiple arguments were passed, pass them all to the log function.
- if (arguments.length > 1) {
- var logArguments = ['Error:'];
- logArguments.push.apply(logArguments, arguments);
- console.log.apply(console, logArguments);
- // Join the arguments into a single string for the lines below.
- msg = [].join.call(arguments, ' ');
- } else {
+ if (PDFJS.verbosity >= PDFJS.VERBOSITY_LEVELS.errors) {
console.log('Error: ' + msg);
+ console.log(backtrace());
}
- console.log(backtrace());
UnsupportedManager.notify(UNSUPPORTED_FEATURES.unknown);
throw new Error(msg);
}
@@ -3126,6 +3119,7 @@ var Catalog = (function CatalogClosure() {
var nodesToVisit = [this.catDict.getRaw('Pages')];
var currentPageIndex = 0;
var xref = this.xref;
+ var checkAllKids = false;
function next() {
while (nodesToVisit.length) {
@@ -3133,7 +3127,7 @@ var Catalog = (function CatalogClosure() {
if (isRef(currentNode)) {
xref.fetchAsync(currentNode).then(function (obj) {
- if ((isDict(obj, 'Page') || (isDict(obj) && !obj.has('Kids')))) {
+ if (isDict(obj, 'Page') || (isDict(obj) && !obj.has('Kids'))) {
if (pageIndex === currentPageIndex) {
capability.resolve([obj, currentNode]);
} else {
@@ -3148,12 +3142,17 @@ var Catalog = (function CatalogClosure() {
return;
}
- // must be a child page dictionary
+ // Must be a child page dictionary.
assert(
isDict(currentNode),
'page dictionary kid reference points to wrong type of object'
);
var count = currentNode.get('Count');
+ // If the current node doesn't have any children, avoid getting stuck
+ // in an empty node further down in the tree (see issue5644.pdf).
+ if (count === 0) {
+ checkAllKids = true;
+ }
// Skip nodes where the page can't be.
if (currentPageIndex + count <= pageIndex) {
currentPageIndex += count;
@@ -3162,7 +3161,7 @@ var Catalog = (function CatalogClosure() {
var kids = currentNode.get('Kids');
assert(isArray(kids), 'page dictionary kids object is not an array');
- if (count === kids.length) {
+ if (!checkAllKids && count === kids.length) {
// Nodes that don't have the page have been skipped and this is the
// bottom of the tree which means the page requested must be a
// descendant of this pages node. Ideally we would just resolve the
@@ -9140,7 +9139,7 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
this.cf = dict.get('CF');
this.stmf = dict.get('StmF') || identityName;
this.strf = dict.get('StrF') || identityName;
- this.eff = dict.get('EFF') || this.strf;
+ this.eff = dict.get('EFF') || this.stmf;
}
}
@@ -9215,6 +9214,7 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
return CipherTransformFactory;
})();
+
var PatternType = {
FUNCTION_BASED: 1,
AXIAL: 2,
@@ -16191,6 +16191,38 @@ var Font = (function FontClosure() {
return readUint32(header, 0) === 0x00010000;
}
+ /**
+ * Helper function for |adjustMapping|.
+ * @return {boolean}
+ */
+ function isProblematicUnicodeLocation(code) {
+ if (code <= 0x1F) { // Control chars
+ return true;
+ }
+ if (code >= 0x80 && code <= 0x9F) { // Control chars
+ return true;
+ }
+ if ((code >= 0x2000 && code <= 0x200F) || // General punctuation chars
+ (code >= 0x2028 && code <= 0x202F) ||
+ (code >= 0x2060 && code <= 0x206F)) {
+ return true;
+ }
+ if (code >= 0xFFF0 && code <= 0xFFFF) { // Specials Unicode block
+ return true;
+ }
+ switch (code) {
+ case 0x7F: // Control char
+ case 0xA0: // Non breaking space
+ case 0xAD: // Soft hyphen
+ case 0x0E33: // Thai character SARA AM
+ case 0x2011: // Non breaking hyphen
+ case 0x205F: // Medium mathematical space
+ case 0x25CC: // Dotted circle (combining mark)
+ return true;
+ }
+ return false;
+ }
+
/**
* Rebuilds the char code to glyph ID map by trying to replace the char codes
* with their unicode value. It also moves char codes that are in known
@@ -16230,15 +16262,7 @@ var Font = (function FontClosure() {
// characters probably aren't in the correct position (fixes an issue
// with firefox and thuluthfont).
if ((usedFontCharCodes[fontCharCode] !== undefined ||
- fontCharCode <= 0x1f || // Control chars
- fontCharCode === 0x7F || // Control char
- fontCharCode === 0xAD || // Soft hyphen
- fontCharCode === 0xA0 || // Non breaking space
- fontCharCode === 0x0E33 || // Thai character SARA AM
- fontCharCode === 0x25CC || // Dotted circle (combining mark)
- (fontCharCode >= 0x80 && fontCharCode <= 0x9F) || // Control chars
- // Prevent drawing characters in the specials unicode block.
- (fontCharCode >= 0xFFF0 && fontCharCode <= 0xFFFF) ||
+ isProblematicUnicodeLocation(fontCharCode) ||
(isSymbolic && isIdentityUnicode)) &&
nextAvailableFontCharCode <= PRIVATE_USE_OFFSET_END) { // Room left.
// Loop to try and find a free spot in the private use area.
@@ -30995,25 +31019,25 @@ var StreamsSequenceStream = (function StreamsSequenceStreamClosure() {
})();
var FlateStream = (function FlateStreamClosure() {
- var codeLenCodeMap = new Uint32Array([
+ var codeLenCodeMap = new Int32Array([
16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
]);
- var lengthDecode = new Uint32Array([
+ var lengthDecode = new Int32Array([
0x00003, 0x00004, 0x00005, 0x00006, 0x00007, 0x00008, 0x00009, 0x0000a,
0x1000b, 0x1000d, 0x1000f, 0x10011, 0x20013, 0x20017, 0x2001b, 0x2001f,
0x30023, 0x3002b, 0x30033, 0x3003b, 0x40043, 0x40053, 0x40063, 0x40073,
0x50083, 0x500a3, 0x500c3, 0x500e3, 0x00102, 0x00102, 0x00102
]);
- var distDecode = new Uint32Array([
+ var distDecode = new Int32Array([
0x00001, 0x00002, 0x00003, 0x00004, 0x10005, 0x10007, 0x20009, 0x2000d,
0x30011, 0x30019, 0x40021, 0x40031, 0x50041, 0x50061, 0x60081, 0x600c1,
0x70101, 0x70181, 0x80201, 0x80301, 0x90401, 0x90601, 0xa0801, 0xa0c01,
0xb1001, 0xb1801, 0xc2001, 0xc3001, 0xd4001, 0xd6001
]);
- var fixedLitCodeTab = [new Uint32Array([
+ var fixedLitCodeTab = [new Int32Array([
0x70100, 0x80050, 0x80010, 0x80118, 0x70110, 0x80070, 0x80030, 0x900c0,
0x70108, 0x80060, 0x80020, 0x900a0, 0x80000, 0x80080, 0x80040, 0x900e0,
0x70104, 0x80058, 0x80018, 0x90090, 0x70114, 0x80078, 0x80038, 0x900d0,
@@ -31080,7 +31104,7 @@ var FlateStream = (function FlateStreamClosure() {
0x7010f, 0x8006f, 0x8002f, 0x900bf, 0x8000f, 0x8008f, 0x8004f, 0x900ff
]), 9];
- var fixedDistCodeTab = [new Uint32Array([
+ var fixedDistCodeTab = [new Int32Array([
0x50000, 0x50010, 0x50008, 0x50018, 0x50004, 0x50014, 0x5000c, 0x5001c,
0x50002, 0x50012, 0x5000a, 0x5001a, 0x50006, 0x50016, 0x5000e, 0x00000,
0x50001, 0x50011, 0x50009, 0x50019, 0x50005, 0x50015, 0x5000d, 0x5001d,
@@ -31177,7 +31201,7 @@ var FlateStream = (function FlateStreamClosure() {
// build the table
var size = 1 << maxLen;
- var codes = new Uint32Array(size);
+ var codes = new Int32Array(size);
for (var len = 1, code = 0, skip = 2;
len <= maxLen;
++len, code <<= 1, skip <<= 1) {
diff --git a/browser/extensions/pdfjs/content/pdfjschildbootstrap.js b/browser/extensions/pdfjs/content/pdfjschildbootstrap.js
index 68e7c28b9fa..788ec68b1a8 100644
--- a/browser/extensions/pdfjs/content/pdfjschildbootstrap.js
+++ b/browser/extensions/pdfjs/content/pdfjschildbootstrap.js
@@ -31,7 +31,8 @@ Components.utils.import('resource://pdf.js/PdfjsContentUtils.jsm');
// init content utils shim pdfjs will use to access privileged apis.
PdfjsContentUtils.init();
-if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) {
+if (Services.appinfo.processType === Services.appinfo.PROCESS_TYPE_CONTENT) {
// register various pdfjs factories that hook us into content loading.
PdfJs.updateRegistration();
}
+
diff --git a/browser/extensions/pdfjs/content/web/viewer.css b/browser/extensions/pdfjs/content/web/viewer.css
index d87ba44f80a..bf57df85343 100644
--- a/browser/extensions/pdfjs/content/web/viewer.css
+++ b/browser/extensions/pdfjs/content/web/viewer.css
@@ -102,12 +102,12 @@
box-shadow: 0px 2px 10px #ff0;
}
-:-moz-full-screen .pdfViewer .page {
+.pdfPresentationMode:-moz-full-screen .pdfViewer .page {
margin-bottom: 100%;
border: 0;
}
-:fullscreen .pdfViewer .page {
+.pdfPresentationMode:fullscreen .pdfViewer .page {
margin-bottom: 100%;
border: 0;
}
@@ -184,7 +184,7 @@ select {
display: none !important;
}
-#viewerContainer:-moz-full-screen {
+#viewerContainer.pdfPresentationMode:-moz-full-screen {
top: 0px;
border-top: 2px solid transparent;
background-color: #000;
@@ -195,7 +195,7 @@ select {
-moz-user-select: none;
}
-#viewerContainer:fullscreen {
+#viewerContainer.pdfPresentationMode:fullscreen {
top: 0px;
border-top: 2px solid transparent;
background-color: #000;
@@ -206,24 +206,24 @@ select {
-moz-user-select: none;
}
-:-moz-full-screen a:not(.internalLink) {
+.pdfPresentationMode:-moz-full-screen a:not(.internalLink) {
display: none;
}
-:fullscreen a:not(.internalLink) {
+.pdfPresentationMode:fullscreen a:not(.internalLink) {
display: none;
}
-:-moz-full-screen .textLayer > div {
+.pdfPresentationMode:-moz-full-screen .textLayer > div {
cursor: none;
}
-:fullscreen .textLayer > div {
+.pdfPresentationMode:fullscreen .textLayer > div {
cursor: none;
}
-#viewerContainer.presentationControls,
-#viewerContainer.presentationControls .textLayer > div {
+.pdfPresentationMode.pdfPresentationModeControls > *,
+.pdfPresentationMode.pdfPresentationModeControls .textLayer > div {
cursor: default;
}
diff --git a/browser/extensions/pdfjs/content/web/viewer.html b/browser/extensions/pdfjs/content/web/viewer.html
index 74809570a87..056bfc9fb67 100644
--- a/browser/extensions/pdfjs/content/web/viewer.html
+++ b/browser/extensions/pdfjs/content/web/viewer.html
@@ -182,7 +182,6 @@ http://sourceforge.net/adobe/cmap/wiki/License/
-
Current View
diff --git a/browser/extensions/pdfjs/content/web/viewer.js b/browser/extensions/pdfjs/content/web/viewer.js
index 15bd5dc7036..0be41038b28 100644
--- a/browser/extensions/pdfjs/content/web/viewer.js
+++ b/browser/extensions/pdfjs/content/web/viewer.js
@@ -15,10 +15,10 @@
* limitations under the License.
*/
/* globals PDFJS, PDFBug, FirefoxCom, Stats, Cache, ProgressBar,
- DownloadManager, getFileName, scrollIntoView, getPDFFileNameFromURL,
+ DownloadManager, getFileName, getPDFFileNameFromURL,
PDFHistory, Preferences, SidebarView, ViewHistory, Stats,
PDFThumbnailViewer, URL, noContextMenuHandler, SecondaryToolbar,
- PasswordPrompt, PresentationMode, HandTool, Promise,
+ PasswordPrompt, PDFPresentationMode, HandTool, Promise,
DocumentProperties, PDFOutlineView, PDFAttachmentView,
OverlayManager, PDFFindController, PDFFindBar, getVisibleElements,
watchScroll, PDFViewer, PDFRenderingQueue, PresentationModeState,
@@ -1343,6 +1343,7 @@ var PDFHistory = {
this.reInitialized = false;
this.allowHashChange = true;
this.historyUnlocked = true;
+ this.isViewerInPresentationMode = false;
this.previousHash = window.location.hash.substring(1);
this.currentBookmark = '';
@@ -1434,6 +1435,10 @@ var PDFHistory = {
// the 'DOMContentLoaded' event is not fired on 'pageshow'.
window.addEventListener('beforeunload', pdfHistoryBeforeUnload, false);
}, false);
+
+ window.addEventListener('presentationmodechanged', function(e) {
+ self.isViewerInPresentationMode = !!e.detail.active;
+ });
},
_isStateObjectDefined: function pdfHistory_isStateObjectDefined(state) {
@@ -1585,7 +1590,7 @@ var PDFHistory = {
return null;
}
var params = { hash: this.currentBookmark, page: this.currentPage };
- if (PresentationMode.active) {
+ if (this.isViewerInPresentationMode) {
params.hash = null;
}
return params;
@@ -1684,7 +1689,6 @@ var SecondaryToolbar = {
initialize: function secondaryToolbarInitialize(options) {
this.toolbar = options.toolbar;
- this.presentationMode = options.presentationMode;
this.documentProperties = options.documentProperties;
this.buttonContainer = this.toolbar.firstElementChild;
@@ -1731,7 +1735,7 @@ var SecondaryToolbar = {
// Event handling functions.
presentationModeClick: function secondaryToolbarPresentationModeClick(evt) {
- this.presentationMode.request();
+ PDFViewerApplication.requestPresentationMode();
this.close();
},
@@ -1823,237 +1827,373 @@ var SecondaryToolbar = {
};
+var DELAY_BEFORE_RESETTING_SWITCH_IN_PROGRESS = 1500; // in ms
var DELAY_BEFORE_HIDING_CONTROLS = 3000; // in ms
-var SELECTOR = 'presentationControls';
-var DELAY_BEFORE_RESETTING_SWITCH_IN_PROGRESS = 1000; // in ms
+var ACTIVE_SELECTOR = 'pdfPresentationMode';
+var CONTROLS_SELECTOR = 'pdfPresentationModeControls';
-var PresentationMode = {
- active: false,
- args: null,
- contextMenuOpen: false,
-
- initialize: function presentationModeInitialize(options) {
- this.container = options.container;
- this.secondaryToolbar = options.secondaryToolbar;
-
- this.viewer = this.container.firstElementChild;
-
- this.firstPage = options.firstPage;
- this.lastPage = options.lastPage;
- this.pageRotateCw = options.pageRotateCw;
- this.pageRotateCcw = options.pageRotateCcw;
-
- this.firstPage.addEventListener('click', function() {
- this.contextMenuOpen = false;
- this.secondaryToolbar.firstPageClick();
- }.bind(this));
- this.lastPage.addEventListener('click', function() {
- this.contextMenuOpen = false;
- this.secondaryToolbar.lastPageClick();
- }.bind(this));
-
- this.pageRotateCw.addEventListener('click', function() {
- this.contextMenuOpen = false;
- this.secondaryToolbar.pageRotateCwClick();
- }.bind(this));
- this.pageRotateCcw.addEventListener('click', function() {
- this.contextMenuOpen = false;
- this.secondaryToolbar.pageRotateCcwClick();
- }.bind(this));
- },
-
- get isFullscreen() {
- return (document.fullscreenElement ||
- document.mozFullScreen ||
- document.webkitIsFullScreen ||
- document.msFullscreenElement);
- },
+/**
+ * @typedef {Object} PDFPresentationModeOptions
+ * @property {HTMLDivElement} container - The container for the viewer element.
+ * @property {HTMLDivElement} viewer - (optional) The viewer element.
+ * @property {PDFThumbnailViewer} pdfThumbnailViewer - (optional) The thumbnail
+ * viewer.
+ * @property {Array} contextMenuItems - (optional) The menuitems that are added
+ * to the context menu in Presentation Mode.
+ */
+/**
+ * @class
+ */
+var PDFPresentationMode = (function PDFPresentationModeClosure() {
/**
- * Initialize a timeout that is used to specify switchInProgress when the
- * browser transitions to fullscreen mode. Since resize events are triggered
- * multiple times during the switch to fullscreen mode, this is necessary in
- * order to prevent the page from being scrolled partially, or completely,
- * out of view when Presentation Mode is enabled.
- * Note: This is only an issue at certain zoom levels, e.g. 'page-width'.
+ * @constructs PDFPresentationMode
+ * @param {PDFPresentationModeOptions} options
*/
- _setSwitchInProgress: function presentationMode_setSwitchInProgress() {
- if (this.switchInProgress) {
- clearTimeout(this.switchInProgress);
- }
- this.switchInProgress = setTimeout(function switchInProgressTimeout() {
- delete this.switchInProgress;
- this._notifyStateChange();
- }.bind(this), DELAY_BEFORE_RESETTING_SWITCH_IN_PROGRESS);
- },
+ function PDFPresentationMode(options) {
+ this.container = options.container;
+ this.viewer = options.viewer || options.container.firstElementChild;
+ this.pdfThumbnailViewer = options.pdfThumbnailViewer || null;
+ var contextMenuItems = options.contextMenuItems || null;
- _resetSwitchInProgress: function presentationMode_resetSwitchInProgress() {
- if (this.switchInProgress) {
- clearTimeout(this.switchInProgress);
- delete this.switchInProgress;
- }
- },
-
- request: function presentationModeRequest() {
- if (!PDFViewerApplication.supportsFullscreen || this.isFullscreen ||
- !this.viewer.hasChildNodes()) {
- return false;
- }
- this._setSwitchInProgress();
- this._notifyStateChange();
-
- if (this.container.requestFullscreen) {
- this.container.requestFullscreen();
- } else if (this.container.mozRequestFullScreen) {
- this.container.mozRequestFullScreen();
- } else if (this.container.webkitRequestFullscreen) {
- this.container.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
- } else if (this.container.msRequestFullscreen) {
- this.container.msRequestFullscreen();
- } else {
- return false;
- }
-
- this.args = {
- page: PDFViewerApplication.page,
- previousScale: PDFViewerApplication.currentScaleValue
- };
-
- return true;
- },
-
- _notifyStateChange: function presentationModeNotifyStateChange() {
- var event = document.createEvent('CustomEvent');
- event.initCustomEvent('presentationmodechanged', true, true, {
- active: PresentationMode.active,
- switchInProgress: !!PresentationMode.switchInProgress
- });
- window.dispatchEvent(event);
- },
-
- enter: function presentationModeEnter() {
- this.active = true;
- this._resetSwitchInProgress();
- this._notifyStateChange();
-
- // Ensure that the correct page is scrolled into view when entering
- // Presentation Mode, by waiting until fullscreen mode in enabled.
- // Note: This is only necessary in non-Mozilla browsers.
- setTimeout(function enterPresentationModeTimeout() {
- PDFViewerApplication.page = this.args.page;
- PDFViewerApplication.setScale('page-fit', true);
- }.bind(this), 0);
-
- window.addEventListener('mousemove', this.mouseMove, false);
- window.addEventListener('mousedown', this.mouseDown, false);
- window.addEventListener('contextmenu', this.contextMenu, false);
-
- this.showControls();
- HandTool.enterPresentationMode();
+ this.active = false;
+ this.args = null;
this.contextMenuOpen = false;
- this.container.setAttribute('contextmenu', 'viewerContextMenu');
+ this.mouseScrollTimeStamp = 0;
+ this.mouseScrollDelta = 0;
- // Text selection is disabled in Presentation Mode, thus it's not possible
- // for the user to deselect text that is selected (e.g. with "Select all")
- // when entering Presentation Mode, hence we remove any active selection.
- window.getSelection().removeAllRanges();
- },
-
- exit: function presentationModeExit() {
- var page = PDFViewerApplication.page;
-
- // Ensure that the correct page is scrolled into view when exiting
- // Presentation Mode, by waiting until fullscreen mode is disabled.
- // Note: This is only necessary in non-Mozilla browsers.
- setTimeout(function exitPresentationModeTimeout() {
- this.active = false;
- this._notifyStateChange();
-
- PDFViewerApplication.setScale(this.args.previousScale, true);
- PDFViewerApplication.page = page;
- this.args = null;
- }.bind(this), 0);
-
- window.removeEventListener('mousemove', this.mouseMove, false);
- window.removeEventListener('mousedown', this.mouseDown, false);
- window.removeEventListener('contextmenu', this.contextMenu, false);
-
- this.hideControls();
- PDFViewerApplication.clearMouseScrollState();
- HandTool.exitPresentationMode();
- this.container.removeAttribute('contextmenu');
- this.contextMenuOpen = false;
-
- // Ensure that the thumbnail of the current page is visible
- // when exiting presentation mode.
- scrollIntoView(document.getElementById('thumbnailContainer' + page));
- },
-
- showControls: function presentationModeShowControls() {
- if (this.controlsTimeout) {
- clearTimeout(this.controlsTimeout);
- } else {
- this.container.classList.add(SELECTOR);
- }
- this.controlsTimeout = setTimeout(function hideControlsTimeout() {
- this.container.classList.remove(SELECTOR);
- delete this.controlsTimeout;
- }.bind(this), DELAY_BEFORE_HIDING_CONTROLS);
- },
-
- hideControls: function presentationModeHideControls() {
- if (!this.controlsTimeout) {
- return;
- }
- this.container.classList.remove(SELECTOR);
- clearTimeout(this.controlsTimeout);
- delete this.controlsTimeout;
- },
-
- mouseMove: function presentationModeMouseMove(evt) {
- PresentationMode.showControls();
- },
-
- mouseDown: function presentationModeMouseDown(evt) {
- var self = PresentationMode;
- if (self.contextMenuOpen) {
- self.contextMenuOpen = false;
- evt.preventDefault();
- return;
- }
-
- if (evt.button === 0) {
- // Enable clicking of links in presentation mode. Please note:
- // Only links pointing to destinations in the current PDF document work.
- var isInternalLink = (evt.target.href &&
- evt.target.classList.contains('internalLink'));
- if (!isInternalLink) {
- // Unless an internal link was clicked, advance one page.
- evt.preventDefault();
- PDFViewerApplication.page += (evt.shiftKey ? -1 : 1);
+ if (contextMenuItems) {
+ for (var i = 0, ii = contextMenuItems.length; i < ii; i++) {
+ var item = contextMenuItems[i];
+ item.element.addEventListener('click', function (handler) {
+ this.contextMenuOpen = false;
+ handler();
+ }.bind(this, item.handler));
}
}
- },
-
- contextMenu: function presentationModeContextMenu(evt) {
- PresentationMode.contextMenuOpen = true;
}
-};
-(function presentationModeClosure() {
- function presentationModeChange(e) {
- if (PresentationMode.isFullscreen) {
- PresentationMode.enter();
- } else {
- PresentationMode.exit();
+ PDFPresentationMode.prototype = {
+ /**
+ * Request the browser to enter fullscreen mode.
+ * @returns {boolean} Indicating if the request was successful.
+ */
+ request: function PDFPresentationMode_request() {
+ if (this.switchInProgress || this.active ||
+ !this.viewer.hasChildNodes()) {
+ return false;
+ }
+ this._addFullscreenChangeListeners();
+ this._setSwitchInProgress();
+ this._notifyStateChange();
+
+ if (this.container.requestFullscreen) {
+ this.container.requestFullscreen();
+ } else if (this.container.mozRequestFullScreen) {
+ this.container.mozRequestFullScreen();
+ } else if (this.container.webkitRequestFullscreen) {
+ this.container.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
+ } else if (this.container.msRequestFullscreen) {
+ this.container.msRequestFullscreen();
+ } else {
+ return false;
+ }
+
+ this.args = {
+ page: PDFViewerApplication.page,
+ previousScale: PDFViewerApplication.currentScaleValue
+ };
+
+ return true;
+ },
+
+ /**
+ * Switches page when the user scrolls (using a scroll wheel or a touchpad)
+ * with large enough motion, to prevent accidental page switches.
+ * @param {number} delta - The delta value from the mouse event.
+ */
+ mouseScroll: function PDFPresentationMode_mouseScroll(delta) {
+ if (!this.active) {
+ return;
+ }
+ var MOUSE_SCROLL_COOLDOWN_TIME = 50;
+ var PAGE_SWITCH_THRESHOLD = 120;
+ var PageSwitchDirection = {
+ UP: -1,
+ DOWN: 1
+ };
+
+ var currentTime = (new Date()).getTime();
+ var storedTime = this.mouseScrollTimeStamp;
+
+ // If we've already switched page, avoid accidentally switching again.
+ if (currentTime > storedTime &&
+ currentTime - storedTime < MOUSE_SCROLL_COOLDOWN_TIME) {
+ return;
+ }
+ // If the scroll direction changed, reset the accumulated scroll delta.
+ if ((this.mouseScrollDelta > 0 && delta < 0) ||
+ (this.mouseScrollDelta < 0 && delta > 0)) {
+ this._resetMouseScrollState();
+ }
+ this.mouseScrollDelta += delta;
+
+ if (Math.abs(this.mouseScrollDelta) >= PAGE_SWITCH_THRESHOLD) {
+ var pageSwitchDirection = (this.mouseScrollDelta > 0) ?
+ PageSwitchDirection.UP : PageSwitchDirection.DOWN;
+ var page = PDFViewerApplication.page;
+ this._resetMouseScrollState();
+
+ // If we're at the first/last page, we don't need to do anything.
+ if ((page === 1 && pageSwitchDirection === PageSwitchDirection.UP) ||
+ (page === PDFViewerApplication.pagesCount &&
+ pageSwitchDirection === PageSwitchDirection.DOWN)) {
+ return;
+ }
+ PDFViewerApplication.page = (page + pageSwitchDirection);
+ this.mouseScrollTimeStamp = currentTime;
+ }
+ },
+
+ get isFullscreen() {
+ return !!(document.fullscreenElement ||
+ document.mozFullScreen ||
+ document.webkitIsFullScreen ||
+ document.msFullscreenElement);
+ },
+
+ /**
+ * @private
+ */
+ _notifyStateChange: function PDFPresentationMode_notifyStateChange() {
+ var event = document.createEvent('CustomEvent');
+ event.initCustomEvent('presentationmodechanged', true, true, {
+ active: this.active,
+ switchInProgress: !!this.switchInProgress
+ });
+ window.dispatchEvent(event);
+ },
+
+ /**
+ * Used to initialize a timeout when requesting Presentation Mode,
+ * i.e. when the browser is requested to enter fullscreen mode.
+ * This timeout is used to prevent the current page from being scrolled
+ * partially, or completely, out of view when entering Presentation Mode.
+ * NOTE: This issue seems limited to certain zoom levels (e.g. page-width).
+ * @private
+ */
+ _setSwitchInProgress: function PDFPresentationMode_setSwitchInProgress() {
+ if (this.switchInProgress) {
+ clearTimeout(this.switchInProgress);
+ }
+ this.switchInProgress = setTimeout(function switchInProgressTimeout() {
+ this._removeFullscreenChangeListeners();
+ delete this.switchInProgress;
+ this._notifyStateChange();
+ }.bind(this), DELAY_BEFORE_RESETTING_SWITCH_IN_PROGRESS);
+ },
+
+ /**
+ * @private
+ */
+ _resetSwitchInProgress:
+ function PDFPresentationMode_resetSwitchInProgress() {
+ if (this.switchInProgress) {
+ clearTimeout(this.switchInProgress);
+ delete this.switchInProgress;
+ }
+ },
+
+ /**
+ * @private
+ */
+ _enter: function PDFPresentationMode_enter() {
+ this.active = true;
+ this._resetSwitchInProgress();
+ this._notifyStateChange();
+ this.container.classList.add(ACTIVE_SELECTOR);
+
+ // Ensure that the correct page is scrolled into view when entering
+ // Presentation Mode, by waiting until fullscreen mode in enabled.
+ setTimeout(function enterPresentationModeTimeout() {
+ PDFViewerApplication.page = this.args.page;
+ PDFViewerApplication.setScale('page-fit', true);
+ }.bind(this), 0);
+
+ this._addWindowListeners();
+ this._showControls();
+ this.contextMenuOpen = false;
+ this.container.setAttribute('contextmenu', 'viewerContextMenu');
+
+ // Text selection is disabled in Presentation Mode, thus it's not possible
+ // for the user to deselect text that is selected (e.g. with "Select all")
+ // when entering Presentation Mode, hence we remove any active selection.
+ window.getSelection().removeAllRanges();
+ },
+
+ /**
+ * @private
+ */
+ _exit: function PDFPresentationMode_exit() {
+ var page = PDFViewerApplication.page;
+ this.container.classList.remove(ACTIVE_SELECTOR);
+
+ // Ensure that the correct page is scrolled into view when exiting
+ // Presentation Mode, by waiting until fullscreen mode is disabled.
+ setTimeout(function exitPresentationModeTimeout() {
+ this.active = false;
+ this._removeFullscreenChangeListeners();
+ this._notifyStateChange();
+
+ PDFViewerApplication.setScale(this.args.previousScale, true);
+ PDFViewerApplication.page = page;
+ this.args = null;
+ }.bind(this), 0);
+
+ this._removeWindowListeners();
+ this._hideControls();
+ this._resetMouseScrollState();
+ this.container.removeAttribute('contextmenu');
+ this.contextMenuOpen = false;
+
+ if (this.pdfThumbnailViewer) {
+ this.pdfThumbnailViewer.ensureThumbnailVisible(page);
+ }
+ },
+
+ /**
+ * @private
+ */
+ _mouseDown: function PDFPresentationMode_mouseDown(evt) {
+ if (this.contextMenuOpen) {
+ this.contextMenuOpen = false;
+ evt.preventDefault();
+ return;
+ }
+ if (evt.button === 0) {
+ // Enable clicking of links in presentation mode. Please note:
+ // Only links pointing to destinations in the current PDF document work.
+ var isInternalLink = (evt.target.href &&
+ evt.target.classList.contains('internalLink'));
+ if (!isInternalLink) {
+ // Unless an internal link was clicked, advance one page.
+ evt.preventDefault();
+ PDFViewerApplication.page += (evt.shiftKey ? -1 : 1);
+ }
+ }
+ },
+
+ /**
+ * @private
+ */
+ _contextMenu: function PDFPresentationMode_contextMenu() {
+ this.contextMenuOpen = true;
+ },
+
+ /**
+ * @private
+ */
+ _showControls: function PDFPresentationMode_showControls() {
+ if (this.controlsTimeout) {
+ clearTimeout(this.controlsTimeout);
+ } else {
+ this.container.classList.add(CONTROLS_SELECTOR);
+ }
+ this.controlsTimeout = setTimeout(function showControlsTimeout() {
+ this.container.classList.remove(CONTROLS_SELECTOR);
+ delete this.controlsTimeout;
+ }.bind(this), DELAY_BEFORE_HIDING_CONTROLS);
+ },
+
+ /**
+ * @private
+ */
+ _hideControls: function PDFPresentationMode_hideControls() {
+ if (!this.controlsTimeout) {
+ return;
+ }
+ clearTimeout(this.controlsTimeout);
+ this.container.classList.remove(CONTROLS_SELECTOR);
+ delete this.controlsTimeout;
+ },
+
+ /**
+ * Resets the properties used for tracking mouse scrolling events.
+ * @private
+ */
+ _resetMouseScrollState:
+ function PDFPresentationMode_resetMouseScrollState() {
+ this.mouseScrollTimeStamp = 0;
+ this.mouseScrollDelta = 0;
+ },
+
+ /**
+ * @private
+ */
+ _addWindowListeners: function PDFPresentationMode_addWindowListeners() {
+ this.showControlsBind = this._showControls.bind(this);
+ this.mouseDownBind = this._mouseDown.bind(this);
+ this.resetMouseScrollStateBind = this._resetMouseScrollState.bind(this);
+ this.contextMenuBind = this._contextMenu.bind(this);
+
+ window.addEventListener('mousemove', this.showControlsBind);
+ window.addEventListener('mousedown', this.mouseDownBind);
+ window.addEventListener('keydown', this.resetMouseScrollStateBind);
+ window.addEventListener('contextmenu', this.contextMenuBind);
+ },
+
+ /**
+ * @private
+ */
+ _removeWindowListeners:
+ function PDFPresentationMode_removeWindowListeners() {
+ window.removeEventListener('mousemove', this.showControlsBind);
+ window.removeEventListener('mousedown', this.mouseDownBind);
+ window.removeEventListener('keydown', this.resetMouseScrollStateBind);
+ window.removeEventListener('contextmenu', this.contextMenuBind);
+
+ delete this.showControlsBind;
+ delete this.mouseDownBind;
+ delete this.resetMouseScrollStateBind;
+ delete this.contextMenuBind;
+ },
+
+ /**
+ * @private
+ */
+ _fullscreenChange: function PDFPresentationMode_fullscreenChange() {
+ if (this.isFullscreen) {
+ this._enter();
+ } else {
+ this._exit();
+ }
+ },
+
+ /**
+ * @private
+ */
+ _addFullscreenChangeListeners:
+ function PDFPresentationMode_addFullscreenChangeListeners() {
+ this.fullscreenChangeBind = this._fullscreenChange.bind(this);
+
+ window.addEventListener('fullscreenchange', this.fullscreenChangeBind);
+ window.addEventListener('mozfullscreenchange', this.fullscreenChangeBind);
+ },
+
+ /**
+ * @private
+ */
+ _removeFullscreenChangeListeners:
+ function PDFPresentationMode_removeFullscreenChangeListeners() {
+ window.removeEventListener('fullscreenchange', this.fullscreenChangeBind);
+ window.removeEventListener('mozfullscreenchange',
+ this.fullscreenChangeBind);
+
+ delete this.fullscreenChangeBind;
}
- }
+ };
- window.addEventListener('fullscreenchange', presentationModeChange, false);
- window.addEventListener('mozfullscreenchange', presentationModeChange, false);
- window.addEventListener('webkitfullscreenchange', presentationModeChange,
- false);
- window.addEventListener('MSFullscreenChange', presentationModeChange, false);
+ return PDFPresentationMode;
})();
@@ -2311,6 +2451,17 @@ var HandTool = {
}
}.bind(this), function rejected(reason) {});
}.bind(this));
+
+ window.addEventListener('presentationmodechanged', function (evt) {
+ if (evt.detail.switchInProgress) {
+ return;
+ }
+ if (evt.detail.active) {
+ this.enterPresentationMode();
+ } else {
+ this.exitPresentationMode();
+ }
+ }.bind(this));
}
},
@@ -2659,8 +2810,7 @@ var DocumentProperties = {
},
parseDate: function documentPropertiesParseDate(inputDate) {
- // This is implemented according to the PDF specification (see
- // http://www.gnupdf.org/Date for an overview), but note that
+ // This is implemented according to the PDF specification, but note that
// Adobe Reader doesn't handle changing the date to universal time
// and doesn't use the user's time zone (they're effectively ignoring
// the HH' and mm' parts of the date string).
@@ -2942,6 +3092,7 @@ var PDFPageView = (function PDFPageViewClosure() {
div.className = 'page';
div.style.width = Math.floor(this.viewport.width) + 'px';
div.style.height = Math.floor(this.viewport.height) + 'px';
+ div.setAttribute('data-page-number', this.id);
this.div = div;
container.appendChild(div);
@@ -4296,11 +4447,8 @@ var PDFViewer = (function pdfViewer() {
if (!noScroll) {
var page = this._currentPageNumber, dest;
- var inPresentationMode =
- this.presentationModeState === PresentationModeState.CHANGING ||
- this.presentationModeState === PresentationModeState.FULLSCREEN;
- if (this.location && !inPresentationMode &&
- !IGNORE_CURRENT_POSITION_ON_ZOOM) {
+ if (this.location && !IGNORE_CURRENT_POSITION_ON_ZOOM &&
+ !(this.isInPresentationMode || this.isChangingPresentationMode)) {
page = this.location.pageNumber;
dest = [null, { name: 'XYZ' }, this.location.left,
this.location.top, null];
@@ -4324,11 +4472,9 @@ var PDFViewer = (function pdfViewer() {
if (!currentPage) {
return;
}
- var inPresentationMode =
- this.presentationModeState === PresentationModeState.FULLSCREEN;
- var hPadding = (inPresentationMode || this.removePageBorders) ?
+ var hPadding = (this.isInPresentationMode || this.removePageBorders) ?
0 : SCROLLBAR_PADDING;
- var vPadding = (inPresentationMode || this.removePageBorders) ?
+ var vPadding = (this.isInPresentationMode || this.removePageBorders) ?
0 : VERTICAL_PADDING;
var pageWidthScale = (this.container.clientWidth - hPadding) /
currentPage.width * currentPage.scale;
@@ -4374,8 +4520,7 @@ var PDFViewer = (function pdfViewer() {
dest) {
var pageView = this.pages[pageNumber - 1];
- if (this.presentationModeState ===
- PresentationModeState.FULLSCREEN) {
+ if (this.isInPresentationMode) {
if (this.linkService.page !== pageView.id) {
// Avoid breaking getVisiblePages in presentation mode.
this.linkService.page = pageView.id;
@@ -4529,7 +4674,7 @@ var PDFViewer = (function pdfViewer() {
currentId = visiblePages[0].id;
}
- if (this.presentationModeState !== PresentationModeState.FULLSCREEN) {
+ if (!this.isInPresentationMode) {
this.currentPageNumber = currentId;
}
@@ -4554,13 +4699,21 @@ var PDFViewer = (function pdfViewer() {
this.container.blur();
},
+ get isInPresentationMode() {
+ return this.presentationModeState === PresentationModeState.FULLSCREEN;
+ },
+
+ get isChangingPresentationMode() {
+ return this.PresentationModeState === PresentationModeState.CHANGING;
+ },
+
get isHorizontalScrollbarEnabled() {
- return (this.presentationModeState === PresentationModeState.FULLSCREEN ?
+ return (this.isInPresentationMode ?
false : (this.container.scrollWidth > this.container.clientWidth));
},
_getVisiblePages: function () {
- if (this.presentationModeState !== PresentationModeState.FULLSCREEN) {
+ if (!this.isInPresentationMode) {
return getVisibleElements(this.container, this.pages, true);
} else {
// The algorithm in getVisibleElements doesn't work in all browsers and
@@ -4631,13 +4784,11 @@ var PDFViewer = (function pdfViewer() {
* @returns {TextLayerBuilder}
*/
createTextLayerBuilder: function (textLayerDiv, pageIndex, viewport) {
- var isViewerInPresentationMode =
- this.presentationModeState === PresentationModeState.FULLSCREEN;
return new TextLayerBuilder({
textLayerDiv: textLayerDiv,
pageIndex: pageIndex,
viewport: viewport,
- findController: isViewerInPresentationMode ? null : this.findController
+ findController: this.isInPresentationMode ? null : this.findController
});
},
@@ -5385,15 +5536,16 @@ var PDFViewerApplication = {
pdfThumbnailViewer: null,
/** @type {PDFRenderingQueue} */
pdfRenderingQueue: null,
+ /** @type {PDFPresentationMode} */
+ pdfPresentationMode: null,
pageRotation: 0,
updateScaleControls: true,
isInitialViewSet: false,
animationStartedPromise: null,
- mouseScrollTimeStamp: 0,
- mouseScrollDelta: 0,
preferenceSidebarViewOnLoad: SidebarView.NONE,
preferencePdfBugEnabled: false,
preferenceShowPreviousViewOnLoad: true,
+ preferenceDefaultZoomValue: '',
isViewerEmbedded: (window.parent !== window),
url: '',
@@ -5451,7 +5603,6 @@ var PDFViewerApplication = {
SecondaryToolbar.initialize({
toolbar: document.getElementById('secondaryToolbar'),
- presentationMode: PresentationMode,
toggleButton: document.getElementById('secondaryToolbarToggle'),
presentationModeButton:
document.getElementById('secondaryPresentationMode'),
@@ -5467,14 +5618,24 @@ var PDFViewerApplication = {
documentPropertiesButton: document.getElementById('documentProperties')
});
- PresentationMode.initialize({
- container: container,
- secondaryToolbar: SecondaryToolbar,
- firstPage: document.getElementById('contextFirstPage'),
- lastPage: document.getElementById('contextLastPage'),
- pageRotateCw: document.getElementById('contextPageRotateCw'),
- pageRotateCcw: document.getElementById('contextPageRotateCcw')
- });
+ if (this.supportsFullscreen) {
+ var toolbar = SecondaryToolbar;
+ this.pdfPresentationMode = new PDFPresentationMode({
+ container: container,
+ viewer: viewer,
+ pdfThumbnailViewer: this.pdfThumbnailViewer,
+ contextMenuItems: [
+ { element: document.getElementById('contextFirstPage'),
+ handler: toolbar.firstPageClick.bind(toolbar) },
+ { element: document.getElementById('contextLastPage'),
+ handler: toolbar.lastPageClick.bind(toolbar) },
+ { element: document.getElementById('contextPageRotateCw'),
+ handler: toolbar.pageRotateCwClick.bind(toolbar) },
+ { element: document.getElementById('contextPageRotateCcw'),
+ handler: toolbar.pageRotateCcwClick.bind(toolbar) }
+ ]
+ });
+ }
PasswordPrompt.initialize({
overlayName: 'passwordOverlay',
@@ -5514,9 +5675,9 @@ var PDFViewerApplication = {
}),
Preferences.get('showPreviousViewOnLoad').then(function resolved(value) {
self.preferenceShowPreviousViewOnLoad = value;
- if (!value && window.history.state) {
- window.history.replaceState(null, '');
- }
+ }),
+ Preferences.get('defaultZoomValue').then(function resolved(value) {
+ self.preferenceDefaultZoomValue = value;
}),
Preferences.get('disableTextLayer').then(function resolved(value) {
if (PDFJS.disableTextLayer === true) {
@@ -5542,7 +5703,6 @@ var PDFViewerApplication = {
Preferences.get('useOnlyCssZoom').then(function resolved(value) {
PDFJS.useOnlyCssZoom = value;
})
-
// TODO move more preferences and other async stuff here
]).catch(function (reason) { });
@@ -5596,8 +5756,8 @@ var PDFViewerApplication = {
get supportsFullscreen() {
var doc = document.documentElement;
- var support = doc.requestFullscreen || doc.mozRequestFullScreen ||
- doc.webkitRequestFullScreen || doc.msRequestFullscreen;
+ var support = !!(doc.requestFullscreen || doc.mozRequestFullScreen ||
+ doc.webkitRequestFullScreen || doc.msRequestFullscreen);
if (document.fullscreenEnabled === false ||
document.mozFullScreenEnabled === false ||
@@ -6103,46 +6263,37 @@ var PDFViewerApplication = {
if (!PDFJS.disableHistory && !self.isViewerEmbedded) {
// The browsing history is only enabled when the viewer is standalone,
// i.e. not when it is embedded in a web page.
+ if (!self.preferenceShowPreviousViewOnLoad && window.history.state) {
+ window.history.replaceState(null, '');
+ }
PDFHistory.initialize(self.documentFingerprint, self);
}
- });
- // Fetch the necessary preference values.
- var defaultZoomValue;
- var defaultZoomValuePromise =
- Preferences.get('defaultZoomValue').then(function (prefValue) {
- defaultZoomValue = prefValue;
- });
+ store.initializedPromise.then(function resolved() {
+ var storedHash = null;
+ if (self.preferenceShowPreviousViewOnLoad &&
+ store.get('exists', false)) {
+ var pageNum = store.get('page', '1');
+ var zoom = self.preferenceDefaultZoomValue ||
+ store.get('zoom', self.pdfViewer.currentScale);
+ var left = store.get('scrollLeft', '0');
+ var top = store.get('scrollTop', '0');
- var storePromise = store.initializedPromise;
- Promise.all([firstPagePromise, storePromise, defaultZoomValuePromise]).then(
- function resolved() {
- var storedHash = null;
- if (PDFViewerApplication.preferenceShowPreviousViewOnLoad &&
- store.get('exists', false)) {
- var pageNum = store.get('page', '1');
- var zoom = defaultZoomValue ||
- store.get('zoom', self.pdfViewer.currentScale);
- var left = store.get('scrollLeft', '0');
- var top = store.get('scrollTop', '0');
+ storedHash = 'page=' + pageNum + '&zoom=' + zoom + ',' +
+ left + ',' + top;
+ } else if (self.preferenceDefaultZoomValue) {
+ storedHash = 'page=1&zoom=' + self.preferenceDefaultZoomValue;
+ }
+ self.setInitialView(storedHash, scale);
- storedHash = 'page=' + pageNum + '&zoom=' + zoom + ',' +
- left + ',' + top;
- } else if (defaultZoomValue) {
- storedHash = 'page=1&zoom=' + defaultZoomValue;
- }
- self.setInitialView(storedHash, scale);
-
- // Make all navigation keys work on document load,
- // unless the viewer is embedded in a web page.
- if (!self.isViewerEmbedded) {
- self.pdfViewer.focus();
- self.pdfViewer.blur();
- }
- }, function rejected(reason) {
- console.error(reason);
-
- firstPagePromise.then(function () {
+ // Make all navigation keys work on document load,
+ // unless the viewer is embedded in a web page.
+ if (!self.isViewerEmbedded) {
+ self.pdfViewer.focus();
+ self.pdfViewer.blur();
+ }
+ }, function rejected(reason) {
+ console.error(reason);
self.setInitialView(null, scale);
});
});
@@ -6554,72 +6705,21 @@ var PDFViewerApplication = {
this.pdfViewer.scrollPageIntoView(pageNumber);
},
- /**
- * This function flips the page in presentation mode if the user scrolls up
- * or down with large enough motion and prevents page flipping too often.
- *
- * @this {PDFView}
- * @param {number} mouseScrollDelta The delta value from the mouse event.
- */
- mouseScroll: function pdfViewMouseScroll(mouseScrollDelta) {
- var MOUSE_SCROLL_COOLDOWN_TIME = 50;
-
- var currentTime = (new Date()).getTime();
- var storedTime = this.mouseScrollTimeStamp;
-
- // In case one page has already been flipped there is a cooldown time
- // which has to expire before next page can be scrolled on to.
- if (currentTime > storedTime &&
- currentTime - storedTime < MOUSE_SCROLL_COOLDOWN_TIME) {
+ requestPresentationMode: function pdfViewRequestPresentationMode() {
+ if (!this.pdfPresentationMode) {
return;
}
-
- // In case the user decides to scroll to the opposite direction than before
- // clear the accumulated delta.
- if ((this.mouseScrollDelta > 0 && mouseScrollDelta < 0) ||
- (this.mouseScrollDelta < 0 && mouseScrollDelta > 0)) {
- this.clearMouseScrollState();
- }
-
- this.mouseScrollDelta += mouseScrollDelta;
-
- var PAGE_FLIP_THRESHOLD = 120;
- if (Math.abs(this.mouseScrollDelta) >= PAGE_FLIP_THRESHOLD) {
-
- var PageFlipDirection = {
- UP: -1,
- DOWN: 1
- };
-
- // In presentation mode scroll one page at a time.
- var pageFlipDirection = (this.mouseScrollDelta > 0) ?
- PageFlipDirection.UP :
- PageFlipDirection.DOWN;
- this.clearMouseScrollState();
- var currentPage = this.page;
-
- // In case we are already on the first or the last page there is no need
- // to do anything.
- if ((currentPage === 1 && pageFlipDirection === PageFlipDirection.UP) ||
- (currentPage === this.pagesCount &&
- pageFlipDirection === PageFlipDirection.DOWN)) {
- return;
- }
-
- this.page += pageFlipDirection;
- this.mouseScrollTimeStamp = currentTime;
- }
+ this.pdfPresentationMode.request();
},
/**
- * This function clears the member attributes used with mouse scrolling in
- * presentation mode.
- *
- * @this {PDFView}
+ * @param {number} delta - The delta value from the mouse event.
*/
- clearMouseScrollState: function pdfViewClearMouseScrollState() {
- this.mouseScrollTimeStamp = 0;
- this.mouseScrollDelta = 0;
+ scrollPresentationMode: function pdfViewScrollPresentationMode(delta) {
+ if (!this.pdfPresentationMode) {
+ return;
+ }
+ this.pdfPresentationMode.mouseScroll(delta);
}
};
@@ -6814,10 +6914,6 @@ function webViewerInitialized() {
PDFViewerApplication.initPassiveLoading();
return;
-
- if (file) {
- PDFViewerApplication.open(file, 0);
- }
}
document.addEventListener('DOMContentLoaded', webViewerLoad, true);
@@ -7064,10 +7160,12 @@ function handleMouseWheel(evt) {
evt.wheelDelta / MOUSE_WHEEL_DELTA_FACTOR;
var direction = (ticks < 0) ? 'zoomOut' : 'zoomIn';
- if (PresentationMode.active) {
+ if (PDFViewerApplication.pdfViewer.isInPresentationMode) {
evt.preventDefault();
- PDFViewerApplication.mouseScroll(ticks * MOUSE_WHEEL_DELTA_FACTOR);
- } else if (evt.ctrlKey) { // Only zoom the pages, not the entire viewer
+ PDFViewerApplication.scrollPresentationMode(ticks *
+ MOUSE_WHEEL_DELTA_FACTOR);
+ } else if (evt.ctrlKey || evt.metaKey) {
+ // Only zoom the pages, not the entire viewer.
evt.preventDefault();
PDFViewerApplication[direction](Math.abs(ticks));
}
@@ -7077,15 +7175,9 @@ window.addEventListener('DOMMouseScroll', handleMouseWheel);
window.addEventListener('mousewheel', handleMouseWheel);
window.addEventListener('click', function click(evt) {
- if (!PresentationMode.active) {
- if (SecondaryToolbar.opened &&
+ if (SecondaryToolbar.opened &&
PDFViewerApplication.pdfViewer.containsElement(evt.target)) {
- SecondaryToolbar.close();
- }
- } else if (evt.button === 0) {
- // Necessary since preventDefault() in 'mousedown' won't stop
- // the event propagation in all circumstances in presentation mode.
- evt.preventDefault();
+ SecondaryToolbar.close();
}
}, false);
@@ -7100,15 +7192,13 @@ window.addEventListener('keydown', function keydown(evt) {
(evt.shiftKey ? 4 : 0) |
(evt.metaKey ? 8 : 0);
+ var pdfViewer = PDFViewerApplication.pdfViewer;
+ var isViewerInPresentationMode = pdfViewer && pdfViewer.isInPresentationMode;
+
// First, handle the key bindings that are independent whether an input
// control is selected or not.
if (cmd === 1 || cmd === 8 || cmd === 5 || cmd === 12) {
// either CTRL or META key with optional SHIFT.
- var pdfViewer = PDFViewerApplication.pdfViewer;
- var inPresentationMode = pdfViewer &&
- (pdfViewer.presentationModeState === PresentationModeState.CHANGING ||
- pdfViewer.presentationModeState === PresentationModeState.FULLSCREEN);
-
switch (evt.keyCode) {
case 70: // f
if (!PDFViewerApplication.supportsIntegratedFind) {
@@ -7127,7 +7217,7 @@ window.addEventListener('keydown', function keydown(evt) {
case 107: // FF '+' and '='
case 187: // Chrome '+'
case 171: // FF with German keyboard
- if (!inPresentationMode) {
+ if (!isViewerInPresentationMode) {
PDFViewerApplication.zoomIn();
}
handled = true;
@@ -7135,14 +7225,14 @@ window.addEventListener('keydown', function keydown(evt) {
case 173: // FF/Mac '-'
case 109: // FF '-'
case 189: // Chrome '-'
- if (!inPresentationMode) {
+ if (!isViewerInPresentationMode) {
PDFViewerApplication.zoomOut();
}
handled = true;
break;
case 48: // '0'
case 96: // '0' on Numpad of Swedish keyboard
- if (!inPresentationMode) {
+ if (!isViewerInPresentationMode) {
// keeping it unhandled (to restore page zoom to 100%)
setTimeout(function () {
// ... and resetting the scale after browser adjusts its scale
@@ -7159,7 +7249,7 @@ window.addEventListener('keydown', function keydown(evt) {
if (cmd === 3 || cmd === 10) {
switch (evt.keyCode) {
case 80: // p
- SecondaryToolbar.presentationModeClick();
+ PDFViewerApplication.requestPresentationMode();
handled = true;
break;
case 71: // g
@@ -7193,15 +7283,15 @@ window.addEventListener('keydown', function keydown(evt) {
case 38: // up arrow
case 33: // pg up
case 8: // backspace
- if (!PresentationMode.active &&
- PDFViewerApplication.currentScaleValue !== 'page-fit') {
+ if (!isViewerInPresentationMode &&
+ PDFViewerApplication.currentScaleValue !== 'page-fit') {
break;
}
/* in presentation mode */
/* falls through */
case 37: // left arrow
// horizontal scrolling using arrow keys
- if (PDFViewerApplication.pdfViewer.isHorizontalScrollbarEnabled) {
+ if (pdfViewer.isHorizontalScrollbarEnabled) {
break;
}
/* falls through */
@@ -7224,14 +7314,14 @@ window.addEventListener('keydown', function keydown(evt) {
case 40: // down arrow
case 34: // pg down
case 32: // spacebar
- if (!PresentationMode.active &&
+ if (!isViewerInPresentationMode &&
PDFViewerApplication.currentScaleValue !== 'page-fit') {
break;
}
/* falls through */
case 39: // right arrow
// horizontal scrolling using arrow keys
- if (PDFViewerApplication.pdfViewer.isHorizontalScrollbarEnabled) {
+ if (pdfViewer.isHorizontalScrollbarEnabled) {
break;
}
/* falls through */
@@ -7242,13 +7332,13 @@ window.addEventListener('keydown', function keydown(evt) {
break;
case 36: // home
- if (PresentationMode.active || PDFViewerApplication.page > 1) {
+ if (isViewerInPresentationMode || PDFViewerApplication.page > 1) {
PDFViewerApplication.page = 1;
handled = true;
}
break;
case 35: // end
- if (PresentationMode.active || (PDFViewerApplication.pdfDocument &&
+ if (isViewerInPresentationMode || (PDFViewerApplication.pdfDocument &&
PDFViewerApplication.page < PDFViewerApplication.pagesCount)) {
PDFViewerApplication.page = PDFViewerApplication.pagesCount;
handled = true;
@@ -7256,7 +7346,7 @@ window.addEventListener('keydown', function keydown(evt) {
break;
case 72: // 'h'
- if (!PresentationMode.active) {
+ if (!isViewerInPresentationMode) {
HandTool.toggle();
}
break;
@@ -7269,7 +7359,7 @@ window.addEventListener('keydown', function keydown(evt) {
if (cmd === 4) { // shift-key
switch (evt.keyCode) {
case 32: // spacebar
- if (!PresentationMode.active &&
+ if (!isViewerInPresentationMode &&
PDFViewerApplication.currentScaleValue !== 'page-fit') {
break;
}
@@ -7283,34 +7373,34 @@ window.addEventListener('keydown', function keydown(evt) {
}
}
- if (!handled && !PresentationMode.active) {
+ if (!handled && !isViewerInPresentationMode) {
// 33=Page Up 34=Page Down 35=End 36=Home
// 37=Left 38=Up 39=Right 40=Down
if (evt.keyCode >= 33 && evt.keyCode <= 40 &&
- !PDFViewerApplication.pdfViewer.containsElement(curElement)) {
+ !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.
- PDFViewerApplication.pdfViewer.focus();
+ pdfViewer.focus();
}
// 32=Spacebar
if (evt.keyCode === 32 && curElementTagName !== 'BUTTON') {
// Workaround for issue in Firefox, that prevents scroll keys from
// working when elements with 'tabindex' are focused. (#3498)
- PDFViewerApplication.pdfViewer.blur();
+ pdfViewer.blur();
}
}
if (cmd === 2) { // alt-key
switch (evt.keyCode) {
case 37: // left arrow
- if (PresentationMode.active) {
+ if (isViewerInPresentationMode) {
PDFHistory.back();
handled = true;
}
break;
case 39: // right arrow
- if (PresentationMode.active) {
+ if (isViewerInPresentationMode) {
PDFHistory.forward();
handled = true;
}
@@ -7320,7 +7410,6 @@ window.addEventListener('keydown', function keydown(evt) {
if (handled) {
evt.preventDefault();
- PDFViewerApplication.clearMouseScrollState();
}
});