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();