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

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

Powered by Google App Engine
This is Rietveld 408576698