OLD | NEW |
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/dom/IntersectionObservation.h" | 5 #include "core/dom/IntersectionObservation.h" |
6 | 6 |
7 #include "core/dom/ElementRareData.h" | 7 #include "core/dom/ElementRareData.h" |
8 #include "core/dom/IntersectionObserver.h" | 8 #include "core/dom/IntersectionObserver.h" |
9 #include "core/frame/FrameView.h" | 9 #include "core/frame/FrameView.h" |
10 #include "core/layout/LayoutBox.h" | 10 #include "core/layout/LayoutBox.h" |
11 #include "core/layout/LayoutText.h" | 11 #include "core/layout/LayoutText.h" |
12 #include "core/layout/LayoutView.h" | 12 #include "core/layout/LayoutView.h" |
13 #include "core/paint/PaintLayer.h" | 13 #include "core/paint/PaintLayer.h" |
14 | 14 |
15 namespace blink { | 15 namespace blink { |
16 | 16 |
17 IntersectionObservation::IntersectionObservation(IntersectionObserver& observer,
Element& target, bool shouldReportRootBounds) | 17 IntersectionObservation::IntersectionObservation(IntersectionObserver& observer,
Element& target, bool shouldReportRootBounds) |
18 : m_observer(observer) | 18 : m_observer(observer) |
19 , m_target(target.ensureIntersectionObserverData().createWeakPtr(&target)) | 19 , m_target(target.ensureIntersectionObserverData().createWeakPtr(&target)) |
20 , m_active(true) | 20 , m_active(true) |
21 , m_shouldReportRootBounds(shouldReportRootBounds) | 21 , m_shouldReportRootBounds(shouldReportRootBounds) |
22 , m_lastThresholdIndex(0) | 22 , m_lastThresholdIndex(0) |
23 { | 23 { |
24 } | 24 } |
25 | 25 |
26 Element* IntersectionObservation::target() const | |
27 { | |
28 return toElement(m_target.get()); | |
29 } | |
30 | |
31 void IntersectionObservation::initializeGeometry(IntersectionGeometry& geometry) | 26 void IntersectionObservation::initializeGeometry(IntersectionGeometry& geometry) |
32 { | 27 { |
33 ASSERT(m_target); | 28 ASSERT(m_target); |
34 LayoutObject* targetLayoutObject = target()->layoutObject(); | 29 LayoutObject* targetLayoutObject = m_target->layoutObject(); |
35 if (targetLayoutObject->isBoxModelObject()) | 30 if (targetLayoutObject->isBoxModelObject()) |
36 geometry.targetRect = toLayoutBoxModelObject(targetLayoutObject)->visual
OverflowRect(); | 31 geometry.targetRect = toLayoutBoxModelObject(targetLayoutObject)->visual
OverflowRect(); |
37 else | 32 else |
38 geometry.targetRect = toLayoutText(targetLayoutObject)->visualOverflowRe
ct(); | 33 geometry.targetRect = toLayoutText(targetLayoutObject)->visualOverflowRe
ct(); |
39 geometry.intersectionRect = geometry.targetRect; | 34 geometry.intersectionRect = geometry.targetRect; |
40 } | 35 } |
41 | 36 |
42 void IntersectionObservation::clipToRoot(LayoutRect& rect) | 37 void IntersectionObservation::clipToRoot(LayoutRect& rect) |
43 { | 38 { |
44 // Map and clip rect into root element coordinates. | 39 // Map and clip rect into root element coordinates. |
45 // TODO(szager): the writing mode flipping needs a test. | 40 // TODO(szager): the writing mode flipping needs a test. |
46 ASSERT(m_target); | 41 ASSERT(m_target); |
47 LayoutObject* rootLayoutObject = m_observer->rootLayoutObject(); | 42 LayoutObject* rootLayoutObject = m_observer->rootLayoutObject(); |
48 LayoutObject* targetLayoutObject = target()->layoutObject(); | 43 LayoutObject* targetLayoutObject = m_target->layoutObject(); |
49 targetLayoutObject->mapToVisibleRectInAncestorSpace(toLayoutBoxModelObject(r
ootLayoutObject), rect, nullptr); | 44 targetLayoutObject->mapToVisibleRectInAncestorSpace(toLayoutBoxModelObject(r
ootLayoutObject), rect, nullptr); |
50 if (rootLayoutObject->hasOverflowClip()) { | 45 if (rootLayoutObject->hasOverflowClip()) { |
51 LayoutBox* rootLayoutBox = toLayoutBox(rootLayoutObject); | 46 LayoutBox* rootLayoutBox = toLayoutBox(rootLayoutObject); |
52 LayoutRect clipRect(LayoutPoint(), LayoutSize(rootLayoutBox->layer()->si
ze())); | 47 LayoutRect clipRect(LayoutPoint(), LayoutSize(rootLayoutBox->layer()->si
ze())); |
53 m_observer->applyRootMargin(clipRect); | 48 m_observer->applyRootMargin(clipRect); |
54 rootLayoutBox->flipForWritingMode(rect); | 49 rootLayoutBox->flipForWritingMode(rect); |
55 rect.intersect(clipRect); | 50 rect.intersect(clipRect); |
56 rootLayoutBox->flipForWritingMode(rect); | 51 rootLayoutBox->flipForWritingMode(rect); |
57 } | 52 } |
58 } | 53 } |
59 | 54 |
60 void IntersectionObservation::clipToFrameView(IntersectionGeometry& geometry) | 55 void IntersectionObservation::clipToFrameView(IntersectionGeometry& geometry) |
61 { | 56 { |
62 Node* rootNode = m_observer->root(); | 57 Element* rootElement = m_observer->root(); |
63 LayoutObject* rootLayoutObject = m_observer->rootLayoutObject(); | 58 LayoutObject* rootLayoutObject = m_observer->rootLayoutObject(); |
64 if (rootLayoutObject->isLayoutView()) { | 59 if (rootElement == rootElement->document().documentElement()) { |
65 geometry.rootRect = LayoutRect(toLayoutView(rootLayoutObject)->frameView
()->visibleContentRect()); | 60 geometry.rootRect = LayoutRect(rootElement->document().view()->visibleCo
ntentRect()); |
66 m_observer->applyRootMargin(geometry.rootRect); | 61 m_observer->applyRootMargin(geometry.rootRect); |
67 geometry.intersectionRect.intersect(geometry.rootRect); | 62 geometry.intersectionRect.intersect(geometry.rootRect); |
68 } else { | 63 } else { |
69 if (rootLayoutObject->isBox()) | 64 if (rootLayoutObject->isBox()) |
70 geometry.rootRect = LayoutRect(toLayoutBox(rootLayoutObject)->absolu
teContentBox()); | 65 geometry.rootRect = LayoutRect(toLayoutBox(rootLayoutObject)->absolu
teContentBox()); |
71 else | 66 else |
72 geometry.rootRect = LayoutRect(rootLayoutObject->absoluteBoundingBox
Rect()); | 67 geometry.rootRect = LayoutRect(rootLayoutObject->absoluteBoundingBox
Rect()); |
73 m_observer->applyRootMargin(geometry.rootRect); | 68 m_observer->applyRootMargin(geometry.rootRect); |
74 } | 69 } |
75 | 70 |
76 LayoutPoint scrollPosition(rootNode->document().view()->scrollPosition()); | 71 LayoutPoint scrollPosition(rootElement->document().view()->scrollPosition())
; |
77 geometry.targetRect.moveBy(-scrollPosition); | 72 geometry.targetRect.moveBy(-scrollPosition); |
78 geometry.intersectionRect.moveBy(-scrollPosition); | 73 geometry.intersectionRect.moveBy(-scrollPosition); |
79 geometry.rootRect.moveBy(-scrollPosition); | 74 geometry.rootRect.moveBy(-scrollPosition); |
80 } | 75 } |
81 | 76 |
82 static void mapRectToDocumentCoordinates(LayoutObject& layoutObject, LayoutRect&
rect) | 77 static void mapRectToDocumentCoordinates(LayoutObject& layoutObject, LayoutRect&
rect) |
83 { | 78 { |
84 rect = LayoutRect(layoutObject.localToAbsoluteQuad(FloatQuad(FloatRect(rect)
), UseTransforms | ApplyContainerFlip | TraverseDocumentBoundaries).boundingBox(
)); | 79 rect = LayoutRect(layoutObject.localToAbsoluteQuad(FloatQuad(FloatRect(rect)
), UseTransforms | ApplyContainerFlip | TraverseDocumentBoundaries).boundingBox(
)); |
85 } | 80 } |
86 | 81 |
87 bool IntersectionObservation::computeGeometry(IntersectionGeometry& geometry) | 82 bool IntersectionObservation::computeGeometry(IntersectionGeometry& geometry) |
88 { | 83 { |
89 ASSERT(m_target); | 84 ASSERT(m_target); |
90 LayoutObject* rootLayoutObject = m_observer->rootLayoutObject(); | 85 LayoutObject* rootLayoutObject = m_observer->rootLayoutObject(); |
91 LayoutObject* targetLayoutObject = target()->layoutObject(); | 86 LayoutObject* targetLayoutObject = m_target->layoutObject(); |
92 if (!rootLayoutObject->isBoxModelObject()) | 87 if (!rootLayoutObject->isBoxModelObject()) |
93 return false; | 88 return false; |
94 if (!targetLayoutObject->isBoxModelObject() && !targetLayoutObject->isText()
) | 89 if (!targetLayoutObject->isBoxModelObject() && !targetLayoutObject->isText()
) |
95 return false; | 90 return false; |
96 | 91 |
97 // Initialize targetRect and intersectionRect to bounds of target, in target
's coordinate space. | 92 // Initialize targetRect and intersectionRect to bounds of target, in target
's coordinate space. |
98 initializeGeometry(geometry); | 93 initializeGeometry(geometry); |
99 | 94 |
100 // TODO(szager): Support intersection observations for zero-area targets. F
or now, we just | 95 // TODO(szager): Support intersection observations for zero-area targets. F
or now, we just |
101 // punt on the observation. | 96 // punt on the observation. |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 pixelSnappedIntRect(geometry.intersectionRect), | 150 pixelSnappedIntRect(geometry.intersectionRect), |
156 targetElement); | 151 targetElement); |
157 observer().enqueueIntersectionObserverEntry(*newEntry); | 152 observer().enqueueIntersectionObserverEntry(*newEntry); |
158 } | 153 } |
159 setLastThresholdIndex(newThresholdIndex); | 154 setLastThresholdIndex(newThresholdIndex); |
160 } | 155 } |
161 | 156 |
162 void IntersectionObservation::disconnect() | 157 void IntersectionObservation::disconnect() |
163 { | 158 { |
164 if (m_target) | 159 if (m_target) |
165 target()->ensureIntersectionObserverData().removeObservation(this->obser
ver()); | 160 m_target->ensureIntersectionObserverData().removeObservation(this->obser
ver()); |
166 m_observer->removeObservation(*this); | 161 m_observer->removeObservation(*this); |
167 m_observer.clear(); | 162 m_observer.clear(); |
168 } | 163 } |
169 | 164 |
170 DEFINE_TRACE(IntersectionObservation) | 165 DEFINE_TRACE(IntersectionObservation) |
171 { | 166 { |
172 visitor->trace(m_observer); | 167 visitor->trace(m_observer); |
173 visitor->trace(m_target); | 168 visitor->trace(m_target); |
174 } | 169 } |
175 | 170 |
176 } // namespace blink | 171 } // namespace blink |
OLD | NEW |