| 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/IntersectionObserver.h" | 5 #include "core/dom/IntersectionObserver.h" |
| 6 | 6 |
| 7 #include "bindings/core/v8/ExceptionState.h" | 7 #include "bindings/core/v8/ExceptionState.h" |
| 8 #include "core/css/parser/CSSParserTokenRange.h" | 8 #include "core/css/parser/CSSParserTokenRange.h" |
| 9 #include "core/css/parser/CSSTokenizer.h" | 9 #include "core/css/parser/CSSTokenizer.h" |
| 10 #include "core/dom/Element.h" | 10 #include "core/dom/Element.h" |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 ASSERT_NOT_REACHED(); | 151 ASSERT_NOT_REACHED(); |
| 152 break; | 152 break; |
| 153 } | 153 } |
| 154 root.document().ensureIntersectionObserverController().addTrackedObserver(*t
his); | 154 root.document().ensureIntersectionObserverController().addTrackedObserver(*t
his); |
| 155 } | 155 } |
| 156 | 156 |
| 157 void IntersectionObserver::clearWeakMembers(Visitor* visitor) | 157 void IntersectionObserver::clearWeakMembers(Visitor* visitor) |
| 158 { | 158 { |
| 159 if (ThreadHeap::isHeapObjectAlive(m_root)) | 159 if (ThreadHeap::isHeapObjectAlive(m_root)) |
| 160 return; | 160 return; |
| 161 disconnect(); | 161 IgnorableExceptionState exceptionState; |
| 162 disconnect(exceptionState); |
| 162 m_root = nullptr; | 163 m_root = nullptr; |
| 163 } | 164 } |
| 164 | 165 |
| 165 LayoutObject* IntersectionObserver::rootLayoutObject() const | 166 LayoutObject* IntersectionObserver::rootLayoutObject() const |
| 166 { | 167 { |
| 167 Node* node = rootNode(); | 168 Node* node = rootNode(); |
| 168 if (node->isDocumentNode()) | 169 if (node->isDocumentNode()) |
| 169 return toDocument(node)->layoutView(); | 170 return toDocument(node)->layoutView(); |
| 170 return toElement(node)->layoutObject(); | 171 return toElement(node)->layoutObject(); |
| 171 } | 172 } |
| 172 | 173 |
| 173 void IntersectionObserver::observe(Element* target) | 174 void IntersectionObserver::observe(Element* target, ExceptionState& exceptionSta
te) |
| 174 { | 175 { |
| 175 if (!m_root || !target || m_root.get() == target) | 176 if (!m_root) { |
| 177 exceptionState.throwDOMException(InvalidStateError, "observe() called on
an IntersectionObserver with an invalid root."); |
| 178 return; |
| 179 } |
| 180 |
| 181 if (!target || m_root.get() == target) |
| 176 return; | 182 return; |
| 177 | 183 |
| 178 if (target->ensureIntersectionObserverData().getObservationFor(*this)) | 184 if (target->ensureIntersectionObserverData().getObservationFor(*this)) |
| 179 return; | 185 return; |
| 180 | 186 |
| 181 bool shouldReportRootBounds = false; | 187 bool shouldReportRootBounds = false; |
| 182 LocalFrame* targetFrame = target->document().frame(); | 188 LocalFrame* targetFrame = target->document().frame(); |
| 183 LocalFrame* rootFrame = rootNode()->document().frame(); | 189 LocalFrame* rootFrame = rootNode()->document().frame(); |
| 184 if (targetFrame && rootFrame) | 190 if (targetFrame && rootFrame) |
| 185 shouldReportRootBounds = targetFrame->securityContext()->getSecurityOrig
in()->canAccess(rootFrame->securityContext()->getSecurityOrigin()); | 191 shouldReportRootBounds = targetFrame->securityContext()->getSecurityOrig
in()->canAccess(rootFrame->securityContext()->getSecurityOrigin()); |
| 186 IntersectionObservation* observation = new IntersectionObservation(*this, *t
arget, shouldReportRootBounds); | 192 IntersectionObservation* observation = new IntersectionObservation(*this, *t
arget, shouldReportRootBounds); |
| 187 target->ensureIntersectionObserverData().addObservation(*observation); | 193 target->ensureIntersectionObserverData().addObservation(*observation); |
| 188 m_observations.add(observation); | 194 m_observations.add(observation); |
| 189 if (!rootFrame) | 195 if (!rootFrame) |
| 190 return; | 196 return; |
| 191 if (FrameView* rootFrameView = rootFrame->view()) | 197 if (FrameView* rootFrameView = rootFrame->view()) |
| 192 rootFrameView->scheduleAnimation(); | 198 rootFrameView->scheduleAnimation(); |
| 193 } | 199 } |
| 194 | 200 |
| 195 void IntersectionObserver::unobserve(Element* target) | 201 void IntersectionObserver::unobserve(Element* target, ExceptionState& exceptionS
tate) |
| 196 { | 202 { |
| 203 if (!m_root) { |
| 204 exceptionState.throwDOMException(InvalidStateError, "unobserve() called
on an IntersectionObserver with an invalid root."); |
| 205 return; |
| 206 } |
| 207 |
| 197 if (!target || !target->intersectionObserverData()) | 208 if (!target || !target->intersectionObserverData()) |
| 198 return; | 209 return; |
| 199 // TODO(szager): unobserve callback | 210 // TODO(szager): unobserve callback |
| 200 if (IntersectionObservation* observation = target->intersectionObserverData(
)->getObservationFor(*this)) | 211 if (IntersectionObservation* observation = target->intersectionObserverData(
)->getObservationFor(*this)) |
| 201 observation->disconnect(); | 212 observation->disconnect(); |
| 202 } | 213 } |
| 203 | 214 |
| 204 void IntersectionObserver::computeIntersectionObservations() | 215 void IntersectionObserver::computeIntersectionObservations() |
| 205 { | 216 { |
| 206 Document* callbackDocument = toDocument(m_callback->getExecutionContext()); | 217 Document* callbackDocument = toDocument(m_callback->getExecutionContext()); |
| 207 if (!callbackDocument) | 218 if (!callbackDocument) |
| 208 return; | 219 return; |
| 209 LocalDOMWindow* callbackDOMWindow = callbackDocument->domWindow(); | 220 LocalDOMWindow* callbackDOMWindow = callbackDocument->domWindow(); |
| 210 if (!callbackDOMWindow) | 221 if (!callbackDOMWindow) |
| 211 return; | 222 return; |
| 212 DOMHighResTimeStamp timestamp = DOMWindowPerformance::performance(*callbackD
OMWindow)->now(); | 223 DOMHighResTimeStamp timestamp = DOMWindowPerformance::performance(*callbackD
OMWindow)->now(); |
| 213 for (auto& observation : m_observations) | 224 for (auto& observation : m_observations) |
| 214 observation->computeIntersectionObservations(timestamp); | 225 observation->computeIntersectionObservations(timestamp); |
| 215 } | 226 } |
| 216 | 227 |
| 217 void IntersectionObserver::disconnect() | 228 void IntersectionObserver::disconnect(ExceptionState& exceptionState) |
| 218 { | 229 { |
| 230 if (!m_root) { |
| 231 exceptionState.throwDOMException(InvalidStateError, "disconnect() called
on an IntersectionObserver with an invalid root."); |
| 232 return; |
| 233 } |
| 234 |
| 219 for (auto& observation : m_observations) | 235 for (auto& observation : m_observations) |
| 220 observation->clearRootAndRemoveFromTarget(); | 236 observation->clearRootAndRemoveFromTarget(); |
| 221 m_observations.clear(); | 237 m_observations.clear(); |
| 222 } | 238 } |
| 223 | 239 |
| 224 void IntersectionObserver::removeObservation(IntersectionObservation& observatio
n) | 240 void IntersectionObserver::removeObservation(IntersectionObservation& observatio
n) |
| 225 { | 241 { |
| 226 m_observations.remove(&observation); | 242 m_observations.remove(&observation); |
| 227 } | 243 } |
| 228 | 244 |
| 229 HeapVector<Member<IntersectionObserverEntry>> IntersectionObserver::takeRecords(
) | 245 HeapVector<Member<IntersectionObserverEntry>> IntersectionObserver::takeRecords(
ExceptionState& exceptionState) |
| 230 { | 246 { |
| 231 HeapVector<Member<IntersectionObserverEntry>> entries; | 247 HeapVector<Member<IntersectionObserverEntry>> entries; |
| 232 entries.swap(m_entries); | 248 |
| 249 if (!m_root) |
| 250 exceptionState.throwDOMException(InvalidStateError, "takeRecords() calle
d on an IntersectionObserver with an invalid root."); |
| 251 else |
| 252 entries.swap(m_entries); |
| 253 |
| 233 return entries; | 254 return entries; |
| 234 } | 255 } |
| 235 | 256 |
| 236 Element* IntersectionObserver::root() const | 257 Element* IntersectionObserver::root() const |
| 237 { | 258 { |
| 238 Node* node = rootNode(); | 259 Node* node = rootNode(); |
| 239 if (node && !node->isDocumentNode()) | 260 if (node && !node->isDocumentNode()) |
| 240 return toElement(node); | 261 return toElement(node); |
| 241 return nullptr; | 262 return nullptr; |
| 242 } | 263 } |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 | 334 |
| 314 DEFINE_TRACE(IntersectionObserver) | 335 DEFINE_TRACE(IntersectionObserver) |
| 315 { | 336 { |
| 316 visitor->template registerWeakMembers<IntersectionObserver, &IntersectionObs
erver::clearWeakMembers>(this); | 337 visitor->template registerWeakMembers<IntersectionObserver, &IntersectionObs
erver::clearWeakMembers>(this); |
| 317 visitor->trace(m_callback); | 338 visitor->trace(m_callback); |
| 318 visitor->trace(m_observations); | 339 visitor->trace(m_observations); |
| 319 visitor->trace(m_entries); | 340 visitor->trace(m_entries); |
| 320 } | 341 } |
| 321 | 342 |
| 322 } // namespace blink | 343 } // namespace blink |
| OLD | NEW |