diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-07-16 11:45:35 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-07-17 08:59:23 +0000 |
commit | 552906b0f222c5d5dd11b9fd73829d510980461a (patch) | |
tree | 3a11e6ed0538a81dd83b20cf3a4783e297f26d91 /chromium/chrome/browser/resources/pdf | |
parent | 1b05827804eaf047779b597718c03e7d38344261 (diff) |
BASELINE: Update Chromium to 83.0.4103.122
Change-Id: Ie3a82f5bb0076eec2a7c6a6162326b4301ee291e
Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/chrome/browser/resources/pdf')
31 files changed, 463 insertions, 308 deletions
diff --git a/chromium/chrome/browser/resources/pdf/.eslintrc.js b/chromium/chrome/browser/resources/pdf/.eslintrc.js new file mode 100644 index 00000000000..18f6e9550ca --- /dev/null +++ b/chromium/chrome/browser/resources/pdf/.eslintrc.js @@ -0,0 +1,11 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module.exports = { + 'env': { + 'browser': true, + 'es6': true, + }, + 'rules': {'eqeqeq': ['error', 'always', {'null': 'ignore'}]}, +}; diff --git a/chromium/chrome/browser/resources/pdf/BUILD.gn b/chromium/chrome/browser/resources/pdf/BUILD.gn index 0acf11807ff..f93045f59b9 100644 --- a/chromium/chrome/browser/resources/pdf/BUILD.gn +++ b/chromium/chrome/browser/resources/pdf/BUILD.gn @@ -18,25 +18,21 @@ js_library("annotation_tool") { } js_library("browser_api") { - deps = [ - "//ui/webui/resources/js:assert.m", - ] + deps = [ "//ui/webui/resources/js:assert.m" ] externs_list = [ "$externs_path/chrome_extensions.js", "$externs_path/mime_handler_private.js", ] } -js_library("pdf_fitting_type") { +js_library("constants") { } js_library("gesture_detector") { } js_library("open_pdf_params_parser") { - deps = [ - ":pdf_fitting_type", - ] + deps = [ ":constants" ] } js_library("pdf_scripting_api") { @@ -47,8 +43,8 @@ js_library("viewport_scroller") { js_library("viewport") { deps = [ + ":constants", ":gesture_detector", - ":pdf_fitting_type", ":zoom_manager", "//ui/webui/resources/js:assert.m", "//ui/webui/resources/js:event_tracker.m", @@ -65,9 +61,7 @@ js_library("zoom_manager") { } js_library("metrics") { - deps = [ - ":pdf_fitting_type", - ] + deps = [ ":constants" ] externs_list = [ "$externs_path/metrics_private.js" ] } @@ -101,6 +95,7 @@ js_library("controller") { js_library("pdf_viewer") { deps = [ + ":constants", ":controller", ":metrics", ":navigator", @@ -135,13 +130,13 @@ js_type_check("pdf_resources") { deps = [ ":annotation_tool", ":browser_api", + ":constants", ":controller", ":gesture_detector", ":main", ":metrics", ":navigator", ":open_pdf_params_parser", - ":pdf_fitting_type", ":pdf_scripting_api", ":pdf_viewer", ":toolbar_manager", diff --git a/chromium/chrome/browser/resources/pdf/browser_api.js b/chromium/chrome/browser/resources/pdf/browser_api.js index 98b37391ed2..53ceeef1da9 100644 --- a/chromium/chrome/browser/resources/pdf/browser_api.js +++ b/chromium/chrome/browser/resources/pdf/browser_api.js @@ -97,7 +97,7 @@ export class BrowserApi { */ setZoom(zoom) { assert( - this.zoomBehavior_ == BrowserApi.ZoomBehavior.MANAGE, + this.zoomBehavior_ === BrowserApi.ZoomBehavior.MANAGE, 'Viewer does not manage browser zoom.'); return new Promise((resolve, reject) => { chrome.tabs.setZoom(this.streamInfo_.tabId, zoom, resolve); @@ -132,15 +132,15 @@ export class BrowserApi { * factor. */ addZoomEventListener(listener) { - if (!(this.zoomBehavior_ == BrowserApi.ZoomBehavior.MANAGE || - this.zoomBehavior_ == BrowserApi.ZoomBehavior.PROPAGATE_PARENT)) { + if (!(this.zoomBehavior_ === BrowserApi.ZoomBehavior.MANAGE || + this.zoomBehavior_ === BrowserApi.ZoomBehavior.PROPAGATE_PARENT)) { return; } chrome.tabs.onZoomChange.addListener(info => { const zoomChangeInfo = /** @type {{tabId: number, newZoomFactor: number}} */ (info); - if (zoomChangeInfo.tabId != this.streamInfo_.tabId) { + if (zoomChangeInfo.tabId !== this.streamInfo_.tabId) { return; } listener(zoomChangeInfo.newZoomFactor); @@ -171,7 +171,7 @@ function createBrowserApiForMimeHandlerView() { .then(function(streamInfo) { const promises = []; let zoomBehavior = BrowserApi.ZoomBehavior.NONE; - if (streamInfo.tabId != -1) { + if (streamInfo.tabId !== -1) { zoomBehavior = streamInfo.embedded ? BrowserApi.ZoomBehavior.PROPAGATE_PARENT : BrowserApi.ZoomBehavior.MANAGE; @@ -183,7 +183,7 @@ function createBrowserApiForMimeHandlerView() { } })); } - if (zoomBehavior == BrowserApi.ZoomBehavior.MANAGE) { + if (zoomBehavior === BrowserApi.ZoomBehavior.MANAGE) { promises.push(new Promise(function(resolve) { chrome.tabs.setZoomSettings( streamInfo.tabId, {mode: 'manual', scope: 'per-tab'}, resolve); @@ -207,7 +207,7 @@ function createBrowserApiForPrintPreview() { streamUrl: url, originalUrl: url, responseHeaders: {}, - embedded: window.parent != window, + embedded: window.parent !== window, tabId: -1, }; return new Promise(function(resolve, reject) { diff --git a/chromium/chrome/browser/resources/pdf/pdf_fitting_type.js b/chromium/chrome/browser/resources/pdf/constants.js index 7ff9bdb951b..70da3e827d7 100644 --- a/chromium/chrome/browser/resources/pdf/pdf_fitting_type.js +++ b/chromium/chrome/browser/resources/pdf/constants.js @@ -10,5 +10,14 @@ export const FittingType = { NONE: 'none', FIT_TO_PAGE: 'fit-to-page', FIT_TO_WIDTH: 'fit-to-width', - FIT_TO_HEIGHT: 'fit-to-height' + FIT_TO_HEIGHT: 'fit-to-height', +}; + +/** + * Enumeration of two up view actions. + * @enum {string} + */ +export const TwoUpViewAction = { + TWO_UP_VIEW_ENABLE: 'two-up-view-enable', + TWO_UP_VIEW_DISABLE: 'two-up-view-disable', }; diff --git a/chromium/chrome/browser/resources/pdf/controller.js b/chromium/chrome/browser/resources/pdf/controller.js index e607c688a85..9eccd835645 100644 --- a/chromium/chrome/browser/resources/pdf/controller.js +++ b/chromium/chrome/browser/resources/pdf/controller.js @@ -91,6 +91,9 @@ export class ContentController { /** @abstract */ rotateCounterclockwise() {} + /** @abstract */ + setTwoUpView(enableTwoUpView) {} + /** Triggers printing of the current document. */ print() {} @@ -175,6 +178,11 @@ export class InkController extends ContentController { } /** @override */ + setTwoUpView(enableTwoUpView) { + // TODO(dstockwell): Implement two up view. + } + + /** @override */ viewportChanged() { this.inkHost_.viewportChanged(); } @@ -268,7 +276,7 @@ export class PluginController extends ContentController { beforeZoom() { this.postMessage_({type: 'stopScrolling'}); - if (this.viewport_.pinchPhase == Viewport.PinchPhase.PINCH_START) { + if (this.viewport_.pinchPhase === Viewport.PinchPhase.PINCH_START) { const position = this.viewport_.position; const zoom = this.viewport_.getZoom(); const pinchPhase = this.viewport_.pinchPhase; @@ -334,6 +342,14 @@ export class PluginController extends ContentController { } /** @override */ + setTwoUpView(enableTwoUpView) { + this.postMessage_({ + type: 'setTwoUpView', + enableTwoUpView: enableTwoUpView, + }); + } + + /** @override */ print() { this.postMessage_({type: 'print'}); } @@ -492,7 +508,7 @@ export class PluginController extends ContentController { `File too large to be saved: ${bufView.length} bytes.`); assert(bufView.length >= MIN_FILE_SIZE); assert( - String.fromCharCode(bufView[0], bufView[1], bufView[2], bufView[3]) == + String.fromCharCode(bufView[0], bufView[1], bufView[2], bufView[3]) === '%PDF'); resolver.resolve(messageData); diff --git a/chromium/chrome/browser/resources/pdf/elements/BUILD.gn b/chromium/chrome/browser/resources/pdf/elements/BUILD.gn index 1ffa8445e8e..923473079db 100644 --- a/chromium/chrome/browser/resources/pdf/elements/BUILD.gn +++ b/chromium/chrome/browser/resources/pdf/elements/BUILD.gn @@ -34,9 +34,7 @@ js_library("viewer-bookmark") { } js_library("viewer-error-screen") { - deps = [ - "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog.m", - ] + deps = [ "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog.m" ] } if (is_chromeos) { @@ -64,15 +62,11 @@ js_library("viewer-page-indicator") { } js_library("viewer-page-selector") { - deps = [ - "//ui/webui/resources/cr_elements/cr_input:cr_input.m", - ] + deps = [ "//ui/webui/resources/cr_elements/cr_input:cr_input.m" ] } js_library("viewer-password-screen") { - deps = [ - "//ui/webui/resources/cr_elements/cr_input:cr_input.m", - ] + deps = [ "//ui/webui/resources/cr_elements/cr_input:cr_input.m" ] } js_library("viewer-pdf-toolbar") { @@ -95,7 +89,7 @@ js_library("viewer-toolbar-dropdown") { js_library("viewer-zoom-toolbar") { deps = [ ":viewer-zoom-button", - "..:pdf_fitting_type", + "..:constants", "//ui/webui/resources/js:assert.m", ] } @@ -189,7 +183,7 @@ polymer_modulizer("icons") { } group("polymer3_elements") { - deps = [ + public_deps = [ ":icons_module", ":shared-vars_module", ":viewer-bookmark_module", @@ -203,7 +197,7 @@ group("polymer3_elements") { ":viewer-zoom-toolbar_module", ] if (is_chromeos) { - deps += [ + public_deps += [ ":viewer-form-warning_module", ":viewer-ink-host_module", ":viewer-pen-options_module", diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark.js b/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark.js index fb9f73b7d1f..20363c71137 100644 --- a/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark.js +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark.js @@ -74,25 +74,25 @@ Polymer({ keyBindings: {'enter': 'onEnter_', 'space': 'onSpace_'}, /** @override */ - attached: function() { + attached() { this.keyEventTarget = this.$.item; }, /** @private */ - bookmarkChanged_: function() { + bookmarkChanged_() { this.$.expand.style.visibility = this.bookmark.children.length > 0 ? 'visible' : 'hidden'; }, /** @private */ - depthChanged_: function() { + depthChanged_() { this.childDepth_ = this.depth + 1; this.$.item.style.paddingInlineStart = (this.depth * BOOKMARK_INDENT) + 'px'; }, /** @private */ - onClick_: function() { + onClick_() { if (this.bookmark.page != null) { if (this.bookmark.zoom != null) { this.fire('change-zoom', {zoom: this.bookmark.zoom}); @@ -118,10 +118,10 @@ Polymer({ * @param {!KeyboardEvent} e * @private */ - onEnter_: function(e) { + onEnter_(e) { // Don't allow events which have propagated up from the expand button to // trigger a click. - if (e.detail.keyboardEvent.target != this.$.expand) { + if (e.detail.keyboardEvent.target !== this.$.expand) { this.onClick_(); } }, @@ -130,7 +130,7 @@ Polymer({ * @param {!KeyboardEvent} e * @private */ - onSpace_: function(e) { + onSpace_(e) { // cr-icon-button stops propagation of space events, so there's no need // to check the event source here. this.onClick_(); @@ -142,7 +142,7 @@ Polymer({ * @param {!Event} e * @private */ - toggleChildren_: function(e) { + toggleChildren_(e) { this.childrenShown_ = !this.childrenShown_; e.stopPropagation(); // Prevent the above onClick_ handler from firing. } diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen.js b/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen.js index 7bb01225d8d..d3383b06e25 100644 --- a/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen.js +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen.js @@ -19,11 +19,11 @@ Polymer({ strings: Object, }, - show: function() { + show() { /** @type {!CrDialogElement} */ (this.$.dialog).showModal(); }, - reload: function() { + reload() { if (this.reloadFn) { this.reloadFn(); } diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-form-warning.js b/chromium/chrome/browser/resources/pdf/elements/viewer-form-warning.js index 5bd8f3c3692..d0cbd6d1de8 100644 --- a/chromium/chrome/browser/resources/pdf/elements/viewer-form-warning.js +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-form-warning.js @@ -21,18 +21,18 @@ Polymer({ /** @private {PromiseResolver} */ resolver_: null, - show: function() { + show() { this.resolver_ = new PromiseResolver(); /** @type {!CrDialogElement} */ (this.$.dialog).showModal(); return this.resolver_.promise; }, - onCancel: function() { + onCancel() { this.resolver_.reject(); this.$.dialog.cancel(); }, - onAction: function() { + onAction() { this.resolver_.resolve(); this.$.dialog.close(); }, diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-ink-host.js b/chromium/chrome/browser/resources/pdf/elements/viewer-ink-host.js index 1de273feb3e..fa208811e90 100644 --- a/chromium/chrome/browser/resources/pdf/elements/viewer-ink-host.js +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-ink-host.js @@ -84,14 +84,14 @@ Polymer({ /** @param {AnnotationTool} tool */ setAnnotationTool(tool) { this.tool_ = tool; - if (this.state_ == State.ACTIVE) { + if (this.state_ === State.ACTIVE) { this.ink_.setAnnotationTool(tool); } }, /** @param {PointerEvent} e */ - isActivePointer_: function(e) { - return this.activePointer_ && this.activePointer_.pointerId == e.pointerId; + isActivePointer_(e) { + return this.activePointer_ && this.activePointer_.pointerId === e.pointerId; }, /** @@ -99,7 +99,7 @@ Polymer({ * * @param {PointerEvent} e */ - dispatchPointerEvent_: function(e) { + dispatchPointerEvent_(e) { // TODO(dstockwell) come up with a solution to propagate e.timeStamp. this.ink_.dispatchPointerEvent(e.type, { pointerId: e.pointerId, @@ -112,7 +112,7 @@ Polymer({ }, /** @param {TouchEvent} e */ - onTouchStart_: function(e) { + onTouchStart_(e) { if (e.timeStamp !== this.allowTouchStartTimeStamp_) { e.preventDefault(); } @@ -120,18 +120,18 @@ Polymer({ }, /** @param {PointerEvent} e */ - onPointerDown_: function(e) { - if (e.pointerType == 'mouse' && e.buttons != 1 || this.pointerGesture_) { + onPointerDown_(e) { + if (e.pointerType === 'mouse' && e.buttons !== 1 || this.pointerGesture_) { return; } - if (e.pointerType == 'pen') { + if (e.pointerType === 'pen') { this.penMode_ = true; } if (this.activePointer_) { - if (this.activePointer_.pointerType == 'touch' && - e.pointerType == 'touch') { + if (this.activePointer_.pointerType === 'touch' && + e.pointerType === 'touch') { // A multi-touch gesture has started with the active pointer. Cancel // the active pointer and suppress further events until it is released. this.pointerGesture_ = true; @@ -144,13 +144,13 @@ Polymer({ } if (!this.viewport.isPointInsidePage({x: e.clientX, y: e.clientY}) && - (e.pointerType == 'touch' || e.pointerType == 'pen')) { + (e.pointerType === 'touch' || e.pointerType === 'pen')) { // If a touch or pen is outside the page, we allow pan gestures to start. this.allowTouchStartTimeStamp_ = e.timeStamp; return; } - if (e.pointerType == 'touch' && this.penMode_) { + if (e.pointerType === 'touch' && this.penMode_) { // If we see a touch after having seen a pen, we allow touches to start // pan gestures anywhere and suppress all touches from drawing. this.allowTouchStartTimeStamp_ = e.timeStamp; @@ -162,37 +162,37 @@ Polymer({ }, /** @param {PointerEvent} e */ - onPointerLeave_: function(e) { - if (e.pointerType != 'mouse' || !this.isActivePointer_(e)) { + onPointerLeave_(e) { + if (e.pointerType !== 'mouse' || !this.isActivePointer_(e)) { return; } this.onPointerUpOrCancel_(new PointerEvent('pointerup', e)); }, /** @param {PointerEvent} e */ - onPointerUpOrCancel_: function(e) { + onPointerUpOrCancel_(e) { if (!this.isActivePointer_(e)) { return; } this.activePointer_ = null; if (!this.pointerGesture_) { this.dispatchPointerEvent_(e); - // If the stroke was not cancelled (type == pointercanel), + // If the stroke was not cancelled (type === pointercanel), // notify about mutation and record metrics. - if (e.type == 'pointerup') { + if (e.type === 'pointerup') { this.dispatchEvent(new CustomEvent('stroke-added')); - if (e.pointerType == 'mouse') { + if (e.pointerType === 'mouse') { PDFMetrics.record(PDFMetrics.UserAction.ANNOTATE_STROKE_DEVICE_MOUSE); - } else if (e.pointerType == 'pen') { + } else if (e.pointerType === 'pen') { PDFMetrics.record(PDFMetrics.UserAction.ANNOTATE_STROKE_DEVICE_PEN); - } else if (e.pointerType == 'touch') { + } else if (e.pointerType === 'touch') { PDFMetrics.record(PDFMetrics.UserAction.ANNOTATE_STROKE_DEVICE_TOUCH); } - if (this.tool_.tool == 'eraser') { + if (this.tool_.tool === 'eraser') { PDFMetrics.record(PDFMetrics.UserAction.ANNOTATE_STROKE_TOOL_ERASER); - } else if (this.tool_.tool == 'pen') { + } else if (this.tool_.tool === 'pen') { PDFMetrics.record(PDFMetrics.UserAction.ANNOTATE_STROKE_TOOL_PEN); - } else if (this.tool_.tool == 'highlighter') { + } else if (this.tool_.tool === 'highlighter') { PDFMetrics.record( PDFMetrics.UserAction.ANNOTATE_STROKE_TOOL_HIGHLIGHTER); } @@ -202,13 +202,13 @@ Polymer({ }, /** @param {PointerEvent} e */ - onPointerMove_: function(e) { + onPointerMove_(e) { if (!this.isActivePointer_(e) || this.pointerGesture_) { return; } let events = e.getCoalescedEvents(); - if (events.length == 0) { + if (events.length === 0) { events = [e]; } for (const event of events) { @@ -246,8 +246,8 @@ Polymer({ this.style.visibility = 'visible'; }, - viewportChanged: function() { - if (this.state_ != State.ACTIVE) { + viewportChanged() { + if (this.state_ !== State.ACTIVE) { return; } const viewport = this.viewport; @@ -295,7 +295,7 @@ Polymer({ * The serialized PDF document including any annotations that were made. */ saveDocument: async function() { - if (this.state_ == State.ACTIVE) { + if (this.state_ === State.ACTIVE) { this.buffer_ = await this.ink_.getPDFDestructive().buffer; this.state_ = State.IDLE; } diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-page-indicator.js b/chromium/chrome/browser/resources/pdf/elements/viewer-page-indicator.js index 469ba84aeeb..5f901bb9db9 100644 --- a/chromium/chrome/browser/resources/pdf/elements/viewer-page-indicator.js +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-page-indicator.js @@ -23,7 +23,7 @@ Polymer({ timerId: undefined, /** @override */ - ready: function() { + ready() { const callback = this.fadeIn_.bind(this); window.addEventListener('scroll', function() { requestAnimationFrame(callback); @@ -31,7 +31,7 @@ Polymer({ }, /** @private */ - fadeIn_: function() { + fadeIn_() { const percent = window.scrollY / (document.scrollingElement.scrollHeight - document.documentElement.clientHeight); @@ -45,7 +45,7 @@ Polymer({ // those platforms, though. assert(document.documentElement.dir); const endEdge = isRTL() ? 'left' : 'right'; - if (window.innerWidth == document.scrollingElement.scrollWidth) { + if (window.innerWidth === document.scrollingElement.scrollWidth) { this.style[endEdge] = '16px'; } else { this.style[endEdge] = '0px'; @@ -60,11 +60,11 @@ Polymer({ }, 2000); }, - pageLabelsChanged: function() { + pageLabelsChanged() { this.indexChanged(); }, - indexChanged: function() { + indexChanged() { if (this.pageLabels) { this.label = this.pageLabels[this.index]; } else { diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector.js b/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector.js index 035e5d8fa9b..5eda31ee514 100644 --- a/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector.js +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector.js @@ -35,7 +35,7 @@ Polymer({ return /** @type {!CrInputElement} */ (this.$.pageselector); }, - pageNoCommitted: function() { + pageNoCommitted() { const page = parseInt(this.pageSelector.value, 10); if (!isNaN(page) && page <= this.docLength && page > 0) { @@ -47,27 +47,27 @@ Polymer({ }, /** @private */ - docLengthChanged_: function() { + docLengthChanged_() { const numDigits = this.docLength.toString().length; this.style.setProperty('--page-length-digits', `${numDigits}`); }, - select: function() { + select() { this.pageSelector.select(); }, /** * @return {boolean} True if the selector input field is currently focused. */ - isActive: function() { - return this.shadowRoot.activeElement == this.pageSelector; + isActive() { + return this.shadowRoot.activeElement === this.pageSelector; }, /** * Immediately remove any non-digit characters. * @private */ - onInputValueChange_: function() { + onInputValueChange_() { this.pageSelector.value = this.pageSelector.value.replace(/[^\d]/, ''); }, }); diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen.js b/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen.js index 96425280dac..79cd849c56b 100644 --- a/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen.js +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen.js @@ -25,17 +25,17 @@ Polymer({ return this.$.dialog.open; }, - show: function() { + show() { this.$.dialog.showModal(); }, - close: function() { + close() { if (this.active) { this.$.dialog.close(); } }, - deny: function() { + deny() { const password = /** @type {!CrInputElement} */ (this.$.password); password.disabled = false; this.$.submit.disabled = false; @@ -43,9 +43,9 @@ Polymer({ password.select(); }, - submit: function() { + submit() { const password = /** @type {!CrInputElement} */ (this.$.password); - if (password.value.length == 0) { + if (password.value.length === 0) { return; } password.disabled = true; @@ -60,7 +60,7 @@ Polymer({ * @param {string} message * @return {string} */ - getErrorMessage_: function(message) { + getErrorMessage_(message) { return this.invalid ? message : ''; } }); diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar.js b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar.js index 4f412de2b53..1a5af6551ab 100644 --- a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar.js +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar.js @@ -111,7 +111,7 @@ Polymer({ * @param {number} oldProgress * @private */ - loadProgressChanged_: function(newProgress, oldProgress) { + loadProgressChanged_(newProgress, oldProgress) { const loaded = newProgress >= 100; const progressReset = newProgress < oldProgress; if (progressReset || loaded) { @@ -122,19 +122,19 @@ Polymer({ } }, - hide: function() { + hide() { if (this.opened && !this.shouldKeepOpen()) { this.toggleVisibility(); } }, - show: function() { + show() { if (!this.opened) { this.toggleVisibility(); } }, - toggleVisibility: function() { + toggleVisibility() { this.opened = !this.opened; // We keep a handle on the animation in order to cancel the filling @@ -160,18 +160,18 @@ Polymer({ } }, - selectPageNumber: function() { + selectPageNumber() { this.$.pageselector.select(); }, /** @return {boolean} Whether the toolbar should be kept open. */ - shouldKeepOpen: function() { + shouldKeepOpen() { return this.$.bookmarks.dropdownOpen || this.loadProgress < 100 || this.$.pageselector.isActive() || this.annotationMode; }, /** @return {boolean} Whether a dropdown was open and was hidden. */ - hideDropdowns: function() { + hideDropdowns() { let result = false; if (this.$.bookmarks.dropdownOpen) { this.$.bookmarks.toggleDropdown(); @@ -189,31 +189,31 @@ Polymer({ }, /** @param {number} lowerBound */ - setDropdownLowerBound: function(lowerBound) { + setDropdownLowerBound(lowerBound) { this.$.bookmarks.lowerBound = lowerBound; }, - rotateRight: function() { + rotateRight() { this.fire('rotate-right'); }, - download: function() { + download() { this.fire('save'); }, - print: function() { + print() { this.fire('print'); }, - undo: function() { + undo() { this.fire('undo'); }, - redo: function() { + redo() { this.fire('redo'); }, - toggleAnnotation: function() { + toggleAnnotation() { this.annotationMode = !this.annotationMode; if (this.annotationMode) { // Select pen tool when entering annotation mode. @@ -230,7 +230,7 @@ Polymer({ * @param {!Event} e * @private */ - annotationToolClicked_: function(e) { + annotationToolClicked_(e) { this.updateAnnotationTool_(/** @type {!HTMLElement} */ (e.currentTarget)); }, @@ -238,9 +238,9 @@ Polymer({ * @param {!Event} e * @private */ - annotationToolOptionChanged_: function(e) { + annotationToolOptionChanged_(e) { const element = e.currentTarget.parentElement; - if (!this.annotationTool || element.id != this.annotationTool.tool) { + if (!this.annotationTool || element.id !== this.annotationTool.tool) { return; } this.updateAnnotationTool_(e.currentTarget.parentElement); @@ -250,7 +250,7 @@ Polymer({ * @param {!HTMLElement} element * @private */ - updateAnnotationTool_: function(element) { + updateAnnotationTool_(element) { const tool = element.id; const options = element.querySelector('viewer-pen-options') || { selectedSize: 1, @@ -260,8 +260,8 @@ Polymer({ attributeStyleMap.set('--pen-tip-fill', options.selectedColor); attributeStyleMap.set( '--pen-tip-border', - options.selectedColor == '#000000' ? 'currentcolor' : - options.selectedColor); + options.selectedColor === '#000000' ? 'currentcolor' : + options.selectedColor); this.annotationTool = { tool: tool, size: options.selectedSize, @@ -274,7 +274,7 @@ Polymer({ * @return {boolean} Whether the annotation tool is using tool |toolName|. * @private */ - isAnnotationTool_: function(toolName) { + isAnnotationTool_(toolName) { return !!this.annotationTool && this.annotationTool.tool === toolName; }, }); diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-pen-options.js b/chromium/chrome/browser/resources/pdf/elements/viewer-pen-options.js index 134a0e8f771..0cc12c94384 100644 --- a/chromium/chrome/browser/resources/pdf/elements/viewer-pen-options.js +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-pen-options.js @@ -91,23 +91,23 @@ Polymer({ expandAnimations_: null, /** @param {Event} e */ - sizeChanged_: function(e) { + sizeChanged_(e) { this.selectedSize = Number(e.target.value); }, /** @param {Event} e */ - colorChanged_: function(e) { + colorChanged_(e) { this.selectedColor = e.target.value; }, /** @private */ - toggleExpanded_: function() { + toggleExpanded_() { this.expanded_ = !this.expanded_; this.updateExpandedState_(); }, /** @private */ - updateExpandedStateAndFinishAnimations_: function() { + updateExpandedStateAndFinishAnimations_() { this.updateExpandedState_(); for (const animation of /** @type {!Array<!Animation>} */ ( this.expandAnimations_)) { @@ -116,7 +116,7 @@ Polymer({ }, /** @override */ - attached: function() { + attached() { beforeNextRender(this, () => { this.updateExpandedStateAndFinishAnimations_(); }); @@ -126,7 +126,7 @@ Polymer({ * Updates the state of the UI to reflect the current value of `expanded`. * Starts or reverses animations and enables/disable controls. */ - updateExpandedState_: function() { + updateExpandedState_() { const colors = this.$.colors; if (!this.expandAnimations_) { const separator = this.$.separator; @@ -190,8 +190,8 @@ Polymer({ * @param {*} a * @param {*} b */ - equal_: function(a, b) { - return a == b; + equal_(a, b) { + return a === b; }, /** @@ -201,7 +201,7 @@ Polymer({ * @param {string} name * @return {string} */ - lookup_: function(strings, name) { + lookup_(strings, name) { return strings ? strings[name] : ''; }, diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown.js b/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown.js index 15c8b4e90af..d4ce32bd9b4 100644 --- a/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown.js +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown.js @@ -108,19 +108,19 @@ Polymer({ * @return {string} Current icon for the dropdown. * @private */ - computeIcon_: function(dropdownOpen, closedIcon, openIcon) { + computeIcon_(dropdownOpen, closedIcon, openIcon) { return dropdownOpen ? openIcon : closedIcon; }, /** @private */ - lowerBoundChanged_: function() { + lowerBoundChanged_() { this.maxHeightValid_ = false; if (this.dropdownOpen) { this.updateMaxHeight(); } }, - toggleDropdown: function() { + toggleDropdown() { if (!this.dropdownOpen && this.openAfterSelect && !this.selected) { // The dropdown has `openAfterSelect` set, but is not yet selected. return; @@ -152,7 +152,7 @@ Polymer({ this.playAnimation_(this.dropdownOpen); }, - updateMaxHeight: function() { + updateMaxHeight() { const scrollContainer = this.$['scroll-container']; let height = this.lowerBound - scrollContainer.getBoundingClientRect().top - DROPDOWN_INNER_PADDING; @@ -167,7 +167,7 @@ Polymer({ * exit. * @private */ - playAnimation_: function(isEntry) { + playAnimation_(isEntry) { this.animation_ = isEntry ? this.animateEntry_() : this.animateExit_(); this.animation_.onfinish = () => { this.animation_ = null; @@ -181,7 +181,7 @@ Polymer({ * @return {!Object} Animation * @private */ - animateEntry_: function() { + animateEntry_() { let maxHeight = this.$.dropdown.getBoundingClientRect().height - DROPDOWN_OUTER_PADDING; @@ -210,7 +210,7 @@ Polymer({ * @return {!Object} Animation * @private */ - animateExit_: function() { + animateExit_() { return this.$.dropdown.animate( [ {transform: 'translateY(0)', opacity: 1}, diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-button.html b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-button.html index 6eab6174020..f51075c5cab 100644 --- a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-button.html +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-button.html @@ -77,6 +77,7 @@ </style> <div id="wrapper"> <cr-icon-button iron-icon="[[visibleIcon_]]" on-click="fireClick_" - aria-label$="[[visibleTooltip_]]" title="[[visibleTooltip_]]"> + aria-label$="[[visibleTooltip_]]" title="[[visibleTooltip_]]" + disabled="[[disabled]]"> </cr-icon-button> </div> diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-button.js b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-button.js index 195bf25cc5a..3182b901947 100644 --- a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-button.js +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-button.js @@ -25,6 +25,11 @@ Polymer({ observer: 'delayChanged_', }, + disabled: { + type: Boolean, + value: false, + }, + /** * Icons to be displayed on the FAB. Multiple icons should be separated with * spaces, and will be cycled through every time the FAB is clicked. @@ -83,7 +88,7 @@ Polymer({ * @return {!Array<string>} Array of icon name strings * @private */ - computeIconsArray_: function(icons) { + computeIconsArray_(icons) { return icons.split(' '); }, @@ -93,7 +98,7 @@ Polymer({ * @return {string} Icon name for the currently visible icon. * @private */ - computeVisibleIcon_: function(icons, activeIndex) { + computeVisibleIcon_(icons, activeIndex) { return icons[activeIndex]; }, @@ -103,25 +108,25 @@ Polymer({ * @return {string} Tooltip for the currently visible icon. * @private */ - computeVisibleTooltip_: function(tooltips, activeIndex) { + computeVisibleTooltip_(tooltips, activeIndex) { return tooltips === undefined ? '' : tooltips[activeIndex]; }, /** @private */ - delayChanged_: function() { + delayChanged_() { this.$.wrapper.style.transitionDelay = this.delay + 'ms'; }, - show: function() { + show() { this.closed_ = false; }, - hide: function() { + hide() { this.closed_ = true; }, /** @private */ - fireClick_: function() { + fireClick_() { // We cannot attach an on-click to the entire viewer-zoom-button, as this // will include clicks on the margins. Instead, proxy clicks on the FAB // through. diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar.html b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar.html index 887999eaefa..ab6a4d461ca 100644 --- a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar.html +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar.html @@ -1,4 +1,4 @@ - <style> + <style include="cr-hidden-style"> :host { --button-position-offset: 48px; bottom: 0; @@ -44,21 +44,33 @@ display: block; } + /* + * A larger gap between the fit button and the two-up view button + * and above the bottom two zoom buttons. + */ + #two-up-view-button, + #zoom-in-button { + margin-top: 24px; + } + /* A small gap between the zoom in/zoom out buttons. */ #zoom-out-button { margin-top: 10px; } - - /* A larger gap between the fit button and bottom two buttons. */ - #zoom-in-button { - margin-top: 24px; - } </style> <div id="zoom-buttons"> - <viewer-zoom-button id="fit-button" on-fabclick="fitToggle" delay="100" + <viewer-zoom-button id="fit-button" on-fabclick="fitToggle" + delay="[[fitButtonDelay_]]" keyboard-navigation-active="[[keyboardNavigationActive_]]" icons="pdf:fullscreen-exit cr:fullscreen"> </viewer-zoom-button> + <!-- TODO(crbug.com/51472): Change icons for two-up-view-button --> + <!-- once they are finalized. --> + <viewer-zoom-button id="two-up-view-button" delay="100" + disabled="[[annotationMode]]" hidden$="[[!twoUpViewEnabled]]" + on-fabclick="twoUpViewToggle_" + keyboard-navigation-active="[[keyboardNavigationActive_]]" + icons="pdf:create pdf:eraser"></viewer-zoom-button> <viewer-zoom-button id="zoom-in-button" icons="pdf:add" keyboard-navigation-active="[[keyboardNavigationActive_]]" on-fabclick="zoomIn" delay="50"></viewer-zoom-button> diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar.js b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar.js index 03376cd29b4..ec5e991934f 100644 --- a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar.js +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar.js @@ -8,7 +8,7 @@ import './viewer-zoom-button.js'; import {assert} from 'chrome://resources/js/assert.m.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {FittingType} from '../pdf_fitting_type.js'; +import {FittingType, TwoUpViewAction} from '../constants.js'; /** * @typedef {{ @@ -21,14 +21,31 @@ export let FitToChangedEvent; const FIT_TO_PAGE_BUTTON_STATE = 0; const FIT_TO_WIDTH_BUTTON_STATE = 1; +const TWO_UP_VIEW_DISABLED_STATE = 0; +const TWO_UP_VIEW_ENABLED_STATE = 1; + Polymer({ is: 'viewer-zoom-toolbar', _template: html`{__html_template__}`, properties: { + /** Whether the viewer is currently in annotation mode. */ + annotationMode: { + type: Boolean, + value: false, + }, + isPrintPreview: Boolean, + twoUpViewEnabled: Boolean, + + /** @private */ + fitButtonDelay_: { + type: Number, + computed: 'computeFitButtonDelay_(twoUpViewEnabled)', + }, + /** @private */ keyboardNavigationActive_: { type: Boolean, @@ -36,6 +53,15 @@ Polymer({ }, }, + /** + * @param {boolean} twoUpViewEnabled Whether two-up view button is enabled. + * @return {number} Delay for :qthe fit button. + * @private + */ + computeFitButtonDelay_(twoUpViewEnabled) { + return twoUpViewEnabled ? 150 : 100; + }, + listeners: { 'focus': 'onFocus_', 'keyup': 'onKeyUp_', @@ -46,12 +72,12 @@ Polymer({ visible_: true, /** @return {boolean} */ - isVisible: function() { + isVisible() { return this.visible_; }, /** @private */ - onFocus_: function() { + onFocus_() { // This can only happen when the plugin is shown within Print Preview using // keyboard navigation. if (!this.visible_) { @@ -62,7 +88,7 @@ Polymer({ }, /** @private */ - onKeyUp_: function() { + onKeyUp_() { if (this.isPrintPreview) { this.fire('keyboard-navigation-active', true); } @@ -70,7 +96,7 @@ Polymer({ }, /** @private */ - onPointerDown_: function() { + onPointerDown_() { if (this.isPrintPreview) { this.fire('keyboard-navigation-active', false); } @@ -81,33 +107,37 @@ Polymer({ * Change button tooltips to match any changes to localized strings. * @param {!{tooltipFitToPage: string, * tooltipFitToWidth: string, + * tooltipTwoUpViewEnable: string, + * tooltipTwoUpViewDisable: string, * tooltipZoomIn: string, * tooltipZoomOut: string}} strings */ - setStrings: function(strings) { + setStrings(strings) { this.$['fit-button'].tooltips = [strings.tooltipFitToPage, strings.tooltipFitToWidth]; + this.$['two-up-view-button'].tooltips = + [strings.tooltipTwoUpViewEnable, strings.tooltipTwoUpViewDisable]; this.$['zoom-in-button'].tooltips = [strings.tooltipZoomIn]; this.$['zoom-out-button'].tooltips = [strings.tooltipZoomOut]; }, /** Handle clicks of the fit-button. */ - fitToggle: function() { + fitToggle() { this.fireFitToChangedEvent_( - this.$['fit-button'].activeIndex == FIT_TO_WIDTH_BUTTON_STATE ? + this.$['fit-button'].activeIndex === FIT_TO_WIDTH_BUTTON_STATE ? FittingType.FIT_TO_WIDTH : FittingType.FIT_TO_PAGE, true); }, /** Handle the keyboard shortcut equivalent of fit-button clicks. */ - fitToggleFromHotKey: function() { + fitToggleFromHotKey() { this.fitToggle(); // Toggle the button state since there was no mouse click. const button = this.$['fit-button']; button.activeIndex = - (button.activeIndex == FIT_TO_WIDTH_BUTTON_STATE ? + (button.activeIndex === FIT_TO_WIDTH_BUTTON_STATE ? FIT_TO_PAGE_BUTTON_STATE : FIT_TO_WIDTH_BUTTON_STATE); }, @@ -116,13 +146,13 @@ Polymer({ * Handle forcing zoom via scripting to a fitting type. * @param {!FittingType} fittingType Page fitting type to force. */ - forceFit: function(fittingType) { + forceFit(fittingType) { this.fireFitToChangedEvent_(fittingType, false); // Set the button state since there was no mouse click. const nextButtonState = - (fittingType == FittingType.FIT_TO_WIDTH ? FIT_TO_PAGE_BUTTON_STATE : - FIT_TO_WIDTH_BUTTON_STATE); + (fittingType === FittingType.FIT_TO_WIDTH ? FIT_TO_PAGE_BUTTON_STATE : + FIT_TO_WIDTH_BUTTON_STATE); this.$['fit-button'].activeIndex = nextButtonState; }, @@ -133,39 +163,55 @@ Polymer({ * action. * @private */ - fireFitToChangedEvent_: function(fittingType, userInitiated) { + fireFitToChangedEvent_(fittingType, userInitiated) { this.fire( 'fit-to-changed', {fittingType: fittingType, userInitiated: userInitiated}); }, /** + * Handle clicks of the two-up-view button. + * @private + */ + twoUpViewToggle_: function() { + assert(this.twoUpViewEnabled); + const twoUpViewAction = this.$['two-up-view-button'].activeIndex === + TWO_UP_VIEW_DISABLED_STATE ? + TwoUpViewAction.TWO_UP_VIEW_ENABLE : + TwoUpViewAction.TWO_UP_VIEW_DISABLE; + + this.fire('two-up-view-changed', twoUpViewAction); + }, + + /** * Handle clicks of the zoom-in-button. */ - zoomIn: function() { + zoomIn() { this.fire('zoom-in'); }, /** * Handle clicks of the zoom-out-button. */ - zoomOut: function() { + zoomOut() { this.fire('zoom-out'); }, - show: function() { + show() { if (!this.visible_) { this.visible_ = true; this.$['fit-button'].show(); + this.$['two-up-view-button'].show(); this.$['zoom-in-button'].show(); this.$['zoom-out-button'].show(); } }, - hide: function() { + hide() { if (this.visible_) { this.visible_ = false; this.$['fit-button'].hide(); + this.$['two-up-view-button'].hide(); this.$['zoom-in-button'].hide(); this.$['zoom-out-button'].hide(); } diff --git a/chromium/chrome/browser/resources/pdf/gesture_detector.js b/chromium/chrome/browser/resources/pdf/gesture_detector.js index f149d801910..e8a0db4e6a3 100644 --- a/chromium/chrome/browser/resources/pdf/gesture_detector.js +++ b/chromium/chrome/browser/resources/pdf/gesture_detector.js @@ -73,7 +73,7 @@ export class GestureDetector { * @return {boolean} True if the last touch start was a two finger touch. */ wasTwoFingerTouch() { - return this.lastTouchTouchesCount_ == 2; + return this.lastTouchTouchesCount_ === 2; } /** diff --git a/chromium/chrome/browser/resources/pdf/index.html b/chromium/chrome/browser/resources/pdf/index.html index 1af4cc2f119..59965552797 100644 --- a/chromium/chrome/browser/resources/pdf/index.html +++ b/chromium/chrome/browser/resources/pdf/index.html @@ -13,7 +13,7 @@ <div id="sizer"></div> <viewer-password-screen id="password-screen"></viewer-password-screen> -<viewer-zoom-toolbar id="zoom-toolbar"></viewer-zoom-toolbar> +<viewer-zoom-toolbar id="zoom-toolbar" hidden></viewer-zoom-toolbar> <viewer-page-indicator id="page-indicator"></viewer-page-indicator> diff --git a/chromium/chrome/browser/resources/pdf/ink/BUILD.gn b/chromium/chrome/browser/resources/pdf/ink/BUILD.gn index b1c2be215bd..ddf46dc4c31 100644 --- a/chromium/chrome/browser/resources/pdf/ink/BUILD.gn +++ b/chromium/chrome/browser/resources/pdf/ink/BUILD.gn @@ -5,15 +5,11 @@ import("//third_party/closure_compiler/compile_js.gni") js_type_check("closure_compile") { - deps = [ - ":ink_api", - ] + deps = [ ":ink_api" ] } js_library("ink_api") { - deps = [ - "..:annotation_tool", - ] + deps = [ "..:annotation_tool" ] externs_list = [ "//third_party/ink/build/ink_lib_externs.js", "$externs_path/pending.js", diff --git a/chromium/chrome/browser/resources/pdf/ink/ink_api.js b/chromium/chrome/browser/resources/pdf/ink/ink_api.js index 99eed15d900..c394b630077 100644 --- a/chromium/chrome/browser/resources/pdf/ink/ink_api.js +++ b/chromium/chrome/browser/resources/pdf/ink/ink_api.js @@ -78,7 +78,7 @@ class InkAPI { highlighter: 'SMART_HIGHLIGHTER_TOOL', }[tool.tool]; this.brush_.setShape(shape); - if (tool.tool != 'eraser') { + if (tool.tool !== 'eraser') { this.brush_.setColor(/** @type {string} */ (tool.color)); } this.brush_.setStrokeWidth(tool.size); diff --git a/chromium/chrome/browser/resources/pdf/metrics.js b/chromium/chrome/browser/resources/pdf/metrics.js index dc7f62a6fb0..d1ca0a8270b 100644 --- a/chromium/chrome/browser/resources/pdf/metrics.js +++ b/chromium/chrome/browser/resources/pdf/metrics.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {FittingType} from './pdf_fitting_type.js'; +import {FittingType, TwoUpViewAction} from './constants.js'; /** * Handles events specific to the PDF viewer and logs the corresponding metrics. @@ -14,9 +14,9 @@ export class PDFMetrics { * @param {FittingType} fittingType the new FittingType. */ static recordFitTo(fittingType) { - if (fittingType == FittingType.FIT_TO_PAGE) { + if (fittingType === FittingType.FIT_TO_PAGE) { PDFMetrics.record(PDFMetrics.UserAction.FIT_TO_PAGE); - } else if (fittingType == FittingType.FIT_TO_WIDTH) { + } else if (fittingType === FittingType.FIT_TO_WIDTH) { PDFMetrics.record(PDFMetrics.UserAction.FIT_TO_WIDTH); } // There is no user action to do a fit-to-height, this only happens with @@ -24,6 +24,18 @@ export class PDFMetrics { } /** + * Records when the two up view mode is enabled or disabled. + * + * @param {TwoUpViewAction} twoUpViewAction the new TwoUpViewAction. + */ + static recordTwoUpView(twoUpViewAction) { + PDFMetrics.record( + twoUpViewAction === TwoUpViewAction.TWO_UP_VIEW_ENABLE ? + PDFMetrics.UserAction.TWO_UP_VIEW_ENABLE : + PDFMetrics.UserAction.TWO_UP_VIEW_DISABLE); + } + + /** * Records the given action to chrome.metricsPrivate. * * @param {PDFMetrics.UserAction} action @@ -149,7 +161,15 @@ PDFMetrics.UserAction = { ANNOTATE_STROKE_DEVICE_PEN_FIRST: 33, ANNOTATE_STROKE_DEVICE_PEN: 34, - NUMBER_OF_ACTIONS: 35, + /** Recorded when two-up view mode is enabled. */ + TWO_UP_VIEW_ENABLE_FIRST: 35, + TWO_UP_VIEW_ENABLE: 36, + + /** Recorded when two-up view mode is disabled. */ + TWO_UP_VIEW_DISABLE_FIRST: 37, + TWO_UP_VIEW_DISABLE: 38, + + NUMBER_OF_ACTIONS: 39, }; // Map from UserAction to the 'FIRST' action. These metrics are recorded @@ -224,4 +244,12 @@ PDFMetrics.firstMap_ = new Map([ PDFMetrics.UserAction.ANNOTATE_STROKE_DEVICE_PEN, PDFMetrics.UserAction.ANNOTATE_STROKE_DEVICE_PEN_FIRST, ], + [ + PDFMetrics.UserAction.TWO_UP_VIEW_ENABLE, + PDFMetrics.UserAction.TWO_UP_VIEW_ENABLE_FIRST, + ], + [ + PDFMetrics.UserAction.TWO_UP_VIEW_DISABLE, + PDFMetrics.UserAction.TWO_UP_VIEW_DISABLE_FIRST, + ], ]); diff --git a/chromium/chrome/browser/resources/pdf/navigator.js b/chromium/chrome/browser/resources/pdf/navigator.js index df4762a46d0..e24d3e8ff02 100644 --- a/chromium/chrome/browser/resources/pdf/navigator.js +++ b/chromium/chrome/browser/resources/pdf/navigator.js @@ -26,7 +26,7 @@ export class NavigatorDelegate { navigateInCurrentTab(url) { // When the PDFviewer is inside a browser tab, prefer the tabs API because // it can navigate from one file:// URL to another. - if (chrome.tabs && this.tabId_ != -1) { + if (chrome.tabs && this.tabId_ !== -1) { chrome.tabs.update(this.tabId_, {url: url}); } else { window.location.href = url; @@ -100,7 +100,7 @@ export class PdfNavigator { * disposition when navigating to the new URL. */ navigate(urlString, disposition) { - if (urlString.length == 0) { + if (urlString.length === 0) { return; } @@ -169,7 +169,7 @@ export class PdfNavigator { } const pageNumber = viewportPosition.page; - if (pageNumber != undefined && this.originalUrl_ && newUrl && + if (pageNumber !== undefined && this.originalUrl_ && newUrl && this.originalUrl_.origin === newUrl.origin && this.originalUrl_.pathname === newUrl.pathname) { this.viewport_.goToPage(pageNumber); @@ -236,7 +236,7 @@ export class PdfNavigator { } if (!url.startsWith('.')) { const domainSeparatorIndex = url.indexOf('/'); - const domainName = domainSeparatorIndex == -1 ? + const domainName = domainSeparatorIndex === -1 ? url : url.substr(0, domainSeparatorIndex); const domainDotCount = (domainName.match(/\./g) || []).length; diff --git a/chromium/chrome/browser/resources/pdf/open_pdf_params_parser.js b/chromium/chrome/browser/resources/pdf/open_pdf_params_parser.js index 941d9a3fe4e..08ef73a94db 100644 --- a/chromium/chrome/browser/resources/pdf/open_pdf_params_parser.js +++ b/chromium/chrome/browser/resources/pdf/open_pdf_params_parser.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {FittingType} from './pdf_fitting_type.js'; +import {FittingType} from './constants.js'; /** * Parses the open pdf parameters passed in the url to set initial viewport @@ -31,7 +31,7 @@ export class OpenPdfParamsParser { */ parseZoomParam_(paramValue) { const paramValueSplit = paramValue.split(','); - if (paramValueSplit.length != 1 && paramValueSplit.length != 3) { + if (paramValueSplit.length !== 1 && paramValueSplit.length !== 3) { return {}; } @@ -42,7 +42,7 @@ export class OpenPdfParamsParser { } // Handle #zoom=scale. - if (paramValueSplit.length == 1) { + if (paramValueSplit.length === 1) { return {'zoom': zoomFactor}; } @@ -105,12 +105,12 @@ export class OpenPdfParamsParser { const params = {}; const paramIndex = url.search('#'); - if (paramIndex == -1) { + if (paramIndex === -1) { return params; } const paramTokens = url.substring(paramIndex + 1).split('&'); - if ((paramTokens.length == 1) && (paramTokens[0].search('=') == -1)) { + if ((paramTokens.length === 1) && (paramTokens[0].search('=') === -1)) { // Handle the case of http://foo.com/bar#NAMEDDEST. This is not // explicitly mentioned except by example in the Adobe // "PDF Open Parameters" document. @@ -120,7 +120,7 @@ export class OpenPdfParamsParser { for (const paramToken of paramTokens) { const keyValueSplit = paramToken.split('='); - if (keyValueSplit.length != 2) { + if (keyValueSplit.length !== 2) { continue; } params[keyValueSplit[0]] = keyValueSplit[1]; @@ -141,7 +141,7 @@ export class OpenPdfParamsParser { const params = this.parseUrlParams_(url); const uiParams = {toolbar: true}; - if ('toolbar' in params && params['toolbar'] == 0) { + if ('toolbar' in params && params['toolbar'] === '0') { uiParams.toolbar = false; } @@ -196,7 +196,7 @@ export class OpenPdfParamsParser { */ onNamedDestinationReceived(pageNumber) { const outstandingRequest = this.outstandingRequests_.shift(); - if (pageNumber != -1) { + if (pageNumber !== -1) { outstandingRequest.params.page = pageNumber; } outstandingRequest.callback(outstandingRequest.params); diff --git a/chromium/chrome/browser/resources/pdf/pdf_scripting_api.js b/chromium/chrome/browser/resources/pdf/pdf_scripting_api.js index e69dd69ee17..8cae862e05d 100644 --- a/chromium/chrome/browser/resources/pdf/pdf_scripting_api.js +++ b/chromium/chrome/browser/resources/pdf/pdf_scripting_api.js @@ -68,7 +68,7 @@ export class PDFScriptingAPI { this.viewportChangedCallback_; /** @private {Function} */ - this.loadCallback_; + this.loadCompleteCallback_; /** @private {Function} */ this.selectedTextCallback_; @@ -80,9 +80,9 @@ export class PDFScriptingAPI { this.plugin_; window.addEventListener('message', event => { - if (event.origin != + if (event.origin !== 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai' && - event.origin != 'chrome://print') { + event.origin !== 'chrome://print') { console.error( 'Received message that was not from the extension: ' + event); return; @@ -108,8 +108,8 @@ export class PDFScriptingAPI { case 'documentLoaded': { const data = /** @type {{load_state: LoadState}} */ (event.data); this.loadState_ = data.load_state; - if (this.loadCallback_) { - this.loadCallback_(this.loadState_ == LoadState.SUCCESS); + if (this.loadCompleteCallback_) { + this.loadCompleteCallback_(this.loadState_ === LoadState.SUCCESS); } break; } @@ -181,10 +181,10 @@ export class PDFScriptingAPI { * * @param {Function} callback the callback to be called. */ - setLoadCallback(callback) { - this.loadCallback_ = callback; - if (this.loadState_ != LoadState.LOADING && this.loadCallback_) { - this.loadCallback_(this.loadState_ == LoadState.SUCCESS); + setLoadCompleteCallback(callback) { + this.loadCompleteCallback_ = callback; + if (this.loadState_ !== LoadState.LOADING && this.loadCompleteCallback_) { + this.loadCompleteCallback_(this.loadState_ === LoadState.SUCCESS); } } @@ -309,15 +309,15 @@ export function PDFCreateOutOfProcessPlugin(src, baseUrl) { }; // Add the functions to the iframe so that they can be called directly. - iframe.setViewportChangedCallback = - client.setViewportChangedCallback.bind(client); - iframe.setLoadCallback = client.setLoadCallback.bind(client); - iframe.setKeyEventCallback = client.setKeyEventCallback.bind(client); - iframe.resetPrintPreviewMode = client.resetPrintPreviewMode.bind(client); + iframe.darkModeChanged = client.darkModeChanged.bind(client); + iframe.hideToolbars = client.hideToolbars.bind(client); iframe.loadPreviewPage = client.loadPreviewPage.bind(client); - iframe.sendKeyEvent = client.sendKeyEvent.bind(client); + iframe.resetPrintPreviewMode = client.resetPrintPreviewMode.bind(client); iframe.scrollPosition = client.scrollPosition.bind(client); - iframe.hideToolbars = client.hideToolbars.bind(client); - iframe.darkModeChanged = client.darkModeChanged.bind(client); + iframe.sendKeyEvent = client.sendKeyEvent.bind(client); + iframe.setKeyEventCallback = client.setKeyEventCallback.bind(client); + iframe.setLoadCompleteCallback = client.setLoadCompleteCallback.bind(client); + iframe.setViewportChangedCallback = + client.setViewportChangedCallback.bind(client); return iframe; } diff --git a/chromium/chrome/browser/resources/pdf/pdf_viewer.js b/chromium/chrome/browser/resources/pdf/pdf_viewer.js index d356d123d87..296c0fc0cce 100644 --- a/chromium/chrome/browser/resources/pdf/pdf_viewer.js +++ b/chromium/chrome/browser/resources/pdf/pdf_viewer.js @@ -9,6 +9,7 @@ import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js'; import {$, hasKeyModifiers, isRTL} from 'chrome://resources/js/util.m.js'; import {BrowserApi} from './browser_api.js'; +import {FittingType, TwoUpViewAction} from './constants.js'; import {ContentController, InkController, MessageData, PluginController, PrintPreviewParams} from './controller.js'; import {Bookmark} from './elements/viewer-bookmark.js'; import {FitToChangedEvent} from './elements/viewer-zoom-toolbar.js'; @@ -16,7 +17,6 @@ import {GestureDetector} from './gesture_detector.js'; import {PDFMetrics} from './metrics.js'; import {NavigatorDelegate, PdfNavigator} from './navigator.js'; import {OpenPdfParamsParser} from './open_pdf_params_parser.js'; -import {FittingType} from './pdf_fitting_type.js'; import {DeserializeKeyEvent, LoadState, SerializeKeyEvent} from './pdf_scripting_api.js'; import {ToolbarManager} from './toolbar_manager.js'; import {LayoutOptions, Point, Viewport} from './viewport.js'; @@ -130,8 +130,8 @@ export function shouldIgnoreKeyEvents(activeElement) { return ( activeElement.isContentEditable || - (activeElement.tagName == 'INPUT' && activeElement.type != 'radio') || - activeElement.tagName == 'TEXTAREA'); + (activeElement.tagName === 'INPUT' && activeElement.type !== 'radio') || + activeElement.tagName === 'TEXTAREA'); } /** @@ -231,7 +231,7 @@ export class PDFViewer { this.errorScreen_ = /** @type {!ViewerErrorScreenElement} */ ($('error-screen')); // Can only reload if we are in a normal tab. - if (chrome.tabs && this.browserApi_.getStreamInfo().tabId != -1) { + if (chrome.tabs && this.browserApi_.getStreamInfo().tabId !== -1) { this.errorScreen_.reloadFn = () => { chrome.tabs.reload(this.browserApi_.getStreamInfo().tabId); }; @@ -243,7 +243,7 @@ export class PDFViewer { const topToolbarHeight = (toolbarEnabled) ? PDFViewer.MATERIAL_TOOLBAR_HEIGHT : 0; const defaultZoom = - this.browserApi_.getZoomBehavior() == BrowserApi.ZoomBehavior.MANAGE ? + this.browserApi_.getZoomBehavior() === BrowserApi.ZoomBehavior.MANAGE ? this.browserApi_.getDefaultZoom() : 1.0; @@ -334,6 +334,10 @@ export class PDFViewer { e => this.fitToChanged_( /** @type {!CustomEvent<FitToChangedEvent>} */ (e))); this.zoomToolbar_.addEventListener( + 'two-up-view-changed', + e => this.twoUpViewChanged_( + /** @type {!CustomEvent<!TwoUpViewAction>} */ (e))); + this.zoomToolbar_.addEventListener( 'zoom-in', () => this.viewport_.zoomIn()); this.zoomToolbar_.addEventListener( 'zoom-out', () => this.viewport_.zoomOut()); @@ -374,9 +378,9 @@ export class PDFViewer { document.body.addEventListener('change-page', e => { this.viewport_.goToPage(e.detail.page); - if (e.detail.origin == 'bookmark') { + if (e.detail.origin === 'bookmark') { PDFMetrics.record(PDFMetrics.UserAction.FOLLOW_BOOKMARK); - } else if (e.detail.origin == 'pageselector') { + } else if (e.detail.origin === 'pageselector') { PDFMetrics.record(PDFMetrics.UserAction.PAGE_SELECTOR_NAVIGATE); } }); @@ -398,7 +402,7 @@ export class PDFViewer { }); document.body.addEventListener('dropdown-opened', e => { - if (e.detail == 'bookmarks') { + if (e.detail === 'bookmarks') { PDFMetrics.record(PDFMetrics.UserAction.OPEN_BOOKMARKS_PANEL); } }); @@ -610,9 +614,9 @@ export class PDFViewer { } handleMouseEvent_(e) { - if (e.type == 'mousemove') { + if (e.type === 'mousemove') { this.toolbarManager_.handleMouseMove(e); - } else if (e.type == 'mouseout') { + } else if (e.type === 'mouseout') { this.toolbarManager_.hideToolbarsForMouseOut(); } } @@ -641,9 +645,10 @@ export class PDFViewer { */ async annotationModeToggled_(e) { const annotationMode = e.detail.value; + this.zoomToolbar_.annotationMode = annotationMode; if (annotationMode) { // Enter annotation mode. - assert(this.currentController_ == this.pluginController_); + assert(this.currentController_ === this.pluginController_); // TODO(dstockwell): set plugin read-only, begin transition this.updateProgress_(0); // TODO(dstockwell): handle save failure @@ -657,6 +662,7 @@ export class PDFViewer { } catch (e) { // The user aborted entering annotation mode. Revert to the plugin. this.toolbar_.annotationMode = false; + this.zoomToolbar_.annotationMode = false; this.updateProgress_(100); return; } @@ -674,7 +680,7 @@ export class PDFViewer { } else { // Exit annotation mode. PDFMetrics.record(PDFMetrics.UserAction.EXIT_ANNOTATION_MODE); - assert(this.currentController_ == this.inkController_); + assert(this.currentController_ === this.inkController_); // TODO(dstockwell): set ink read-only, begin transition this.updateProgress_(0); // This runs separately to allow other consumers of `loaded` to queue @@ -702,6 +708,7 @@ export class PDFViewer { return; } this.toolbar_.toggleAnnotation(); + this.zoomToolbar_.annotationMode = false; await this.loaded; } @@ -711,12 +718,12 @@ export class PDFViewer { * @private */ fitToChanged_(e) { - if (e.detail.fittingType == FittingType.FIT_TO_PAGE) { + if (e.detail.fittingType === FittingType.FIT_TO_PAGE) { this.viewport_.fitToPage(); this.toolbarManager_.forceHideTopToolbar(); - } else if (e.detail.fittingType == FittingType.FIT_TO_WIDTH) { + } else if (e.detail.fittingType === FittingType.FIT_TO_WIDTH) { this.viewport_.fitToWidth(); - } else if (e.detail.fittingType == FittingType.FIT_TO_HEIGHT) { + } else if (e.detail.fittingType === FittingType.FIT_TO_HEIGHT) { this.viewport_.fitToHeight(); this.toolbarManager_.forceHideTopToolbar(); } @@ -727,12 +734,28 @@ export class PDFViewer { } /** + * Changes two up view mode for the controller. Controller will trigger + * layout update later, which will update the viewport accordingly. + * @param {!CustomEvent<!TwoUpViewAction>} e + * @private + */ + twoUpViewChanged_(e) { + this.currentController_.setTwoUpView( + e.detail === TwoUpViewAction.TWO_UP_VIEW_ENABLE); + this.toolbarManager_.forceHideTopToolbar(); + this.toolbar_.annotationAvailable = + (e.detail !== TwoUpViewAction.TWO_UP_VIEW_ENABLE); + + PDFMetrics.recordTwoUpView(e.detail); + } + + /** * Sends a 'documentLoaded' message to the PDFScriptingAPI if the document has * finished loading. * @private */ sendDocumentLoadedMessage_() { - if (this.loadState_ == LoadState.LOADING) { + if (this.loadState_ === LoadState.LOADING) { return; } if (this.isPrintPreview_ && !this.isPrintPreviewLoadingFinished_) { @@ -768,9 +791,9 @@ export class PDFViewer { const zoomedPositionShift = params.viewPosition * this.viewport_.getZoom(); const currentViewportPosition = this.viewport_.position; - if (params.view == FittingType.FIT_TO_WIDTH) { + if (params.view === FittingType.FIT_TO_WIDTH) { currentViewportPosition.y += zoomedPositionShift; - } else if (params.view == FittingType.FIT_TO_HEIGHT) { + } else if (params.view === FittingType.FIT_TO_HEIGHT) { currentViewportPosition.x += zoomedPositionShift; } this.viewport_.position = currentViewportPosition; @@ -790,7 +813,7 @@ export class PDFViewer { */ goToPageAndXY_(origin, page, message) { this.viewport_.goToPageAndXY(page, message.x, message.y); - if (origin == 'bookmark') { + if (origin === 'bookmark') { PDFMetrics.record(PDFMetrics.UserAction.FOLLOW_BOOKMARK); } } @@ -821,19 +844,20 @@ export class PDFViewer { * @private */ setLoadState_(loadState) { - if (this.loadState_ == loadState) { + if (this.loadState_ === loadState) { return; } assert( - loadState == LoadState.LOADING || this.loadState_ == LoadState.LOADING); + loadState === LoadState.LOADING || + this.loadState_ === LoadState.LOADING); this.loadState_ = loadState; if (!this.initialLoadComplete_) { this.initialLoadComplete_ = true; return; } - if (loadState == LoadState.SUCCESS) { + if (loadState === LoadState.SUCCESS) { this.loaded_.resolve(); - } else if (loadState == LoadState.FAILED) { + } else if (loadState === LoadState.FAILED) { this.loaded_.reject(); } else { this.loaded_ = new PromiseResolver(); @@ -851,7 +875,7 @@ export class PDFViewer { this.toolbar_.loadProgress = progress; } - if (progress == -1) { + if (progress === -1) { // Document load failed. this.errorScreen_.show(); this.sizer_.style.display = 'none'; @@ -862,7 +886,7 @@ export class PDFViewer { this.setLoadState_(LoadState.FAILED); this.isPrintPreviewLoadingFinished_ = true; this.sendDocumentLoadedMessage_(); - } else if (progress == 100) { + } else if (progress === 100) { // Document load complete. if (this.lastViewportPosition_) { this.viewport_.position = this.lastViewportPosition_; @@ -901,6 +925,13 @@ export class PDFViewer { document.documentElement.lang = stringsDictionary.language; loadTimeData.data = strings; + + // Predefined zoom factors to be used when zooming in/out. These are in + // ascending order. + const presetZoomFactors = /** @type {!Array<number>} */ ( + JSON.parse(loadTimeData.getString('presetZoomFactors'))); + this.viewport_.setZoomFactorRange(presetZoomFactors); + if (this.isPrintPreview_) { this.sendBackgroundColorForPrintPreview_(); } @@ -910,6 +941,11 @@ export class PDFViewer { loadTimeData.getBoolean('pdfAnnotationsEnabled'); $('toolbar').printingEnabled = loadTimeData.getBoolean('printingEnabled'); $('zoom-toolbar').setStrings(strings); + $('zoom-toolbar').twoUpViewEnabled = + loadTimeData.getBoolean('pdfTwoUpViewEnabled') && !this.isPrintPreview_; + // Display the zoom toolbar after the UI text direction is set, to ensure it + // appears on the correct side of the PDF viewer. + $('zoom-toolbar').hidden = false; $('password-screen').strings = strings; $('error-screen').strings = strings; if ($('form-warning')) { @@ -933,7 +969,7 @@ export class PDFViewer { * @private */ setUserInitiated_(userInitiated) { - assert(this.isUserInitiatedEvent_ != userInitiated); + assert(this.isUserInitiatedEvent_ !== userInitiated); this.isUserInitiatedEvent_ = userInitiated; } @@ -1053,11 +1089,11 @@ export class PDFViewer { * @param {!MessageObject} message The message to handle. */ handleScriptingMessage(message) { - if (this.parentWindow_ != message.source) { + if (this.parentWindow_ !== message.source) { this.parentWindow_ = message.source; this.parentOrigin_ = message.origin; // Ensure that we notify the embedder if the document is loaded. - if (this.loadState_ != LoadState.LOADING) { + if (this.loadState_ !== LoadState.LOADING) { this.sendDocumentLoadedMessage_(); } } @@ -1068,7 +1104,7 @@ export class PDFViewer { // Delay scripting messages from users of the scripting API until the // document is loaded. This simplifies use of the APIs. - if (this.loadState_ != LoadState.SUCCESS) { + if (this.loadState_ !== LoadState.SUCCESS) { this.delayedScriptingMessages_.push(message); return; } @@ -1171,9 +1207,9 @@ export class PDFViewer { // unless we're sending it to ourselves (which could happen in the case // of tests). We also allow documentLoaded messages through as this won't // leak important information. - if (this.parentOrigin_ == window.location.origin) { + if (this.parentOrigin_ === window.location.origin) { targetOrigin = this.parentOrigin_; - } else if (message.type == 'documentLoaded') { + } else if (message.type === 'documentLoaded') { targetOrigin = '*'; } else { targetOrigin = this.originalUrl_; @@ -1390,7 +1426,7 @@ export class PDFViewer { * @private */ async onSave_(streamUrl) { - if (streamUrl != this.browserApi_.getStreamInfo().streamUrl) { + if (streamUrl !== this.browserApi_.getStreamInfo().streamUrl) { return; } @@ -1426,7 +1462,7 @@ export class PDFViewer { chrome.fileSystem.chooseEntry( {type: 'saveFile', suggestedName: fileName}, entry => { if (chrome.runtime.lastError) { - if (chrome.runtime.lastError.message != 'User cancelled') { + if (chrome.runtime.lastError.message !== 'User cancelled') { console.log( 'chrome.fileSystem.chooseEntry failed: ' + chrome.runtime.lastError.message); @@ -1463,7 +1499,7 @@ export class PDFViewer { return; } let annotationAvailable = true; - if (this.viewport_.getClockwiseRotations() != 0) { + if (this.viewport_.getClockwiseRotations() !== 0) { annotationAvailable = false; } if (this.hadPassword_) { diff --git a/chromium/chrome/browser/resources/pdf/toolbar_manager.js b/chromium/chrome/browser/resources/pdf/toolbar_manager.js index f5ce74235d4..847b21172fc 100644 --- a/chromium/chrome/browser/resources/pdf/toolbar_manager.js +++ b/chromium/chrome/browser/resources/pdf/toolbar_manager.js @@ -144,7 +144,7 @@ export class ToolbarManager { * @private */ isHighVelocityMouseMove_(e) { - if (e.type == 'mousemove') { + if (e.type === 'mousemove') { if (this.lastMovementTimestamp == null) { this.lastMovementTimestamp = this.getCurrentTimestamp_(); } else { @@ -154,7 +154,7 @@ export class ToolbarManager { const interval = newTime - this.lastMovementTimestamp; this.lastMovementTimestamp = newTime; - if (interval != 0) { + if (interval !== 0) { return movement / interval > SHOW_VELOCITY; } } @@ -219,8 +219,8 @@ export class ToolbarManager { // Remove focus to make any visible tooltips disappear -- otherwise they'll // still be visible on screen when the toolbar is off screen. - if ((this.toolbar_ && document.activeElement == this.toolbar_) || - document.activeElement == this.zoomToolbar_) { + if ((this.toolbar_ && document.activeElement === this.toolbar_) || + document.activeElement === this.zoomToolbar_) { document.activeElement.blur(); } diff --git a/chromium/chrome/browser/resources/pdf/viewport.js b/chromium/chrome/browser/resources/pdf/viewport.js index 3034d9eecab..37967176729 100644 --- a/chromium/chrome/browser/resources/pdf/viewport.js +++ b/chromium/chrome/browser/resources/pdf/viewport.js @@ -6,7 +6,7 @@ import {assert} from 'chrome://resources/js/assert.m.js'; import {EventTracker} from 'chrome://resources/js/event_tracker.m.js'; import {$} from 'chrome://resources/js/util.m.js'; -import {FittingType} from './pdf_fitting_type.js'; +import {FittingType} from './constants.js'; import {InactiveZoomManager, ZoomManager} from './zoom_manager.js'; /** @@ -19,7 +19,12 @@ import {InactiveZoomManager, ZoomManager} from './zoom_manager.js'; */ let DocumentDimensions; -/** @typedef {{defaultPageOrientation: number}} */ +/** + * @typedef {{ + * defaultPageOrientation: number, + * twoUpViewEnabled: boolean, + * }} + */ export let LayoutOptions; /** @typedef {{x: number, y: number}} */ @@ -35,17 +40,6 @@ let Size; let ViewportRect; /** - * Clamps the zoom factor (or page scale factor) to be within the limits. - * @param {number} factor The zoom/scale factor. - * @return {number} The factor clamped within the limits. - */ -function clampZoom(factor) { - return Math.max( - Viewport.ZOOM_FACTOR_RANGE.min, - Math.min(factor, Viewport.ZOOM_FACTOR_RANGE.max)); -} - -/** * @param {!ViewportRect} rect1 * @param {!ViewportRect} rect2 * @return {number} The area of the intersection of the rects @@ -128,6 +122,13 @@ export class Viewport { /** @private {number} */ this.internalZoom_ = 1; + /** + * Predefined zoom factors to be used when zooming in/out. These are in + * ascending order. + * @private {!Array<number>} + */ + this.presetZoomFactors_ = []; + /** @private {?ZoomManager} */ this.zoomManager_ = null; @@ -140,12 +141,6 @@ export class Viewport { /** @private {!FittingType} */ this.fittingType_ = FittingType.NONE; - /** - * |twoUpView_| should be in sync with |two_up_view_| in PDFiumEngine. - * @private {boolean} - */ - this.twoUpView_ = false; - /** @private {number} */ this.prevScale_ = 1; @@ -224,9 +219,35 @@ export class Viewport { return this.rotations_; } - /** @param {boolean} twoUpView The new two up view state to set. */ - setTwoUpView(twoUpView) { - this.twoUpView_ = twoUpView; + /** @return {boolean} Whether viewport is in two-up view mode. */ + twoUpViewEnabled() { + const options = this.getLayoutOptions(); + if (options === undefined) { + return false; + } + return options.twoUpViewEnabled; + } + + /** + * Clamps the zoom factor (or page scale factor) to be within the limits. + * @param {number} factor The zoom/scale factor. + * @return {number} The factor clamped within the limits. + * @private + */ + clampZoom_(factor) { + return Math.max( + this.presetZoomFactors_[0], + Math.min( + factor, + this.presetZoomFactors_[this.presetZoomFactors_.length - 1])); + } + + /** + * @param {!Array<number>} factors Array containing zoom/scale factors. + */ + setZoomFactorRange(factors) { + assert(factors.length !== 0); + this.presetZoomFactors_ = factors; } /** @@ -247,11 +268,11 @@ export class Viewport { const rotation = this.rotations_ * 90; // Set origin for rotation. - if (rotation == 90) { + if (rotation === 90) { matrix.translateSelf(width, 0); - } else if (rotation == 180) { + } else if (rotation === 180) { matrix.translateSelf(width, height); - } else if (rotation == 270) { + } else if (rotation === 270) { matrix.translateSelf(0, height); } matrix.rotateSelf(0, 0, rotation); @@ -395,13 +416,13 @@ export class Viewport { * @private */ resize_() { - if (this.fittingType_ == FittingType.FIT_TO_PAGE) { + if (this.fittingType_ === FittingType.FIT_TO_PAGE) { this.fitToPageInternal_(false); - } else if (this.fittingType_ == FittingType.FIT_TO_WIDTH) { + } else if (this.fittingType_ === FittingType.FIT_TO_WIDTH) { this.fitToWidth(); - } else if (this.fittingType_ == FittingType.FIT_TO_HEIGHT) { + } else if (this.fittingType_ === FittingType.FIT_TO_HEIGHT) { this.fitToHeightInternal_(false); - } else if (this.internalZoom_ == 0) { + } else if (this.internalZoom_ === 0) { this.fitToNone(); } else { this.updateViewport_(); @@ -532,7 +553,7 @@ export class Viewport { this.allowedToChangeZoom_, 'Called Viewport.setPinchZoomInternal_ without calling ' + 'Viewport.mightZoom_.'); - this.internalZoom_ = clampZoom(this.internalZoom_ * scaleDelta); + this.internalZoom_ = this.clampZoom_(this.internalZoom_ * scaleDelta); const newCenterInContent = this.frameToContent_(center); const delta = { @@ -574,7 +595,7 @@ export class Viewport { setZoom(newZoom) { this.fittingType_ = FittingType.NONE; this.mightZoom_(() => { - this.setZoomInternal_(clampZoom(newZoom)); + this.setZoomInternal_(this.clampZoom_(newZoom)); this.updateViewport_(); }); } @@ -659,7 +680,7 @@ export class Viewport { getLastPageInViewport_(viewportRect) { const pageAtY = this.getPageAtY_(viewportRect.y + viewportRect.height); - if (!this.twoUpView_ || pageAtY % 2 == 1 || + if (!this.twoUpViewEnabled() || pageAtY % 2 === 1 || pageAtY + 1 >= this.pageDimensions_.length) { return pageAtY; } @@ -943,10 +964,10 @@ export class Viewport { zoomOut() { this.mightZoom_(() => { this.fittingType_ = FittingType.NONE; - let nextZoom = Viewport.ZOOM_FACTORS[0]; - for (let i = 0; i < Viewport.ZOOM_FACTORS.length; i++) { - if (Viewport.ZOOM_FACTORS[i] < this.internalZoom_) { - nextZoom = Viewport.ZOOM_FACTORS[i]; + let nextZoom = this.presetZoomFactors_[0]; + for (let i = 0; i < this.presetZoomFactors_.length; i++) { + if (this.presetZoomFactors_[i] < this.internalZoom_) { + nextZoom = this.presetZoomFactors_[i]; } } this.setZoomInternal_(nextZoom); @@ -958,10 +979,11 @@ export class Viewport { zoomIn() { this.mightZoom_(() => { this.fittingType_ = FittingType.NONE; - let nextZoom = Viewport.ZOOM_FACTORS[Viewport.ZOOM_FACTORS.length - 1]; - for (let i = Viewport.ZOOM_FACTORS.length - 1; i >= 0; i--) { - if (Viewport.ZOOM_FACTORS[i] > this.internalZoom_) { - nextZoom = Viewport.ZOOM_FACTORS[i]; + const maxZoomIndex = this.presetZoomFactors_.length - 1; + let nextZoom = this.presetZoomFactors_[maxZoomIndex]; + for (let i = maxZoomIndex; i >= 0; i--) { + if (this.presetZoomFactors_[i] > this.internalZoom_) { + nextZoom = this.presetZoomFactors_[i]; } } this.setZoomInternal_(nextZoom); @@ -975,7 +997,7 @@ export class Viewport { */ pinchZoom(e) { this.mightZoom_(() => { - this.pinchPhase_ = e.direction == 'out' ? + this.pinchPhase_ = e.direction === 'out' ? Viewport.PinchPhase.PINCH_UPDATE_ZOOM_OUT : Viewport.PinchPhase.PINCH_UPDATE_ZOOM_IN; @@ -987,7 +1009,7 @@ export class Viewport { const needsScrollbars = this.documentNeedsScrollbars_(this.zoomManager_.applyBrowserZoom( - clampZoom(this.internalZoom_ * scaleDelta))); + this.clampZoom_(this.internalZoom_ * scaleDelta))); this.pinchCenter_ = e.center; @@ -1051,7 +1073,8 @@ export class Viewport { */ goToNextPage() { const currentPage = this.getMostVisiblePage(); - const nextPageOffset = (this.twoUpView_ && currentPage % 2 == 0) ? 2 : 1; + const nextPageOffset = + (this.twoUpViewEnabled() && currentPage % 2 === 0) ? 2 : 1; this.goToPage(currentPage + nextPageOffset); } @@ -1063,8 +1086,8 @@ export class Viewport { const currentPage = this.getMostVisiblePage(); let previousPageOffset = -1; - if (this.twoUpView_) { - previousPageOffset = (currentPage % 2 == 0) ? -2 : -3; + if (this.twoUpViewEnabled()) { + previousPageOffset = (currentPage % 2 === 0) ? -2 : -3; } this.goToPage(currentPage + previousPageOffset); @@ -1193,8 +1216,8 @@ export class Viewport { */ isPagedMode() { return ( - this.fittingType_ == FittingType.FIT_TO_PAGE || - this.fittingType_ == FittingType.FIT_TO_HEIGHT); + this.fittingType_ === FittingType.FIT_TO_PAGE || + this.fittingType_ === FittingType.FIT_TO_HEIGHT); } /** @@ -1203,11 +1226,11 @@ export class Viewport { scrollTo(point) { let changed = false; const newPosition = this.position; - if (point.x !== undefined && point.x != newPosition.x) { + if (point.x !== undefined && point.x !== newPosition.x) { newPosition.x = point.x; changed = true; } - if (point.y !== undefined && point.y != newPosition.y) { + if (point.y !== undefined && point.y !== newPosition.y) { newPosition.y = point.y; changed = true; } @@ -1254,23 +1277,6 @@ Viewport.PinchPhase = { */ Viewport.SCROLL_INCREMENT = 40; -/** - * Predefined zoom factors to be used when zooming in/out. These are in - * ascending order. This should match the lists in - * components/zoom/page_zoom_constants.h and - * chrome/browser/resources/settings/appearance_page/appearance_page.js - */ -Viewport.ZOOM_FACTORS = [ - 0.25, 1 / 3, 0.5, 2 / 3, 0.75, 0.8, 0.9, 1, 1.1, 1.25, 1.5, 1.75, 2, 2.5, 3, - 4, 5 -]; - -/** The minimum and maximum range to be used to clip zoom factor. */ -Viewport.ZOOM_FACTOR_RANGE = { - min: Viewport.ZOOM_FACTORS[0], - max: Viewport.ZOOM_FACTORS[Viewport.ZOOM_FACTORS.length - 1] -}; - /** The width of the page shadow around pages in pixels. */ Viewport.PAGE_SHADOW = { top: 3, |