diff options
-rw-r--r-- | chrome/browser/resources/component_extension_resources.grd | 1 | ||||
-rw-r--r-- | chrome/browser/resources/pdf/index-material.html | 1 | ||||
-rw-r--r-- | chrome/browser/resources/pdf/index.html | 1 | ||||
-rw-r--r-- | chrome/browser/resources/pdf/pdf.js | 17 | ||||
-rw-r--r-- | chrome/browser/resources/pdf/viewport_scroller.js | 135 | ||||
-rw-r--r-- | pdf/out_of_process_instance.cc | 11 | ||||
-rw-r--r-- | pdf/out_of_process_instance.h | 1 | ||||
-rw-r--r-- | pdf/pdf_engine.h | 3 | ||||
-rw-r--r-- | pdf/pdfium/pdfium_engine.cc | 11 | ||||
-rw-r--r-- | pdf/pdfium/pdfium_engine.h | 3 |
10 files changed, 172 insertions, 12 deletions
diff --git a/chrome/browser/resources/component_extension_resources.grd b/chrome/browser/resources/component_extension_resources.grd index 3d14d35..42e7712 100644 --- a/chrome/browser/resources/component_extension_resources.grd +++ b/chrome/browser/resources/component_extension_resources.grd @@ -169,6 +169,7 @@ <include name="IDR_PDF_VIEWPORT_JS" file="pdf/viewport.js" type="BINDATA" /> <include name="IDR_PDF_OPEN_PDF_PARAMS_PARSER_JS" file="pdf/open_pdf_params_parser.js" type="BINDATA" /> <include name="IDR_PDF_NAVIGATOR_JS" file="pdf/navigator.js" type="BINDATA" /> + <include name="IDR_PDF_VIEWPORT_SCROLLER_JS" file="pdf/viewport_scroller.js" type="BINDATA" /> <include name="IDR_PDF_PDF_SCRIPTING_API_JS" file="pdf/pdf_scripting_api.js" type="BINDATA" /> <include name="IDR_PDF_CONTENT_SCRIPT_JS" file="pdf/content_script.js" type="BINDATA" /> diff --git a/chrome/browser/resources/pdf/index-material.html b/chrome/browser/resources/pdf/index-material.html index 11b26ca..5fc52f5 100644 --- a/chrome/browser/resources/pdf/index-material.html +++ b/chrome/browser/resources/pdf/index-material.html @@ -51,6 +51,7 @@ <script src="viewport.js"></script> <script src="open_pdf_params_parser.js"></script> <script src="navigator.js"></script> +<script src="viewport_scroller.js"></script> <script src="pdf_scripting_api.js"></script> <script src="chrome://resources/js/util.js"></script> <script src="pdf.js"></script> diff --git a/chrome/browser/resources/pdf/index.html b/chrome/browser/resources/pdf/index.html index 308c793..40ed9a9 100644 --- a/chrome/browser/resources/pdf/index.html +++ b/chrome/browser/resources/pdf/index.html @@ -51,6 +51,7 @@ <script src="viewport.js"></script> <script src="open_pdf_params_parser.js"></script> <script src="navigator.js"></script> +<script src="viewport_scroller.js"></script> <script src="pdf_scripting_api.js"></script> <script src="chrome://resources/js/util.js"></script> <script src="pdf.js"></script> diff --git a/chrome/browser/resources/pdf/pdf.js b/chrome/browser/resources/pdf/pdf.js index e44317c..309886f 100644 --- a/chrome/browser/resources/pdf/pdf.js +++ b/chrome/browser/resources/pdf/pdf.js @@ -194,6 +194,8 @@ function PDFViewer(streamDetails) { this.navigator_ = new Navigator(this.streamDetails_.originalUrl, this.viewport_, this.paramsParser_, onNavigateInCurrentTab, onNavigateInNewTab); + this.viewportScroller_ = + new ViewportScroller(this.viewport_, this.plugin_, window); } PDFViewer.prototype = { @@ -348,21 +350,13 @@ PDFViewer.prototype = { * @private * Notify the plugin to print. */ - print_: function() { - this.plugin_.postMessage({ - type: 'print' - }); - }, + print_: function() { this.plugin_.postMessage({type: 'print'}); }, /** * @private * Notify the plugin to save. */ - save_: function() { - this.plugin_.postMessage({ - type: 'save' - }); - }, + save_: function() { this.plugin_.postMessage({type: 'save'}); }, /** * @private @@ -522,6 +516,9 @@ PDFViewer.prototype = { this.materialToolbar_.hasBookmarks = true; } break; + case 'setIsSelecting': + this.viewportScroller_.setEnableScrolling(message.data.isSelecting); + break; } }, diff --git a/chrome/browser/resources/pdf/viewport_scroller.js b/chrome/browser/resources/pdf/viewport_scroller.js new file mode 100644 index 0000000..f46ef4d --- /dev/null +++ b/chrome/browser/resources/pdf/viewport_scroller.js @@ -0,0 +1,135 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +'use strict'; + +/** + * @private + * The period of time in milliseconds to wait between updating the viewport + * position by the scroll velocity. + */ +ViewportScroller.DRAG_TIMER_INTERVAL_MS_ = 100; + +/** + * @private + * The maximum drag scroll distance per DRAG_TIMER_INTERVAL in pixels. + */ +ViewportScroller.MAX_DRAG_SCROLL_DISTANCE_ = 100; + +/** + * Creates a new ViewportScroller. + * A ViewportScroller scrolls the page in response to drag selection with the + * mouse. + * @param {Object} viewport The viewport info of the page. + * @param {Object} plugin The PDF plugin element. + * @param {Object} window The window containing the viewer. + */ +function ViewportScroller(viewport, plugin, window) { + this.viewport_ = viewport; + this.plugin_ = plugin; + this.window_ = window; + this.mousemoveCallback_ = null; + this.timerId_ = null; + this.scrollVelocity_ = null; + this.lastFrameTime_ = 0; +} + +ViewportScroller.prototype = { + /** + * @private + * Start scrolling the page by |scrollVelocity_| every + * |DRAG_TIMER_INTERVAL_MS_|. + */ + startDragScrollTimer_: function() { + if (this.timerId_ === null) { + this.timerId_ = + this.window_.setInterval(this.dragScrollPage_.bind(this), + ViewportScroller.DRAG_TIMER_INTERVAL_MS_); + this.lastFrameTime_ = Date.now(); + } + }, + + /** + * @private + * Stops the drag scroll timer if it is active. + */ + stopDragScrollTimer_: function() { + if (this.timerId_ !== null) { + this.window_.clearInterval(this.timerId_); + this.timerId_ = null; + this.lastFrameTime_ = 0; + } + }, + + /** + * @private + * Scrolls the viewport by the current scroll velocity. + */ + dragScrollPage_: function() { + var position = this.viewport_.position; + var currentFrameTime = Date.now(); + var timeAdjustment = (currentFrameTime - this.lastFrameTime_) / + ViewportScroller.DRAG_TIMER_INTERVAL_MS_; + position.y += (this.scrollVelocity_.y * timeAdjustment); + position.x += (this.scrollVelocity_.x * timeAdjustment); + this.viewport_.position = position; + this.lastFrameTime_ = currentFrameTime; + }, + + /** + * @private + * Calculate the velocity to scroll while dragging using the distance of the + * cursor outside the viewport. + * @param {Object} event The mousemove event. + * @return {Object} Object with x and y direction scroll velocity. + */ + calculateVelocity_: function(event) { + var x = Math.min(Math.max(-event.offsetX, + event.offsetX - this.plugin_.offsetWidth, 0), + ViewportScroller.MAX_DRAG_SCROLL_DISTANCE_) * + Math.sign(event.offsetX); + var y = Math.min(Math.max(-event.offsetY, + event.offsetY - this.plugin_.offsetHeight, 0), + ViewportScroller.MAX_DRAG_SCROLL_DISTANCE_) * + Math.sign(event.offsetY); + return { + x: x, + y: y + }; + }, + + /** + * @private + * Handles mousemove events. It updates the scroll velocity and starts and + * stops timer based on scroll velocity. + * @param {Object} event The mousemove event. + */ + onMousemove_: function(event) { + this.scrollVelocity_ = this.calculateVelocity_(event); + if (!this.scrollVelocity_.x && !this.scrollVelocity_.y) + this.stopDragScrollTimer_(); + else if (!this.timerId_) + this.startDragScrollTimer_(); + }, + + /** + * Sets whether to scroll the viewport when the mouse is outside the + * viewport. + * @param {boolean} isSelecting Represents selection status. + */ + setEnableScrolling: function(isSelecting) { + if (isSelecting) { + if (!this.mousemoveCallback_) + this.mousemoveCallback_ = this.onMousemove_.bind(this); + this.plugin_.addEventListener('mousemove', this.mousemoveCallback_, + false); + } else { + this.stopDragScrollTimer_(); + if (this.mousemoveCallback_) { + this.plugin_.removeEventListener('mousemove', this.mousemoveCallback_, + false); + } + } + } +}; diff --git a/pdf/out_of_process_instance.cc b/pdf/out_of_process_instance.cc index 169a440..74544d9 100644 --- a/pdf/out_of_process_instance.cc +++ b/pdf/out_of_process_instance.cc @@ -144,6 +144,10 @@ const char kJSSelectedText[] = "selectedText"; const char kJSSetNamedDestinationsType[] = "setNamedDestinations"; const char kJSNamedDestinations[] = "namedDestinations"; +// Selecting text in document (Plugin -> Page) +const char kJSSetIsSelectingType[] = "setIsSelecting"; +const char kJSIsSelecting[] = "isSelecting"; + const int kFindResultCooldownMs = 100; const double kMinZoom = 0.01; @@ -1351,6 +1355,13 @@ uint32 OutOfProcessInstance::GetBackgroundColor() { return background_color_; } +void OutOfProcessInstance::IsSelectingChanged(bool is_selecting) { + pp::VarDictionary message; + message.Set(kType, kJSSetIsSelectingType); + message.Set(kJSIsSelecting, pp::Var(is_selecting)); + PostMessage(message); +} + void OutOfProcessInstance::ProcessPreviewPageInfo(const std::string& url, int dst_page_index) { if (!IsPrintPreview()) diff --git a/pdf/out_of_process_instance.h b/pdf/out_of_process_instance.h index 58e9b29..62d21c1 100644 --- a/pdf/out_of_process_instance.h +++ b/pdf/out_of_process_instance.h @@ -137,6 +137,7 @@ class OutOfProcessInstance : public pp::Instance, void FormTextFieldFocusChange(bool in_focus) override; bool IsPrintPreview() override; uint32 GetBackgroundColor() override; + void IsSelectingChanged(bool is_selecting) override; // PreviewModeClient::Client implementation. void PreviewDocumentLoadComplete() override; diff --git a/pdf/pdf_engine.h b/pdf/pdf_engine.h index befb1b8..0ef9da0 100644 --- a/pdf/pdf_engine.h +++ b/pdf/pdf_engine.h @@ -176,6 +176,9 @@ class PDFEngine { // Get the background color of the PDF. virtual uint32 GetBackgroundColor() = 0; + + // Sets selection status. + virtual void IsSelectingChanged(bool is_selecting){}; }; // Factory method to create an instance of the PDF Engine. diff --git a/pdf/pdfium/pdfium_engine.cc b/pdf/pdfium/pdfium_engine.cc index 294ab2f..51e5676 100644 --- a/pdf/pdfium/pdfium_engine.cc +++ b/pdf/pdfium/pdfium_engine.cc @@ -1731,7 +1731,7 @@ bool PDFiumEngine::OnMouseDown(const pp::MouseInputEvent& event) { } void PDFiumEngine::OnSingleClick(int page_index, int char_index) { - selecting_ = true; + SetSelecting(true); selection_.push_back(PDFiumRange(pages_[page_index], char_index, 0)); } @@ -1794,7 +1794,7 @@ bool PDFiumEngine::OnMouseUp(const pp::MouseInputEvent& event) { if (!selecting_) return false; - selecting_ = false; + SetSelecting(false); return true; } @@ -3471,6 +3471,13 @@ void PDFiumEngine::RotateInternal() { } } +void PDFiumEngine::SetSelecting(bool selecting) { + bool was_selecting = selecting_; + selecting_ = selecting; + if (selecting_ != was_selecting) + client_->IsSelectingChanged(selecting); +} + void PDFiumEngine::Form_Invalidate(FPDF_FORMFILLINFO* param, FPDF_PAGE page, double left, diff --git a/pdf/pdfium/pdfium_engine.h b/pdf/pdfium/pdfium_engine.h index d7b4835..be52763 100644 --- a/pdf/pdfium/pdfium_engine.h +++ b/pdf/pdfium/pdfium_engine.h @@ -423,6 +423,9 @@ class PDFiumEngine : public PDFEngine, // Common code shared by RotateClockwise() and RotateCounterclockwise(). void RotateInternal(); + // Setting selection status of document. + void SetSelecting(bool selecting); + // FPDF_FORMFILLINFO callbacks. static void Form_Invalidate(FPDF_FORMFILLINFO* param, FPDF_PAGE page, |