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