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

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

Issue 2650343008: Implement Element.scrollIntoView for scroll-behavior: smooth. (Closed)
Patch Set: Fixed the comments 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 af710a5670f2b3475c8303f1f71f48bc76d84b35..3d3c72add7ed3c47d61115e86e68b3303dea30e5 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"
@@ -438,27 +441,86 @@ void Element::setNonce(const AtomicString& nonce) {
EnsureElementRareData().SetNonce(nonce);
}
+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) {
+ ScrollIntoViewOptionsOrBoolean arg;
+ arg.setBoolean(align_to_top);
+ scrollIntoView(arg);
+}
+
+static ScrollAlignment ToPhysicalAlignment(const ScrollIntoViewOptions& options,
+ ScrollOrientation axis,
+ ScrollOrientation writing_mode) {
bokan 2017/05/19 18:37:14 While it kind of makes sense here, writing mode is
sunyunjia 2017/05/19 22:30:41 Done.
+ String alignment =
+ (axis == writing_mode) ? options.inlinePosition() : options.block();
+
+ if (alignment == "center")
+ return ScrollAlignment::kAlignCenterAlways;
+ if (alignment == "nearest")
+ return ScrollAlignment::kAlignToEdgeIfNeeded;
+ if (alignment == "start") {
+ return (axis == kHorizontalScroll) ? ScrollAlignment::kAlignLeftAlways
+ : ScrollAlignment::kAlignTopAlways;
+ }
+ if (alignment == "end") {
+ return (axis == kHorizontalScroll) ? ScrollAlignment::kAlignRightAlways
+ : ScrollAlignment::kAlignBottomAlways;
+ }
+
+ // Default values
+ if (writing_mode == kHorizontalScroll) {
+ return (axis == kHorizontalScroll) ? ScrollAlignment::kAlignToEdgeIfNeeded
+ : ScrollAlignment::kAlignTopAlways;
+ }
+ return (axis == kHorizontalScroll) ? ScrollAlignment::kAlignLeftAlways
+ : ScrollAlignment::kAlignToEdgeIfNeeded;
+}
+
+void Element::scrollIntoViewWithOptions(const ScrollIntoViewOptions& options) {
GetDocument().EnsurePaintLocationDataValidForNode(this);
- if (!GetLayoutObject())
+ if (!GetLayoutObject() || !GetDocument().GetPage())
return;
bool make_visible_in_visual_viewport =
!GetDocument().GetPage()->GetSettings().GetInertVisualViewport();
+ ScrollBehavior behavior = (options.behavior() == "smooth")
+ ? kScrollBehaviorSmooth
+ : kScrollBehaviorAuto;
+
+ ScrollOrientation orientation = GetComputedStyle()->IsHorizontalWritingMode()
+ ? kHorizontalScroll
+ : kVerticalScroll;
+ ScrollAlignment align_x =
+ ToPhysicalAlignment(options, kHorizontalScroll, orientation);
+ ScrollAlignment align_y =
+ ToPhysicalAlignment(options, kVerticalScroll, orientation);
+
+ 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);
+
+ GetDocument().GetPage()->GetSmoothScrollSequencer()->RunQueuedAnimations();
GetDocument().SetSequentialFocusNavigationStartingPoint(this);
}

Powered by Google App Engine
This is Rietveld 408576698