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

Unified Diff: third_party/WebKit/Source/core/page/scrolling/RootScroller.cpp

Issue 1913843004: Implementing document.setRootScroller API for main thread scrolling. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@overscrollController
Patch Set: Rebase and remove whitespace in Document.idl Created 4 years, 8 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/page/scrolling/RootScroller.cpp
diff --git a/third_party/WebKit/Source/core/page/scrolling/RootScroller.cpp b/third_party/WebKit/Source/core/page/scrolling/RootScroller.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e89c0fcc0f39dbfd9a2f37afcd5fb92c43c47e6e
--- /dev/null
+++ b/third_party/WebKit/Source/core/page/scrolling/RootScroller.cpp
@@ -0,0 +1,159 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/page/scrolling/RootScroller.h"
+
+#include "core/dom/Element.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/FrameView.h"
+#include "core/layout/LayoutBox.h"
+#include "core/page/Page.h"
+#include "core/page/scrolling/ViewportScrollCallback.h"
+#include "core/paint/PaintLayerScrollableArea.h"
+#include "platform/scroll/ScrollableArea.h"
+
+namespace blink {
+
+namespace {
+
+Document* topDocument(FrameHost* frameHost)
+{
+ DCHECK(frameHost);
+ if (!frameHost->page().mainFrame())
+ return nullptr;
+
+ DCHECK(frameHost->page().mainFrame()->isLocalFrame());
esprehn 2016/05/05 17:29:46 There's no reason to go through the FrameHost like
bokan 2016/05/05 21:19:48 Acknowledged.
+ return toLocalFrame(frameHost->page().mainFrame())->document();
+}
+
+ScrollableArea* scrollableAreaFor(Element& element)
+{
+ if (!element.layoutObject() || !element.layoutObject()->isBox())
+ return nullptr;
+
+ LayoutBox* box = toLayoutBox(element.layoutObject());
+
+ if (box->isDocumentElement() && element.document().view())
esprehn 2016/05/05 17:29:46 it's impossible for view() to be null here if the
bokan 2016/05/05 21:19:49 Acknowledged.
+ return element.document().view()->getScrollableArea();
+
+ return static_cast<PaintInvalidationCapableScrollableArea*>(
esprehn 2016/05/05 17:29:46 this needs a toPaintInvalidationCapableScrollableA
bokan 2016/05/05 21:19:49 This is an upcast though. LayoutBoxModelObject::ge
+ box->getScrollableArea());
+}
+
+} // namespace
+
+RootScroller::RootScroller(FrameHost& frameHost)
+ : m_frameHost(&frameHost)
esprehn 2016/05/05 17:29:46 use a Frame, not the FrameHost.
bokan 2016/05/05 21:19:48 Yah, I hadn't thought this through and had a 1 Roo
+{
+}
+
+DEFINE_TRACE(RootScroller)
+{
+ visitor->trace(m_frameHost);
+ visitor->trace(m_viewportApplyScroll);
+ visitor->trace(m_rootScroller);
+}
+
+bool RootScroller::set(Element& newRootScroller)
+{
+ if (!isValid(newRootScroller))
+ return false;
+
+ DCHECK(m_frameHost);
+
+ Document* document = topDocument(m_frameHost);
+ if (!document)
+ return false;
+
+ ScrollableArea* newRootScrollableArea = scrollableAreaFor(newRootScroller);
+ if (!newRootScrollableArea)
+ return false;
+
+ if (m_rootScroller)
+ m_rootScroller->removeApplyScroll();
+
+ m_rootScroller = &newRootScroller;
+
+ createApplyScrollIfNeeded();
+
+ // Ideally, the scrolling infrastructure would pass this to the callback but
+ // we don't get that today so we set it manually.
+ m_viewportApplyScroll->setScroller(*newRootScrollableArea);
+
+ // Installs the viewport scrolling callback (the "applyScroll" in Scroll
+ // Customization lingo) on the given element. This callback is
+ // responsible for viewport related scroll actions like top controls
+ // movement and overscroll glow as well as actually scrolling the element.
+ // Use disable-native-scroll since the ViewportScrollCallback needs to
+ // apply scroll actions before (TopControls) and after (overscroll)
+ // scrolling the element so it applies scroll to the element itself.
+ m_rootScroller->setApplyScroll(
+ m_viewportApplyScroll,
+ "disable-native-scroll");
+
+ return true;
+}
+
+Element* RootScroller::get() const
+{
+ if (!m_frameHost)
+ return nullptr;
+
+ return m_rootScroller;
+}
+
+void RootScroller::resetToDefault()
+{
+ if (!m_frameHost)
+ return;
+
+ Document* document = topDocument(m_frameHost);
+ if (!document)
+ return;
+
+ if (Element* defaultRootElement = document->documentElement())
+ set(*defaultRootElement);
+}
+
+void RootScroller::didUpdateTopDocumentLayout()
+{
+ if (m_rootScroller && isValid(*m_rootScroller))
+ return;
+
+ resetToDefault();
+}
+
+bool RootScroller::isValid(Element& element) const
+{
+ if (!m_frameHost)
+ return false;
+
+ if (element.document() != topDocument(m_frameHost))
esprehn 2016/05/05 17:29:46 you want to hook Element::removedFrom not layout f
bokan 2016/05/05 21:19:48 There's other cases that make an Element invalid t
+ return false;
+
+ if (!element.isInTreeScope())
esprehn 2016/05/05 17:29:46 the layoutObject check below is a proxy for this,
bokan 2016/05/05 21:19:48 Acknowledged.
+ return false;
+
+ if (!element.layoutObject())
esprehn 2016/05/05 17:29:46 this check doesn't make sense, it means if you dis
bokan 2016/05/05 21:19:48 Yah, that was the intention, though I can see that
+ return false;
+
+ if (!element.layoutObject()->isLayoutBlockFlow()
+ && !element.layoutObject()->isLayoutIFrame())
+ return false;
+
+ return true;
+}
+
+void RootScroller::createApplyScrollIfNeeded()
+{
+ if (!m_viewportApplyScroll) {
+ TopControls& topControls = m_frameHost->topControls();
+ OverscrollController& overscrollController =
+ m_frameHost->overscrollController();
+ m_viewportApplyScroll =
+ new ViewportScrollCallback(topControls, overscrollController);
+ }
+}
+
+} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698