1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// found in the LICENSE file.
4a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)'use strict';
6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
7a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch<include src="../../../../ui/webui/resources/js/util.js">
8a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch<include src="pdf_scripting_api.js">
9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)<include src="viewport.js">
10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
11c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch/**
12010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) * @return {number} Width of a scrollbar in pixels
13010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) */
14010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)function getScrollbarWidth() {
15010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  var div = document.createElement('div');
16010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  div.style.visibility = 'hidden';
17010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  div.style.overflow = 'scroll';
18010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  div.style.width = '50px';
19010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  div.style.height = '50px';
20010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  div.style.position = 'absolute';
21010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  document.body.appendChild(div);
22010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  var result = div.offsetWidth - div.clientWidth;
23010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  div.parentNode.removeChild(div);
24010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return result;
25010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
26010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
27010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)/**
28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * The minimum number of pixels to offset the toolbar by from the bottom and
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * right side of the screen.
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)PDFViewer.MIN_TOOLBAR_OFFSET = 15;
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/**
34c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * Creates a new PDFViewer. There should only be one of these objects per
35c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * document.
36c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch */
37c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochfunction PDFViewer() {
386d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  this.loaded = false;
396d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
40c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // The sizer element is placed behind the plugin element to cause scrollbars
41c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // to be displayed in the window. It is sized according to the document size
42c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // of the pdf and zoom level.
43c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  this.sizer_ = $('sizer');
44c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  this.toolbar_ = $('toolbar');
45c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  this.pageIndicator_ = $('page-indicator');
46c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  this.progressBar_ = $('progress-bar');
47c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  this.passwordScreen_ = $('password-screen');
48c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  this.passwordScreen_.addEventListener('password-submitted',
49c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                        this.onPasswordSubmitted_.bind(this));
50c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  this.errorScreen_ = $('error-screen');
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
52c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Create the viewport.
53c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  this.viewport_ = new Viewport(window,
54c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                this.sizer_,
55010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                this.viewportChangedCallback_.bind(this),
56010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                getScrollbarWidth());
57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
58c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Create the plugin object dynamically so we can set its src. The plugin
59c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // element is sized to fill the entire window and is set to be fixed
60c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // positioning, acting as a viewport. The plugin renders into this viewport
61c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // according to the scroll position of the window.
62c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  this.plugin_ = document.createElement('object');
63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // NOTE: The plugin's 'id' field must be set to 'plugin' since
64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // chrome/renderer/printing/print_web_view_helper.cc actually references it.
65c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  this.plugin_.id = 'plugin';
66c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  this.plugin_.type = 'application/x-google-chrome-pdf';
67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  this.plugin_.addEventListener('message', this.handlePluginMessage_.bind(this),
68c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                false);
69a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Handle scripting messages from outside the extension that wish to interact
71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // with it. We also send a message indicating that extension has loaded and
72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // is ready to receive messages.
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  window.addEventListener('message', this.handleScriptingMessage_.bind(this),
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          false);
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  this.sendScriptingMessage_({type: 'readyToReceive'});
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
77a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // If the viewer is started from a MIME type request, there will be a
78a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // background page and stream details object with the details of the request.
79a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // Otherwise, we take the query string of the URL to indicate the URL of the
80a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // PDF to load. This is used for print preview in particular.
815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (chrome.extension.getBackgroundPage &&
825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      chrome.extension.getBackgroundPage()) {
83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    this.streamDetails =
84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        chrome.extension.getBackgroundPage().popStreamDetails();
855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
86a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!this.streamDetails) {
88a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // The URL of this page will be of the form
89a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // "chrome-extension://<extension id>?<pdf url>". We pull out the <pdf url>
90a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // part here.
91a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    var url = window.location.search.substring(1);
92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    this.streamDetails = {
93a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      streamUrl: url,
94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      originalUrl: url,
95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      responseHeaders: ''
96a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    };
97a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
98a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  this.plugin_.setAttribute('src', this.streamDetails.originalUrl);
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  this.plugin_.setAttribute('stream-url', this.streamDetails.streamUrl);
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  var headers = '';
102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (var header in this.streamDetails.responseHeaders) {
103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    headers += header + ': ' +
104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        this.streamDetails.responseHeaders[header] + '\n';
105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  this.plugin_.setAttribute('headers', headers);
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
108010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (window.top == window)
109010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    this.plugin_.setAttribute('full-frame', '');
110c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  document.body.appendChild(this.plugin_);
111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Setup the button event listeners.
113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  $('fit-to-width-button').addEventListener('click',
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      this.viewport_.fitToWidth.bind(this.viewport_));
115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  $('fit-to-page-button').addEventListener('click',
116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      this.viewport_.fitToPage.bind(this.viewport_));
117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  $('zoom-in-button').addEventListener('click',
118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      this.viewport_.zoomIn.bind(this.viewport_));
119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  $('zoom-out-button').addEventListener('click',
120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      this.viewport_.zoomOut.bind(this.viewport_));
121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  $('save-button-link').href = this.streamDetails.originalUrl;
122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  $('print-button').addEventListener('click', this.print_.bind(this));
123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Setup the keyboard event listener.
125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  document.onkeydown = this.handleKeyEvent_.bind(this);
126c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
128c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochPDFViewer.prototype = {
129c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  /**
130c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch   * @private
131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)   * Handle key events. These may come from the user directly or via the
132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)   * scripting API.
133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)   * @param {KeyboardEvent} e the event to handle.
134c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch   */
135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  handleKeyEvent_: function(e) {
136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    var position = this.viewport_.position;
137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Certain scroll events may be sent from outside of the extension.
138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    var fromScriptingAPI = e.type == 'scriptingKeypress';
139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    switch (e.keyCode) {
141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case 33:  // Page up key.
142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        // Go to the previous page if we are fit-to-page.
143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        if (this.viewport_.fittingType == Viewport.FittingType.FIT_TO_PAGE) {
144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          this.viewport_.goToPage(this.viewport_.getMostVisiblePage() - 1);
145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          // Since we do the movement of the page.
146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          e.preventDefault();
147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        } else if (fromScriptingAPI) {
148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          position.y -= this.viewport.size.height;
149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          this.viewport.position = position;
150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        }
151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        return;
152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case 34:  // Page down key.
153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        // Go to the next page if we are fit-to-page.
154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        if (this.viewport_.fittingType == Viewport.FittingType.FIT_TO_PAGE) {
155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          this.viewport_.goToPage(this.viewport_.getMostVisiblePage() + 1);
156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          // Since we do the movement of the page.
157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          e.preventDefault();
158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        } else if (fromScriptingAPI) {
159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          position.y += this.viewport.size.height;
160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          this.viewport.position = position;
161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        }
162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        return;
163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case 37:  // Left arrow key.
164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        // Go to the previous page if there are no horizontal scrollbars.
165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        if (!this.viewport_.documentHasScrollbars().x) {
166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          this.viewport_.goToPage(this.viewport_.getMostVisiblePage() - 1);
167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          // Since we do the movement of the page.
168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          e.preventDefault();
169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        } else if (fromScriptingAPI) {
170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          position.x -= Viewport.SCROLL_INCREMENT;
171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          this.viewport.position = position;
172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        }
173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        return;
174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case 38:  // Up arrow key.
175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        if (fromScriptingAPI) {
176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          position.y -= Viewport.SCROLL_INCREMENT;
177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          this.viewport.position = position;
178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        }
179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        return;
180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case 39:  // Right arrow key.
181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        // Go to the next page if there are no horizontal scrollbars.
182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        if (!this.viewport_.documentHasScrollbars().x) {
183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          this.viewport_.goToPage(this.viewport_.getMostVisiblePage() + 1);
184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          // Since we do the movement of the page.
185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          e.preventDefault();
186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        } else if (fromScriptingAPI) {
187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          position.x += Viewport.SCROLL_INCREMENT;
188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          this.viewport.position = position;
189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        }
190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        return;
191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case 40:  // Down arrow key.
192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        if (fromScriptingAPI) {
193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          position.y += Viewport.SCROLL_INCREMENT;
194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          this.viewport.position = position;
195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        }
196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        return;
197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case 187:  // +/= key.
198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case 107:  // Numpad + key.
199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        if (e.ctrlKey || e.metaKey) {
200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          this.viewport_.zoomIn();
201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          // Since we do the zooming of the page.
202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          e.preventDefault();
203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        }
204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        return;
205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case 189:  // -/_ key.
206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case 109:  // Numpad - key.
207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        if (e.ctrlKey || e.metaKey) {
208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          this.viewport_.zoomOut();
209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          // Since we do the zooming of the page.
210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          e.preventDefault();
211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        }
212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        return;
213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case 83:  // s key.
214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        if (e.ctrlKey || e.metaKey) {
215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          // Simulate a click on the button so that the <a download ...>
216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          // attribute is used.
217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          $('save-button-link').click();
218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          // Since we do the saving of the page.
219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          e.preventDefault();
220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        }
221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        return;
222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case 80:  // p key.
223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        if (e.ctrlKey || e.metaKey) {
224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          this.print_();
225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          // Since we do the printing of the page.
226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          e.preventDefault();
227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        }
228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        return;
229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
230c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  },
231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
232c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  /**
233c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch   * @private
234c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch   * Notify the plugin to print.
235c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch   */
236c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  print_: function() {
237c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    this.plugin_.postMessage({
238c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      type: 'print',
239c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    });
240c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  },
241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
242c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  /**
243c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch   * @private
244c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch   * Update the loading progress of the document in response to a progress
245c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch   * message being received from the plugin.
246c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch   * @param {number} progress the progress as a percentage.
247c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch   */
248c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  updateProgress_: function(progress) {
249c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    this.progressBar_.progress = progress;
250c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    if (progress == -1) {
251c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      // Document load failed.
252c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      this.errorScreen_.style.visibility = 'visible';
253c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      this.sizer_.style.display = 'none';
254c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      this.toolbar_.style.visibility = 'hidden';
255c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      if (this.passwordScreen_.active) {
256c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        this.passwordScreen_.deny();
257c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        this.passwordScreen_.active = false;
258c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      }
259a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    } else if (progress == 100) {
260a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      // Document load complete.
2616d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      this.loaded = true;
2625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      var loadEvent = new Event('pdfload');
2635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      window.dispatchEvent(loadEvent);
264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      this.sendScriptingMessage_({
265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        type: 'documentLoaded'
266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      });
267a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      if (this.lastViewportPosition_)
268a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        this.viewport_.position = this.lastViewportPosition_;
269c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    }
270c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  },
271a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
272c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  /**
273c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch   * @private
274c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch   * An event handler for handling password-submitted events. These are fired
275c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch   * when an event is entered into the password screen.
276c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch   * @param {Object} event a password-submitted event.
277c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch   */
278c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  onPasswordSubmitted_: function(event) {
279c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    this.plugin_.postMessage({
280c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      type: 'getPasswordComplete',
281c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      password: event.detail.password
282c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    });
283c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  },
284a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
285c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  /**
286c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch   * @private
287c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch   * An event handler for handling message events received from the plugin.
288c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch   * @param {MessageObject} message a message event.
289c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch   */
290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  handlePluginMessage_: function(message) {
291c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    switch (message.data.type.toString()) {
292c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      case 'documentDimensions':
293c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        this.documentDimensions_ = message.data;
294c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        this.viewport_.setDocumentDimensions(this.documentDimensions_);
295c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        this.toolbar_.style.visibility = 'visible';
296c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        // If we received the document dimensions, the password was good so we
297c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        // can dismiss the password screen.
298c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        if (this.passwordScreen_.active)
299c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          this.passwordScreen_.accept();
300a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
301c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        this.pageIndicator_.initialFadeIn();
302c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        this.toolbar_.initialFadeIn();
303c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        break;
304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case 'email':
305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        var href = 'mailto:' + message.data.to + '?cc=' + message.data.cc +
306cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            '&bcc=' + message.data.bcc + '&subject=' + message.data.subject +
307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            '&body=' + message.data.body;
308cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        var w = window.open(href, '_blank', 'width=1,height=1');
309cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        if (w)
310cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          w.close();
311cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        break;
312cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case 'getAccessibilityJSONReply':
313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        this.sendScriptingMessage_(message.data);
314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        break;
315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case 'getPassword':
316cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        // If the password screen isn't up, put it up. Otherwise we're
317cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        // responding to an incorrect password so deny it.
318cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        if (!this.passwordScreen_.active)
319cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          this.passwordScreen_.active = true;
320cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        else
321cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          this.passwordScreen_.deny();
322c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        break;
323c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      case 'goToPage':
324c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        this.viewport_.goToPage(message.data.page);
325c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        break;
326cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case 'loadProgress':
327cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        this.updateProgress_(message.data.progress);
328cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        break;
329cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case 'navigate':
330cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        if (message.data.newTab)
331cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          window.open(message.data.url);
332cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        else
333cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          window.location.href = message.data.url;
334cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        break;
335a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      case 'setScrollPosition':
336a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        var position = this.viewport_.position;
337a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        if (message.data.x != undefined)
338a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          position.x = message.data.x;
339a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        if (message.data.y != undefined)
340a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          position.y = message.data.y;
341a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        this.viewport_.position = position;
342a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        break;
3435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      case 'setTranslatedStrings':
3445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        this.passwordScreen_.text = message.data.getPasswordString;
3455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        this.progressBar_.text = message.data.loadingString;
3465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        this.errorScreen_.text = message.data.loadFailedString;
3475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        break;
348cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case 'cancelStreamUrl':
349cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        chrome.streamsPrivate.abort(this.streamDetails.streamUrl);
350cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        break;
351c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    }
352c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  },
353a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
354c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  /**
355c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch   * @private
356c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch   * A callback that's called when the viewport changes.
357c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch   */
358a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  viewportChangedCallback_: function() {
359a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    if (!this.documentDimensions_)
360a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      return;
361a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
362a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // Update the buttons selected.
363a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    $('fit-to-page-button').classList.remove('polymer-selected');
364a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    $('fit-to-width-button').classList.remove('polymer-selected');
365a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    if (this.viewport_.fittingType == Viewport.FittingType.FIT_TO_PAGE) {
366a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      $('fit-to-page-button').classList.add('polymer-selected');
367a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    } else if (this.viewport_.fittingType ==
368a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch               Viewport.FittingType.FIT_TO_WIDTH) {
369a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      $('fit-to-width-button').classList.add('polymer-selected');
370a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    }
371a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
372a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    var hasScrollbars = this.viewport_.documentHasScrollbars();
373a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    var scrollbarWidth = this.viewport_.scrollbarWidth;
374c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // Offset the toolbar position so that it doesn't move if scrollbars appear.
375cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    var toolbarRight = Math.max(PDFViewer.MIN_TOOLBAR_OFFSET, scrollbarWidth);
376cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    var toolbarBottom = Math.max(PDFViewer.MIN_TOOLBAR_OFFSET, scrollbarWidth);
377cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (hasScrollbars.vertical)
378cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      toolbarRight -= scrollbarWidth;
379cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (hasScrollbars.horizontal)
380cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      toolbarBottom -= scrollbarWidth;
381c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    this.toolbar_.style.right = toolbarRight + 'px';
382c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    this.toolbar_.style.bottom = toolbarBottom + 'px';
383a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
384a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // Update the page indicator.
385cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    var visiblePage = this.viewport_.getMostVisiblePage();
386cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    this.pageIndicator_.index = visiblePage;
3870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (this.documentDimensions_.pageDimensions.length > 1 &&
3880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        hasScrollbars.vertical) {
389c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      this.pageIndicator_.style.visibility = 'visible';
3900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    } else {
391c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      this.pageIndicator_.style.visibility = 'hidden';
3920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
393a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
394a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    var position = this.viewport_.position;
395a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    var zoom = this.viewport_.zoom;
396c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // Notify the plugin of the viewport change.
397c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    this.plugin_.postMessage({
398c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      type: 'viewport',
399c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      zoom: zoom,
400a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      xOffset: position.x,
401a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      yOffset: position.y
402c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    });
403cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
404cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    var visiblePageDimensions = this.viewport_.getPageScreenRect(visiblePage);
405cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    var size = this.viewport_.size;
406cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    this.sendScriptingMessage_({
407cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      type: 'viewport',
408cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      pageX: visiblePageDimensions.x,
409cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      pageY: visiblePageDimensions.y,
410cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      pageWidth: visiblePageDimensions.width,
411cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      viewportWidth: size.width,
412cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      viewportHeight: size.height,
413cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    });
414c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  },
415a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
416a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  /**
417cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)   * @private
418cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)   * Handle a scripting message from outside the extension (typically sent by
419cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)   * PDFScriptingAPI in a page containing the extension) to interact with the
420cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)   * plugin.
421cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)   * @param {MessageObject} message the message to handle.
422a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch   */
423cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  handleScriptingMessage_: function(message) {
424cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    switch (message.data.type.toString()) {
425cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case 'getAccessibilityJSON':
426cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case 'loadPreviewPage':
427cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        this.plugin_.postMessage(message.data);
428cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        break;
429cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case 'resetPrintPreviewMode':
430cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        if (!this.inPrintPreviewMode_) {
431cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          this.inPrintPreviewMode_ = true;
432cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          this.viewport_.fitToPage();
433cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        }
434cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
435cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        // Stash the scroll location so that it can be restored when the new
436cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        // document is loaded.
437cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        this.lastViewportPosition_ = this.viewport_.position;
438cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
439cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        // TODO(raymes): Disable these properly in the plugin.
440cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        var printButton = $('print-button');
441cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        if (printButton)
442cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          printButton.parentNode.removeChild(printButton);
443cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        var saveButton = $('save-button');
444cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        if (saveButton)
445cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          saveButton.parentNode.removeChild(saveButton);
446cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
447cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        this.pageIndicator_.pageLabels = message.data.pageNumbers;
448cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
449cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        this.plugin_.postMessage({
450cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          type: 'resetPrintPreviewMode',
451cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          url: message.data.url,
452cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          grayscale: message.data.grayscale,
453cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          // If the PDF isn't modifiable we send 0 as the page count so that no
454cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          // blank placeholder pages get appended to the PDF.
455cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          pageCount: (message.data.modifiable ?
456cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                      message.data.pageNumbers.length : 0)
457cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        });
458cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        break;
459cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case 'sendKeyEvent':
460cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        var e = document.createEvent('Event');
461cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        e.initEvent('scriptingKeypress');
462cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        e.keyCode = message.data.keyCode;
463cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        this.handleKeyEvent_(e);
464cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        break;
465a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    }
466a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
467a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  },
468a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
469a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  /**
470cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)   * @private
471cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)   * Send a scripting message outside the extension (typically to
472cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)   * PDFScriptingAPI in a page containing the extension).
473cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)   * @param {Object} message the message to send.
474a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch   */
475cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  sendScriptingMessage_: function(message) {
476cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    window.parent.postMessage(message, '*');
477a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  },
478a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
479a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  /**
480a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch   * @type {Viewport} the viewport of the PDF viewer.
481a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch   */
482a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  get viewport() {
483a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return this.viewport_;
484a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
4855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu};
486a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
4875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvar viewer = new PDFViewer();
488