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

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

Issue 823813002: Modify pdf_scripting_api.js to support postMessage using BrowserPlugin (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 11 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
« no previous file with comments | « chrome/browser/resources/pdf/main.js ('k') | chrome/browser/resources/pdf/pdf_scripting_api.js » ('j') | 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 '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
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
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
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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 position.y = message.data.y; 398 position.y = message.data.y;
410 this.viewport_.position = position; 399 this.viewport_.position = position;
411 break; 400 break;
412 case 'setTranslatedStrings': 401 case 'setTranslatedStrings':
413 this.passwordScreen_.text = message.data.getPasswordString; 402 this.passwordScreen_.text = message.data.getPasswordString;
414 this.progressBar_.text = message.data.loadingString; 403 this.progressBar_.text = message.data.loadingString;
415 this.progressBar_.style.visibility = 'visible'; 404 this.progressBar_.style.visibility = 'visible';
416 this.errorScreen_.text = message.data.loadFailedString; 405 this.errorScreen_.text = message.data.loadFailedString;
417 break; 406 break;
418 case 'cancelStreamUrl': 407 case 'cancelStreamUrl':
419 chrome.streamsPrivate.abort(this.streamDetails.streamUrl); 408 chrome.streamsPrivate.abort(this.streamDetails_.streamUrl);
420 break; 409 break;
421 } 410 }
422 }, 411 },
423 412
424 /** 413 /**
425 * @private 414 * @private
426 * A callback that's called before the zoom changes. Notify the plugin to stop 415 * A callback that's called before the zoom changes. Notify the plugin to stop
427 * reacting to scroll events while zoom is taking place to avoid flickering. 416 * reacting to scroll events while zoom is taking place to avoid flickering.
428 */ 417 */
429 beforeZoom_: function() { 418 beforeZoom_: function() {
430 this.plugin_.postMessage({ 419 this.plugin_.postMessage({
431 type: 'stopScrolling' 420 type: 'stopScrolling'
432 }); 421 });
433 }, 422 },
434 423
435 /** 424 /**
436 * @private 425 * @private
437 * A callback that's called after the zoom changes. Notify the plugin of the 426 * A callback that's called after the zoom changes. Notify the plugin of the
438 * zoom change and to continue reacting to scroll events. 427 * zoom change and to continue reacting to scroll events.
439 */ 428 */
440 afterZoom_: function() { 429 afterZoom_: function() {
441 var position = this.viewport_.position; 430 var position = this.viewport_.position;
442 var zoom = this.viewport_.zoom; 431 var zoom = this.viewport_.zoom;
443 if (this.shouldManageZoom_() && !this.setZoomInProgress_) { 432 if (this.shouldManageZoom_() && !this.setZoomInProgress_) {
444 this.setZoomInProgress_ = true; 433 this.setZoomInProgress_ = true;
445 chrome.tabs.setZoom(this.streamDetails.tabId, zoom, 434 chrome.tabs.setZoom(this.streamDetails_.tabId, zoom,
446 this.setZoomComplete_.bind(this, zoom)); 435 this.setZoomComplete_.bind(this, zoom));
447 } 436 }
448 this.plugin_.postMessage({ 437 this.plugin_.postMessage({
449 type: 'viewport', 438 type: 'viewport',
450 zoom: zoom, 439 zoom: zoom,
451 xOffset: position.x, 440 xOffset: position.x,
452 yOffset: position.y 441 yOffset: position.y
453 }); 442 });
454 }, 443 },
455 444
456 /** 445 /**
457 * @private 446 * @private
458 * A callback that's called after chrome.tabs.setZoom is complete. This will 447 * A callback that's called after chrome.tabs.setZoom is complete. This will
459 * call chrome.tabs.setZoom again if the zoom level has changed since it was 448 * call chrome.tabs.setZoom again if the zoom level has changed since it was
460 * last called. 449 * last called.
461 * @param {number} lastZoom the zoom level that chrome.tabs.setZoom was called 450 * @param {number} lastZoom the zoom level that chrome.tabs.setZoom was called
462 * with. 451 * with.
463 */ 452 */
464 setZoomComplete_: function(lastZoom) { 453 setZoomComplete_: function(lastZoom) {
465 var zoom = this.viewport_.zoom; 454 var zoom = this.viewport_.zoom;
466 if (zoom != lastZoom) { 455 if (zoom != lastZoom) {
467 chrome.tabs.setZoom(this.streamDetails.tabId, zoom, 456 chrome.tabs.setZoom(this.streamDetails_.tabId, zoom,
468 this.setZoomComplete_.bind(this, zoom)); 457 this.setZoomComplete_.bind(this, zoom));
469 } else { 458 } else {
470 this.setZoomInProgress_ = false; 459 this.setZoomInProgress_ = false;
471 } 460 }
472 }, 461 },
473 462
474 /** 463 /**
475 * @private 464 * @private
476 * A callback that's called after the viewport changes. 465 * A callback that's called after the viewport changes.
477 */ 466 */
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 }); 517 });
529 }, 518 },
530 519
531 /** 520 /**
532 * @private 521 * @private
533 * Handle a scripting message from outside the extension (typically sent by 522 * Handle a scripting message from outside the extension (typically sent by
534 * PDFScriptingAPI in a page containing the extension) to interact with the 523 * PDFScriptingAPI in a page containing the extension) to interact with the
535 * plugin. 524 * plugin.
536 * @param {MessageObject} message the message to handle. 525 * @param {MessageObject} message the message to handle.
537 */ 526 */
538 handleScriptingMessage_: function(message) { 527 handleScriptingMessage: function(message) {
539 switch (message.data.type.toString()) { 528 switch (message.data.type.toString()) {
540 case 'getAccessibilityJSON': 529 case 'getAccessibilityJSON':
541 case 'loadPreviewPage': 530 case 'loadPreviewPage':
542 this.plugin_.postMessage(message.data); 531 this.plugin_.postMessage(message.data);
543 break; 532 break;
544 case 'resetPrintPreviewMode': 533 case 'resetPrintPreviewMode':
545 if (!this.inPrintPreviewMode_) { 534 if (!this.inPrintPreviewMode_) {
546 this.inPrintPreviewMode_ = true; 535 this.inPrintPreviewMode_ = true;
547 this.viewport_.fitToPage(); 536 this.viewport_.fitToPage();
548 } 537 }
(...skipping 21 matching lines...) Expand all
570 pageCount: (message.data.modifiable ? 559 pageCount: (message.data.modifiable ?
571 message.data.pageNumbers.length : 0) 560 message.data.pageNumbers.length : 0)
572 }); 561 });
573 break; 562 break;
574 case 'sendKeyEvent': 563 case 'sendKeyEvent':
575 var e = document.createEvent('Event'); 564 var e = document.createEvent('Event');
576 e.initEvent('scriptingKeypress'); 565 e.initEvent('scriptingKeypress');
577 e.keyCode = message.data.keyCode; 566 e.keyCode = message.data.keyCode;
578 this.handleKeyEvent_(e); 567 this.handleKeyEvent_(e);
579 break; 568 break;
569 case 'setParentWindow':
570 if (this.parentWindow_ != message.source) {
571 this.parentWindow_ = message.source;
572 // If the document has already loaded, we always send a message that
573 // indicates that so that the embedder is aware.
574 if (this.loaded_) {
575 this.sendScriptingMessage_({
576 type: 'documentLoaded'
577 });
578 }
579 }
580 break;
580 } 581 }
581
582 }, 582 },
583 583
584 /** 584 /**
585 * @private 585 * @private
586 * Send a scripting message outside the extension (typically to 586 * Send a scripting message outside the extension (typically to
587 * PDFScriptingAPI in a page containing the extension). 587 * PDFScriptingAPI in a page containing the extension).
588 * @param {Object} message the message to send. 588 * @param {Object} message the message to send.
589 */ 589 */
590 sendScriptingMessage_: function(message) { 590 sendScriptingMessage_: function(message) {
591 window.parent.postMessage(message, '*'); 591 if (this.parentWindow_)
592 this.parentWindow_.postMessage(message, '*');
592 }, 593 },
593 594
594 /** 595 /**
595 * @private 596 * @private
596 * Return whether this PDFViewer should manage zoom for its containing page. 597 * Return whether this PDFViewer should manage zoom for its containing page.
597 * @return {boolean} Whether this PDFViewer should manage zoom for its 598 * @return {boolean} Whether this PDFViewer should manage zoom for its
598 * containing page. 599 * containing page.
599 */ 600 */
600 shouldManageZoom_: function() { 601 shouldManageZoom_: function() {
601 return !!(chrome.tabs && !this.streamDetails.embedded && 602 return !!(chrome.tabs && !this.streamDetails_.embedded &&
602 this.streamDetails.tabId != -1); 603 this.streamDetails_.tabId != -1);
603 }, 604 },
604 605
605 /** 606 /**
606 * @type {Viewport} the viewport of the PDF viewer. 607 * @type {Viewport} the viewport of the PDF viewer.
607 */ 608 */
608 get viewport() { 609 get viewport() {
609 return this.viewport_; 610 return this.viewport_;
610 } 611 }
611 }; 612 };
OLDNEW
« no previous file with comments | « chrome/browser/resources/pdf/main.js ('k') | chrome/browser/resources/pdf/pdf_scripting_api.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698