diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-03-12 09:13:00 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-03-16 09:58:26 +0000 |
commit | 03561cae90f1d99b5c54b1ef3be69f10e882b25e (patch) | |
tree | cc5f0958e823c044e7ae51cc0117fe51432abe5e /chromium/chrome/browser/resources/pdf | |
parent | fa98118a45f7e169f8846086dc2c22c49a8ba310 (diff) |
BASELINE: Update Chromium to 88.0.4324.208
Change-Id: I3ae87d23e4eff4b4a469685658740a213600c667
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/chrome/browser/resources/pdf')
18 files changed, 521 insertions, 286 deletions
diff --git a/chromium/chrome/browser/resources/pdf/BUILD.gn b/chromium/chrome/browser/resources/pdf/BUILD.gn index c320099d0a3..2ee93e8d469 100644 --- a/chromium/chrome/browser/resources/pdf/BUILD.gn +++ b/chromium/chrome/browser/resources/pdf/BUILD.gn @@ -121,6 +121,7 @@ js_library("controller") { deps = [ ":viewport", "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:cr.m", "//ui/webui/resources/js:load_time_data.m", "//ui/webui/resources/js:promise_resolver.m", "//ui/webui/resources/js/cr:event_target.m", @@ -166,7 +167,6 @@ js_library("pdf_viewer") { "elements:viewer-pdf-sidenav", "elements:viewer-pdf-toolbar", "elements:viewer-pdf-toolbar-new", - "elements:viewer-thumbnail", "elements:viewer-zoom-toolbar", "//ui/webui/resources/js:assert.m", "//ui/webui/resources/js:event_tracker.m", diff --git a/chromium/chrome/browser/resources/pdf/controller.js b/chromium/chrome/browser/resources/pdf/controller.js index f063c5001d3..7f28fd283c8 100644 --- a/chromium/chrome/browser/resources/pdf/controller.js +++ b/chromium/chrome/browser/resources/pdf/controller.js @@ -3,6 +3,7 @@ // found in the LICENSE file. import {assert} from 'chrome://resources/js/assert.m.js'; +import {addSingletonGetter} from 'chrome://resources/js/cr.m.js'; import {NativeEventTarget as EventTarget} from 'chrome://resources/js/cr/event_target.m.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js'; @@ -62,32 +63,33 @@ function createToken() { .join(''); } -/** @abstract */ +/** @interface */ export class ContentController { constructor() {} + /** @return {!EventTarget} */ + getEventTarget() {} + + /** @return {boolean} */ + get isActive() {} + + /** @param {boolean} isActive */ + set isActive(isActive) {} + beforeZoom() {} afterZoom() {} viewportChanged() {} - /** @abstract */ rotateClockwise() {} - /** @abstract */ rotateCounterclockwise() {} - /** - * @param {boolean} displayAnnotations - * @abstract - */ + /** @param {boolean} displayAnnotations */ setDisplayAnnotations(displayAnnotations) {} - /** - * @param {boolean} enableTwoUpView - * @abstract - */ + /** @param {boolean} enableTwoUpView */ setTwoUpView(enableTwoUpView) {} /** Triggers printing of the current document. */ @@ -104,8 +106,7 @@ export class ContentController { * @param {!SaveRequestType} requestType The type of save request. If * ANNOTATION, a response is required, otherwise the controller may save * the document to disk internally. - * @return {Promise<{fileName: string, dataToSave: ArrayBuffer}>} - * @abstract + * @return {!Promise<!{fileName: string, dataToSave: !ArrayBuffer}>} */ save(requestType) {} @@ -121,30 +122,45 @@ export class ContentController { * Loads PDF document from `data` activates UI. * @param {string} fileName * @param {!ArrayBuffer} data - * @return {Promise<void>} - * @abstract + * @return {!Promise<void>} */ load(fileName, data) {} - /** - * Unloads the current document and removes the UI. - * @abstract - */ + /** Unloads the current document and removes the UI. */ unload() {} } -// PDF plugin controller, responsible for communicating with the embedded plugin -// element. Dispatches a 'plugin-message' event containing the message from the -// plugin, if a message type not handled by this controller is received. -export class PluginController extends ContentController { +/** + * Event types dispatched by the plugin controller. + * @enum {string} + */ +export const PluginControllerEventType = { + IS_ACTIVE_CHANGED: 'PluginControllerEventType.IS_ACTIVE_CHANGED', + PLUGIN_MESSAGE: 'PluginControllerEventType.PLUGIN_MESSAGE', +}; + +/** + * PDF plugin controller singleton, responsible for communicating with the + * embedded plugin element. Dispatches a + * `PluginControllerEventType.PLUGIN_MESSAGE` event containing the message from + * the plugin, if a message type not handled by this controller is received. + * @implements {ContentController} + */ +export class PluginController { + constructor() { + /** @private {!EventTarget} */ + this.eventTarget_ = new EventTarget(); + } + /** * @param {!HTMLEmbedElement} plugin * @param {!Viewport} viewport * @param {function():boolean} getIsUserInitiatedCallback * @param {function():?Promise} getLoadedCallback */ - constructor(plugin, viewport, getIsUserInitiatedCallback, getLoadedCallback) { - super(); + init(plugin, viewport, getIsUserInitiatedCallback, getLoadedCallback) { + /** @private {boolean} */ + this.isActive_ = false; /** @private {!HTMLEmbedElement} */ this.plugin_ = plugin; @@ -163,9 +179,6 @@ export class PluginController extends ContentController { this.plugin_.addEventListener( 'message', e => this.handlePluginMessage_(e), false); - /** @private {!EventTarget} */ - this.eventTarget_ = new EventTarget(); - /** * Counter for use with createUid * @private {number} @@ -177,6 +190,30 @@ export class PluginController extends ContentController { } /** + * @return {boolean} + * @override + */ + get isActive() { + // Check whether `plugin_` is defined as a signal that `init()` was called. + return !!this.plugin_ && this.isActive_; + } + + /** + * @param {boolean} isActive + * @override + */ + set isActive(isActive) { + const wasActive = this.isActive; + this.isActive_ = isActive; + if (this.isActive === wasActive) { + return; + } + + this.eventTarget_.dispatchEvent(new CustomEvent( + PluginControllerEventType.IS_ACTIVE_CHANGED, {detail: this.isActive})); + } + + /** * @return {number} A new unique ID. * @private */ @@ -184,7 +221,10 @@ export class PluginController extends ContentController { return this.uidCounter_++; } - /** @return {!EventTarget} */ + /** + * @return {!EventTarget} + * @override + */ getEventTarget() { return this.eventTarget_; } @@ -197,6 +237,12 @@ export class PluginController extends ContentController { this.postMessage_({type: 'updateScroll', x, y}); } + viewportChanged() {} + + redo() {} + + undo() {} + /** * Notify the plugin to stop reacting to scroll events while zoom is taking * place to avoid flickering. @@ -407,6 +453,7 @@ export class PluginController extends ContentController { this.plugin_.style.display = 'block'; try { await this.getLoadedCallback_(); + this.isActive = true; } finally { URL.revokeObjectURL(url); } @@ -415,6 +462,7 @@ export class PluginController extends ContentController { /** @override */ unload() { this.plugin_.style.display = 'none'; + this.isActive = false; } /** @@ -458,8 +506,8 @@ export class PluginController extends ContentController { resolver.resolve(null); break; default: - this.eventTarget_.dispatchEvent( - new CustomEvent('plugin-message', {detail: messageData})); + this.eventTarget_.dispatchEvent(new CustomEvent( + PluginControllerEventType.PLUGIN_MESSAGE, {detail: messageData})); } } @@ -502,3 +550,5 @@ export class PluginController extends ContentController { resolver.resolve(messageData); } } + +addSingletonGetter(PluginController); diff --git a/chromium/chrome/browser/resources/pdf/elements/BUILD.gn b/chromium/chrome/browser/resources/pdf/elements/BUILD.gn index d27f749c983..b42bf012dcb 100644 --- a/chromium/chrome/browser/resources/pdf/elements/BUILD.gn +++ b/chromium/chrome/browser/resources/pdf/elements/BUILD.gn @@ -146,6 +146,7 @@ js_library("viewer-pdf-toolbar-new") { ":viewer-download-controls", "..:metrics", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:assert.m", ] } @@ -163,8 +164,10 @@ js_library("viewer-thumbnail") { js_library("viewer-thumbnail-bar") { deps = [ ":viewer-thumbnail", + "..:controller", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:event_tracker.m", "//ui/webui/resources/js:load_time_data.m", "//ui/webui/resources/js/cr/ui:focus_outline_manager.m", ] diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-annotations-bar.js b/chromium/chrome/browser/resources/pdf/elements/viewer-annotations-bar.js index d483280c4cb..02fecc24dee 100644 --- a/chromium/chrome/browser/resources/pdf/elements/viewer-annotations-bar.js +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-annotations-bar.js @@ -12,7 +12,7 @@ import './viewer-pen-options.js'; import {EventTracker} from 'chrome://resources/js/event_tracker.m.js'; import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {InkController} from '../ink_controller.js'; +import {InkController, InkControllerEventType} from '../ink_controller.js'; export class ViewerAnnotationsBarElement extends PolymerElement { static get is() { @@ -67,13 +67,16 @@ export class ViewerAnnotationsBarElement extends PolymerElement { } this.tracker_.add( - this.inkController.getEventTarget(), 'set-annotation-undo-state', + this.inkController.getEventTarget(), + InkControllerEventType.SET_ANNOTATION_UNDO_STATE, e => this.setAnnotationUndoState_(e)); - this.tracker_.add(this.inkController.getEventTarget(), 'loaded', () => { - if (this.annotationTool_) { - this.inkController.setAnnotationTool(this.annotationTool_); - } - }); + this.tracker_.add( + this.inkController.getEventTarget(), InkControllerEventType.LOADED, + () => { + if (this.annotationTool_) { + this.inkController.setAnnotationTool(this.annotationTool_); + } + }); } /** diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar-new.html b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar-new.html index 4d777770a06..cc1f1b521e2 100644 --- a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar-new.html +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar-new.html @@ -168,6 +168,11 @@ margin-inline-end: 12px; width: 16px; } + + cr-action-menu hr { + border: none; + border-top: var(--cr-separator-line); + } </style> <div id="toolbar"> <div id="start"> @@ -186,6 +191,7 @@ </viewer-page-selector> <span id="zoom-controls"> <cr-icon-button iron-icon="pdf:remove" title="$i18n{tooltipZoomOut}" + disabled="[[isAtMinimumZoom_(zoomBounds.min, viewportZoomPercent_)]]" aria-label="$i18n{tooltipZoomOut}" on-click="onZoomOutClick_"> </cr-icon-button> <input type="text" value="100%" @@ -194,6 +200,7 @@ on-blur="onZoomChange_"> </input> <cr-icon-button iron-icon="pdf:add" title="$i18n{tooltipZoomIn}" + disabled="[[isAtMaximumZoom_(zoomBounds.max, viewportZoomPercent_)]]" aria-label="$i18n{tooltipZoomIn}" on-click="onZoomInClick_"> </cr-icon-button> </span> @@ -264,6 +271,15 @@ </span> $i18n{annotationsShowToggle} </button> + + <template is="dom-if" if="[[presentationModeEnabled]]"> + <hr> + <button id="fullscreen-button" class="dropdown-item" + on-click="onFullscreenClick_"> + <span class="check-container" aria-hidden="true"></span> + $i18n{fullscreen} + </button> + </template> </cr-action-menu> <if expr="chromeos"> diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar-new.js b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar-new.js index 30dc17050ec..1ca3ae48995 100644 --- a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar-new.js +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar-new.js @@ -17,6 +17,7 @@ import './shared-css.js'; import './shared-vars.js'; import {AnchorAlignment} from 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.m.js'; +import {assert} from 'chrome://resources/js/assert.m.js'; import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {FittingType} from '../constants.js'; @@ -70,12 +71,10 @@ export class ViewerPdfToolbarNewElement extends PolymerElement { pageNo: Number, pdfAnnotationsEnabled: Boolean, pdfFormSaveEnabled: Boolean, + presentationModeEnabled: Boolean, printingEnabled: Boolean, rotated: Boolean, - viewportZoom: { - type: Number, - observer: 'viewportZoomChanged_', - }, + viewportZoom: Number, /** @type {!{min: number, max: number}} */ zoomBounds: Object, @@ -95,6 +94,13 @@ export class ViewerPdfToolbarNewElement extends PolymerElement { computed: 'computeFitToButtonIcon_(fittingType_)', }, + /** @private */ + viewportZoomPercent_: { + type: Number, + computed: 'computeViewportZoomPercent_(viewportZoom)', + observer: 'viewportZoomPercentChanged_', + }, + // <if expr="chromeos"> /** @private */ showAnnotationsModeDialog_: { @@ -156,6 +162,14 @@ export class ViewerPdfToolbarNewElement extends PolymerElement { } /** + * @return {number} + * @private + */ + computeViewportZoomPercent_() { + return Math.round(100 * this.viewportZoom); + } + + /** * @param {string} fitToPageTooltip * @param {string} fitToWidthTooltip * @return {string} The appropriate tooltip for the current state @@ -172,9 +186,8 @@ export class ViewerPdfToolbarNewElement extends PolymerElement { } /** @private */ - viewportZoomChanged_() { - const zoom = Math.round(this.viewportZoom * 100); - this.getZoomInput_().value = `${zoom}%`; + viewportZoomPercentChanged_() { + this.getZoomInput_().value = `${this.viewportZoomPercent_}%`; } // <if expr="chromeos"> @@ -212,6 +225,13 @@ export class ViewerPdfToolbarNewElement extends PolymerElement { // </if> } + /** @private */ + onFullscreenClick_() { + assert(this.presentationModeEnabled); + this.getMenu_().close(); + this.dispatchEvent(new CustomEvent('fullscreen-click')); + } + /** * @param {boolean} checked * @return {string} @@ -300,8 +320,7 @@ export class ViewerPdfToolbarNewElement extends PolymerElement { return; } - const zoom = Math.round(this.viewportZoom * 100); - const zoomString = `${zoom}%`; + const zoomString = `${this.viewportZoomPercent_}%`; input.value = zoomString; } @@ -351,6 +370,24 @@ export class ViewerPdfToolbarNewElement extends PolymerElement { this.moreMenuOpen_ = e.detail.value; } + /** + * @return {boolean} + * @private + */ + isAtMinimumZoom_() { + return this.zoomBounds !== undefined && + this.viewportZoomPercent_ === this.zoomBounds.min; + } + + /** + * @return {boolean} + * @private + */ + isAtMaximumZoom_() { + return this.zoomBounds !== undefined && + this.viewportZoomPercent_ === this.zoomBounds.max; + } + // <if expr="chromeos"> /** @private */ onDialogClose_() { diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-thumbnail-bar.html b/chromium/chrome/browser/resources/pdf/elements/viewer-thumbnail-bar.html index 1db869df44a..db88cfec6a3 100644 --- a/chromium/chrome/browser/resources/pdf/elements/viewer-thumbnail-bar.html +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-thumbnail-bar.html @@ -16,7 +16,7 @@ padding-top: 24px; } </style> -<div id="thumbnails"> +<div id="thumbnails" hidden$="[[!isPluginActive_]]"> <template is="dom-repeat" items="[[pageNumbers_]]" on-dom-change="onDomChange_"> <viewer-thumbnail tabindex="0" role="button" diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-thumbnail-bar.js b/chromium/chrome/browser/resources/pdf/elements/viewer-thumbnail-bar.js index 850169d45fe..1fea43ff954 100644 --- a/chromium/chrome/browser/resources/pdf/elements/viewer-thumbnail-bar.js +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-thumbnail-bar.js @@ -4,9 +4,11 @@ import {assert} from 'chrome://resources/js/assert.m.js'; import {FocusOutlineManager} from 'chrome://resources/js/cr/ui/focus_outline_manager.m.js'; +import {EventTracker} from 'chrome://resources/js/event_tracker.m.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {PluginController, PluginControllerEventType} from '../controller.js'; import {ViewerThumbnailElement} from './viewer-thumbnail.js'; export class ViewerThumbnailBarElement extends PolymerElement { @@ -29,6 +31,8 @@ export class ViewerThumbnailBarElement extends PolymerElement { docLength: Number, + isPluginActive_: Boolean, + /** @private {Array<number>} */ pageNumbers_: { type: Array, @@ -37,6 +41,31 @@ export class ViewerThumbnailBarElement extends PolymerElement { }; } + constructor() { + super(); + + // TODO(dhoss): Remove `this.inTest` when implemented a mock plugin + // controller. + /** @type {boolean} */ + this.inTest = false; + + /** @private {!PluginController} */ + this.pluginController_ = PluginController.getInstance(); + + /** @private {boolean} */ + this.isPluginActive_ = this.pluginController_.isActive; + + /** @private {!EventTracker} */ + this.tracker_ = new EventTracker(); + + // Listen to whether the plugin is active. Thumbnails should be hidden + // when the plugin is inactive. + this.tracker_.add( + this.pluginController_.getEventTarget(), + PluginControllerEventType.IS_ACTIVE_CHANGED, + e => this.isPluginActive_ = e.detail); + } + ready() { super.ready(); @@ -59,11 +88,18 @@ export class ViewerThumbnailBarElement extends PolymerElement { if (thumbnail.isPainted()) { return; } - thumbnail.setPainted(); - this.dispatchEvent(new CustomEvent( - 'paint-thumbnail', - {detail: thumbnail, bubbles: true, composed: true})); + + if (!this.isPluginActive_ || this.inTest) { + return; + } + + this.pluginController_.requestThumbnail(thumbnail.pageNumber) + .then(response => { + const array = new Uint8ClampedArray(response.imageData); + const imageData = new ImageData(array, response.width); + thumbnail.image = imageData; + }); }); }, { root: thumbnailsDiv, @@ -84,7 +120,7 @@ export class ViewerThumbnailBarElement extends PolymerElement { */ activePageChanged_() { if (this.shadowRoot.activeElement) { - this.getThumbnailForPage_(this.activePage).focusAndScroll(); + this.getThumbnailForPage(this.activePage).focusAndScroll(); } } @@ -97,7 +133,16 @@ export class ViewerThumbnailBarElement extends PolymerElement { return; } - this.getThumbnailForPage_(pageNumber).getClickTarget().click(); + this.getThumbnailForPage(pageNumber).getClickTarget().click(); + } + + /** + * @param {number} pageNumber + * @return {?ViewerThumbnailElement} + */ + getThumbnailForPage(pageNumber) { + return /** @type {ViewerThumbnailElement} */ (this.shadowRoot.querySelector( + `viewer-thumbnail:nth-child(${pageNumber})`)); } /** @@ -118,16 +163,6 @@ export class ViewerThumbnailBarElement extends PolymerElement { } /** - * @param {number} pageNumber - * @return {ViewerThumbnailElement} - * @private - */ - getThumbnailForPage_(pageNumber) { - return /** @type {ViewerThumbnailElement} */ (this.shadowRoot.querySelector( - `viewer-thumbnail:nth-child(${pageNumber})`)); - } - - /** * @param {number} page * @return {boolean} Whether the page is the current page. * @private diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-thumbnail.html b/chromium/chrome/browser/resources/pdf/elements/viewer-thumbnail.html index b8054fa2200..9150335c91d 100644 --- a/chromium/chrome/browser/resources/pdf/elements/viewer-thumbnail.html +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-thumbnail.html @@ -11,10 +11,12 @@ #thumbnail { align-items: center; display: inline-flex; + height: 140px; justify-content: center; margin-bottom: 12px; margin-inline-end: auto; margin-inline-start: auto; + width: 108px; } :host([is-active]) #thumbnail { @@ -49,7 +51,5 @@ line-height: 1; } </style> -<div id="thumbnail" on-click="onClick_"> - <canvas width="108" height="140"></canvas> -</div> +<div id="thumbnail" on-click="onClick_"></div> <div id="pageNumber">[[pageNumber]]</div> diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-thumbnail.js b/chromium/chrome/browser/resources/pdf/elements/viewer-thumbnail.js index 03c8dce39c3..efbd4485236 100644 --- a/chromium/chrome/browser/resources/pdf/elements/viewer-thumbnail.js +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-thumbnail.js @@ -17,7 +17,7 @@ const PORTRAIT_WIDTH = 108; const LANDSCAPE_WIDTH = 140; /** @type {string} */ -const PAINTED_ATTRIBUTE = 'painted'; +export const PAINTED_ATTRIBUTE = 'painted'; export class ViewerThumbnailElement extends PolymerElement { static get is() { @@ -33,6 +33,7 @@ export class ViewerThumbnailElement extends PolymerElement { clockwiseRotations: { type: Number, value: 0, + observer: 'clockwiseRotationsChanged_', }, isActive: { @@ -45,12 +46,6 @@ export class ViewerThumbnailElement extends PolymerElement { }; } - static get observers() { - return [ - 'styleCanvas_(clockwiseRotations)', - ]; - } - constructor() { super(); @@ -61,7 +56,12 @@ export class ViewerThumbnailElement extends PolymerElement { /** @param {!ImageData} imageData */ set image(imageData) { - const canvas = this.getCanvas_(); + let canvas = this.getCanvas_(); + if (!canvas) { + canvas = document.createElement('canvas'); + this.shadowRoot.querySelector('#thumbnail').appendChild(canvas); + } + canvas.width = imageData.width; canvas.height = imageData.height; @@ -76,13 +76,13 @@ export class ViewerThumbnailElement extends PolymerElement { return; } + // `canvas` can be `null` in tests because `image` is set only in response + // to the plugin. const canvas = this.getCanvas_(); - const ctx = canvas.getContext('2d'); - ctx.clearRect(0, 0, canvas.width, canvas.height); + if (canvas) { + canvas.remove(); + } this.removeAttribute(PAINTED_ATTRIBUTE); - - // For tests - this.dispatchEvent(new CustomEvent('clear-thumbnail-for-testing')); } /** @return {!HTMLElement} */ @@ -91,12 +91,19 @@ export class ViewerThumbnailElement extends PolymerElement { this.shadowRoot.querySelector('#thumbnail')); } + /** @private */ + clockwiseRotationsChanged_() { + if (this.getCanvas_()) { + this.styleCanvas_(); + } + } + /** - * @return {!HTMLCanvasElement} + * @return {?HTMLCanvasElement} * @private */ getCanvas_() { - return /** @type {!HTMLCanvasElement} */ ( + return /** @type {?HTMLCanvasElement} */ ( this.shadowRoot.querySelector('canvas')); } diff --git a/chromium/chrome/browser/resources/pdf/index_pp.html b/chromium/chrome/browser/resources/pdf/index_pp.html index 2f4cfc16dca..f4c4c5a3c29 100644 --- a/chromium/chrome/browser/resources/pdf/index_pp.html +++ b/chromium/chrome/browser/resources/pdf/index_pp.html @@ -2,6 +2,7 @@ <html is-print-preview dir="$i18n{textdirection}" lang="$i18n{language}"> <head> <meta charset="utf-8"> + <meta name="color-scheme" content="light dark"> <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> <link rel="stylesheet" href="index.css"> diff --git a/chromium/chrome/browser/resources/pdf/ink_controller.js b/chromium/chrome/browser/resources/pdf/ink_controller.js index b880cecc026..a83466877ac 100644 --- a/chromium/chrome/browser/resources/pdf/ink_controller.js +++ b/chromium/chrome/browser/resources/pdf/ink_controller.js @@ -24,20 +24,31 @@ import {Viewport} from './viewport.js'; */ let ViewerInkHostElement; -// Controller for annotation mode, on Chrome OS only. Fires the following events -// from its event target: -// has-unsaved-changes: Fired to indicate there are ink annotations that have -// not been saved. -// set-annotation-undo-state: Contains information about whether undo or redo -// options are available. -export class InkController extends ContentController { +/** + * Event types dispatched by the ink controller. + * @enum {string} + */ +export const InkControllerEventType = { + HAS_UNSAVED_CHANGES: 'InkControllerEventType.HAS_UNSAVED_CHANGES', + LOADED: 'InkControllerEventType.LOADED', + SET_ANNOTATION_UNDO_STATE: 'InkControllerEventType.SET_ANNOTATION_UNDO_STATE', +}; + +/** + * Controller for annotation mode, on Chrome OS only. Fires the following events + * from its event target: + * InkControllerEventType.HAS_UNSAVED_CHANGES: Fired to indicate there are ink + * annotations that have not been saved. + * InkControllerEventType.SET_ANNOTATION_UNDO_STATE: Contains information + * about whether undo or redo options are available. + * @implements {ContentController} + */ +export class InkController { /** * @param {!Viewport} viewport * @param {!HTMLDivElement} contentElement */ constructor(viewport, contentElement) { - super(); - /** @private {!Viewport} */ this.viewport_ = viewport; @@ -54,7 +65,27 @@ export class InkController extends ContentController { this.tool_ = null; } - /** @return {!EventTarget} */ + /** + * @return {boolean} + * @override + */ + get isActive() { + // TODO(crbug.com/1134208): Implement when InkController is a singleton. + return false; + } + + /** + * @param {boolean} isActive + * @override + */ + set isActive(isActive) { + // TODO(crbug.com/1134208): Implement when InkController is a singleton. + } + + /** + * @return {!EventTarget} + * @override + */ getEventTarget() { return this.eventTarget_; } @@ -67,6 +98,12 @@ export class InkController extends ContentController { } } + beforeZoom() {} + + afterZoom() {} + + print() {} + /** @override */ rotateClockwise() { // TODO(dstockwell): implement rotation @@ -116,15 +153,18 @@ export class InkController extends ContentController { this.inkHost_ = /** @type {!ViewerInkHostElement} */ (inkHost); this.inkHost_.viewport = this.viewport_; inkHost.addEventListener('stroke-added', e => { - this.eventTarget_.dispatchEvent(new CustomEvent('has-unsaved-changes')); + this.eventTarget_.dispatchEvent( + new CustomEvent(InkControllerEventType.HAS_UNSAVED_CHANGES)); }); inkHost.addEventListener('undo-state-changed', e => { - this.eventTarget_.dispatchEvent( - new CustomEvent('set-annotation-undo-state', {detail: e.detail})); + this.eventTarget_.dispatchEvent(new CustomEvent( + InkControllerEventType.SET_ANNOTATION_UNDO_STATE, + {detail: e.detail})); }); } return this.inkHost_.load(filename, data).then(() => { - this.eventTarget_.dispatchEvent(new CustomEvent('loaded')); + this.eventTarget_.dispatchEvent( + new CustomEvent(InkControllerEventType.LOADED)); }); } 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 d03df1e27c8..1828eaa830c 100644 --- a/chromium/chrome/browser/resources/pdf/open_pdf_params_parser.js +++ b/chromium/chrome/browser/resources/pdf/open_pdf_params_parser.js @@ -4,6 +4,7 @@ import {assert} from 'chrome://resources/js/assert.m.js'; import {FittingType, NamedDestinationMessageData, Point} from './constants.js'; +import {Size} from './viewport.js'; /** * @typedef {{ @@ -27,6 +28,28 @@ export class OpenPdfParamsParser { constructor(getNamedDestinationCallback) { /** @private {!function(string):!Promise<!NamedDestinationMessageData>} */ this.getNamedDestinationCallback_ = getNamedDestinationCallback; + + /** @private {!Size} */ + this.viewportDimensions_; + } + + /** + * Calculate the zoom level needed for making viewport focus on a rectangular + * area in the PDF document. + * @param {!Size} size The dimensions of the rectangular area to be focused + * on. + * @return {number} The zoom level needed for focusing on the rectangular + * area. A zoom level of 0 indicates that the zoom level cannot be + * calculated with the given information. + * @private + */ + calculateRectZoomLevel_(size) { + if (size.height === 0 || size.width === 0) { + return 0; + } + return Math.min( + this.viewportDimensions_.height / size.height, + this.viewportDimensions_.width / size.width); } /** @@ -129,7 +152,26 @@ export class OpenPdfParamsParser { } if (viewMode === 'fitr' && viewModeComponents.length === 5) { - // TODO(crbug.com/535978): Add support for fit type "FitR" in nameddest. + assert(this.viewportDimensions_ !== undefined); + let x1 = parseFloat(viewModeComponents[1]); + let y1 = parseFloat(viewModeComponents[2]); + let x2 = parseFloat(viewModeComponents[3]); + let y2 = parseFloat(viewModeComponents[4]); + if (!Number.isNaN(x1) && !Number.isNaN(y1) && !Number.isNaN(x2) && + !Number.isNaN(y2)) { + if (x1 > x2) { + [x1, x2] = [x2, x1]; + } + if (y1 > y2) { + [y1, y2] = [y2, y1]; + } + const rectSize = {width: x2 - x1, height: y2 - y1}; + params['position'] = {x: x1, y: y1}; + const zoom = this.calculateRectZoomLevel_(rectSize); + if (zoom !== 0) { + params['zoom'] = zoom; + } + } return params; } @@ -161,6 +203,14 @@ export class OpenPdfParamsParser { } /** + * Store current viewport's dimensions. + * @param {!Size} dimensions + */ + setViewportDimensions(dimensions) { + this.viewportDimensions_ = dimensions; + } + + /** * @param {string} url that needs to be parsed. * @return {boolean} Whether the toolbar UI element should be shown. */ @@ -184,7 +234,7 @@ export class OpenPdfParamsParser { const urlParams = this.parseUrlParams_(url); if (urlParams.has('page')) { - // |pageNumber| is 1-based, but goToPage() take a zero-based page number. + // |pageNumber| is 1-based, but goToPage() take a zero-based page index. const pageNumber = parseInt(urlParams.get('page'), 10); if (!Number.isNaN(pageNumber) && pageNumber > 0) { params['page'] = pageNumber - 1; diff --git a/chromium/chrome/browser/resources/pdf/pdf_viewer.html b/chromium/chrome/browser/resources/pdf/pdf_viewer.html index 775c73e323c..15373b411de 100644 --- a/chromium/chrome/browser/resources/pdf/pdf_viewer.html +++ b/chromium/chrome/browser/resources/pdf/pdf_viewer.html @@ -156,6 +156,7 @@ load-progress="[[loadProgress_]]" has-edits="[[hasEdits_]]" has-entered-annotation-mode="[[hasEnteredAnnotationMode_]]" pdf-form-save-enabled="[[pdfFormSaveEnabled_]]" + presentation-mode-enabled="[[presentationModeEnabled_]]" printing-enabled="[[printingEnabled_]]" rotated="[[isRotated_(clockwiseRotations_)]]" is-form-field-focused="[[isFormFieldFocused_]]" @@ -171,6 +172,7 @@ on-display-annotations-changed="onDisplayAnnotationsChanged_" on-dropdown-opened="onDropdownOpened_" on-fit-to-changed="onFitToChanged" + on-fullscreen-click="onFullscreenClick_" on-annotation-mode-dialog-confirmed="onResetView_" on-sidenav-toggle-click="onSidenavToggleClick_" on-two-up-view-changed="onTwoUpViewChanged_" @@ -191,8 +193,7 @@ active-page="[[pageNo_]]" bookmarks="[[bookmarks_]]" clockwise-rotations="[[clockwiseRotations_]]" doc-length="[[docLength_]]" on-change-page="onChangePage_" - on-change-page-and-xy="onChangePageAndXy_" on-navigate="onNavigate_" - on-paint-thumbnail="onPaintThumbnail_"> + on-change-page-and-xy="onChangePageAndXy_" on-navigate="onNavigate_"> </viewer-pdf-sidenav> </div> <div id="main"> diff --git a/chromium/chrome/browser/resources/pdf/pdf_viewer.js b/chromium/chrome/browser/resources/pdf/pdf_viewer.js index 1edf4b6713f..f43949c9b51 100644 --- a/chromium/chrome/browser/resources/pdf/pdf_viewer.js +++ b/chromium/chrome/browser/resources/pdf/pdf_viewer.js @@ -24,11 +24,11 @@ import {html} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min. import {Bookmark} from './bookmark_type.js'; import {BrowserApi} from './browser_api.js'; import {Attachment, FittingType, Point, SaveRequestType} from './constants.js'; +import {PluginController} from './controller.js'; import {ViewerPdfSidenavElement} from './elements/viewer-pdf-sidenav.js'; import {ViewerPdfToolbarNewElement} from './elements/viewer-pdf-toolbar-new.js'; -import {ViewerThumbnailElement} from './elements/viewer-thumbnail.js'; // <if expr="chromeos"> -import {InkController} from './ink_controller.js'; +import {InkController, InkControllerEventType} from './ink_controller.js'; //</if> import {LocalStorageProxyImpl} from './local_storage_proxy.js'; import {PDFMetrics, UserAction} from './metrics.js'; @@ -114,6 +114,7 @@ export function getFilenameFromURL(url) { /** @type {string} */ const LOCAL_STORAGE_SIDENAV_COLLAPSED_KEY = 'sidenavCollapsed'; +/** @polymer */ export class PDFViewerElement extends PDFViewerBaseElement { static get is() { return 'pdf-viewer'; @@ -125,6 +126,7 @@ export class PDFViewerElement extends PDFViewerBaseElement { static get properties() { return { + /** @private */ annotationAvailable_: { type: Boolean, computed: 'computeAnnotationAvailable_(' + @@ -132,121 +134,166 @@ export class PDFViewerElement extends PDFViewerBaseElement { 'twoUpViewEnabled_)', }, + /** @private */ annotationMode_: { type: Boolean, value: false, }, - attachments_: Array, + /** @private {!Array<!Attachment>} */ + attachments_: { + type: Array, + value: () => [], + }, + + /** @private {!Array<!Bookmark>} */ + bookmarks_: { + type: Array, + value: () => [], + }, + + /** @private */ + canSerializeDocument_: { + type: Boolean, + value: false, + }, - bookmarks_: Array, + /** @private */ + clockwiseRotations_: { + type: Number, + value: 0, + }, - clockwiseRotations_: Number, + /** + * The number of pages in the PDF document. + * @private + */ + docLength_: Number, + /** @private */ documentHasFocus_: { type: Boolean, value: false, }, + /** @private */ + hadPassword_: { + type: Boolean, + value: false, + }, + + /** @private */ hasEdits_: { type: Boolean, value: false, }, + /** @private */ hasEnteredAnnotationMode_: { type: Boolean, value: false, }, - hadPassword_: Boolean, - - canSerializeDocument_: Boolean, - - title_: String, - - sidenavCollapsed_: Boolean, - twoUpViewEnabled_: Boolean, - - isFormFieldFocused_: Boolean, - - pdfViewerUpdateEnabled_: Boolean, + /** @private */ + isFormFieldFocused_: { + type: Boolean, + value: false, + }, - docLength_: Number, - // <if expr="chromeos"> - inkController_: Object, - // </if> + /** + * The current loading progress of the PDF document (0 - 100). + * @private + */ loadProgress_: Number, - pageNo_: Number, - pdfFormSaveEnabled_: Boolean, - pdfAnnotationsEnabled_: Boolean, - printingEnabled_: Boolean, - viewportZoom_: Number, - zoomBounds_: Object, - }; - } - constructor() { - super(); - - // Polymer properties - /** @private {boolean} */ - this.annotationAvailable_; - - /** @private {boolean} */ - this.annotationMode_ = false; - - /** @private {!Array<!Attachment>} */ - this.attachments_ = []; - - /** @private {!Array<!Bookmark>} */ - this.bookmarks_ = []; + /** + * The number of the page being viewed (1-based). + * @private + */ + pageNo_: Number, - /** @private {number} */ - this.clockwiseRotations_ = 0; + /** @private */ + pdfAnnotationsEnabled_: { + type: Boolean, + value: false, + }, - /** @private {boolean} */ - this.documentHasFocus_ = false; + /** @private */ + pdfFormSaveEnabled_: { + type: Boolean, + value: false, + }, - /** @private {boolean} */ - this.hasEdits_ = false; + /** @private */ + presentationModeEnabled_: { + type: Boolean, + value: false, + }, - /** @private {boolean} */ - this.hasEnteredAnnotationMode_ = false; + /** @private */ + pdfViewerUpdateEnabled_: Boolean, - /** @private {boolean} */ - this.hadPassword_ = false; + /** @private */ + printingEnabled_: { + type: Boolean, + value: false, + }, - /** @private {boolean} */ - this.canSerializeDocument_ = false; + /** @private */ + sidenavCollapsed_: { + type: Boolean, + value: false, + }, - /** @private {string} */ - this.title_ = ''; + /** @private */ + title_: { + type: String, + value: '', + }, - /** @private {boolean} */ - this.twoUpViewEnabled_ = false; + /** @private */ + twoUpViewEnabled_: { + type: Boolean, + value: false, + }, - /** @private {boolean} */ - this.isFormFieldFocused_ = false; + /** @private */ + viewportZoom_: { + type: Number, + value: 1, + }, - // <if expr="chromeos"> - /** @private {?InkController} */ - this.inkController_ = null; - // </if> + /** @private {!{ min: number, max: number }} */ + zoomBounds_: { + type: Object, + value: () => ({min: 0, max: 0}), + }, - /** @private {boolean} */ - this.pdfAnnotationsEnabled_ = false; + // <if expr="chromeos"> + /** @private {?InkController} */ + inkController_: { + type: Object, + value: null, + }, + // </if> + }; + } - /** @private {boolean} */ - this.pdfFormSaveEnabled_ = false; + constructor() { + super(); - /** @private {boolean} */ - this.printingEnabled_ = false; + // Polymer properties - /** @private {number} */ - this.viewportZoom_ = 1; + this.pdfViewerUpdateEnabled_ = + document.documentElement.hasAttribute('pdf-viewer-update-enabled'); - /** @private {!{ min: number, max: number }} */ - this.zoomBounds_ = {min: 0, max: 0}; + if (this.pdfViewerUpdateEnabled_) { + // TODO(dpapad): Add tests after crbug.com/1111459 is fixed. + this.sidenavCollapsed_ = Boolean(Number.parseInt( + LocalStorageProxyImpl.getInstance().getItem( + LOCAL_STORAGE_SIDENAV_COLLAPSED_KEY), + 10)); + } // Non-Polymer properties @@ -254,9 +301,6 @@ export class PDFViewerElement extends PDFViewerBaseElement { this.beepCount = 0; /** @private {boolean} */ - this.hadPassword_ = false; - - /** @private {boolean} */ this.toolbarEnabled_ = false; /** @private {?ToolbarManager} */ @@ -265,48 +309,12 @@ export class PDFViewerElement extends PDFViewerBaseElement { /** @private {?PdfNavigator} */ this.navigator_ = null; - /** @private {string} */ - this.title_ = ''; - - /** - * The number of pages in the PDF document. - * @private {number} - */ - this.docLength_; - - /** - * The number of the page being viewed (1-based). - * @private {number} - */ - this.pageNo_; - - /** - * The current loading progress of the PDF document (0 - 100). - * @private {number} - */ - this.loadProgress_; - - /** @private {boolean} */ - this.pdfViewerUpdateEnabled_ = - document.documentElement.hasAttribute('pdf-viewer-update-enabled'); - - /** @private {boolean} */ - this.sidenavCollapsed_ = false; - /** * The state to restore sidenavCollapsed_ to after exiting annotation mode. * @private {boolean} */ this.sidenavRestoreState_ = false; - if (this.pdfViewerUpdateEnabled_) { - // TODO(dpapad): Add tests after crbug.com/1111459 is fixed. - this.sidenavCollapsed_ = Boolean(Number.parseInt( - LocalStorageProxyImpl.getInstance().getItem( - LOCAL_STORAGE_SIDENAV_COLLAPSED_KEY), - 10)); - } - FocusOutlineManager.forDocument(document); } @@ -379,11 +387,15 @@ export class PDFViewerElement extends PDFViewerBaseElement { init(browserApi) { super.init(browserApi); + /** @private {?PluginController} */ + this.pluginController_ = PluginController.getInstance(); + // <if expr="chromeos"> this.inkController_ = new InkController( this.viewport, /** @type {!HTMLDivElement} */ (this.getContent())); this.tracker.add( - this.inkController_.getEventTarget(), 'has-unsaved-changes', + this.inkController_.getEventTarget(), + InkControllerEventType.HAS_UNSAVED_CHANGES, () => chrome.mimeHandlerPrivate.setShowBeforeUnloadDialog(true)); // </if> @@ -478,7 +490,7 @@ export class PDFViewerElement extends PDFViewerBaseElement { switch (e.key) { case 'a': if (e.ctrlKey || e.metaKey) { - this.pluginController.selectAll(); + this.pluginController_.selectAll(); // Since we do selection ourselves. e.preventDefault(); } @@ -557,7 +569,7 @@ export class PDFViewerElement extends PDFViewerBaseElement { const annotationMode = e.detail; if (annotationMode) { // Enter annotation mode. - assert(this.currentController === this.pluginController); + assert(this.pluginController_.isActive); // TODO(dstockwell): set plugin read-only, begin transition this.updateProgress(0); @@ -572,7 +584,7 @@ export class PDFViewerElement extends PDFViewerBaseElement { // TODO(dstockwell): handle save failure const saveResult = - await this.pluginController.save(SaveRequestType.ANNOTATION); + await this.pluginController_.save(SaveRequestType.ANNOTATION); // Data always exists when save is called with requestType = ANNOTATION. const result = /** @type {!RequiredSaveResult} */ (saveResult); if (result.hasUnsavedChanges) { @@ -593,11 +605,12 @@ export class PDFViewerElement extends PDFViewerBaseElement { this.updateProgress(50); await this.inkController_.load(result.fileName, result.dataToSave); this.currentController = this.inkController_; - this.pluginController.unload(); + this.pluginController_.unload(); this.updateProgress(100); } else { // Exit annotation mode. PDFMetrics.record(UserAction.EXIT_ANNOTATION_MODE); + assert(!this.pluginController_.isActive); assert(this.currentController === this.inkController_); // TODO(dstockwell): set ink read-only, begin transition this.updateProgress(0); @@ -605,7 +618,7 @@ export class PDFViewerElement extends PDFViewerBaseElement { // This runs separately to allow other consumers of `loaded` to queue // up after this task. this.loaded.then(() => { - this.currentController = this.pluginController; + this.currentController = this.pluginController_; this.inkController_.unload(); }); // TODO(dstockwell): handle save failure @@ -616,9 +629,9 @@ export class PDFViewerElement extends PDFViewerBaseElement { if (this.pdfViewerUpdateEnabled_) { await this.restoreSidenav_(); } - await this.pluginController.load(result.fileName, result.dataToSave); + await this.pluginController_.load(result.fileName, result.dataToSave); // Ensure the plugin gets the initial viewport. - this.pluginController.afterZoom(); + this.pluginController_.afterZoom(); } } @@ -652,9 +665,8 @@ export class PDFViewerElement extends PDFViewerBaseElement { * @private */ onScroll_(e) { - if (this.currentController === this.pluginController && - !this.annotationMode_) { - this.pluginController.updateScroll( + if (this.pluginController_.isActive && !this.annotationMode_) { + this.pluginController_.updateScroll( e.target.scrollLeft, e.target.scrollTop); } } @@ -673,6 +685,12 @@ export class PDFViewerElement extends PDFViewerBaseElement { } } + /** @private */ + onFullscreenClick_() { + assert(this.presentationModeEnabled_); + this.shadowRoot.querySelector('#main').requestFullscreen(); + } + /** * Changes two up view mode for the controller. Controller will trigger * layout update later, which will update the viewport accordingly. @@ -740,7 +758,7 @@ export class PDFViewerElement extends PDFViewerBaseElement { * @private */ onPasswordSubmitted_(event) { - this.pluginController.getPasswordComplete(event.detail.password); + this.pluginController_.getPasswordComplete(event.detail.password); } /** @override */ @@ -766,6 +784,8 @@ export class PDFViewerElement extends PDFViewerBaseElement { this.pdfAnnotationsEnabled_ = loadTimeData.getBoolean('pdfAnnotationsEnabled'); this.pdfFormSaveEnabled_ = loadTimeData.getBoolean('pdfFormSaveEnabled'); + this.presentationModeEnabled_ = + loadTimeData.getBoolean('presentationModeEnabled'); this.printingEnabled_ = loadTimeData.getBoolean('printingEnabled'); const presetZoomFactors = this.viewport.presetZoomFactors; this.zoomBounds_.min = Math.round(presetZoomFactors[0] * 100); @@ -783,21 +803,21 @@ export class PDFViewerElement extends PDFViewerBaseElement { switch (message.data.type.toString()) { case 'getSelectedText': - this.pluginController.getSelectedText().then( + this.pluginController_.getSelectedText().then( this.handleSelectedTextReply.bind(this)); break; case 'getThumbnail': const getThumbnailData = /** @type {GetThumbnailMessageData} */ (message.data); const page = getThumbnailData.page; - this.pluginController.requestThumbnail(page).then( + this.pluginController_.requestThumbnail(page).then( this.sendScriptingMessage.bind(this)); break; case 'print': - this.pluginController.print(); + this.pluginController_.print(); break; case 'selectAll': - this.pluginController.selectAll(); + this.pluginController_.selectAll(); break; } } @@ -1081,22 +1101,6 @@ export class PDFViewerElement extends PDFViewerBaseElement { this.navigator_.navigate(e.detail.uri, disposition); } - /** - * @param {!CustomEvent<!ViewerThumbnailElement>} e - * @private - */ - onPaintThumbnail_(e) { - assert(this.currentController === this.pluginController); - assert(!this.annotationMode_); - const thumbnail = e.detail; - this.pluginController.requestThumbnail(thumbnail.pageNumber) - .then(response => { - const array = new Uint8ClampedArray(response.imageData); - const imageData = new ImageData(array, response.width); - thumbnail.image = imageData; - }); - } - /** @private */ onSidenavToggleClick_() { assert(this.pdfViewerUpdateEnabled_); diff --git a/chromium/chrome/browser/resources/pdf/pdf_viewer_base.js b/chromium/chrome/browser/resources/pdf/pdf_viewer_base.js index a8616e5b64c..cfa57cccc36 100644 --- a/chromium/chrome/browser/resources/pdf/pdf_viewer_base.js +++ b/chromium/chrome/browser/resources/pdf/pdf_viewer_base.js @@ -10,7 +10,7 @@ import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/poly import {BrowserApi, ZoomBehavior} from './browser_api.js'; import {FittingType, Point} from './constants.js'; -import {ContentController, MessageData, PluginController} from './controller.js'; +import {ContentController, MessageData, PluginController, PluginControllerEventType} from './controller.js'; import {PDFMetrics, UserAction} from './metrics.js'; import {OpenPdfParamsParser} from './open_pdf_params_parser.js'; import {LoadState} from './pdf_scripting_api.js'; @@ -44,6 +44,7 @@ export class PDFViewerBaseElement extends PolymerElement { static get properties() { return { + /** @protected {Object|undefined} */ strings: Object, }; } @@ -51,9 +52,6 @@ export class PDFViewerBaseElement extends PolymerElement { constructor() { super(); - /** @protected {Object|undefined} */ - this.strings = undefined; - /** @protected {?BrowserApi} */ this.browserApi = null; @@ -105,9 +103,6 @@ export class PDFViewerBaseElement extends PolymerElement { /** @private {?Viewport} */ this.viewport_ = null; - /** @private {?PluginController} */ - this.pluginController_ = null; - /** @private {?HTMLEmbedElement} */ this.plugin_ = null; @@ -228,7 +223,7 @@ export class PDFViewerBaseElement extends PolymerElement { // Parse open pdf parameters. this.paramsParser = new OpenPdfParamsParser(destination => { - return this.pluginController_.getNamedDestination(destination); + return PluginController.getInstance().getNamedDestination(destination); }); // Can only reload if we are in a normal tab. @@ -276,12 +271,17 @@ export class PDFViewerBaseElement extends PolymerElement { // Create the plugin. this.plugin_ = this.createPlugin_(pdfViewerUpdateEnabled); this.getContent().appendChild(this.plugin_); - this.pluginController_ = new PluginController( + + const pluginController = PluginController.getInstance(); + pluginController.init( this.plugin_, this.viewport_, () => this.isUserInitiatedEvent, () => this.loaded); - this.currentController = this.pluginController_; + pluginController.isActive = true; + this.currentController = pluginController; + this.tracker.add( - this.pluginController_.getEventTarget(), 'plugin-message', + pluginController.getEventTarget(), + PluginControllerEventType.PLUGIN_MESSAGE, e => this.handlePluginMessage(e)); document.body.addEventListener('change-page-and-xy', e => { @@ -375,6 +375,8 @@ export class PDFViewerBaseElement extends PolymerElement { const visiblePage = this.viewport_.getMostVisiblePage(); const visiblePageDimensions = this.viewport_.getPageScreenRect(visiblePage); const size = this.viewport_.size; + this.paramsParser.setViewportDimensions(size); + this.sendScriptingMessage({ type: 'viewport', pageX: visiblePageDimensions.x, @@ -431,6 +433,7 @@ export class PDFViewerBaseElement extends PolymerElement { this.documentDimensions = documentDimensions; this.isUserInitiatedEvent = false; this.viewport_.setDocumentDimensions(this.documentDimensions); + this.paramsParser.setViewportDimensions(this.viewport_.size); this.isUserInitiatedEvent = true; } @@ -449,14 +452,6 @@ export class PDFViewerBaseElement extends PolymerElement { } /** - * @return {!PluginController} - * @protected - */ - get pluginController() { - return assert(this.pluginController_); - } - - /** * Updates the load state and triggers completion of the `loaded` * promise if necessary. * @param {!LoadState} loadState diff --git a/chromium/chrome/browser/resources/pdf/pdf_viewer_pp.js b/chromium/chrome/browser/resources/pdf/pdf_viewer_pp.js index a719346fca3..a4f6745ef58 100644 --- a/chromium/chrome/browser/resources/pdf/pdf_viewer_pp.js +++ b/chromium/chrome/browser/resources/pdf/pdf_viewer_pp.js @@ -15,7 +15,7 @@ import {html} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min. import {BrowserApi} from './browser_api.js'; import {FittingType} from './constants.js'; -import {MessageData, PrintPreviewParams} from './controller.js'; +import {MessageData, PluginController, PrintPreviewParams} from './controller.js'; import {DeserializeKeyEvent, LoadState, SerializeKeyEvent} from './pdf_scripting_api.js'; import {PDFViewerBaseElement} from './pdf_viewer_base.js'; import {DestinationMessageData, DocumentDimensionsMessageData, MessageObject, shouldIgnoreKeyEvents} from './pdf_viewer_utils.js'; @@ -78,6 +78,9 @@ class PDFViewerPPElement extends PDFViewerBaseElement { init(browserApi) { super.init(browserApi); + /** @private {?PluginController} */ + this.pluginController_ = PluginController.getInstance(); + this.toolbarManager_ = new ToolbarManager(window, null, this.getZoomToolbar_()); @@ -112,26 +115,16 @@ class PDFViewerPPElement extends PDFViewerBaseElement { break; // Ensure escape falls through to the print-preview handler. case 'a': if (e.ctrlKey || e.metaKey) { - this.pluginController.selectAll(); + this.pluginController_.selectAll(); // Since we do selection ourselves. e.preventDefault(); } return; - case '[': - if (e.ctrlKey) { - this.rotateCounterclockwise(); - } - return; case '\\': if (e.ctrlKey) { this.getZoomToolbar_().fitToggleFromHotKey(); } return; - case ']': - if (e.ctrlKey) { - this.rotateClockwise(); - } - return; } // Give print preview a chance to handle the key event. @@ -148,7 +141,7 @@ class PDFViewerPPElement extends PDFViewerBaseElement { /** @private */ sendBackgroundColorForPrintPreview_() { - this.pluginController.backgroundColorChanged( + this.pluginController_.backgroundColorChanged( this.dark_ ? PRINT_PREVIEW_DARK_BACKGROUND_COLOR : PRINT_PREVIEW_BACKGROUND_COLOR); } @@ -192,7 +185,7 @@ class PDFViewerPPElement extends PDFViewerBaseElement { pageIndicator.style.visibility = 'hidden'; } - this.pluginController.viewportChanged(); + this.pluginController_.viewportChanged(); } /** @override */ @@ -209,11 +202,11 @@ class PDFViewerPPElement extends PDFViewerBaseElement { switch (message.data.type.toString()) { case 'getSelectedText': - this.pluginController.getSelectedText().then( + this.pluginController_.getSelectedText().then( this.sendScriptingMessage.bind(this)); break; case 'selectAll': - this.pluginController.selectAll(); + this.pluginController_.selectAll(); break; } } @@ -230,7 +223,7 @@ class PDFViewerPPElement extends PDFViewerBaseElement { case 'loadPreviewPage': messageData = /** @type {{ url: string, index: number }} */ (messageData); - this.pluginController.loadPreviewPage( + this.pluginController_.loadPreviewPage( messageData.url, messageData.index); return true; case 'resetPrintPreviewMode': @@ -249,7 +242,7 @@ class PDFViewerPPElement extends PDFViewerBaseElement { this.lastViewportPosition = this.viewport.position; this.$$('#page-indicator').pageLabels = messageData.pageNumbers; - this.pluginController.resetPrintPreviewMode(messageData); + this.pluginController_.resetPrintPreviewMode(messageData); return true; case 'sendKeyEvent': this.handleKeyEvent_(/** @type {!KeyboardEvent} */ (DeserializeKeyEvent( diff --git a/chromium/chrome/browser/resources/pdf/viewport.js b/chromium/chrome/browser/resources/pdf/viewport.js index c27b902dcec..5d965d21587 100644 --- a/chromium/chrome/browser/resources/pdf/viewport.js +++ b/chromium/chrome/browser/resources/pdf/viewport.js @@ -32,7 +32,7 @@ export let LayoutOptions; export let PartialPoint; /** @typedef {{width: number, height: number}} */ -let Size; +export let Size; /** @typedef {{x: number, y: number, width: number, height: number}} */ let ViewportRect; |