Index: chrome/browser/resources/pdf/pdf.js |
diff --git a/chrome/browser/resources/pdf/pdf.js b/chrome/browser/resources/pdf/pdf.js |
index 88e3d26bc5ee57ec2f9146b5605513fb2deda1ae..5e970849f0df5f2973e6634a6bb9854baa4512ec 100644 |
--- a/chrome/browser/resources/pdf/pdf.js |
+++ b/chrome/browser/resources/pdf/pdf.js |
@@ -39,12 +39,11 @@ PDFViewer.MIN_TOOLBAR_OFFSET = 15; |
/** |
* Creates a new PDFViewer. There should only be one of these objects per |
* document. |
- * @param {Object} streamDetails The stream object which points to the data |
- * contained in the PDF. |
*/ |
-function PDFViewer(streamDetails) { |
- this.streamDetails = streamDetails; |
- this.loaded = false; |
+function PDFViewer() { |
+ this.pluginLoaded_ = false; |
+ this.documentLoaded_ = false; |
Sam McNally
2015/01/06 05:31:03
The public "loaded" property is still used by the
raymes
2015/01/07 03:17:58
I removed the use of it.
|
+ |
// The sizer element is placed behind the plugin element to cause scrollbars |
// to be displayed in the window. It is sized according to the document size |
@@ -54,110 +53,117 @@ function PDFViewer(streamDetails) { |
this.pageIndicator_ = $('page-indicator'); |
this.progressBar_ = $('progress-bar'); |
this.passwordScreen_ = $('password-screen'); |
- this.passwordScreen_.addEventListener('password-submitted', |
- this.onPasswordSubmitted_.bind(this)); |
this.errorScreen_ = $('error-screen'); |
- // Create the viewport. |
- this.viewport_ = new Viewport(window, |
- this.sizer_, |
- this.viewportChanged_.bind(this), |
- this.beforeZoom_.bind(this), |
- this.afterZoom_.bind(this), |
- getScrollbarWidth()); |
- var isPrintPreview = |
- this.streamDetails.originalUrl.indexOf('chrome://print') == 0; |
- // Create the plugin object dynamically so we can set its src. The plugin |
- // element is sized to fill the entire window and is set to be fixed |
- // positioning, acting as a viewport. The plugin renders into this viewport |
- // according to the scroll position of the window. |
- // |
- // TODO(sammc): Remove special casing for print preview. This is currently |
- // necessary because setting the src for an embed element triggers origin |
- // checking and the PDF extension is not allowed to embed URLs with a scheme |
- // of "chrome", which is used by print preview. |
- this.plugin_ = document.createElement(isPrintPreview ? 'object' : 'embed'); |
- // NOTE: The plugin's 'id' field must be set to 'plugin' since |
- // chrome/renderer/printing/print_web_view_helper.cc actually references it. |
- this.plugin_.id = 'plugin'; |
- this.plugin_.type = 'application/x-google-chrome-pdf'; |
- this.plugin_.addEventListener('message', this.handlePluginMessage_.bind(this), |
- false); |
- |
// Handle scripting messages from outside the extension that wish to interact |
- // with it. We also send a message indicating that extension has loaded and |
- // is ready to receive messages. |
+ // with it. |
window.addEventListener('message', this.handleScriptingMessage_.bind(this), |
false); |
- this.sendScriptingMessage_({type: 'readyToReceive'}); |
- |
- document.title = getFilenameFromURL(this.streamDetails.originalUrl); |
- this.plugin_.setAttribute('src', this.streamDetails.originalUrl); |
- this.plugin_.setAttribute('stream-url', this.streamDetails.streamUrl); |
- var headers = ''; |
- for (var header in this.streamDetails.responseHeaders) { |
- headers += header + ': ' + |
- this.streamDetails.responseHeaders[header] + '\n'; |
- } |
- this.plugin_.setAttribute('headers', headers); |
- |
- if (!this.streamDetails.embedded) |
- this.plugin_.setAttribute('full-frame', ''); |
- document.body.appendChild(this.plugin_); |
- |
- // TODO(raymes): Remove this spurious message once crbug.com/388606 is fixed. |
- // This is a hack to initialize pepper sync scripting and avoid re-entrancy. |
- this.plugin_.postMessage({ |
- type: 'viewport', |
- zoom: 1, |
- xOffset: 0, |
- yOffset: 0 |
- }); |
- |
- // Setup the button event listeners. |
- $('fit-to-width-button').addEventListener('click', |
- this.viewport_.fitToWidth.bind(this.viewport_)); |
- $('fit-to-page-button').addEventListener('click', |
- this.viewport_.fitToPage.bind(this.viewport_)); |
- $('zoom-in-button').addEventListener('click', |
- this.viewport_.zoomIn.bind(this.viewport_)); |
- $('zoom-out-button').addEventListener('click', |
- this.viewport_.zoomOut.bind(this.viewport_)); |
- $('save-button').addEventListener('click', this.save_.bind(this)); |
- $('print-button').addEventListener('click', this.print_.bind(this)); |
- |
- // Setup the keyboard event listener. |
- document.onkeydown = this.handleKeyEvent_.bind(this); |
- |
- // Set up the zoom API. |
- if (this.shouldManageZoom_()) { |
- chrome.tabs.setZoomSettings(this.streamDetails.tabId, |
- {mode: 'manual', scope: 'per-tab'}, |
- this.afterZoom_.bind(this)); |
- chrome.tabs.onZoomChange.addListener(function(zoomChangeInfo) { |
- if (zoomChangeInfo.tabId != this.streamDetails.tabId) |
- return; |
- // If the zoom level is close enough to the current zoom level, don't |
- // change it. This avoids us getting into an infinite loop of zoom changes |
- // due to floating point error. |
- var MIN_ZOOM_DELTA = 0.01; |
- var zoomDelta = Math.abs(this.viewport_.zoom - |
- zoomChangeInfo.newZoomFactor); |
- // We should not change zoom level when we are responsible for initiating |
- // the zoom. onZoomChange() is called before setZoomComplete() callback |
- // when we initiate the zoom. |
- if ((zoomDelta > MIN_ZOOM_DELTA) && !this.setZoomInProgress_) |
- this.viewport_.setZoom(zoomChangeInfo.newZoomFactor); |
- }.bind(this)); |
- } |
- |
- // Parse open pdf parameters. |
- var paramsParser = new OpenPDFParamsParser(this.streamDetails.originalUrl); |
- this.urlParams_ = paramsParser.urlParams; |
} |
PDFViewer.prototype = { |
/** |
+ * Initialize the PDF viewer with the details of the stream object pointing to |
+ * the PDF data. |
+ * @param {Object} streamDetails The stream object which points to the data |
+ * contained in the PDF. |
+ */ |
+ init: function(streamDetails) { |
Sam McNally
2015/01/06 05:31:04
How about setStreamDetails?
raymes
2015/01/07 03:17:57
I ended up not needing the init function so I've g
|
+ this.streamDetails_ = streamDetails; |
+ |
+ // Create the viewport. |
+ this.viewport_ = new Viewport(window, |
+ this.sizer_, |
+ this.viewportChanged_.bind(this), |
+ this.beforeZoom_.bind(this), |
+ this.afterZoom_.bind(this), |
+ getScrollbarWidth()); |
+ |
+ document.title = getFilenameFromURL(this.streamDetails_.originalUrl); |
+ |
+ var isPrintPreview = |
+ this.streamDetails_.originalUrl.indexOf('chrome://print') == 0; |
+ // Create the plugin object dynamically so we can set its src. The plugin |
+ // element is sized to fill the entire window and is set to be fixed |
+ // positioning, acting as a viewport. The plugin renders into this viewport |
+ // according to the scroll position of the window. |
+ // |
+ // TODO(sammc): Remove special casing for print preview. This is currently |
+ // necessary because setting the src for an embed element triggers origin |
+ // checking and the PDF extension is not allowed to embed URLs with a scheme |
+ // of "chrome", which is used by print preview. |
+ this.plugin_ = document.createElement(isPrintPreview ? 'object' : 'embed'); |
+ // NOTE: The plugin's 'id' field must be set to 'plugin' since |
+ // chrome/renderer/printing/print_web_view_helper.cc actually references it. |
+ this.plugin_.id = 'plugin'; |
+ this.plugin_.type = 'application/x-google-chrome-pdf'; |
+ this.plugin_.addEventListener('message', |
+ this.handlePluginMessage_.bind(this), false); |
+ this.plugin_.setAttribute('src', this.streamDetails_.originalUrl); |
+ this.plugin_.setAttribute('stream-url', this.streamDetails_.streamUrl); |
+ var headers = ''; |
+ for (var header in this.streamDetails_.responseHeaders) { |
+ headers += header + ': ' + |
+ this.streamDetails_.responseHeaders[header] + '\n'; |
+ } |
+ this.plugin_.setAttribute('headers', headers); |
+ |
+ if (!this.streamDetails_.embedded) |
+ this.plugin_.setAttribute('full-frame', ''); |
+ document.body.appendChild(this.plugin_); |
+ |
+ // Add the password event listener. |
+ this.passwordScreen_.addEventListener('password-submitted', |
+ this.onPasswordSubmitted_.bind(this)); |
+ |
+ // Setup the button event listeners. |
+ $('fit-to-width-button').addEventListener('click', |
+ this.viewport_.fitToWidth.bind(this.viewport_)); |
+ $('fit-to-page-button').addEventListener('click', |
+ this.viewport_.fitToPage.bind(this.viewport_)); |
+ $('zoom-in-button').addEventListener('click', |
+ this.viewport_.zoomIn.bind(this.viewport_)); |
+ $('zoom-out-button').addEventListener('click', |
+ this.viewport_.zoomOut.bind(this.viewport_)); |
+ $('save-button').addEventListener('click', this.save_.bind(this)); |
+ $('print-button').addEventListener('click', this.print_.bind(this)); |
+ |
+ // Setup the keyboard event listener. |
+ document.onkeydown = this.handleKeyEvent_.bind(this); |
+ |
+ // Set up the zoom API. |
+ if (this.shouldManageZoom_()) { |
+ chrome.tabs.setZoomSettings(this.streamDetails_.tabId, |
+ {mode: 'manual', scope: 'per-tab'}, |
+ this.afterZoom_.bind(this)); |
+ chrome.tabs.onZoomChange.addListener(function(zoomChangeInfo) { |
+ if (zoomChangeInfo.tabId != this.streamDetails_.tabId) |
+ return; |
+ // If the zoom level is close enough to the current zoom level, don't |
+ // change it. This avoids us getting into an infinite loop of zoom |
+ // changes due to floating point error. |
+ var MIN_ZOOM_DELTA = 0.01; |
+ var zoomDelta = Math.abs(this.viewport_.zoom - |
+ zoomChangeInfo.newZoomFactor); |
+ // We should not change zoom level when we are responsible for |
+ // initiating the zoom. onZoomChange() is called before |
+ // setZoomComplete() callback when we initiate the zoom. |
+ if ((zoomDelta > MIN_ZOOM_DELTA) && !this.setZoomInProgress_) |
+ this.viewport_.setZoom(zoomChangeInfo.newZoomFactor); |
+ }.bind(this)); |
+ } |
+ |
+ // Parse open pdf parameters. |
+ var paramsParser = new OpenPDFParamsParser(this.streamDetails_.originalUrl); |
+ this.urlParams_ = paramsParser.urlParams; |
+ |
+ this.pluginLoaded_ = true; |
+ this.sendScriptingMessage_({ |
+ type: 'readyToReceive' |
+ }); |
+ }, |
+ |
+ /** |
* @private |
* Handle key events. These may come from the user directly or via the |
* scripting API. |
@@ -331,9 +337,7 @@ PDFViewer.prototype = { |
if (this.lastViewportPosition_) |
this.viewport_.position = this.lastViewportPosition_; |
this.handleURLParams_(); |
- this.loaded = true; |
- var loadEvent = new Event('pdfload'); |
- window.dispatchEvent(loadEvent); |
+ this.documentLoaded_ = true; |
this.sendScriptingMessage_({ |
type: 'documentLoaded' |
}); |
@@ -417,7 +421,7 @@ PDFViewer.prototype = { |
this.errorScreen_.text = message.data.loadFailedString; |
break; |
case 'cancelStreamUrl': |
- chrome.streamsPrivate.abort(this.streamDetails.streamUrl); |
+ chrome.streamsPrivate.abort(this.streamDetails_.streamUrl); |
break; |
} |
}, |
@@ -443,7 +447,7 @@ PDFViewer.prototype = { |
var zoom = this.viewport_.zoom; |
if (this.shouldManageZoom_() && !this.setZoomInProgress_) { |
this.setZoomInProgress_ = true; |
- chrome.tabs.setZoom(this.streamDetails.tabId, zoom, |
+ chrome.tabs.setZoom(this.streamDetails_.tabId, zoom, |
this.setZoomComplete_.bind(this, zoom)); |
} |
this.plugin_.postMessage({ |
@@ -465,7 +469,7 @@ PDFViewer.prototype = { |
setZoomComplete_: function(lastZoom) { |
var zoom = this.viewport_.zoom; |
if (zoom != lastZoom) { |
- chrome.tabs.setZoom(this.streamDetails.tabId, zoom, |
+ chrome.tabs.setZoom(this.streamDetails_.tabId, zoom, |
this.setZoomComplete_.bind(this, zoom)); |
} else { |
this.setZoomInProgress_ = false; |
@@ -578,6 +582,15 @@ PDFViewer.prototype = { |
e.keyCode = message.data.keyCode; |
this.handleKeyEvent_(e); |
break; |
+ case 'setParentWindow': |
+ // Set the parent window to which messages will be sent. |
+ this.parentWindow_ = message.source; |
+ if (this.pluginLoaded_) { |
+ this.sendScriptingMessage_({ |
+ type: 'readyToReceive' |
+ }); |
+ } |
+ break; |
} |
}, |
@@ -589,7 +602,8 @@ PDFViewer.prototype = { |
* @param {Object} message the message to send. |
*/ |
sendScriptingMessage_: function(message) { |
- window.parent.postMessage(message, '*'); |
+ if (this.parentWindow_) |
Sam McNally
2015/01/06 05:31:03
Won't this lose messages?
raymes
2015/01/07 03:17:58
Yes, but that's ok. I've made it always send a doc
|
+ this.parentWindow_.postMessage(message, '*'); |
}, |
/** |
@@ -599,8 +613,8 @@ PDFViewer.prototype = { |
* containing page. |
*/ |
shouldManageZoom_: function() { |
- return !!(chrome.tabs && !this.streamDetails.embedded && |
- this.streamDetails.tabId != -1); |
+ return !!(chrome.tabs && !this.streamDetails_.embedded && |
+ this.streamDetails_.tabId != -1); |
}, |
/** |