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

Side by Side Diff: third_party/WebKit/Source/core/dom/IntersectionObserver.cpp

Issue 2511143006: Detect change on the intersection of video and viewport. (Closed)
Patch Set: Rebase again. Created 4 years 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/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"
11 #include "core/dom/ExceptionCode.h" 11 #include "core/dom/ExceptionCode.h"
12 #include "core/dom/ExecutionContext.h" 12 #include "core/dom/ExecutionContext.h"
13 #include "core/dom/IntersectionObserverCallback.h" 13 #include "core/dom/IntersectionObserverCallback.h"
14 #include "core/dom/IntersectionObserverController.h" 14 #include "core/dom/IntersectionObserverController.h"
15 #include "core/dom/IntersectionObserverEntry.h" 15 #include "core/dom/IntersectionObserverEntry.h"
16 #include "core/dom/IntersectionObserverInit.h" 16 #include "core/dom/IntersectionObserverInit.h"
17 #include "core/dom/NodeIntersectionObserverData.h" 17 #include "core/dom/NodeIntersectionObserverData.h"
18 #include "core/frame/FrameView.h" 18 #include "core/frame/FrameView.h"
19 #include "core/frame/LocalDOMWindow.h" 19 #include "core/frame/LocalDOMWindow.h"
20 #include "core/frame/LocalFrame.h" 20 #include "core/frame/LocalFrame.h"
21 #include "core/html/HTMLFrameOwnerElement.h" 21 #include "core/html/HTMLFrameOwnerElement.h"
22 #include "core/inspector/ConsoleMessage.h" 22 #include "core/inspector/ConsoleMessage.h"
23 #include "core/layout/api/LayoutAPIShim.h"
24 #include "core/layout/api/LayoutViewItem.h"
25 #include "core/timing/DOMWindowPerformance.h" 23 #include "core/timing/DOMWindowPerformance.h"
26 #include "core/timing/Performance.h" 24 #include "core/timing/Performance.h"
27 #include "platform/Timer.h" 25 #include "platform/Timer.h"
28 #include <algorithm> 26 #include <algorithm>
29 27
30 namespace blink { 28 namespace blink {
31 29
32 namespace { 30 namespace {
33 31
34 // Internal implementation of IntersectionObserverCallback when using 32 // Internal implementation of IntersectionObserverCallback when using
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 } 234 }
237 235
238 void IntersectionObserver::clearWeakMembers(Visitor* visitor) { 236 void IntersectionObserver::clearWeakMembers(Visitor* visitor) {
239 if (ThreadHeap::isHeapObjectAlive(m_root)) 237 if (ThreadHeap::isHeapObjectAlive(m_root))
240 return; 238 return;
241 IgnorableExceptionState exceptionState; 239 IgnorableExceptionState exceptionState;
242 disconnect(exceptionState); 240 disconnect(exceptionState);
243 m_root = nullptr; 241 m_root = nullptr;
244 } 242 }
245 243
246 LayoutObject* IntersectionObserver::rootLayoutObject() const {
247 Node* node = rootNode();
248 if (node->isDocumentNode())
249 return LayoutAPIShim::layoutObjectFrom(toDocument(node)->layoutViewItem());
250 return toElement(node)->layoutObject();
251 }
252
253 void IntersectionObserver::observe(Element* target, 244 void IntersectionObserver::observe(Element* target,
254 ExceptionState& exceptionState) { 245 ExceptionState& exceptionState) {
255 if (!m_root) { 246 if (!m_root) {
256 exceptionState.throwDOMException( 247 exceptionState.throwDOMException(
257 InvalidStateError, 248 InvalidStateError,
258 "observe() called on an IntersectionObserver with an invalid root."); 249 "observe() called on an IntersectionObserver with an invalid root.");
259 return; 250 return;
260 } 251 }
261 252
262 if (!target || m_root.get() == target) 253 if (!target || m_root.get() == target)
263 return; 254 return;
264 255
265 if (target->ensureIntersectionObserverData().getObservationFor(*this)) 256 if (target->ensureIntersectionObserverData().getObservationFor(*this))
266 return; 257 return;
267 bool shouldReportRootBounds = false; 258 bool shouldReportRootBounds = false;
268 bool isDOMDescendant = false; 259 bool isDOMDescendant = false;
269 LocalFrame* targetFrame = target->document().frame(); 260 LocalFrame* targetFrame = target->document().frame();
270 LocalFrame* rootFrame = m_root->document().frame(); 261 LocalFrame* rootFrame = m_root->document().frame();
271 262
272 if (target->document() == rootNode()->document()) { 263 if (target->document() == rootNode()->document()) {
273 shouldReportRootBounds = true; 264 shouldReportRootBounds = true;
274 isDOMDescendant = rootNode()->isShadowIncludingInclusiveAncestorOf(target); 265 isDOMDescendant = rootNode()->isShadowIncludingInclusiveAncestorOf(target);
275 } else if (targetFrame && rootFrame) { 266 } else if (targetFrame && rootFrame) {
276 shouldReportRootBounds = 267 shouldReportRootBounds =
277 targetFrame->securityContext()->getSecurityOrigin()->canAccess( 268 targetFrame->securityContext()->getSecurityOrigin()->canAccess(
278 rootFrame->securityContext()->getSecurityOrigin()); 269 rootFrame->securityContext()->getSecurityOrigin());
279 isDOMDescendant = (targetFrame->tree().top() == rootFrame); 270 isDOMDescendant = (targetFrame->tree().top() == rootFrame);
280 } 271 }
281 272
282 IntersectionObservation* observation = 273 IntersectionObservation* observation = new IntersectionObservation(
283 new IntersectionObservation(*this, *target, shouldReportRootBounds); 274 *this, *target,
275 shouldReportRootBounds
276 ? IntersectionGeometry::ReportRootBounds::kShouldReportRootBounds
277 : IntersectionGeometry::ReportRootBounds::kShouldNotReportRootBounds);
284 target->ensureIntersectionObserverData().addObservation(*observation); 278 target->ensureIntersectionObserverData().addObservation(*observation);
285 m_observations.add(observation); 279 m_observations.add(observation);
286 280
287 if (!isDOMDescendant) { 281 if (!isDOMDescendant) {
288 m_root->document().addConsoleMessage( 282 m_root->document().addConsoleMessage(
289 ConsoleMessage::create(JSMessageSource, WarningMessageLevel, 283 ConsoleMessage::create(JSMessageSource, WarningMessageLevel,
290 "IntersectionObserver.observe(target): target " 284 "IntersectionObserver.observe(target): target "
291 "element is not a descendant of root.")); 285 "element is not a descendant of root."));
292 return; 286 return;
293 } 287 }
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 } 393 }
400 394
401 void IntersectionObserver::enqueueIntersectionObserverEntry( 395 void IntersectionObserver::enqueueIntersectionObserverEntry(
402 IntersectionObserverEntry& entry) { 396 IntersectionObserverEntry& entry) {
403 m_entries.append(&entry); 397 m_entries.append(&entry);
404 toDocument(m_callback->getExecutionContext()) 398 toDocument(m_callback->getExecutionContext())
405 ->ensureIntersectionObserverController() 399 ->ensureIntersectionObserverController()
406 .scheduleIntersectionObserverForDelivery(*this); 400 .scheduleIntersectionObserverForDelivery(*this);
407 } 401 }
408 402
409 static LayoutUnit computeMargin(const Length& length,
410 LayoutUnit referenceLength) {
411 if (length.type() == Percent)
412 return LayoutUnit(
413 static_cast<int>(referenceLength.toFloat() * length.percent() / 100.0));
414 DCHECK_EQ(length.type(), Fixed);
415 return LayoutUnit(length.intValue());
416 }
417
418 void IntersectionObserver::applyRootMargin(LayoutRect& rect) const {
419 // TODO(szager): Make sure the spec is clear that left/right margins are
420 // resolved against width and not height.
421 LayoutUnit topMargin = computeMargin(m_topMargin, rect.height());
422 LayoutUnit rightMargin = computeMargin(m_rightMargin, rect.width());
423 LayoutUnit bottomMargin = computeMargin(m_bottomMargin, rect.height());
424 LayoutUnit leftMargin = computeMargin(m_leftMargin, rect.width());
425
426 rect.setX(rect.x() - leftMargin);
427 rect.setWidth(rect.width() + leftMargin + rightMargin);
428 rect.setY(rect.y() - topMargin);
429 rect.setHeight(rect.height() + topMargin + bottomMargin);
430 }
431
432 unsigned IntersectionObserver::firstThresholdGreaterThan(float ratio) const { 403 unsigned IntersectionObserver::firstThresholdGreaterThan(float ratio) const {
433 unsigned result = 0; 404 unsigned result = 0;
434 while (result < m_thresholds.size() && m_thresholds[result] <= ratio) 405 while (result < m_thresholds.size() && m_thresholds[result] <= ratio)
435 ++result; 406 ++result;
436 return result; 407 return result;
437 } 408 }
438 409
439 void IntersectionObserver::deliver() { 410 void IntersectionObserver::deliver() {
440 if (m_entries.isEmpty()) 411 if (m_entries.isEmpty())
441 return; 412 return;
442 413
443 HeapVector<Member<IntersectionObserverEntry>> entries; 414 HeapVector<Member<IntersectionObserverEntry>> entries;
444 entries.swap(m_entries); 415 entries.swap(m_entries);
445 m_callback->handleEvent(entries, *this); 416 m_callback->handleEvent(entries, *this);
446 } 417 }
447 418
448 DEFINE_TRACE(IntersectionObserver) { 419 DEFINE_TRACE(IntersectionObserver) {
449 visitor->template registerWeakMembers< 420 visitor->template registerWeakMembers<
450 IntersectionObserver, &IntersectionObserver::clearWeakMembers>(this); 421 IntersectionObserver, &IntersectionObserver::clearWeakMembers>(this);
451 visitor->trace(m_callback); 422 visitor->trace(m_callback);
452 visitor->trace(m_observations); 423 visitor->trace(m_observations);
453 visitor->trace(m_entries); 424 visitor->trace(m_entries);
454 } 425 }
455 426
456 } // namespace blink 427 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/dom/IntersectionObserver.h ('k') | third_party/WebKit/Source/core/html/HTMLMediaElement.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698