Do not scroll invisible selection into view.

When we call focus() on an <input> element, we would scroll the element
into view, then the selected text in it into view. However, if the
<input> element has a selection that is not currently visible, it will
first scroll the <input> into view, then try to scroll an empty
LayoutRect(0, 0, 0x0) into view, which might cause the <input> out of
view at last.

In this patch, we would check whether the selection's visible rect is
empty before scrolling it into view.

Bug: 796880
Change-Id: Id5f7783a4efe137b180771280bd0c0c9dd1ab1ad
Reviewed-on: https://chromium-review.googlesource.com/854779
Commit-Queue: Sandra Sun <[email protected]>
Reviewed-by: David Bokan <[email protected]>
Cr-Commit-Position: refs/heads/master@{#529638}
diff --git a/third_party/WebKit/LayoutTests/fast/scrolling/scroll-into-view-ignores-invisible-selection.html b/third_party/WebKit/LayoutTests/fast/scrolling/scroll-into-view-ignores-invisible-selection.html
new file mode 100644
index 0000000..cbc425e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/scrolling/scroll-into-view-ignores-invisible-selection.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+
+<style>
+#space {
+  height: 1000px;
+}
+#input {
+  width: 100px;
+}
+</style>
+
+<div id="space"></div>
+<input type="text" id="input" value="abcdefghijklmnopqrstuvwxyz"/>
+
+<script>
+test(function(t) {
+  var input = document.getElementById("input");
+  input.setSelectionRange(20, 22);
+  input.focus();
+  assert_not_equals(window.scrollY, 0);
+}, "Tests that when focusing on an input element with invisible selections, " +
+   "the page doesn't reset to top.");
+</script>
diff --git a/third_party/WebKit/Source/core/editing/FrameSelection.cpp b/third_party/WebKit/Source/core/editing/FrameSelection.cpp
index b0cbc4a8..173f619 100644
--- a/third_party/WebKit/Source/core/editing/FrameSelection.cpp
+++ b/third_party/WebKit/Source/core/editing/FrameSelection.cpp
@@ -972,9 +972,11 @@
   // This function is needed to make sure that ComputeRectToScroll below has the
   // sticky offset info available before the computation.
   GetDocument().EnsurePaintLocationDataValidForNode(start.AnchorNode());
-  if (!start.AnchorNode()->GetLayoutObject()->ScrollRectToVisible(
-          LayoutRect(ComputeRectToScroll(reveal_extent_option)),
-          WebScrollIntoViewParams(alignment, alignment)))
+  LayoutRect selection_rect =
+      LayoutRect(ComputeRectToScroll(reveal_extent_option));
+  if (selection_rect == LayoutRect() ||
+      !start.AnchorNode()->GetLayoutObject()->ScrollRectToVisible(
+          selection_rect, WebScrollIntoViewParams(alignment, alignment)))
     return;
 
   UpdateAppearance();