OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * (C) 2001 Dirk Mueller (mueller@kde.org) | 4 * (C) 2001 Dirk Mueller (mueller@kde.org) |
5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) | 5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) |
6 * Copyright (C) 2004-2018 Apple Inc. All rights reserved. | 6 * Copyright (C) 2004-2018 Apple Inc. All rights reserved. |
7 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t
orchmobile.com/) | 7 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t
orchmobile.com/) |
8 * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved. | 8 * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved. |
9 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) | 9 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) |
10 * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved. | 10 * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved. |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 #include "Comment.h" | 46 #include "Comment.h" |
47 #include "CommonVM.h" | 47 #include "CommonVM.h" |
48 #include "CompositionEvent.h" | 48 #include "CompositionEvent.h" |
49 #include "ConstantPropertyMap.h" | 49 #include "ConstantPropertyMap.h" |
50 #include "ContentSecurityPolicy.h" | 50 #include "ContentSecurityPolicy.h" |
51 #include "CookieJar.h" | 51 #include "CookieJar.h" |
52 #include "CustomElementReactionQueue.h" | 52 #include "CustomElementReactionQueue.h" |
53 #include "CustomElementRegistry.h" | 53 #include "CustomElementRegistry.h" |
54 #include "CustomEvent.h" | 54 #include "CustomEvent.h" |
55 #include "DOMImplementation.h" | 55 #include "DOMImplementation.h" |
| 56 #include "DOMRectInit.h" |
56 #include "DOMWindow.h" | 57 #include "DOMWindow.h" |
57 #include "DateComponents.h" | 58 #include "DateComponents.h" |
58 #include "DebugPageOverlays.h" | 59 #include "DebugPageOverlays.h" |
59 #include "DocumentAnimationScheduler.h" | 60 #include "DocumentAnimationScheduler.h" |
60 #include "DocumentLoader.h" | 61 #include "DocumentLoader.h" |
61 #include "DocumentMarkerController.h" | 62 #include "DocumentMarkerController.h" |
62 #include "DocumentSharedObjectPool.h" | 63 #include "DocumentSharedObjectPool.h" |
63 #include "DocumentTimeline.h" | 64 #include "DocumentTimeline.h" |
64 #include "DocumentType.h" | 65 #include "DocumentType.h" |
65 #include "Editing.h" | 66 #include "Editing.h" |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 #include "HTMLTitleElement.h" | 103 #include "HTMLTitleElement.h" |
103 #include "HTMLUnknownElement.h" | 104 #include "HTMLUnknownElement.h" |
104 #include "HTTPHeaderNames.h" | 105 #include "HTTPHeaderNames.h" |
105 #include "HTTPParsers.h" | 106 #include "HTTPParsers.h" |
106 #include "HashChangeEvent.h" | 107 #include "HashChangeEvent.h" |
107 #include "History.h" | 108 #include "History.h" |
108 #include "HitTestResult.h" | 109 #include "HitTestResult.h" |
109 #include "ImageBitmapRenderingContext.h" | 110 #include "ImageBitmapRenderingContext.h" |
110 #include "ImageLoader.h" | 111 #include "ImageLoader.h" |
111 #include "InspectorInstrumentation.h" | 112 #include "InspectorInstrumentation.h" |
| 113 #include "IntersectionObserver.h" |
112 #include "JSCustomElementInterface.h" | 114 #include "JSCustomElementInterface.h" |
113 #include "JSDOMPromiseDeferred.h" | 115 #include "JSDOMPromiseDeferred.h" |
114 #include "JSLazyEventListener.h" | 116 #include "JSLazyEventListener.h" |
115 #include "KeyboardEvent.h" | 117 #include "KeyboardEvent.h" |
116 #include "KeyframeEffectReadOnly.h" | 118 #include "KeyframeEffectReadOnly.h" |
117 #include "LayoutDisallowedScope.h" | 119 #include "LayoutDisallowedScope.h" |
118 #include "LibWebRTCProvider.h" | 120 #include "LibWebRTCProvider.h" |
119 #include "LoaderStrategy.h" | 121 #include "LoaderStrategy.h" |
120 #include "Logging.h" | 122 #include "Logging.h" |
121 #include "MediaCanStartListener.h" | 123 #include "MediaCanStartListener.h" |
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
496 , m_documentCreationTime(MonotonicTime::now()) | 498 , m_documentCreationTime(MonotonicTime::now()) |
497 , m_scriptRunner(std::make_unique<ScriptRunner>(*this)) | 499 , m_scriptRunner(std::make_unique<ScriptRunner>(*this)) |
498 , m_moduleLoader(std::make_unique<ScriptModuleLoader>(*this)) | 500 , m_moduleLoader(std::make_unique<ScriptModuleLoader>(*this)) |
499 #if ENABLE(XSLT) | 501 #if ENABLE(XSLT) |
500 , m_applyPendingXSLTransformsTimer(*this, &Document::applyPendingXSLTransfor
msTimerFired) | 502 , m_applyPendingXSLTransformsTimer(*this, &Document::applyPendingXSLTransfor
msTimerFired) |
501 #endif | 503 #endif |
502 , m_xmlVersion("1.0"_s) | 504 , m_xmlVersion("1.0"_s) |
503 , m_constantPropertyMap(std::make_unique<ConstantPropertyMap>(*this)) | 505 , m_constantPropertyMap(std::make_unique<ConstantPropertyMap>(*this)) |
504 , m_documentClasses(documentClasses) | 506 , m_documentClasses(documentClasses) |
505 , m_eventQueue(*this) | 507 , m_eventQueue(*this) |
| 508 #if ENABLE(INTERSECTION_OBSERVER) |
| 509 , m_intersectionObserversNotifyTimer(*this, &Document::notifyIntersectionObs
erversTimerFired) |
| 510 #endif |
506 , m_loadEventDelayTimer(*this, &Document::loadEventDelayTimerFired) | 511 , m_loadEventDelayTimer(*this, &Document::loadEventDelayTimerFired) |
507 #if PLATFORM(IOS) | 512 #if PLATFORM(IOS) |
508 #if ENABLE(DEVICE_ORIENTATION) | 513 #if ENABLE(DEVICE_ORIENTATION) |
509 , m_deviceMotionClient(std::make_unique<DeviceMotionClientIOS>()) | 514 , m_deviceMotionClient(std::make_unique<DeviceMotionClientIOS>()) |
510 , m_deviceMotionController(std::make_unique<DeviceMotionController>(m_device
MotionClient.get())) | 515 , m_deviceMotionController(std::make_unique<DeviceMotionController>(m_device
MotionClient.get())) |
511 , m_deviceOrientationClient(std::make_unique<DeviceOrientationClientIOS>()) | 516 , m_deviceOrientationClient(std::make_unique<DeviceOrientationClientIOS>()) |
512 , m_deviceOrientationController(std::make_unique<DeviceOrientationController
>(m_deviceOrientationClient.get())) | 517 , m_deviceOrientationController(std::make_unique<DeviceOrientationController
>(m_deviceOrientationClient.get())) |
513 #endif | 518 #endif |
514 #endif | 519 #endif |
515 , m_pendingTasksTimer(*this, &Document::pendingTasksTimerFired) | 520 , m_pendingTasksTimer(*this, &Document::pendingTasksTimerFired) |
(...skipping 1443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1959 styleScope().flushPendingUpdate(); | 1964 styleScope().flushPendingUpdate(); |
1960 | 1965 |
1961 if (!needsStyleRecalc()) | 1966 if (!needsStyleRecalc()) |
1962 return false; | 1967 return false; |
1963 } | 1968 } |
1964 | 1969 |
1965 // The early exit above for !needsStyleRecalc() is needed when updateWidgetP
ositions() is called in runOrScheduleAsynchronousTasks(). | 1970 // The early exit above for !needsStyleRecalc() is needed when updateWidgetP
ositions() is called in runOrScheduleAsynchronousTasks(). |
1966 RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(isSafeToUpdateStyleOrLayout(*this))
; | 1971 RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(isSafeToUpdateStyleOrLayout(*this))
; |
1967 | 1972 |
1968 resolveStyle(); | 1973 resolveStyle(); |
| 1974 updateIntersectionObservations(); |
1969 return true; | 1975 return true; |
1970 } | 1976 } |
1971 | 1977 |
1972 void Document::updateLayout() | 1978 void Document::updateLayout() |
1973 { | 1979 { |
1974 ASSERT(isMainThread()); | 1980 ASSERT(isMainThread()); |
1975 | 1981 |
1976 RefPtr<FrameView> frameView = view(); | 1982 RefPtr<FrameView> frameView = view(); |
1977 if (frameView && frameView->layoutContext().isInRenderTreeLayout()) { | 1983 if (frameView && frameView->layoutContext().isInRenderTreeLayout()) { |
1978 // View layout should not be re-entrant. | 1984 // View layout should not be re-entrant. |
(...skipping 5394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7373 void Document::addViewportDependentPicture(HTMLPictureElement& picture) | 7379 void Document::addViewportDependentPicture(HTMLPictureElement& picture) |
7374 { | 7380 { |
7375 m_viewportDependentPictures.add(&picture); | 7381 m_viewportDependentPictures.add(&picture); |
7376 } | 7382 } |
7377 | 7383 |
7378 void Document::removeViewportDependentPicture(HTMLPictureElement& picture) | 7384 void Document::removeViewportDependentPicture(HTMLPictureElement& picture) |
7379 { | 7385 { |
7380 m_viewportDependentPictures.remove(&picture); | 7386 m_viewportDependentPictures.remove(&picture); |
7381 } | 7387 } |
7382 | 7388 |
| 7389 #if ENABLE(INTERSECTION_OBSERVER) |
| 7390 |
| 7391 void Document::addToIntersectionObserverTargets(Element& element) |
| 7392 { |
| 7393 m_intersectionObserverTargets.add(&element); |
| 7394 } |
| 7395 |
| 7396 void Document::removeFromIntersectionObserverTargets(Element& element) |
| 7397 { |
| 7398 m_intersectionObserverTargets.remove(&element); |
| 7399 } |
| 7400 |
| 7401 void Document::collectIntersectionObservers(HashSet<IntersectionObserver*>& obse
rvers) |
| 7402 { |
| 7403 for (auto element : m_intersectionObserverTargets) { |
| 7404 auto registrations = element->intersectionObserverRegistrations(); |
| 7405 if (!registrations) |
| 7406 continue; |
| 7407 |
| 7408 for (auto& registration : *registrations) { |
| 7409 auto root = registration.observer->root(); |
| 7410 if (!root || (root->isConnected() && &root->document() == this)) |
| 7411 observers.add(registration.observer.get()); |
| 7412 } |
| 7413 } |
| 7414 } |
| 7415 |
| 7416 void Document::updateIntersectionObservations() |
| 7417 { |
| 7418 if (m_intersectionObserverTargets.isEmpty()) |
| 7419 return; |
| 7420 |
| 7421 // FIXME: For cross-document observation, do we need to check for pending la
yout in ancestor frames? In other frames? (which might move this one offscreen) |
| 7422 auto frameView = view(); |
| 7423 bool needsLayout = frameView && renderView() && (frameView->layoutContext().
isLayoutPending() || renderView()->needsLayout()); |
| 7424 if (needsLayout || hasPendingStyleRecalc()) |
| 7425 return; |
| 7426 |
| 7427 // FIXME: this timestamp should probably be shared with subsequent rAF. |
| 7428 double timeStamp = domWindow()->nowTimestamp(); |
| 7429 |
| 7430 // 1. Let observer list be a list of all IntersectionObservers whose root is
in the DOM tree of document. |
| 7431 HashSet<IntersectionObserver*> observers; |
| 7432 collectIntersectionObservers(observers); |
| 7433 |
| 7434 LOG(IntersectionObserver, "Document %p updateIntersectionObservations(), %u
target elements, %u observers", this, m_intersectionObserverTargets.size(), obse
rvers.size()); |
| 7435 |
| 7436 // 2. For each observer in observer list: |
| 7437 bool needNotify = false; |
| 7438 for (auto observer : observers) { |
| 7439 if (updateIntersectionObserveration(*observer, timeStamp)) |
| 7440 needNotify = true; |
| 7441 } |
| 7442 |
| 7443 if (needNotify) |
| 7444 m_intersectionObserversNotifyTimer.startOneShot(0_s); |
| 7445 } |
| 7446 |
| 7447 static float floatValueForLengthInLayoutUnits(const Length& length, float extent
, float cssToLayoutScale) |
| 7448 { |
| 7449 float unscaled = floatValueForLength(length, extent); |
| 7450 return length.isPercent() ? unscaled : unscaled * cssToLayoutScale; |
| 7451 } |
| 7452 |
| 7453 static bool computeAbsoluteTargetIntersection(FrameView& frameView, Intersection
Observer& observer, Element* target, FloatRect& absTargetRect, FloatRect& absRoo
tBounds, FloatRect& absIntersectionRect, bool& isIntersecting) |
| 7454 { |
| 7455 if (!target->renderer()) |
| 7456 return false; |
| 7457 |
| 7458 RenderElement& rendererForTarget = *target->renderer(); |
| 7459 RenderBlock* rendererForRoot = nullptr; |
| 7460 |
| 7461 // 1. If the intersection root is not the implicit root and target is not a
descendant of the intersection root |
| 7462 // in the containing block chain, skip further processing for target. |
| 7463 if (observer.root()) { |
| 7464 // 2. If the intersection root is not the implicit root, and target is n
ot in the same Document as the intersection root, |
| 7465 // skip further processing for target. |
| 7466 if (observer.root()->document() != target->document()) |
| 7467 return false; |
| 7468 |
| 7469 if (!observer.root()->renderer()) |
| 7470 return false; |
| 7471 |
| 7472 RenderElement* rootRenderer = observer.root()->renderer(); |
| 7473 if (!is<RenderBlock>(rootRenderer)) |
| 7474 return false; |
| 7475 |
| 7476 rendererForRoot = downcast<RenderBlock>(rootRenderer); |
| 7477 |
| 7478 if (!rendererForRoot->isContainingBlockAncestorFor(rendererForTarget)) |
| 7479 return false; |
| 7480 } |
| 7481 |
| 7482 float cssToLayoutScale = 1.0f; |
| 7483 |
| 7484 // We compute the intersections in the local space of the coordinate root. |
| 7485 // See the return line at the end of this function where we transform from |
| 7486 // local to absolute space. |
| 7487 // |
| 7488 // The coordinate root is usually the root element, but in the implicit root |
| 7489 // case, it is the main frame's layout viewport rect. |
| 7490 |
| 7491 // 1. Let rootBounds be observers root intersection rectangle. |
| 7492 FloatRect rootBounds; |
| 7493 RenderBlock* coordinateRoot = rendererForRoot; |
| 7494 if (rendererForRoot) { |
| 7495 // If the intersection root is a scrollable element, it's the elements c
ontent area. |
| 7496 if (rendererForRoot->hasOverflowClip()) { |
| 7497 // This is local/content space. See RenderBox::absoluteContentQuad. |
| 7498 rootBounds = rendererForRoot->contentBoxRect(); |
| 7499 } else { |
| 7500 // Otherwise, it's the result of running the getBoundingClientRect()
algorithm on the intersection root. |
| 7501 // We just take the RenderBox's bounds in local coordinates (see Ren
derBox::absoluteQuads() which is what getBoundingClientRect() uses); |
| 7502 rootBounds = { { 0, 0 }, rendererForRoot->size() }; |
| 7503 } |
| 7504 cssToLayoutScale = frameView.frame().pageZoomFactor() * frameView.frame(
).frameScaleFactor(); |
| 7505 } else { |
| 7506 // If the intersection root is the implicit root, it's the viewport. |
| 7507 coordinateRoot = &rendererForTarget.view(); |
| 7508 |
| 7509 if (frameView.frame().isMainFrame()) |
| 7510 rootBounds = frameView.layoutViewportRect(); |
| 7511 else { |
| 7512 // FIXME: need a version of windowClipRect() that ignores paintsEnti
reContents() |
| 7513 rootBounds = frameView.windowToContents(frameView.windowClipRect()); |
| 7514 } |
| 7515 } |
| 7516 |
| 7517 const LengthBox& rootMarginBox = observer.marginBox(); |
| 7518 // FIXME: handle writing modes. |
| 7519 FloatBoxExtent rootMarginBoxExtent( |
| 7520 floatValueForLengthInLayoutUnits(rootMarginBox.top(), rootBounds.height(
), cssToLayoutScale), |
| 7521 floatValueForLengthInLayoutUnits(rootMarginBox.right(), rootBounds.width
(), cssToLayoutScale), |
| 7522 floatValueForLengthInLayoutUnits(rootMarginBox.bottom(), rootBounds.heig
ht(), cssToLayoutScale), |
| 7523 floatValueForLengthInLayoutUnits(rootMarginBox.left(), rootBounds.width(
), cssToLayoutScale)); |
| 7524 |
| 7525 rootBounds.move(-rootMarginBoxExtent.left(), -rootMarginBoxExtent.top()); |
| 7526 |
| 7527 // FIXME: The spec says to only do this expansion if root and target are sim
ilar-origin. Check what other browsers |
| 7528 // do. |
| 7529 rootBounds.expand(rootMarginBoxExtent.left() + rootMarginBoxExtent.right(),
rootMarginBoxExtent.top() + rootMarginBoxExtent.bottom()); |
| 7530 |
| 7531 // Map rootBounds into absolute coords for the caller. |
| 7532 absRootBounds = coordinateRoot->localToAbsoluteQuad(rootBounds).boundingBox(
); |
| 7533 |
| 7534 // 1. Let intersectionRect be the result of running the getBoundingClientRec
t() algorithm on the target. |
| 7535 // This gets targetBounds in target-local coordinates. |
| 7536 LayoutRect targetBounds; |
| 7537 if (is<RenderBoxModelObject>(rendererForTarget)) |
| 7538 targetBounds = downcast<RenderBoxModelObject>(rendererForTarget).borderB
oundingBox(); |
| 7539 else if (rendererForTarget.element() && rendererForTarget.element()->isSVGEl
ement()) { |
| 7540 // Get the bounding rectangle from the SVG model. |
| 7541 SVGElement& svgElement = downcast<SVGElement>(*rendererForTarget.element
()); |
| 7542 FloatRect localRect; |
| 7543 if (svgElement.getBoundingBox(localRect)) |
| 7544 targetBounds = LayoutRect(localRect); |
| 7545 } |
| 7546 |
| 7547 absTargetRect = rendererForTarget.localToAbsoluteQuad(FloatRect(targetBounds
)).boundingBox(); |
| 7548 |
| 7549 // 2-3. Map to coordinateRoot, clipping along the way. |
| 7550 // FIXME: clippedOverflowRectForRepaint() may do some things we don't want. |
| 7551 // 4. Map intersectionRect to the coordinate space of the intersection root. |
| 7552 isIntersecting = true; |
| 7553 FloatRect intersectionRect = rendererForTarget.computeRectForRepaint(targetB
ounds, coordinateRoot, {false /* hasPositionFixedDescendant */, false /* dirtyRe
ctIsFlipped */, true /* useInclusiveIntersection */, &isIntersecting}); |
| 7554 |
| 7555 LOG_WITH_STREAM(IntersectionObserver, stream << " target in root space " <<
intersectionRect << " root bounds " << rootBounds); |
| 7556 |
| 7557 if (isIntersecting) { |
| 7558 // 5. Update intersectionRect by intersecting it with the root intersect
ion rectangle. |
| 7559 // FIXME: Use "inclusive intersection" (like Blink's LayoutRect::Inlucis
veIntersect) to correctly handle |
| 7560 // edge-adjacent intersection. |
| 7561 isIntersecting = intersectionRect.inclusiveIntersect(rootBounds); |
| 7562 } |
| 7563 |
| 7564 if (isIntersecting) { |
| 7565 // 6. Map intersectionRect to the coordinate space of the viewport of th
e Document containing the target. |
| 7566 // We'll use absolute coordinates instead. |
| 7567 absIntersectionRect = coordinateRoot->localToAbsoluteQuad(intersectionRe
ct).boundingBox(); |
| 7568 } |
| 7569 return true; |
| 7570 } |
| 7571 |
| 7572 bool Document::updateIntersectionObserveration(IntersectionObserver& observer, d
ouble timeStamp) |
| 7573 { |
| 7574 FrameView* frameView = view(); |
| 7575 if (!frameView) |
| 7576 return false; |
| 7577 |
| 7578 bool anyNeedNotify = false; |
| 7579 |
| 7580 // 2. For each target in observer's internal [[ObservationTargets]] slot, |
| 7581 // processed in the same order that observe() was called on each target: |
| 7582 for (auto target : observer.observationTargets()) { |
| 7583 FloatRect absTargetRect; |
| 7584 FloatRect absRootBounds; |
| 7585 FloatRect absIntersectionRect; |
| 7586 bool isIntersecting; |
| 7587 |
| 7588 bool computedIntersection = computeAbsoluteTargetIntersection(*frameView
, observer, target, absTargetRect, absRootBounds, absIntersectionRect, isInterse
cting); |
| 7589 |
| 7590 LOG_WITH_STREAM(IntersectionObserver, stream << " observer " << &observe
r << " target" << target << " absTargetRect" << absTargetRect << " absIntersecti
onRect " << absIntersectionRect); |
| 7591 |
| 7592 // 5. Let targetArea be targetRect's area. |
| 7593 // 6. Let intersectionArea be intersectionRect's area. |
| 7594 // 7. Let intersectionRatio be intersectionArea divided by targetArea if
targetArea is non-zero, and 0 otherwise. |
| 7595 float targetArea = absTargetRect.area(); |
| 7596 float intersectionRatio; |
| 7597 if (targetArea) |
| 7598 intersectionRatio = absIntersectionRect.area() / targetArea; |
| 7599 else if (isIntersecting) |
| 7600 intersectionRatio = 1; |
| 7601 else |
| 7602 intersectionRatio = 0; |
| 7603 |
| 7604 // 8. If intersectionRatio is equal to 0, let threshold be 0. If interse
ctionRatio is equal to 1, |
| 7605 // let threshold be the length of observer.thresholds. Otherwise, let th
reshold be the index of the first entry |
| 7606 // in observer.thresholds whose value is greater than intersectionRatio. |
| 7607 size_t thresholdIndex = 0; |
| 7608 if (!isIntersecting) |
| 7609 thresholdIndex = 0; |
| 7610 else if (intersectionRatio == 1) |
| 7611 thresholdIndex = observer.thresholds().size(); |
| 7612 else { |
| 7613 bool setIndex = false; |
| 7614 for (size_t i = 0; i < observer.thresholds().size(); ++i) { |
| 7615 if (observer.thresholds()[i] > intersectionRatio) { |
| 7616 thresholdIndex = i; |
| 7617 setIndex = true; |
| 7618 break; |
| 7619 } |
| 7620 } |
| 7621 if (!setIndex) |
| 7622 thresholdIndex = observer.thresholds().size(); |
| 7623 } |
| 7624 |
| 7625 // 9. Let intersectionObserverRegistration be the IntersectionObserverRe
gistration record in |
| 7626 // target's internal [[RegisteredIntersectionObservers]] slot whose obse
rver property is equal to observer. |
| 7627 // FIXME: sucks to have to re-find this when we had it in updateIntersec
tionObservations(). |
| 7628 IntersectionObserverRegistration* registration = nullptr; |
| 7629 auto registrations = target->intersectionObserverRegistrations(); |
| 7630 if (registrations) { |
| 7631 for (auto& currRegistration : *registrations) { |
| 7632 if (currRegistration.observer == &observer) { |
| 7633 registration = &currRegistration; |
| 7634 break; |
| 7635 } |
| 7636 } |
| 7637 } |
| 7638 |
| 7639 if (!registration) { |
| 7640 ASSERT_NOT_REACHED(); |
| 7641 continue; |
| 7642 } |
| 7643 |
| 7644 // 10. Let previousThreshold be set to intersectionObserverRegistration'
s previousThreshold property. |
| 7645 // 11. If threshold does not equal previousThreshold, queue an Intersect
ionObserverEntry, |
| 7646 // passing in observer, time, rootBounds, boundingClientRect, intersecti
onRect and target. |
| 7647 LOG_WITH_STREAM(IntersectionObserver, stream << " registration->previous
ThresholdIndex " << registration->previousThresholdIndex << " thresholdIndex " <
< thresholdIndex); |
| 7648 |
| 7649 if (thresholdIndex != registration->previousThresholdIndex || isIntersec
ting != registration->previousIsIntersecting) { |
| 7650 // These two rects are in client coordinates in target's frame. |
| 7651 FloatRect entryRootBounds; |
| 7652 FloatRect targetClientRect; |
| 7653 FloatRect clientIntersectionRect; |
| 7654 |
| 7655 if (computedIntersection) { |
| 7656 // FIXME: unclear if this needs to be reported in client coordin
ates: https://github.com/WICG/IntersectionObserver/issues/170 |
| 7657 if (observer.root()) { |
| 7658 // If there's an explicit root, we've already checked that t
he target's document is this, and the root and target are in |
| 7659 // the same document. |
| 7660 entryRootBounds = frameView->documentToClientRect(frameView-
>absoluteToDocumentRect(absRootBounds)); |
| 7661 |
| 7662 } else { |
| 7663 // Only supply the rootBounds if we are the main frame. |
| 7664 // FIXME: do we need this restriction?: https://github.com/W
ICG/IntersectionObserver/issues/170#issuecomment-257174868 |
| 7665 if (frameView->frame().isMainFrame()) |
| 7666 entryRootBounds = frameView->documentToClientRect(frameV
iew->absoluteToDocumentRect(absRootBounds)); |
| 7667 } |
| 7668 |
| 7669 targetClientRect = target->boundingRectInClientCoordinates(); |
| 7670 // FIXME: Condition on the isIntersecting bool (once we start co
mputing that). |
| 7671 if (isIntersecting) |
| 7672 clientIntersectionRect = frameView->contentsToView(enclosing
IntRect(absIntersectionRect)); |
| 7673 } |
| 7674 |
| 7675 observer.appendQueuedEntry(IntersectionObserverEntry::create({ |
| 7676 timeStamp, |
| 7677 { entryRootBounds.x(), entryRootBounds.y(), entryRootBounds.widt
h(), entryRootBounds.height() }, // rootBounds |
| 7678 { targetClientRect.x(), targetClientRect.y(), targetClientRect.w
idth(), targetClientRect.height() }, // target's boundingClientRect |
| 7679 { clientIntersectionRect.x(), clientIntersectionRect.y(), client
IntersectionRect.width(), clientIntersectionRect.height() }, // intersectionRect |
| 7680 isIntersecting, |
| 7681 intersectionRatio, |
| 7682 target |
| 7683 })); |
| 7684 |
| 7685 // 12. Assign threshold to intersectionObserverRegistration's previo
usThreshold property. |
| 7686 registration->previousThresholdIndex = thresholdIndex; |
| 7687 registration->previousIsIntersecting = isIntersecting; |
| 7688 anyNeedNotify = true; |
| 7689 } |
| 7690 } |
| 7691 |
| 7692 return anyNeedNotify; |
| 7693 } |
| 7694 |
| 7695 void Document::notifyIntersectionObserversTimerFired() |
| 7696 { |
| 7697 LOG_WITH_STREAM(IntersectionObserver, stream << "notifyIntersectionObservers
TimerFired"); |
| 7698 // 1. Let observer list be a list of all IntersectionObservers whose root is
in the DOM tree of document. |
| 7699 HashSet<IntersectionObserver*> observers; |
| 7700 collectIntersectionObservers(observers); |
| 7701 |
| 7702 // 2. For each observer in observer list: |
| 7703 for (auto observer : observers) |
| 7704 observer->notify(); |
| 7705 } |
| 7706 |
| 7707 #endif |
| 7708 |
7383 const AtomicString& Document::dir() const | 7709 const AtomicString& Document::dir() const |
7384 { | 7710 { |
7385 auto* documentElement = this->documentElement(); | 7711 auto* documentElement = this->documentElement(); |
7386 if (!is<HTMLHtmlElement>(documentElement)) | 7712 if (!is<HTMLHtmlElement>(documentElement)) |
7387 return nullAtom(); | 7713 return nullAtom(); |
7388 return downcast<HTMLHtmlElement>(*documentElement).dir(); | 7714 return downcast<HTMLHtmlElement>(*documentElement).dir(); |
7389 } | 7715 } |
7390 | 7716 |
7391 void Document::setDir(const AtomicString& value) | 7717 void Document::setDir(const AtomicString& value) |
7392 { | 7718 { |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7660 auto pageID = m_frame->loader().client().pageID(); | 7986 auto pageID = m_frame->loader().client().pageID(); |
7661 if (!page || !frameID || !pageID) { | 7987 if (!page || !frameID || !pageID) { |
7662 promise->reject(); | 7988 promise->reject(); |
7663 return; | 7989 return; |
7664 } | 7990 } |
7665 | 7991 |
7666 page->chrome().client().requestStorageAccess(WTFMove(iframeHost), WTFMove(to
pHost), frameID.value(), pageID.value(), [documentReference = makeWeakPtr(*this)
, promise = WTFMove(promise)] (bool wasGranted) mutable { | 7992 page->chrome().client().requestStorageAccess(WTFMove(iframeHost), WTFMove(to
pHost), frameID.value(), pageID.value(), [documentReference = makeWeakPtr(*this)
, promise = WTFMove(promise)] (bool wasGranted) mutable { |
7667 Document* document = documentReference.get(); | 7993 Document* document = documentReference.get(); |
7668 if (!document) | 7994 if (!document) |
7669 return; | 7995 return; |
7670 | 7996 |
7671 if (wasGranted) { | 7997 if (wasGranted) { |
7672 document->setHasFrameSpecificStorageAccess(true); | 7998 document->setHasFrameSpecificStorageAccess(true); |
7673 MicrotaskQueue::mainThreadQueue().append(std::make_unique<VoidMicrot
ask>([documentReference = makeWeakPtr(*document)] () { | 7999 MicrotaskQueue::mainThreadQueue().append(std::make_unique<VoidMicrot
ask>([documentReference = makeWeakPtr(*document)] () { |
7674 if (auto* document = documentReference.get()) | 8000 if (auto* document = documentReference.get()) |
7675 document->enableTemporaryTimeUserGesture(); | 8001 document->enableTemporaryTimeUserGesture(); |
7676 })); | 8002 })); |
7677 promise->resolve(); | 8003 promise->resolve(); |
7678 MicrotaskQueue::mainThreadQueue().append(std::make_unique<VoidMicrot
ask>([documentReference = WTFMove(documentReference)] () { | 8004 MicrotaskQueue::mainThreadQueue().append(std::make_unique<VoidMicrot
ask>([documentReference = WTFMove(documentReference)] () { |
7679 if (auto* document = documentReference.get()) | 8005 if (auto* document = documentReference.get()) |
7680 document->consumeTemporaryTimeUserGesture(); | 8006 document->consumeTemporaryTimeUserGesture(); |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7878 | 8204 |
7879 String Document::signedPublicKeyAndChallengeString(unsigned keySizeIndex, const
String& challengeString, const URL& url) | 8205 String Document::signedPublicKeyAndChallengeString(unsigned keySizeIndex, const
String& challengeString, const URL& url) |
7880 { | 8206 { |
7881 Page* page = this->page(); | 8207 Page* page = this->page(); |
7882 if (!page) | 8208 if (!page) |
7883 return emptyString(); | 8209 return emptyString(); |
7884 return page->chrome().client().signedPublicKeyAndChallengeString(keySizeInde
x, challengeString, url); | 8210 return page->chrome().client().signedPublicKeyAndChallengeString(keySizeInde
x, challengeString, url); |
7885 } | 8211 } |
7886 | 8212 |
7887 } // namespace WebCore | 8213 } // namespace WebCore |
OLD | NEW |