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

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

Issue 1970763002: Fixed up root scroller API to be more webby (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 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 unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/page/scrolling/RootScroller.h" 5 #include "core/page/scrolling/RootScroller.h"
6 6
7 #include "core/dom/Document.h"
7 #include "core/dom/Element.h" 8 #include "core/dom/Element.h"
8 #include "core/frame/FrameHost.h" 9 #include "core/frame/FrameHost.h"
9 #include "core/frame/FrameView.h" 10 #include "core/frame/FrameView.h"
11 #include "core/frame/TopControls.h"
10 #include "core/layout/LayoutBox.h" 12 #include "core/layout/LayoutBox.h"
11 #include "core/page/Page.h" 13 #include "core/page/Page.h"
14 #include "core/page/scrolling/OverscrollController.h"
12 #include "core/page/scrolling/ViewportScrollCallback.h" 15 #include "core/page/scrolling/ViewportScrollCallback.h"
13 #include "core/paint/PaintLayerScrollableArea.h" 16 #include "core/paint/PaintLayerScrollableArea.h"
14 #include "platform/scroll/ScrollableArea.h" 17 #include "platform/scroll/ScrollableArea.h"
15 18
16 namespace blink { 19 namespace blink {
17 20
18 namespace { 21 namespace {
19 22
20 Document* topDocument(FrameHost* frameHost) 23 ScrollableArea* scrollableAreaFor(const Element& element)
21 {
22 DCHECK(frameHost);
23 if (!frameHost->page().mainFrame())
24 return nullptr;
25
26 DCHECK(frameHost->page().mainFrame()->isLocalFrame());
27 return toLocalFrame(frameHost->page().mainFrame())->document();
28 }
29
30 ScrollableArea* scrollableAreaFor(Element& element)
31 { 24 {
32 if (!element.layoutObject() || !element.layoutObject()->isBox()) 25 if (!element.layoutObject() || !element.layoutObject()->isBox())
33 return nullptr; 26 return nullptr;
34 27
35 LayoutBox* box = toLayoutBox(element.layoutObject()); 28 LayoutBox* box = toLayoutBox(element.layoutObject());
36 29
37 if (box->isDocumentElement() && element.document().view()) 30 if (box->isDocumentElement())
38 return element.document().view()->getScrollableArea(); 31 return element.document().view()->getScrollableArea();
39 32
40 return static_cast<PaintInvalidationCapableScrollableArea*>( 33 return static_cast<PaintInvalidationCapableScrollableArea*>(
41 box->getScrollableArea()); 34 box->getScrollableArea());
42 } 35 }
43 36
37 bool fillsViewport(const Element& element)
38 {
39 DCHECK(element.layoutObject());
40 DCHECK(element.layoutObject()->isBox());
41
42 LayoutObject* layoutObject = element.layoutObject();
43 Document& topDocument = element.document().topDocument();
esprehn 2016/05/11 17:37:05 hmm, this might be broken for OOPIF. I bet it is.
bokan 2016/06/02 15:49:55 Acknowledged. Added a TODO.
44
45 Vector<FloatQuad> quads;
46 layoutObject->absoluteQuads(quads);
47 DCHECK_EQ(quads.size(), 1u);
48
49 if (!quads[0].isRectilinear())
50 return false;
51
52 LayoutRect boundingBox(quads[0].boundingBox());
53
54 return boundingBox.location() == LayoutPoint::zero()
55 && boundingBox.size() == topDocument.layoutViewItem().size();
56 }
57
58 bool isValidRootScroller(const Element& element)
59 {
60 if (!element.layoutObject())
61 return false;
62
63 if (!scrollableAreaFor(element))
64 return false;
65
66 if (!fillsViewport(element))
67 return false;
68
69 return true;
70 }
71
44 } // namespace 72 } // namespace
45 73
46 RootScroller::RootScroller(FrameHost& frameHost) 74 ViewportScrollCallback* RootScroller::createViewportApplyScroll(
47 : m_frameHost(&frameHost) 75 TopControls& topControls, OverscrollController& overscrollController)
76 {
77 return new ViewportScrollCallback(topControls, overscrollController);
78 }
79
80 RootScroller::RootScroller(Document& document, ViewportScrollCallback* applyScro llCallback)
81 : m_document(&document)
82 , m_viewportApplyScroll(applyScrollCallback)
48 { 83 {
49 } 84 }
50 85
51 DEFINE_TRACE(RootScroller) 86 DEFINE_TRACE(RootScroller)
52 { 87 {
53 visitor->trace(m_frameHost); 88 visitor->trace(m_document);
54 visitor->trace(m_viewportApplyScroll); 89 visitor->trace(m_viewportApplyScroll);
55 visitor->trace(m_rootScroller); 90 visitor->trace(m_rootScroller);
91 visitor->trace(m_effectiveRootScroller);
56 } 92 }
57 93
58 bool RootScroller::set(Element& newRootScroller) 94 void RootScroller::set(Element* newRootScroller)
esprehn 2016/05/11 17:37:05 I think I'd rename this to RootScrollController or
bokan 2016/06/02 15:49:55 Acknowledged.
59 { 95 {
60 if (!isValid(newRootScroller)) 96 m_rootScroller = newRootScroller;
61 return false; 97 updateEffectiveRootScroller();
62
63 DCHECK(m_frameHost);
64
65 Document* document = topDocument(m_frameHost);
66 if (!document)
67 return false;
68
69 ScrollableArea* newRootScrollableArea = scrollableAreaFor(newRootScroller);
70 if (!newRootScrollableArea)
71 return false;
72
73 if (m_rootScroller)
74 m_rootScroller->removeApplyScroll();
75
76 m_rootScroller = &newRootScroller;
77
78 createApplyScrollIfNeeded();
79
80 // Ideally, the scrolling infrastructure would pass this to the callback but
81 // we don't get that today so we set it manually.
82 m_viewportApplyScroll->setScroller(*newRootScrollableArea);
83
84 // Installs the viewport scrolling callback (the "applyScroll" in Scroll
85 // Customization lingo) on the given element. This callback is
86 // responsible for viewport related scroll actions like top controls
87 // movement and overscroll glow as well as actually scrolling the element.
88 // Use disable-native-scroll since the ViewportScrollCallback needs to
89 // apply scroll actions before (TopControls) and after (overscroll)
90 // scrolling the element so it applies scroll to the element itself.
91 m_rootScroller->setApplyScroll(
92 m_viewportApplyScroll,
93 "disable-native-scroll");
94
95 return true;
96 } 98 }
97 99
98 Element* RootScroller::get() const 100 Element* RootScroller::get() const
99 { 101 {
100 if (!m_frameHost)
101 return nullptr;
102
103 return m_rootScroller; 102 return m_rootScroller;
104 } 103 }
105 104
106 void RootScroller::resetToDefault() 105 Element* RootScroller::effectiveRootScroller() const
107 { 106 {
108 if (!m_frameHost) 107 return m_effectiveRootScroller;
108 }
109
110 void RootScroller::didUpdateLayout()
111 {
112 updateEffectiveRootScroller();
esprehn 2016/05/11 17:37:05 we probably want to only do this for pipeline upda
bokan 2016/06/02 15:49:55 Acknowledged.
113 }
114
115 void RootScroller::updateEffectiveRootScroller()
116 {
117 bool rootScrollerValid =
118 m_rootScroller && isValidRootScroller(*m_rootScroller);
119
120 Element* newEffectiveRootScroller = rootScrollerValid
121 ? m_rootScroller.get()
122 : defaultEffectiveRootScroller();
123
124 if (m_effectiveRootScroller == newEffectiveRootScroller)
109 return; 125 return;
110 126
111 Document* document = topDocument(m_frameHost); 127 moveViewportApplyScroll(newEffectiveRootScroller);
112 if (!document) 128 m_effectiveRootScroller = newEffectiveRootScroller;
129 }
130
131 void RootScroller::moveViewportApplyScroll(Element* target)
132 {
133 if (!m_viewportApplyScroll)
113 return; 134 return;
114 135
115 if (Element* defaultRootElement = document->documentElement()) 136 if (m_effectiveRootScroller)
116 set(*defaultRootElement); 137 m_effectiveRootScroller->removeApplyScroll();
138
139 ScrollableArea* targetScroller = nullptr;
140
141 if (target) {
142 targetScroller = scrollableAreaFor(*target);
143 DCHECK(targetScroller);
144
145 // Use disable-native-scroll since the ViewportScrollCallback needs to
146 // apply scroll actions both before (TopControls) and after (overscroll)
147 // scrolling the element so it will apply scroll to the element itself.
148 target->setApplyScroll(
149 m_viewportApplyScroll,
150 "disable-native-scroll");
151 }
152
153 // Ideally, scroll customization would pass the current element to scroll to
154 // the apply scroll callback but this doesn't happen today so we set it
155 // through a back door here.
156 m_viewportApplyScroll->setScroller(targetScroller);
117 } 157 }
118 158
119 void RootScroller::didUpdateTopDocumentLayout() 159 Element* RootScroller::defaultEffectiveRootScroller()
120 { 160 {
121 if (m_rootScroller && isValid(*m_rootScroller)) 161 if (!m_document)
122 return; 162 return nullptr;
123 163
124 resetToDefault(); 164 return m_document->documentElement();
125 }
126
127 bool RootScroller::isValid(Element& element) const
128 {
129 if (!m_frameHost)
130 return false;
131
132 if (element.document() != topDocument(m_frameHost))
133 return false;
134
135 if (!element.isInTreeScope())
136 return false;
137
138 if (!element.layoutObject())
139 return false;
140
141 if (!element.layoutObject()->isLayoutBlockFlow()
142 && !element.layoutObject()->isLayoutIFrame())
143 return false;
144
145 return true;
146 }
147
148 void RootScroller::createApplyScrollIfNeeded()
149 {
150 if (!m_viewportApplyScroll) {
151 TopControls& topControls = m_frameHost->topControls();
152 OverscrollController& overscrollController =
153 m_frameHost->overscrollController();
154 m_viewportApplyScroll =
155 new ViewportScrollCallback(topControls, overscrollController);
156 }
157 } 165 }
158 166
159 } // namespace blink 167 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698