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

Unified Diff: third_party/WebKit/Source/core/dom/Element.cpp

Issue 2650343008: Implement Element.scrollIntoView for scroll-behavior: smooth. (Closed)
Patch Set: Added web platform test. Created 3 years, 7 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 side-by-side diff with in-line comments
Download patch
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);
}

Powered by Google App Engine
This is Rietveld 408576698