Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 'use strict'; | 5 'use strict'; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * @return {number} Width of a scrollbar in pixels | 8 * @return {number} Width of a scrollbar in pixels |
| 9 */ | 9 */ |
| 10 function getScrollbarWidth() { | 10 function getScrollbarWidth() { |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 36 */ | 36 */ |
| 37 PDFViewer.MIN_TOOLBAR_OFFSET = 15; | 37 PDFViewer.MIN_TOOLBAR_OFFSET = 15; |
| 38 | 38 |
| 39 /** | 39 /** |
| 40 * Creates a new PDFViewer. There should only be one of these objects per | 40 * Creates a new PDFViewer. There should only be one of these objects per |
| 41 * document. | 41 * document. |
| 42 * @param {Object} streamDetails The stream object which points to the data | 42 * @param {Object} streamDetails The stream object which points to the data |
| 43 * contained in the PDF. | 43 * contained in the PDF. |
| 44 */ | 44 */ |
| 45 function PDFViewer(streamDetails) { | 45 function PDFViewer(streamDetails) { |
| 46 this.streamDetails = streamDetails; | 46 this.streamDetails_ = streamDetails; |
| 47 this.loaded = false; | 47 this.loaded_ = false; |
| 48 this.parentWindow_ = null; | |
| 48 | 49 |
| 49 // The sizer element is placed behind the plugin element to cause scrollbars | 50 // The sizer element is placed behind the plugin element to cause scrollbars |
| 50 // to be displayed in the window. It is sized according to the document size | 51 // to be displayed in the window. It is sized according to the document size |
| 51 // of the pdf and zoom level. | 52 // of the pdf and zoom level. |
| 52 this.sizer_ = $('sizer'); | 53 this.sizer_ = $('sizer'); |
| 53 this.toolbar_ = $('toolbar'); | 54 this.toolbar_ = $('toolbar'); |
| 54 this.pageIndicator_ = $('page-indicator'); | 55 this.pageIndicator_ = $('page-indicator'); |
| 55 this.progressBar_ = $('progress-bar'); | 56 this.progressBar_ = $('progress-bar'); |
| 56 this.passwordScreen_ = $('password-screen'); | 57 this.passwordScreen_ = $('password-screen'); |
| 57 this.passwordScreen_.addEventListener('password-submitted', | 58 this.passwordScreen_.addEventListener('password-submitted', |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 73 // NOTE: The plugin's 'id' field must be set to 'plugin' since | 74 // NOTE: The plugin's 'id' field must be set to 'plugin' since |
| 74 // chrome/renderer/printing/print_web_view_helper.cc actually references it. | 75 // chrome/renderer/printing/print_web_view_helper.cc actually references it. |
| 75 this.plugin_.id = 'plugin'; | 76 this.plugin_.id = 'plugin'; |
| 76 this.plugin_.type = 'application/x-google-chrome-pdf'; | 77 this.plugin_.type = 'application/x-google-chrome-pdf'; |
| 77 this.plugin_.addEventListener('message', this.handlePluginMessage_.bind(this), | 78 this.plugin_.addEventListener('message', this.handlePluginMessage_.bind(this), |
| 78 false); | 79 false); |
| 79 | 80 |
| 80 // Handle scripting messages from outside the extension that wish to interact | 81 // Handle scripting messages from outside the extension that wish to interact |
| 81 // with it. We also send a message indicating that extension has loaded and | 82 // with it. We also send a message indicating that extension has loaded and |
| 82 // is ready to receive messages. | 83 // is ready to receive messages. |
| 83 window.addEventListener('message', this.handleScriptingMessage_.bind(this), | 84 window.addEventListener('message', this.handleScriptingMessage.bind(this), |
| 84 false); | 85 false); |
| 85 this.sendScriptingMessage_({type: 'readyToReceive'}); | |
| 86 | 86 |
| 87 document.title = getFilenameFromURL(this.streamDetails.originalUrl); | 87 document.title = getFilenameFromURL(this.streamDetails_.originalUrl); |
| 88 this.plugin_.setAttribute('src', this.streamDetails.originalUrl); | 88 this.plugin_.setAttribute('src', this.streamDetails_.originalUrl); |
| 89 this.plugin_.setAttribute('stream-url', this.streamDetails.streamUrl); | 89 this.plugin_.setAttribute('stream-url', this.streamDetails_.streamUrl); |
| 90 var headers = ''; | 90 var headers = ''; |
| 91 for (var header in this.streamDetails.responseHeaders) { | 91 for (var header in this.streamDetails_.responseHeaders) { |
| 92 headers += header + ': ' + | 92 headers += header + ': ' + |
| 93 this.streamDetails.responseHeaders[header] + '\n'; | 93 this.streamDetails_.responseHeaders[header] + '\n'; |
| 94 } | 94 } |
| 95 this.plugin_.setAttribute('headers', headers); | 95 this.plugin_.setAttribute('headers', headers); |
| 96 | 96 |
| 97 if (!this.streamDetails.embedded) | 97 if (!this.streamDetails_.embedded) |
| 98 this.plugin_.setAttribute('full-frame', ''); | 98 this.plugin_.setAttribute('full-frame', ''); |
| 99 document.body.appendChild(this.plugin_); | 99 document.body.appendChild(this.plugin_); |
| 100 | 100 |
| 101 // TODO(raymes): Remove this spurious message once crbug.com/388606 is fixed. | |
| 102 // This is a hack to initialize pepper sync scripting and avoid re-entrancy. | |
| 103 this.plugin_.postMessage({ | |
| 104 type: 'viewport', | |
| 105 zoom: 1, | |
| 106 xOffset: 0, | |
| 107 yOffset: 0 | |
| 108 }); | |
| 109 | |
| 110 // Setup the button event listeners. | 101 // Setup the button event listeners. |
| 111 $('fit-to-width-button').addEventListener('click', | 102 $('fit-to-width-button').addEventListener('click', |
| 112 this.viewport_.fitToWidth.bind(this.viewport_)); | 103 this.viewport_.fitToWidth.bind(this.viewport_)); |
| 113 $('fit-to-page-button').addEventListener('click', | 104 $('fit-to-page-button').addEventListener('click', |
| 114 this.viewport_.fitToPage.bind(this.viewport_)); | 105 this.viewport_.fitToPage.bind(this.viewport_)); |
| 115 $('zoom-in-button').addEventListener('click', | 106 $('zoom-in-button').addEventListener('click', |
| 116 this.viewport_.zoomIn.bind(this.viewport_)); | 107 this.viewport_.zoomIn.bind(this.viewport_)); |
| 117 $('zoom-out-button').addEventListener('click', | 108 $('zoom-out-button').addEventListener('click', |
| 118 this.viewport_.zoomOut.bind(this.viewport_)); | 109 this.viewport_.zoomOut.bind(this.viewport_)); |
| 119 $('save-button').addEventListener('click', this.save_.bind(this)); | 110 $('save-button').addEventListener('click', this.save_.bind(this)); |
| 120 $('print-button').addEventListener('click', this.print_.bind(this)); | 111 $('print-button').addEventListener('click', this.print_.bind(this)); |
| 121 | 112 |
| 122 // Setup the keyboard event listener. | 113 // Setup the keyboard event listener. |
| 123 document.onkeydown = this.handleKeyEvent_.bind(this); | 114 document.onkeydown = this.handleKeyEvent_.bind(this); |
| 124 | 115 |
| 125 // Set up the zoom API. | 116 // Set up the zoom API. |
| 126 if (this.shouldManageZoom_()) { | 117 if (this.shouldManageZoom_()) { |
| 127 chrome.tabs.setZoomSettings(this.streamDetails.tabId, | 118 chrome.tabs.setZoomSettings(this.streamDetails_.tabId, |
| 128 {mode: 'manual', scope: 'per-tab'}, | 119 {mode: 'manual', scope: 'per-tab'}, |
| 129 this.afterZoom_.bind(this)); | 120 this.afterZoom_.bind(this)); |
| 130 chrome.tabs.onZoomChange.addListener(function(zoomChangeInfo) { | 121 chrome.tabs.onZoomChange.addListener(function(zoomChangeInfo) { |
| 131 if (zoomChangeInfo.tabId != this.streamDetails.tabId) | 122 if (zoomChangeInfo.tabId != this.streamDetails_.tabId) |
| 132 return; | 123 return; |
| 133 // If the zoom level is close enough to the current zoom level, don't | 124 // If the zoom level is close enough to the current zoom level, don't |
| 134 // change it. This avoids us getting into an infinite loop of zoom changes | 125 // change it. This avoids us getting into an infinite loop of zoom changes |
| 135 // due to floating point error. | 126 // due to floating point error. |
| 136 var MIN_ZOOM_DELTA = 0.01; | 127 var MIN_ZOOM_DELTA = 0.01; |
| 137 var zoomDelta = Math.abs(this.viewport_.zoom - | 128 var zoomDelta = Math.abs(this.viewport_.zoom - |
| 138 zoomChangeInfo.newZoomFactor); | 129 zoomChangeInfo.newZoomFactor); |
| 139 // We should not change zoom level when we are responsible for initiating | 130 // We should not change zoom level when we are responsible for initiating |
| 140 // the zoom. onZoomChange() is called before setZoomComplete() callback | 131 // the zoom. onZoomChange() is called before setZoomComplete() callback |
| 141 // when we initiate the zoom. | 132 // when we initiate the zoom. |
| 142 if ((zoomDelta > MIN_ZOOM_DELTA) && !this.setZoomInProgress_) | 133 if ((zoomDelta > MIN_ZOOM_DELTA) && !this.setZoomInProgress_) |
| 143 this.viewport_.setZoom(zoomChangeInfo.newZoomFactor); | 134 this.viewport_.setZoom(zoomChangeInfo.newZoomFactor); |
| 144 }.bind(this)); | 135 }.bind(this)); |
| 145 } | 136 } |
| 146 | 137 |
| 147 // Parse open pdf parameters. | 138 // Parse open pdf parameters. |
| 148 var paramsParser = new OpenPDFParamsParser(this.streamDetails.originalUrl); | 139 var paramsParser = new OpenPDFParamsParser(this.streamDetails_.originalUrl); |
| 149 this.urlParams_ = paramsParser.urlParams; | 140 this.urlParams_ = paramsParser.urlParams; |
| 150 } | 141 } |
| 151 | 142 |
| 152 PDFViewer.prototype = { | 143 PDFViewer.prototype = { |
| 153 /** | 144 /** |
| 154 * @private | 145 * @private |
| 155 * Handle key events. These may come from the user directly or via the | 146 * Handle key events. These may come from the user directly or via the |
| 156 * scripting API. | 147 * scripting API. |
| 157 * @param {KeyboardEvent} e the event to handle. | 148 * @param {KeyboardEvent} e the event to handle. |
| 158 */ | 149 */ |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 321 this.toolbar_.style.visibility = 'hidden'; | 312 this.toolbar_.style.visibility = 'hidden'; |
| 322 if (this.passwordScreen_.active) { | 313 if (this.passwordScreen_.active) { |
| 323 this.passwordScreen_.deny(); | 314 this.passwordScreen_.deny(); |
| 324 this.passwordScreen_.active = false; | 315 this.passwordScreen_.active = false; |
| 325 } | 316 } |
| 326 } else if (progress == 100) { | 317 } else if (progress == 100) { |
| 327 // Document load complete. | 318 // Document load complete. |
| 328 if (this.lastViewportPosition_) | 319 if (this.lastViewportPosition_) |
| 329 this.viewport_.position = this.lastViewportPosition_; | 320 this.viewport_.position = this.lastViewportPosition_; |
| 330 this.handleURLParams_(); | 321 this.handleURLParams_(); |
| 331 this.loaded = true; | 322 this.loaded_ = true; |
| 332 var loadEvent = new Event('pdfload'); | |
| 333 window.dispatchEvent(loadEvent); | |
| 334 this.sendScriptingMessage_({ | 323 this.sendScriptingMessage_({ |
| 335 type: 'documentLoaded' | 324 type: 'documentLoaded' |
| 336 }); | 325 }); |
| 337 } | 326 } |
| 338 }, | 327 }, |
| 339 | 328 |
| 340 /** | 329 /** |
| 341 * @private | 330 * @private |
| 342 * An event handler for handling password-submitted events. These are fired | 331 * An event handler for handling password-submitted events. These are fired |
| 343 * when an event is entered into the password screen. | 332 * when an event is entered into the password screen. |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 407 position.y = message.data.y; | 396 position.y = message.data.y; |
| 408 this.viewport_.position = position; | 397 this.viewport_.position = position; |
| 409 break; | 398 break; |
| 410 case 'setTranslatedStrings': | 399 case 'setTranslatedStrings': |
| 411 this.passwordScreen_.text = message.data.getPasswordString; | 400 this.passwordScreen_.text = message.data.getPasswordString; |
| 412 this.progressBar_.text = message.data.loadingString; | 401 this.progressBar_.text = message.data.loadingString; |
| 413 this.progressBar_.style.visibility = 'visible'; | 402 this.progressBar_.style.visibility = 'visible'; |
| 414 this.errorScreen_.text = message.data.loadFailedString; | 403 this.errorScreen_.text = message.data.loadFailedString; |
| 415 break; | 404 break; |
| 416 case 'cancelStreamUrl': | 405 case 'cancelStreamUrl': |
| 417 chrome.streamsPrivate.abort(this.streamDetails.streamUrl); | 406 chrome.streamsPrivate.abort(this.streamDetails_.streamUrl); |
| 418 break; | 407 break; |
| 419 } | 408 } |
| 420 }, | 409 }, |
| 421 | 410 |
| 422 /** | 411 /** |
| 423 * @private | 412 * @private |
| 424 * A callback that's called before the zoom changes. Notify the plugin to stop | 413 * A callback that's called before the zoom changes. Notify the plugin to stop |
| 425 * reacting to scroll events while zoom is taking place to avoid flickering. | 414 * reacting to scroll events while zoom is taking place to avoid flickering. |
| 426 */ | 415 */ |
| 427 beforeZoom_: function() { | 416 beforeZoom_: function() { |
| 428 this.plugin_.postMessage({ | 417 this.plugin_.postMessage({ |
| 429 type: 'stopScrolling' | 418 type: 'stopScrolling' |
| 430 }); | 419 }); |
| 431 }, | 420 }, |
| 432 | 421 |
| 433 /** | 422 /** |
| 434 * @private | 423 * @private |
| 435 * A callback that's called after the zoom changes. Notify the plugin of the | 424 * A callback that's called after the zoom changes. Notify the plugin of the |
| 436 * zoom change and to continue reacting to scroll events. | 425 * zoom change and to continue reacting to scroll events. |
| 437 */ | 426 */ |
| 438 afterZoom_: function() { | 427 afterZoom_: function() { |
| 439 var position = this.viewport_.position; | 428 var position = this.viewport_.position; |
| 440 var zoom = this.viewport_.zoom; | 429 var zoom = this.viewport_.zoom; |
| 441 if (this.shouldManageZoom_() && !this.setZoomInProgress_) { | 430 if (this.shouldManageZoom_() && !this.setZoomInProgress_) { |
| 442 this.setZoomInProgress_ = true; | 431 this.setZoomInProgress_ = true; |
| 443 chrome.tabs.setZoom(this.streamDetails.tabId, zoom, | 432 chrome.tabs.setZoom(this.streamDetails_.tabId, zoom, |
| 444 this.setZoomComplete_.bind(this, zoom)); | 433 this.setZoomComplete_.bind(this, zoom)); |
| 445 } | 434 } |
| 446 this.plugin_.postMessage({ | 435 this.plugin_.postMessage({ |
| 447 type: 'viewport', | 436 type: 'viewport', |
| 448 zoom: zoom, | 437 zoom: zoom, |
| 449 xOffset: position.x, | 438 xOffset: position.x, |
| 450 yOffset: position.y | 439 yOffset: position.y |
| 451 }); | 440 }); |
| 452 }, | 441 }, |
| 453 | 442 |
| 454 /** | 443 /** |
| 455 * @private | 444 * @private |
| 456 * A callback that's called after chrome.tabs.setZoom is complete. This will | 445 * A callback that's called after chrome.tabs.setZoom is complete. This will |
| 457 * call chrome.tabs.setZoom again if the zoom level has changed since it was | 446 * call chrome.tabs.setZoom again if the zoom level has changed since it was |
| 458 * last called. | 447 * last called. |
| 459 * @param {number} lastZoom the zoom level that chrome.tabs.setZoom was called | 448 * @param {number} lastZoom the zoom level that chrome.tabs.setZoom was called |
| 460 * with. | 449 * with. |
| 461 */ | 450 */ |
| 462 setZoomComplete_: function(lastZoom) { | 451 setZoomComplete_: function(lastZoom) { |
| 463 var zoom = this.viewport_.zoom; | 452 var zoom = this.viewport_.zoom; |
| 464 if (zoom != lastZoom) { | 453 if (zoom != lastZoom) { |
| 465 chrome.tabs.setZoom(this.streamDetails.tabId, zoom, | 454 chrome.tabs.setZoom(this.streamDetails_.tabId, zoom, |
| 466 this.setZoomComplete_.bind(this, zoom)); | 455 this.setZoomComplete_.bind(this, zoom)); |
| 467 } else { | 456 } else { |
| 468 this.setZoomInProgress_ = false; | 457 this.setZoomInProgress_ = false; |
| 469 } | 458 } |
| 470 }, | 459 }, |
| 471 | 460 |
| 472 /** | 461 /** |
| 473 * @private | 462 * @private |
| 474 * A callback that's called after the viewport changes. | 463 * A callback that's called after the viewport changes. |
| 475 */ | 464 */ |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 526 }); | 515 }); |
| 527 }, | 516 }, |
| 528 | 517 |
| 529 /** | 518 /** |
| 530 * @private | 519 * @private |
| 531 * Handle a scripting message from outside the extension (typically sent by | 520 * Handle a scripting message from outside the extension (typically sent by |
| 532 * PDFScriptingAPI in a page containing the extension) to interact with the | 521 * PDFScriptingAPI in a page containing the extension) to interact with the |
| 533 * plugin. | 522 * plugin. |
| 534 * @param {MessageObject} message the message to handle. | 523 * @param {MessageObject} message the message to handle. |
| 535 */ | 524 */ |
| 536 handleScriptingMessage_: function(message) { | 525 handleScriptingMessage: function(message) { |
| 526 console.error(message); | |
|
Sam McNally
2015/01/08 03:50:26
Remove.
raymes
2015/01/08 22:08:21
Done.
| |
| 537 switch (message.data.type.toString()) { | 527 switch (message.data.type.toString()) { |
| 538 case 'getAccessibilityJSON': | 528 case 'getAccessibilityJSON': |
| 539 case 'loadPreviewPage': | 529 case 'loadPreviewPage': |
| 540 this.plugin_.postMessage(message.data); | 530 this.plugin_.postMessage(message.data); |
| 541 break; | 531 break; |
| 542 case 'resetPrintPreviewMode': | 532 case 'resetPrintPreviewMode': |
| 543 if (!this.inPrintPreviewMode_) { | 533 if (!this.inPrintPreviewMode_) { |
| 544 this.inPrintPreviewMode_ = true; | 534 this.inPrintPreviewMode_ = true; |
| 545 this.viewport_.fitToPage(); | 535 this.viewport_.fitToPage(); |
| 546 } | 536 } |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 568 pageCount: (message.data.modifiable ? | 558 pageCount: (message.data.modifiable ? |
| 569 message.data.pageNumbers.length : 0) | 559 message.data.pageNumbers.length : 0) |
| 570 }); | 560 }); |
| 571 break; | 561 break; |
| 572 case 'sendKeyEvent': | 562 case 'sendKeyEvent': |
| 573 var e = document.createEvent('Event'); | 563 var e = document.createEvent('Event'); |
| 574 e.initEvent('scriptingKeypress'); | 564 e.initEvent('scriptingKeypress'); |
| 575 e.keyCode = message.data.keyCode; | 565 e.keyCode = message.data.keyCode; |
| 576 this.handleKeyEvent_(e); | 566 this.handleKeyEvent_(e); |
| 577 break; | 567 break; |
| 568 case 'setParentWindow': | |
| 569 if (this.parentWindow_ != message.source) { | |
| 570 this.parentWindow_ = message.source; | |
| 571 // If the document has already loaded, we always send a message that | |
| 572 // indicates that so that the embedder is aware. | |
| 573 if (this.loaded_) { | |
| 574 this.sendScriptingMessage_({ | |
| 575 type: 'documentLoaded' | |
| 576 }); | |
| 577 } | |
| 578 } | |
| 579 break; | |
| 578 } | 580 } |
| 579 | |
| 580 }, | 581 }, |
| 581 | 582 |
| 582 /** | 583 /** |
| 583 * @private | 584 * @private |
| 584 * Send a scripting message outside the extension (typically to | 585 * Send a scripting message outside the extension (typically to |
| 585 * PDFScriptingAPI in a page containing the extension). | 586 * PDFScriptingAPI in a page containing the extension). |
| 586 * @param {Object} message the message to send. | 587 * @param {Object} message the message to send. |
| 587 */ | 588 */ |
| 588 sendScriptingMessage_: function(message) { | 589 sendScriptingMessage_: function(message) { |
| 589 window.parent.postMessage(message, '*'); | 590 if (this.parentWindow_) |
| 591 this.parentWindow_.postMessage(message, '*'); | |
| 590 }, | 592 }, |
| 591 | 593 |
| 592 /** | 594 /** |
| 593 * @private | 595 * @private |
| 594 * Return whether this PDFViewer should manage zoom for its containing page. | 596 * Return whether this PDFViewer should manage zoom for its containing page. |
| 595 * @return {boolean} Whether this PDFViewer should manage zoom for its | 597 * @return {boolean} Whether this PDFViewer should manage zoom for its |
| 596 * containing page. | 598 * containing page. |
| 597 */ | 599 */ |
| 598 shouldManageZoom_: function() { | 600 shouldManageZoom_: function() { |
| 599 return !!(chrome.tabs && !this.streamDetails.embedded && | 601 return !!(chrome.tabs && !this.streamDetails_.embedded && |
| 600 this.streamDetails.tabId != -1); | 602 this.streamDetails_.tabId != -1); |
| 601 }, | 603 }, |
| 602 | 604 |
| 603 /** | 605 /** |
| 604 * @type {Viewport} the viewport of the PDF viewer. | 606 * @type {Viewport} the viewport of the PDF viewer. |
| 605 */ | 607 */ |
| 606 get viewport() { | 608 get viewport() { |
| 607 return this.viewport_; | 609 return this.viewport_; |
| 608 } | 610 } |
| 609 }; | 611 }; |
| OLD | NEW |