Index: third_party/WebKit/Source/core/dom/Element.cpp |
diff --git a/third_party/WebKit/Source/core/dom/Element.cpp b/third_party/WebKit/Source/core/dom/Element.cpp |
index 9e22bf067b59f01a58ce245bc9a14358d1735e64..54df566f3353ab7b02894efd3db3e7b5db11efa0 100644 |
--- a/third_party/WebKit/Source/core/dom/Element.cpp |
+++ b/third_party/WebKit/Source/core/dom/Element.cpp |
@@ -30,6 +30,7 @@ |
#include "bindings/core/v8/Dictionary.h" |
#include "bindings/core/v8/ExceptionMessages.h" |
#include "bindings/core/v8/ExceptionState.h" |
+#include "bindings/core/v8/ScrollIntoViewOptionsOrBoolean.h" |
#include "bindings/core/v8/V8DOMActivityLogger.h" |
#include "core/CSSValueKeywords.h" |
#include "core/SVGNames.h" |
@@ -94,6 +95,7 @@ |
#include "core/frame/HostsUsingFeatures.h" |
#include "core/frame/LocalDOMWindow.h" |
#include "core/frame/LocalFrame.h" |
+#include "core/frame/ScrollIntoViewOptions.h" |
#include "core/frame/ScrollToOptions.h" |
#include "core/frame/Settings.h" |
#include "core/frame/UseCounter.h" |
@@ -141,6 +143,7 @@ |
#include "platform/graphics/CompositorMutableProperties.h" |
#include "platform/graphics/CompositorMutation.h" |
#include "platform/scroll/ScrollableArea.h" |
+#include "platform/scroll/SmoothScrollSequencer.h" |
#include "platform/wtf/BitVector.h" |
#include "platform/wtf/HashFunctions.h" |
#include "platform/wtf/text/CString.h" |
@@ -430,7 +433,67 @@ AtomicString Element::LowercaseIfNecessary(const AtomicString& name) const { |
: name; |
} |
+void Element::scrollIntoView(ScrollIntoViewOptionsOrBoolean arg) { |
+ ScrollIntoViewOptions options; |
+ if (arg.isBoolean()) { |
+ if (arg.getAsBoolean()) |
+ options.setBlock("start"); |
+ else |
+ options.setBlock("end"); |
+ options.setInlinePosition("nearest"); |
+ } else if (arg.isScrollIntoViewOptions()) { |
+ options = arg.getAsScrollIntoViewOptions(); |
+ if (!RuntimeEnabledFeatures::cssomSmoothScrollEnabled() && |
+ options.behavior() == "smooth") { |
+ options.setBehavior("instant"); |
+ } |
+ } |
+ scrollIntoViewWithOptions(options); |
+} |
+ |
void Element::scrollIntoView(bool align_to_top) { |
+ ScrollIntoViewOptions options; |
+ if (align_to_top) |
+ options.setBlock("start"); |
+ else |
+ options.setBlock("end"); |
+ options.setInlinePosition("nearest"); |
+ scrollIntoViewWithOptions(options); |
+} |
+ |
+static ScrollAlignment InputAlignmentToXYAlignment( |
+ const ScrollIntoViewOptions& options, |
+ bool is_x, |
+ bool is_horizontal) { |
+ String alignment = options.block(); |
+ if ((is_x && is_horizontal) || ((!is_x) && (!is_horizontal))) |
+ alignment = options.inlinePosition(); |
+ if (alignment == "center") |
+ return ScrollAlignment::kAlignCenterAlways; |
+ if (alignment == "nearest") |
+ return ScrollAlignment::kAlignToEdgeIfNeeded; |
+ if (alignment == "start") { |
+ return is_x ? ScrollAlignment::kAlignLeftAlways |
+ : ScrollAlignment::kAlignTopAlways; |
+ } |
+ if (alignment == "end") { |
+ return is_x ? ScrollAlignment::kAlignRightAlways |
+ : ScrollAlignment::kAlignBottomAlways; |
+ } |
+ |
+ // Default values |
+ if (is_horizontal) { |
+ if (is_x) |
+ return ScrollAlignment::kAlignToEdgeIfNeeded; |
+ return ScrollAlignment::kAlignTopAlways; |
+ } |
+ // if (is_vertical) |
+ if (is_x) |
+ return ScrollAlignment::kAlignLeftAlways; |
+ return ScrollAlignment::kAlignToEdgeIfNeeded; |
+} |
+ |
+void Element::scrollIntoViewWithOptions(const ScrollIntoViewOptions& options) { |
GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this); |
if (!GetLayoutObject()) |
@@ -439,18 +502,26 @@ void Element::scrollIntoView(bool align_to_top) { |
bool make_visible_in_visual_viewport = |
!GetDocument().GetPage()->GetSettings().GetInertVisualViewport(); |
+ ScrollBehavior behavior = kScrollBehaviorAuto; |
+ if (options.behavior() == "smooth") { |
+ behavior = kScrollBehaviorSmooth; |
+ } |
+ |
+ bool is_horizontal = GetComputedStyle()->IsHorizontalWritingMode(); |
+ ScrollAlignment align_x = |
+ InputAlignmentToXYAlignment(options, true, is_horizontal); |
+ ScrollAlignment align_y = |
+ InputAlignmentToXYAlignment(options, false, is_horizontal); |
+ |
+ if (GetDocument().GetPage()) |
+ GetDocument().GetPage()->GetSmoothScrollSequencer()->AbortAnimations(); |
LayoutRect bounds = BoundingBox(); |
- // Align to the top / bottom and to the closest edge. |
- if (align_to_top) |
- GetLayoutObject()->ScrollRectToVisible( |
- bounds, ScrollAlignment::kAlignToEdgeIfNeeded, |
- ScrollAlignment::kAlignTopAlways, kProgrammaticScroll, |
- make_visible_in_visual_viewport); |
- else |
- GetLayoutObject()->ScrollRectToVisible( |
- bounds, ScrollAlignment::kAlignToEdgeIfNeeded, |
- ScrollAlignment::kAlignBottomAlways, kProgrammaticScroll, |
- make_visible_in_visual_viewport); |
+ GetLayoutObject()->ScrollRectToVisible( |
+ bounds, align_x, align_y, kProgrammaticScroll, |
+ make_visible_in_visual_viewport, behavior); |
+ |
+ if (GetDocument().GetPage()) |
+ GetDocument().GetPage()->GetSmoothScrollSequencer()->RunQueuedAnimations(); |
GetDocument().SetSequentialFocusNavigationStartingPoint(this); |
} |