| Index: Source/core/dom/Element.cpp
|
| diff --git a/Source/core/dom/Element.cpp b/Source/core/dom/Element.cpp
|
| index 11fd64410aed458f4724644c0aa80bf11ce89a07..3e566abf16ce2457f0f45f2980a0d8e2cbe0a6b2 100644
|
| --- a/Source/core/dom/Element.cpp
|
| +++ b/Source/core/dom/Element.cpp
|
| @@ -113,7 +113,9 @@
|
| #include "core/page/Page.h"
|
| #include "core/page/PointerLockController.h"
|
| #include "core/page/SpatialNavigation.h"
|
| +#include "core/page/scrolling/ScrollCustomizationCallbacks.h"
|
| #include "core/page/scrolling/ScrollState.h"
|
| +#include "core/page/scrolling/ScrollStateCallback.h"
|
| #include "core/paint/DeprecatedPaintLayer.h"
|
| #include "core/svg/SVGDocumentExtensions.h"
|
| #include "core/svg/SVGElement.h"
|
| @@ -129,6 +131,25 @@
|
|
|
| namespace blink {
|
|
|
| +namespace {
|
| +
|
| +// We need to retain the scroll customization callbacks until the element
|
| +// they're associated with is destroyed. It would be simplest if the callbacks
|
| +// could be stored in ElementRareData, but we can't afford the space
|
| +// increase. Instead, keep the scroll customization callbacks here. The other
|
| +// option would be to store these callbacks on the FrameHost or document, but
|
| +// that necessitates a bunch more logic for transferring the callbacks between
|
| +// FrameHosts when elements are moved around.
|
| +ScrollCustomizationCallbacks& scrollCustomizationCallbacks()
|
| +{
|
| + ASSERT(RuntimeEnabledFeatures::scrollCustomizationEnabled());
|
| + DEFINE_STATIC_LOCAL(Persistent<ScrollCustomizationCallbacks>,
|
| + scrollCustomizationCallbacks, (new ScrollCustomizationCallbacks()));
|
| + return *scrollCustomizationCallbacks;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| using namespace HTMLNames;
|
| using namespace XMLNames;
|
|
|
| @@ -156,6 +177,9 @@ Element::~Element()
|
| if (isCustomElement())
|
| CustomElement::wasDestroyed(this);
|
|
|
| + if (RuntimeEnabledFeatures::scrollCustomizationEnabled())
|
| + scrollCustomizationCallbacks().removeCallbacksForElement(this);
|
| +
|
| // With Oilpan, either the Element has been removed from the Document
|
| // or the Document is dead as well. If the Element has been removed from
|
| // the Document the element has already been removed from the pending
|
| @@ -471,7 +495,19 @@ void Element::scrollIntoViewIfNeeded(bool centerIfNeeded)
|
| layoutObject()->scrollRectToVisible(bounds, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
|
| }
|
|
|
| -void Element::distributeScroll(ScrollState& scrollState)
|
| +void Element::setDistributeScroll(ScrollStateCallback* scrollStateCallback, String nativeScrollBehavior)
|
| +{
|
| + scrollStateCallback->setNativeScrollBehavior(ScrollStateCallback::toNativeScrollBehavior(nativeScrollBehavior));
|
| + scrollCustomizationCallbacks().setDistributeScroll(this, scrollStateCallback);
|
| +}
|
| +
|
| +void Element::setApplyScroll(ScrollStateCallback* scrollStateCallback, String nativeScrollBehavior)
|
| +{
|
| + scrollStateCallback->setNativeScrollBehavior(ScrollStateCallback::toNativeScrollBehavior(nativeScrollBehavior));
|
| + scrollCustomizationCallbacks().setApplyScroll(this, scrollStateCallback);
|
| +}
|
| +
|
| +void Element::nativeDistributeScroll(ScrollState& scrollState)
|
| {
|
| ASSERT(RuntimeEnabledFeatures::scrollCustomizationEnabled());
|
| if (scrollState.fullyConsumed())
|
| @@ -491,13 +527,29 @@ void Element::distributeScroll(ScrollState& scrollState)
|
| const double deltaX = scrollState.deltaX();
|
| const double deltaY = scrollState.deltaY();
|
|
|
| - applyScroll(scrollState);
|
| + callApplyScroll(scrollState);
|
|
|
| if (deltaX != scrollState.deltaX() || deltaY != scrollState.deltaY())
|
| scrollState.setCurrentNativeScrollingElement(this);
|
| }
|
|
|
| -void Element::applyScroll(ScrollState& scrollState)
|
| +void Element::callDistributeScroll(ScrollState& scrollState)
|
| +{
|
| + ScrollStateCallback* callback = scrollCustomizationCallbacks().getDistributeScroll(this);
|
| + if (!callback) {
|
| + nativeDistributeScroll(scrollState);
|
| + return;
|
| + }
|
| +
|
| + if (callback->nativeScrollBehavior() != NativeScrollBehavior::PerformAfterNativeScroll)
|
| + callback->handleEvent(&scrollState);
|
| + if (callback->nativeScrollBehavior() != NativeScrollBehavior::DisableNativeScroll)
|
| + nativeDistributeScroll(scrollState);
|
| + if (callback->nativeScrollBehavior() == NativeScrollBehavior::PerformAfterNativeScroll)
|
| + callback->handleEvent(&scrollState);
|
| +};
|
| +
|
| +void Element::nativeApplyScroll(ScrollState& scrollState)
|
| {
|
| ASSERT(RuntimeEnabledFeatures::scrollCustomizationEnabled());
|
| if (scrollState.fullyConsumed())
|
| @@ -507,8 +559,11 @@ void Element::applyScroll(ScrollState& scrollState)
|
| const double deltaY = scrollState.deltaY();
|
| bool scrolled = false;
|
|
|
| - // Handle the documentElement separately, as it scrolls the FrameView.
|
| - if (this == document().documentElement()) {
|
| + if (deltaY || deltaX)
|
| + document().updateLayoutIgnorePendingStylesheets();
|
| +
|
| + // Handle the scrollingElement separately, as it scrolls the viewport.
|
| + if (this == document().scrollingElement()) {
|
| FloatSize delta(deltaX, deltaY);
|
| if (document().frame()->applyScrollDelta(delta, scrollState.isBeginning()).didScroll()) {
|
| scrolled = true;
|
| @@ -545,6 +600,22 @@ void Element::applyScroll(ScrollState& scrollState)
|
| }
|
| };
|
|
|
| +void Element::callApplyScroll(ScrollState& scrollState)
|
| +{
|
| + ScrollStateCallback* callback = scrollCustomizationCallbacks().getApplyScroll(this);
|
| + if (!callback) {
|
| + nativeApplyScroll(scrollState);
|
| + return;
|
| + }
|
| +
|
| + if (callback->nativeScrollBehavior() != NativeScrollBehavior::PerformAfterNativeScroll)
|
| + callback->handleEvent(&scrollState);
|
| + if (callback->nativeScrollBehavior() != NativeScrollBehavior::DisableNativeScroll)
|
| + nativeApplyScroll(scrollState);
|
| + if (callback->nativeScrollBehavior() == NativeScrollBehavior::PerformAfterNativeScroll)
|
| + callback->handleEvent(&scrollState);
|
| +};
|
| +
|
| static float localZoomForLayoutObject(LayoutObject& layoutObject)
|
| {
|
| // FIXME: This does the wrong thing if two opposing zooms are in effect and canceled each
|
|
|