Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(909)

Side by Side Diff: chrome/browser/resources/pdf/pdf.js

Issue 223363002: Convert the code in pdf.js to an object (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 (function() { 5 (function() {
6 'use strict'; 6 'use strict';
7 7
8 <include src="../../../../ui/webui/resources/js/util.js"></include> 8 <include src="../../../../ui/webui/resources/js/util.js"></include>
9 <include src="viewport.js"></include> 9 <include src="viewport.js"></include>
10 10
11 // The plugin element is sized to fill the entire window and is set to be fixed 11 /**
12 // positioning, acting as a viewport. The plugin renders into this viewport 12 * Creates a new PDFViewer.
13 // according to the scroll position of the window. 13 */
14 var plugin; 14 function PDFViewer() {
15 15 // The sizer element is placed behind the plugin element to cause scrollbars
16 // This element is placed behind the plugin element to cause scrollbars to be 16 // to be displayed in the window. It is sized according to the document size
17 // displayed in the window. It is sized according to the document size of the 17 // of the pdf and zoom level.
18 // pdf and zoom level. 18 this.sizer_ = $('sizer');
arv (Not doing code reviews) 2014/04/07 21:01:44 This pattern is a bit strange. You are creating a
raymes 2014/04/08 01:44:06 It is a bit weird. It would be less weird if the d
arv (Not doing code reviews) 2014/04/08 16:36:22 Now that I look at it. Why is everything private?
19 var sizer; 19 this.toolbar_ = $('toolbar');
20 20 this.pageIndicator_ = $('page-indicator');
21 // The toolbar element. 21 this.progressBar_ = $('progress-bar');
22 var viewerToolbar; 22 this.passwordScreen_ = $('password-screen');
23 23 this.passwordScreen_.addEventListener('password-submitted',
24 // The page indicator element. 24 this.onPasswordSubmitted_.bind(this));
25 var viewerPageIndicator; 25 this.errorScreen_ = $('error-screen');
26 26 this.errorScreen_.text = 'Failed to load PDF document';
27 // The progress bar element.
28 var viewerProgressBar;
29
30 // The element indicating there was an error loading the document.
31 var viewerErrorScreen;
32
33 // The viewport object.
34 var viewport;
35
36 // The element displaying the password screen.
37 var viewerPasswordScreen;
38
39 // The document dimensions.
40 var documentDimensions;
41
42 // Notify the plugin to print.
43 function print() {
44 plugin.postMessage({
45 type: 'print',
46 });
47 }
48
49 // Returns true if the fit-to-page button is enabled.
50 function isFitToPageEnabled() {
51 return $('fit-to-page-button').classList.contains('polymer-selected');
52 }
53
54 function updateProgress(progress) {
55 viewerProgressBar.progress = progress;
56 if (progress == -1) {
57 // Document load failed.
58 viewerErrorScreen.style.visibility = 'visible';
59 sizer.style.display = 'none';
60 viewerToolbar.style.visibility = 'hidden';
61 if (viewerPasswordScreen.active) {
62 viewerPasswordScreen.deny();
63 viewerPasswordScreen.active = false;
64 }
65 }
66 }
67
68 function onPasswordSubmitted(event) {
69 plugin.postMessage({
70 type: 'getPasswordComplete',
71 password: event.detail.password
72 });
73 }
74
75 // Called when a message is received from the plugin.
76 function handleMessage(message) {
77 switch (message.data.type.toString()) {
78 case 'documentDimensions':
79 documentDimensions = message.data;
80 viewport.setDocumentDimensions(documentDimensions);
81 viewerToolbar.style.visibility = 'visible';
82 // If we received the document dimensions, the password was good so we can
83 // dismiss the password screen.
84 if (viewerPasswordScreen.active)
85 viewerPasswordScreen.accept();
86
87 viewerPageIndicator.initialFadeIn();
88 viewerToolbar.initialFadeIn();
89 break;
90 case 'loadProgress':
91 updateProgress(message.data.progress);
92 break;
93 case 'goToPage':
94 viewport.goToPage(message.data.page);
95 break;
96 case 'getPassword':
97 // If the password screen isn't up, put it up. Otherwise we're responding
98 // to an incorrect password so deny it.
99 if (!viewerPasswordScreen.active)
100 viewerPasswordScreen.active = true;
101 else
102 viewerPasswordScreen.deny();
103 }
104 }
105
106 // Callback that's called when the viewport changes.
107 function viewportChangedCallback(zoom,
108 x,
109 y,
110 scrollbarWidth,
111 hasScrollbars,
112 page) {
113 // Offset the toolbar position so that it doesn't move if scrollbars appear.
114 var toolbarRight = hasScrollbars.y ? 0 : scrollbarWidth;
115 var toolbarBottom = hasScrollbars.x ? 0 : scrollbarWidth;
116 viewerToolbar.style.right = toolbarRight + 'px';
117 viewerToolbar.style.bottom = toolbarBottom + 'px';
118
119 // Show or hide the page indicator.
120 if (documentDimensions.pageDimensions.length > 1 && hasScrollbars.y)
121 viewerPageIndicator.style.visibility = 'visible';
122 else
123 viewerPageIndicator.style.visibility = 'hidden';
124
125 // Update the most visible page.
126 viewerPageIndicator.text = page + 1;
127
128 // Notify the plugin of the viewport change.
129 plugin.postMessage({
130 type: 'viewport',
131 zoom: zoom,
132 xOffset: x,
133 yOffset: y
134 });
135 }
136
137 function load() {
138 sizer = $('sizer');
139 viewerToolbar = $('toolbar');
140 viewerPageIndicator = $('page-indicator');
141 viewerProgressBar = $('progress-bar');
142 viewerPasswordScreen = $('password-screen');
143 viewerPasswordScreen.addEventListener('password-submitted',
144 onPasswordSubmitted);
145 viewerErrorScreen = $('error-screen');
146 viewerErrorScreen.text = 'Failed to load PDF document';
147 27
148 // Create the viewport. 28 // Create the viewport.
149 viewport = new Viewport(window, 29 this.viewport_ = new Viewport(window,
150 sizer, 30 this.sizer_,
151 isFitToPageEnabled, 31 this.isFitToPageEnabled_.bind(this),
152 viewportChangedCallback); 32 this.viewportChangedCallback_.bind(this));
153 33
154 // Create the plugin object dynamically so we can set its src. 34 // Create the plugin object dynamically so we can set its src. The plugin
155 plugin = document.createElement('object'); 35 // element is sized to fill the entire window and is set to be fixed
156 plugin.id = 'plugin'; 36 // positioning, acting as a viewport. The plugin renders into this viewport
157 plugin.type = 'application/x-google-chrome-pdf'; 37 // according to the scroll position of the window.
158 plugin.addEventListener('message', handleMessage, false); 38 this.plugin_ = document.createElement('object');
39 this.plugin_.id = 'plugin';
40 this.plugin_.type = 'application/x-google-chrome-pdf';
41 this.plugin_.addEventListener('message', this.handleMessage_.bind(this),
42 false);
159 // The pdf location is passed in stream details in the background page. 43 // The pdf location is passed in stream details in the background page.
160 var streamDetails = chrome.extension.getBackgroundPage().popStreamDetails(); 44 var streamDetails = chrome.extension.getBackgroundPage().popStreamDetails();
161 plugin.setAttribute('src', streamDetails.streamUrl); 45 this.plugin_.setAttribute('src', streamDetails.streamUrl);
162 document.body.appendChild(plugin); 46 document.body.appendChild(this.plugin_);
163 47
164 // Setup the button event listeners. 48 this.setupEventListeners_(streamDetails);
165 $('fit-to-width-button').addEventListener('click', 49 }
166 viewport.fitToWidth.bind(viewport)); 50
167 $('fit-to-page-button').addEventListener('click', 51 PDFViewer.prototype = {
168 viewport.fitToPage.bind(viewport)); 52 /**
169 $('zoom-in-button').addEventListener('click', 53 * @private
170 viewport.zoomIn.bind(viewport)); 54 * Sets up event listeners for key shortcuts and also the UI buttons.
171 $('zoom-out-button').addEventListener('click', 55 * @param {Object} streamDetails the details of the original HTTP request for
172 viewport.zoomOut.bind(viewport)); 56 * the PDF.
173 $('save-button-link').href = streamDetails.originalUrl; 57 */
174 $('print-button').addEventListener('click', print); 58 setupEventListeners_: function(streamDetails) {
175 59 // Setup the button event listeners.
176 60 $('fit-to-width-button').addEventListener('click',
177 // Setup keyboard event listeners. 61 this.viewport_.fitToWidth.bind(this.viewport_));
178 document.onkeydown = function(e) { 62 $('fit-to-page-button').addEventListener('click',
179 switch (e.keyCode) { 63 this.viewport_.fitToPage.bind(this.viewport_));
180 case 37: // Left arrow key. 64 $('zoom-in-button').addEventListener('click',
181 // Go to the previous page if there are no horizontal scrollbars. 65 this.viewport_.zoomIn.bind(this.viewport_));
182 if (!viewport.documentHasScrollbars().x) { 66 $('zoom-out-button').addEventListener('click',
183 viewport.goToPage(viewport.getMostVisiblePage() - 1); 67 this.viewport_.zoomOut.bind(this.viewport_));
184 // Since we do the movement of the page. 68 $('save-button-link').href = streamDetails.originalUrl;
185 e.preventDefault(); 69 $('print-button').addEventListener('click', this.print_.bind(this));
186 } 70
187 return; 71 // Setup keyboard event listeners.
188 case 33: // Page up key. 72 document.onkeydown = function(e) {
189 // Go to the previous page if we are fit-to-page. 73 switch (e.keyCode) {
190 if (isFitToPageEnabled()) { 74 case 37: // Left arrow key.
191 viewport.goToPage(viewport.getMostVisiblePage() - 1); 75 // Go to the previous page if there are no horizontal scrollbars.
192 // Since we do the movement of the page. 76 if (!this.viewport_.documentHasScrollbars().x) {
arv (Not doing code reviews) 2014/04/07 21:01:44 this is not lexically bound but dynamically bound.
raymes 2014/04/08 01:44:06 Good catch :) I bound the function.
193 e.preventDefault(); 77 this.viewport_.goToPage(this.viewport_.getMostVisiblePage() - 1);
194 } 78 // Since we do the movement of the page.
195 return; 79 e.preventDefault();
196 case 39: // Right arrow key. 80 }
197 // Go to the next page if there are no horizontal scrollbars. 81 return;
198 if (!viewport.documentHasScrollbars().x) { 82 case 33: // Page up key.
199 viewport.goToPage(viewport.getMostVisiblePage() + 1); 83 // Go to the previous page if we are fit-to-page.
200 // Since we do the movement of the page. 84 if (isFitToPageEnabled()) {
201 e.preventDefault(); 85 this.viewport_.goToPage(this.viewport_.getMostVisiblePage() - 1);
202 } 86 // Since we do the movement of the page.
203 return; 87 e.preventDefault();
204 case 34: // Page down key. 88 }
205 // Go to the next page if we are fit-to-page. 89 return;
206 if (isFitToPageEnabled()) { 90 case 39: // Right arrow key.
207 viewport.goToPage(viewport.getMostVisiblePage() + 1); 91 // Go to the next page if there are no horizontal scrollbars.
208 // Since we do the movement of the page. 92 if (!this.viewport_.documentHasScrollbars().x) {
209 e.preventDefault(); 93 this.viewport_.goToPage(this.viewport_.getMostVisiblePage() + 1);
210 } 94 // Since we do the movement of the page.
211 return; 95 e.preventDefault();
212 case 187: // +/= key. 96 }
213 case 107: // Numpad + key. 97 return;
214 if (e.ctrlKey || e.metaKey) { 98 case 34: // Page down key.
215 viewport.zoomIn(); 99 // Go to the next page if we are fit-to-page.
216 // Since we do the zooming of the page. 100 if (isFitToPageEnabled()) {
217 e.preventDefault(); 101 this.viewport_.goToPage(this.viewport_.getMostVisiblePage() + 1);
218 } 102 // Since we do the movement of the page.
219 return; 103 e.preventDefault();
220 case 189: // -/_ key. 104 }
221 case 109: // Numpad - key. 105 return;
222 if (e.ctrlKey || e.metaKey) { 106 case 187: // +/= key.
223 viewport.zoomOut(); 107 case 107: // Numpad + key.
224 // Since we do the zooming of the page. 108 if (e.ctrlKey || e.metaKey) {
225 e.preventDefault(); 109 this.viewport_.zoomIn();
226 } 110 // Since we do the zooming of the page.
227 return; 111 e.preventDefault();
228 case 83: // s key. 112 }
229 if (e.ctrlKey || e.metaKey) { 113 return;
230 // Simulate a click on the button so that the <a download ...> 114 case 189: // -/_ key.
231 // attribute is used. 115 case 109: // Numpad - key.
232 $('save-button-link').click(); 116 if (e.ctrlKey || e.metaKey) {
233 // Since we do the saving of the page. 117 this.viewport_.zoomOut();
234 e.preventDefault(); 118 // Since we do the zooming of the page.
235 } 119 e.preventDefault();
236 return; 120 }
237 case 80: // p key. 121 return;
238 if (e.ctrlKey || e.metaKey) { 122 case 83: // s key.
239 print(); 123 if (e.ctrlKey || e.metaKey) {
240 // Since we do the printing of the page. 124 // Simulate a click on the button so that the <a download ...>
241 e.preventDefault(); 125 // attribute is used.
242 } 126 $('save-button-link').click();
243 return; 127 // Since we do the saving of the page.
128 e.preventDefault();
129 }
130 return;
131 case 80: // p key.
132 if (e.ctrlKey || e.metaKey) {
133 this.print_();
134 // Since we do the printing of the page.
135 e.preventDefault();
136 }
137 return;
138 }
139 };
140 },
141
142
143 /**
144 * @private
145 * Notify the plugin to print.
146 */
147 print_: function() {
148 this.plugin_.postMessage({
149 type: 'print',
150 });
151 },
152
153 /**
154 * @private
155 * @return {boolean} true if the fit-to-page button is enabled.
156 */
157 isFitToPageEnabled_: function() {
158 return $('fit-to-page-button').classList.contains('polymer-selected');
159 },
160
161 /**
162 * @private
163 * Update the loading progress of the document in response to a progress
164 * message being received from the plugin.
165 * @param {number} progress the progress as a percentage.
166 */
167 updateProgress_: function(progress) {
168 this.progressBar_.progress = progress;
169 if (progress == -1) {
170 // Document load failed.
171 this.errorScreen_.style.visibility = 'visible';
172 this.sizer_.style.display = 'none';
173 this.toolbar_.style.visibility = 'hidden';
174 if (this.passwordScreen_.active) {
175 this.passwordScreen_.deny();
176 this.passwordScreen_.active = false;
177 }
244 } 178 }
245 }; 179 },
180
181 /**
182 * @private
183 * An event handler for handling password-submitted events. These are fired
184 * when an event is entered into the password screen.
185 * @param {Object} event a password-submitted event.
186 */
187 onPasswordSubmitted_: function(event) {
188 this.plugin_.postMessage({
189 type: 'getPasswordComplete',
190 password: event.detail.password
191 });
192 },
193
194 /**
195 * @private
196 * An event handler for handling message events received from the plugin.
197 * @param {Object} message a message event.
arv (Not doing code reviews) 2014/04/07 21:01:44 Maybe use {MessageEvent} as the type?
raymes 2014/04/08 01:44:06 Done.
198 */
199 handleMessage_: function(message) {
200 switch (message.data.type.toString()) {
201 case 'documentDimensions':
202 this.documentDimensions_ = message.data;
203 this.viewport_.setDocumentDimensions(this.documentDimensions_);
204 this.toolbar_.style.visibility = 'visible';
205 // If we received the document dimensions, the password was good so we
206 // can dismiss the password screen.
207 if (this.passwordScreen_.active)
208 this.passwordScreen_.accept();
209
210 this.pageIndicator_.initialFadeIn();
211 this.toolbar_.initialFadeIn();
212 break;
213 case 'loadProgress':
214 this.updateProgress_(message.data.progress);
215 break;
216 case 'goToPage':
217 this.viewport_.goToPage(message.data.page);
218 break;
219 case 'getPassword':
220 // If the password screen isn't up, put it up. Otherwise we're
221 // responding to an incorrect password so deny it.
222 if (!this.passwordScreen_.active)
223 this.passwordScreen_.active = true;
224 else
225 this.passwordScreen_.deny();
226 }
227 },
228
229 /**
230 * @private
231 * A callback that's called when the viewport changes.
232 * @param {number} zoom the zoom level.
233 * @param {number} x the x scroll coordinate.
234 * @param {number} y the y scroll coordinate.
235 * @param {number} scrollbarWidth the width of scrollbars on the page.
236 * @param {Object} hasScrollbars whether the viewport has a
237 * horizontal/vertical scrollbar.
238 * @param {number} page the index of the most visible page in the viewport.
239 */
240 viewportChangedCallback_: function(zoom,
241 x,
242 y,
243 scrollbarWidth,
244 hasScrollbars,
245 page) {
246 // Offset the toolbar position so that it doesn't move if scrollbars appear.
247 var toolbarRight = hasScrollbars.y ? 0 : scrollbarWidth;
248 var toolbarBottom = hasScrollbars.x ? 0 : scrollbarWidth;
249 this.toolbar_.style.right = toolbarRight + 'px';
250 this.toolbar_.style.bottom = toolbarBottom + 'px';
251
252 // Show or hide the page indicator.
253 if (this.documentDimensions_.pageDimensions.length > 1 && hasScrollbars.y)
254 this.pageIndicator_.style.visibility = 'visible';
255 else
256 this.pageIndicator_.style.visibility = 'hidden';
257
258 // Update the most visible page.
259 this.pageIndicator_.text = page + 1;
260
261 // Notify the plugin of the viewport change.
262 this.plugin_.postMessage({
263 type: 'viewport',
264 zoom: zoom,
265 xOffset: x,
266 yOffset: y
267 });
268 },
246 } 269 }
247 270
248 load(); 271 new PDFViewer();
249 272
250 })(); 273 })();
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698