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

Side by Side Diff: third_party/WebKit/Source/core/dom/Element.cpp

Issue 2650343008: Implement Element.scrollIntoView for scroll-behavior: smooth. (Closed)
Patch Set: Added SimTest. Created 3 years, 10 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Peter Kelly (pmk@post.com) 4 * (C) 2001 Peter Kelly (pmk@post.com)
5 * (C) 2001 Dirk Mueller (mueller@kde.org) 5 * (C) 2001 Dirk Mueller (mueller@kde.org)
6 * (C) 2007 David Smith (catfish.man@gmail.com) 6 * (C) 2007 David Smith (catfish.man@gmail.com)
7 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013 Apple Inc. 7 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013 Apple Inc.
8 * All rights reserved. 8 * All rights reserved.
9 * (C) 2007 Eric Seidel (eric@webkit.org) 9 * (C) 2007 Eric Seidel (eric@webkit.org)
10 * 10 *
11 * This library is free software; you can redistribute it and/or 11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Library General Public 12 * modify it under the terms of the GNU Library General Public
13 * License as published by the Free Software Foundation; either 13 * License as published by the Free Software Foundation; either
14 * version 2 of the License, or (at your option) any later version. 14 * version 2 of the License, or (at your option) any later version.
15 * 15 *
16 * This library is distributed in the hope that it will be useful, 16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Library General Public License for more details. 19 * Library General Public License for more details.
20 * 20 *
21 * You should have received a copy of the GNU Library General Public License 21 * You should have received a copy of the GNU Library General Public License
22 * along with this library; see the file COPYING.LIB. If not, write to 22 * along with this library; see the file COPYING.LIB. If not, write to
23 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 23 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 * Boston, MA 02110-1301, USA. 24 * Boston, MA 02110-1301, USA.
25 */ 25 */
26 26
27 #include "core/dom/Element.h" 27 #include "core/dom/Element.h"
28 28
29 #include <memory>
29 #include "bindings/core/v8/DOMDataStore.h" 30 #include "bindings/core/v8/DOMDataStore.h"
30 #include "bindings/core/v8/Dictionary.h" 31 #include "bindings/core/v8/Dictionary.h"
31 #include "bindings/core/v8/ExceptionMessages.h" 32 #include "bindings/core/v8/ExceptionMessages.h"
32 #include "bindings/core/v8/ExceptionState.h" 33 #include "bindings/core/v8/ExceptionState.h"
34 #include "bindings/core/v8/ScrollIntoViewOptionsOrBoolean.h"
33 #include "bindings/core/v8/V8DOMActivityLogger.h" 35 #include "bindings/core/v8/V8DOMActivityLogger.h"
34 #include "bindings/core/v8/V8DOMWrapper.h" 36 #include "bindings/core/v8/V8DOMWrapper.h"
35 #include "bindings/core/v8/V8PerContextData.h" 37 #include "bindings/core/v8/V8PerContextData.h"
36 #include "core/CSSValueKeywords.h" 38 #include "core/CSSValueKeywords.h"
37 #include "core/SVGNames.h" 39 #include "core/SVGNames.h"
38 #include "core/XMLNames.h" 40 #include "core/XMLNames.h"
39 #include "core/animation/AnimationTimeline.h" 41 #include "core/animation/AnimationTimeline.h"
40 #include "core/animation/CustomCompositorAnimations.h" 42 #include "core/animation/CustomCompositorAnimations.h"
41 #include "core/animation/css/CSSAnimations.h" 43 #include "core/animation/css/CSSAnimations.h"
42 #include "core/css/CSSIdentifierValue.h" 44 #include "core/css/CSSIdentifierValue.h"
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 #include "core/editing/FrameSelection.h" 92 #include "core/editing/FrameSelection.h"
91 #include "core/editing/iterators/TextIterator.h" 93 #include "core/editing/iterators/TextIterator.h"
92 #include "core/editing/serializers/Serialization.h" 94 #include "core/editing/serializers/Serialization.h"
93 #include "core/events/EventDispatcher.h" 95 #include "core/events/EventDispatcher.h"
94 #include "core/events/FocusEvent.h" 96 #include "core/events/FocusEvent.h"
95 #include "core/frame/FrameHost.h" 97 #include "core/frame/FrameHost.h"
96 #include "core/frame/FrameView.h" 98 #include "core/frame/FrameView.h"
97 #include "core/frame/HostsUsingFeatures.h" 99 #include "core/frame/HostsUsingFeatures.h"
98 #include "core/frame/LocalDOMWindow.h" 100 #include "core/frame/LocalDOMWindow.h"
99 #include "core/frame/LocalFrame.h" 101 #include "core/frame/LocalFrame.h"
102 #include "core/frame/ScrollIntoViewOptions.h"
100 #include "core/frame/ScrollToOptions.h" 103 #include "core/frame/ScrollToOptions.h"
101 #include "core/frame/Settings.h" 104 #include "core/frame/Settings.h"
102 #include "core/frame/UseCounter.h" 105 #include "core/frame/UseCounter.h"
103 #include "core/frame/VisualViewport.h" 106 #include "core/frame/VisualViewport.h"
104 #include "core/frame/csp/ContentSecurityPolicy.h" 107 #include "core/frame/csp/ContentSecurityPolicy.h"
105 #include "core/html/ClassList.h" 108 #include "core/html/ClassList.h"
106 #include "core/html/HTMLCanvasElement.h" 109 #include "core/html/HTMLCanvasElement.h"
107 #include "core/html/HTMLCollection.h" 110 #include "core/html/HTMLCollection.h"
108 #include "core/html/HTMLDocument.h" 111 #include "core/html/HTMLDocument.h"
109 #include "core/html/HTMLElement.h" 112 #include "core/html/HTMLElement.h"
(...skipping 14 matching lines...) Expand all
124 #include "core/loader/DocumentLoader.h" 127 #include "core/loader/DocumentLoader.h"
125 #include "core/page/ChromeClient.h" 128 #include "core/page/ChromeClient.h"
126 #include "core/page/FocusController.h" 129 #include "core/page/FocusController.h"
127 #include "core/page/Page.h" 130 #include "core/page/Page.h"
128 #include "core/page/PointerLockController.h" 131 #include "core/page/PointerLockController.h"
129 #include "core/page/SpatialNavigation.h" 132 #include "core/page/SpatialNavigation.h"
130 #include "core/page/scrolling/RootScrollerController.h" 133 #include "core/page/scrolling/RootScrollerController.h"
131 #include "core/page/scrolling/ScrollCustomizationCallbacks.h" 134 #include "core/page/scrolling/ScrollCustomizationCallbacks.h"
132 #include "core/page/scrolling/ScrollState.h" 135 #include "core/page/scrolling/ScrollState.h"
133 #include "core/page/scrolling/ScrollStateCallback.h" 136 #include "core/page/scrolling/ScrollStateCallback.h"
137 #include "core/page/scrolling/ScrollingCoordinator.h"
134 #include "core/page/scrolling/TopDocumentRootScrollerController.h" 138 #include "core/page/scrolling/TopDocumentRootScrollerController.h"
135 #include "core/paint/PaintLayer.h" 139 #include "core/paint/PaintLayer.h"
136 #include "core/svg/SVGAElement.h" 140 #include "core/svg/SVGAElement.h"
137 #include "core/svg/SVGElement.h" 141 #include "core/svg/SVGElement.h"
138 #include "core/svg/SVGTreeScopeResources.h" 142 #include "core/svg/SVGTreeScopeResources.h"
139 #include "platform/EventDispatchForbiddenScope.h" 143 #include "platform/EventDispatchForbiddenScope.h"
140 #include "platform/RuntimeEnabledFeatures.h" 144 #include "platform/RuntimeEnabledFeatures.h"
141 #include "platform/graphics/CompositorMutableProperties.h" 145 #include "platform/graphics/CompositorMutableProperties.h"
142 #include "platform/graphics/CompositorMutation.h" 146 #include "platform/graphics/CompositorMutation.h"
147 #include "platform/scroll/ProgrammaticScrollCoordinator.h"
143 #include "platform/scroll/ScrollableArea.h" 148 #include "platform/scroll/ScrollableArea.h"
144 #include "wtf/BitVector.h" 149 #include "wtf/BitVector.h"
145 #include "wtf/HashFunctions.h" 150 #include "wtf/HashFunctions.h"
146 #include "wtf/text/CString.h" 151 #include "wtf/text/CString.h"
147 #include "wtf/text/StringBuilder.h" 152 #include "wtf/text/StringBuilder.h"
148 #include "wtf/text/TextPosition.h" 153 #include "wtf/text/TextPosition.h"
149 #include <memory>
150 154
151 namespace blink { 155 namespace blink {
152 156
153 namespace { 157 namespace {
154 158
155 // We need to retain the scroll customization callbacks until the element 159 // We need to retain the scroll customization callbacks until the element
156 // they're associated with is destroyed. It would be simplest if the callbacks 160 // they're associated with is destroyed. It would be simplest if the callbacks
157 // could be stored in ElementRareData, but we can't afford the space 161 // could be stored in ElementRareData, but we can't afford the space
158 // increase. Instead, keep the scroll customization callbacks here. The other 162 // increase. Instead, keep the scroll customization callbacks here. The other
159 // option would be to store these callbacks on the FrameHost or document, but 163 // option would be to store these callbacks on the FrameHost or document, but
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 synchronizeAttribute(name); 425 synchronizeAttribute(name);
422 if (const Attribute* attribute = elementData()->attributes().find(name)) 426 if (const Attribute* attribute = elementData()->attributes().find(name))
423 return attribute->value(); 427 return attribute->value();
424 return nullAtom; 428 return nullAtom;
425 } 429 }
426 430
427 bool Element::shouldIgnoreAttributeCase() const { 431 bool Element::shouldIgnoreAttributeCase() const {
428 return isHTMLElement() && document().isHTMLDocument(); 432 return isHTMLElement() && document().isHTMLDocument();
429 } 433 }
430 434
435 void Element::scrollIntoView(ExceptionState& exception) {
436 ScrollIntoViewOptions options;
437 options.setBlock("start");
438 options.setInlinePosition("nearest");
439 scrollIntoViewWithOptions(options);
440 }
441
442 void Element::scrollIntoView(ScrollIntoViewOptionsOrBoolean arg,
443 ExceptionState& exception) {
444 ScrollIntoViewOptions options;
445 if (arg.isBoolean()) {
446 if (arg.getAsBoolean())
447 options.setBlock("start");
448 else
449 options.setBlock("end");
450 options.setInlinePosition("nearest");
451 } else if (arg.isScrollIntoViewOptions()) {
452 options = arg.getAsScrollIntoViewOptions();
453 if (!RuntimeEnabledFeatures::cssomSmoothScrollEnabled() &&
454 options.behavior() == "smooth") {
455 exception.throwTypeError(
456 "Smooth ScrollIntoView is an Experimental Web"
bokan 2017/03/28 16:29:53 I don't think we usually throw for a feature being
sunyunjia 2017/04/07 13:53:20 Done.
457 " Platform Feature, go to chrome://flags to enable it.");
458 return;
459 }
460 } else {
461 exception.throwTypeError(
462 "ScrollIntoView only supports bool or"
463 " ScrollIntoViewOptions as argument.");
464 return;
465 }
466 scrollIntoViewWithOptions(options);
467 }
468
431 void Element::scrollIntoView(bool alignToTop) { 469 void Element::scrollIntoView(bool alignToTop) {
470 ScrollIntoViewOptions options;
471 if (alignToTop)
472 options.setBlock("start");
473 else
474 options.setBlock("end");
475 options.setInlinePosition("nearest");
476 scrollIntoViewWithOptions(options);
477 }
478
479 void Element::scrollIntoViewWithOptions(const ScrollIntoViewOptions& options) {
432 document().updateStyleAndLayoutIgnorePendingStylesheetsForNode(this); 480 document().updateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
433 481
434 if (!layoutObject()) 482 if (!layoutObject())
435 return; 483 return;
436 484
437 bool makeVisibleInVisualViewport = 485 bool makeVisibleInVisualViewport =
438 !document().page()->settings().getInertVisualViewport(); 486 !document().page()->settings().getInertVisualViewport();
439 487
488 ScrollBehavior behavior = ScrollBehaviorAuto;
489 if (options.behavior() == "smooth") {
490 behavior = ScrollBehaviorSmooth;
491 }
492 // Block Alignment to the top / bottom and to the closest edge.
493 ScrollAlignment blockAlignment = ScrollAlignment::alignTopAlways;
494 if (options.block() == "center")
495 blockAlignment = ScrollAlignment::alignCenterAlways;
496 else if (options.block() == "end")
497 blockAlignment = ScrollAlignment::alignBottomAlways;
498 else if (options.block() == "nearest")
499 blockAlignment = ScrollAlignment::alignToEdgeIfNeeded;
500
501 // Inline Alignment to the top / bottom and to the closest edge.
502 ScrollAlignment inlineAlignment = ScrollAlignment::alignToEdgeIfNeeded;
503 if (options.inlinePosition() == "start")
504 inlineAlignment = ScrollAlignment::alignLeftAlways;
505 else if (options.inlinePosition() == "center")
506 inlineAlignment = ScrollAlignment::alignCenterAlways;
507 else if (options.inlinePosition() == "end")
508 inlineAlignment = ScrollAlignment::alignRightAlways;
509
440 LayoutRect bounds = boundingBox(); 510 LayoutRect bounds = boundingBox();
441 // Align to the top / bottom and to the closest edge. 511 layoutObject()->scrollRectToVisible(bounds, inlineAlignment, blockAlignment,
442 if (alignToTop) 512 ProgrammaticScroll,
443 layoutObject()->scrollRectToVisible( 513 makeVisibleInVisualViewport, behavior);
444 bounds, ScrollAlignment::alignToEdgeIfNeeded, 514
445 ScrollAlignment::alignTopAlways, ProgrammaticScroll, 515 if (document().page()->scrollingCoordinator()) {
446 makeVisibleInVisualViewport); 516 document()
447 else 517 .page()
448 layoutObject()->scrollRectToVisible( 518 ->scrollingCoordinator()
449 bounds, ScrollAlignment::alignToEdgeIfNeeded, 519 ->programmaticScrollCoordinator()
450 ScrollAlignment::alignBottomAlways, ProgrammaticScroll, 520 ->runQueuedAnimations();
451 makeVisibleInVisualViewport); 521 }
452 522
453 document().setSequentialFocusNavigationStartingPoint(this); 523 document().setSequentialFocusNavigationStartingPoint(this);
454 } 524 }
455 525
456 void Element::scrollIntoViewIfNeeded(bool centerIfNeeded) { 526 void Element::scrollIntoViewIfNeeded(bool centerIfNeeded) {
457 document().updateStyleAndLayoutIgnorePendingStylesheetsForNode(this); 527 document().updateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
458 528
459 if (!layoutObject()) 529 if (!layoutObject())
460 return; 530 return;
461 531
(...skipping 3770 matching lines...) Expand 10 before | Expand all | Expand 10 after
4232 } 4302 }
4233 4303
4234 DEFINE_TRACE_WRAPPERS(Element) { 4304 DEFINE_TRACE_WRAPPERS(Element) {
4235 if (hasRareData()) { 4305 if (hasRareData()) {
4236 visitor->traceWrappers(elementRareData()); 4306 visitor->traceWrappers(elementRareData());
4237 } 4307 }
4238 ContainerNode::traceWrappers(visitor); 4308 ContainerNode::traceWrappers(visitor);
4239 } 4309 }
4240 4310
4241 } // namespace blink 4311 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698