Skip to content

Commit

Permalink
Adopt more smart pointers in ContentVisibilityDocumentState
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=263237

Reviewed by Ryosuke Niwa.

* Source/WebCore/dom/ContentVisibilityDocumentState.cpp:
(WebCore::ContentVisibilityDocumentState::observe):
(WebCore::ContentVisibilityDocumentState::unobserve):
(WebCore::ContentVisibilityDocumentState::intersectionObserver):
(WebCore::ContentVisibilityDocumentState::checkRelevancyOfContentVisibilityElement const):
(WebCore::ContentVisibilityDocumentState::updateRelevancyOfContentVisibilityElements const):
(WebCore::ContentVisibilityDocumentState::determineInitialVisibleContentVisibility const):
(WebCore::ContentVisibilityDocumentState::updateContentRelevancyForScrollIfNeeded):
(WebCore::ContentVisibilityDocumentState::updateViewportProximity):
(WebCore::ContentVisibilityDocumentState::updateAnimations):

Canonical link: https://commits.webkit.org/269408@main
  • Loading branch information
cdumez committed Oct 17, 2023
1 parent 10709eb commit a1ad490
Showing 1 changed file with 25 additions and 26 deletions.
51 changes: 25 additions & 26 deletions Source/WebCore/dom/ContentVisibilityDocumentState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class ContentVisibilityIntersectionObserverCallback final : public IntersectionO
ASSERT(!entries.isEmpty());

for (auto& entry : entries) {
if (auto* element = entry->target())
if (RefPtr element = entry->target())
element->document().contentVisibilityDocumentState().updateViewportProximity(*element, entry->isIntersecting() ? ViewportProximity::Near : ViewportProximity::Far);
}
return { };
Expand All @@ -73,15 +73,15 @@ void ContentVisibilityDocumentState::observe(Element& element)
{
Ref document = element.document();
auto& state = document->contentVisibilityDocumentState();
if (auto* intersectionObserver = state.intersectionObserver(document))
if (RefPtr intersectionObserver = state.intersectionObserver(document))
intersectionObserver->observe(element);
}

void ContentVisibilityDocumentState::unobserve(Element& element)
{
Ref document = element.document();
auto& state = document->contentVisibilityDocumentState();
if (auto& intersectionObserver = state.m_observer) {
if (RefPtr intersectionObserver = state.m_observer) {
intersectionObserver->unobserve(element);
state.removeViewportProximity(element);
}
Expand All @@ -96,7 +96,7 @@ IntersectionObserver* ContentVisibilityDocumentState::intersectionObserver(Docum
auto observer = IntersectionObserver::create(document, WTFMove(callback), WTFMove(options));
if (observer.hasException())
return nullptr;
m_observer = observer.returnValue().ptr();
m_observer = observer.releaseReturnValue();
}
return m_observer.get();
}
Expand Down Expand Up @@ -130,7 +130,7 @@ bool ContentVisibilityDocumentState::checkRelevancyOfContentVisibilityElement(El
setRelevancyValue(ContentRelevancy::Selected, targetContainsSelection(target));

auto hasTopLayerinSubtree = [](const Element& target) {
for (auto& element : target.document().topLayerElements()) {
for (Ref element : target.document().topLayerElements()) {
if (element->isDescendantOf(target))
return true;
}
Expand Down Expand Up @@ -158,8 +158,8 @@ bool ContentVisibilityDocumentState::checkRelevancyOfContentVisibilityElement(El
DidUpdateAnyContentRelevancy ContentVisibilityDocumentState::updateRelevancyOfContentVisibilityElements(OptionSet<ContentRelevancy> relevancyToCheck) const
{
auto didUpdateAnyContentRelevancy = DidUpdateAnyContentRelevancy::No;
for (auto target : m_observer->observationTargets()) {
if (target) {
for (auto& weakTarget : m_observer->observationTargets()) {
if (RefPtr target = weakTarget.get()) {
if (checkRelevancyOfContentVisibilityElement(*target, relevancyToCheck))
didUpdateAnyContentRelevancy = DidUpdateAnyContentRelevancy::Yes;
}
Expand All @@ -172,16 +172,16 @@ HadInitialVisibleContentVisibilityDetermination ContentVisibilityDocumentState::
if (!m_observer)
return HadInitialVisibleContentVisibilityDetermination::No;
Vector<Ref<Element>> elementsToCheck;
for (auto target : m_observer->observationTargets()) {
if (target) {
for (auto& weakTarget : m_observer->observationTargets()) {
if (RefPtr target = weakTarget.get()) {
bool checkForInitialDetermination = !m_elementViewportProximities.contains(*target) && !target->isRelevantToUser();
if (checkForInitialDetermination)
elementsToCheck.append(*target);
elementsToCheck.append(target.releaseNonNull());
}
}
auto hadInitialVisibleContentVisibilityDetermination = HadInitialVisibleContentVisibilityDetermination::No;
if (!elementsToCheck.isEmpty()) {
elementsToCheck.first()->document().updateIntersectionObservations({ m_observer });
elementsToCheck.first()->protectedDocument()->updateIntersectionObservations({ m_observer });
for (auto& element : elementsToCheck) {
checkRelevancyOfContentVisibilityElement(element, { ContentRelevancy::OnScreen });
if (element->isRelevantToUser())
Expand All @@ -199,26 +199,26 @@ void ContentVisibilityDocumentState::updateContentRelevancyForScrollIfNeeded(con
{
if (!m_observer)
return;
auto findSkippedContentRoot = [](const Element& element) -> const Element* {
const Element* found = nullptr;
auto findSkippedContentRoot = [](const Element& element) -> RefPtr<const Element> {
RefPtr<const Element> found;
if (element.renderer() && element.renderer()->isSkippedContent()) {
for (auto candidate = &element; candidate; candidate = candidate->parentElementInComposedTree()) {
for (RefPtr candidate = &element; candidate; candidate = candidate->parentElementInComposedTree()) {
if (candidate->renderer() && candidate->renderStyle()->contentVisibility() == ContentVisibility::Auto)
found = candidate;
}
}
return found;
};

if (auto* scrollAnchorRoot = findSkippedContentRoot(scrollAnchor)) {
for (auto target : m_observer->observationTargets()) {
if (target) {
if (RefPtr scrollAnchorRoot = findSkippedContentRoot(scrollAnchor)) {
for (auto& weakTarget : m_observer->observationTargets()) {
if (RefPtr target = weakTarget.get()) {
ASSERT(target->renderer() && target->renderStyle()->contentVisibility() == ContentVisibility::Auto);
updateViewportProximity(*target, ViewportProximity::Far);
}
}
updateViewportProximity(*scrollAnchorRoot, ViewportProximity::Near);
scrollAnchorRoot->document().updateRelevancyOfContentVisibilityElements();
scrollAnchorRoot->protectedDocument()->updateRelevancyOfContentVisibilityElements();
}
}

Expand All @@ -227,7 +227,7 @@ void ContentVisibilityDocumentState::updateViewportProximity(const Element& elem
// No need to schedule content relevancy update for first time call, since
// that will be handled by determineInitialVisibleContentVisibility.
if (m_elementViewportProximities.contains(element))
element.document().scheduleContentRelevancyUpdate(ContentRelevancy::OnScreen);
element.protectedDocument()->scheduleContentRelevancyUpdate(ContentRelevancy::OnScreen);
m_elementViewportProximities.ensure(element, [] {
return ViewportProximity::Far;
}).iterator->value = viewportProximity;
Expand All @@ -242,17 +242,16 @@ void ContentVisibilityDocumentState::updateAnimations(const Element& element, Is
{
if (wasSkipped == IsSkippedContent::No || becomesSkipped == IsSkippedContent::Yes)
return;
for (auto* animation : WebAnimation::instances()) {
if (!animation->isDeclarativeAnimation())
for (RefPtr animation : WebAnimation::instances()) {
RefPtr declarativeAnimation = dynamicDowncast<DeclarativeAnimation>(animation.releaseNonNull());
if (!declarativeAnimation)
continue;

auto& declarativeAnimation = downcast<DeclarativeAnimation>(*animation);
auto owningElement = declarativeAnimation.owningElement();
auto owningElement = declarativeAnimation->owningElement();
if (!owningElement || !owningElement->element.isDescendantOrShadowDescendantOf(&element))
continue;

if (auto* timeline = declarativeAnimation.timeline())
timeline->animationTimingDidChange(declarativeAnimation);
if (RefPtr timeline = declarativeAnimation->timeline())
timeline->animationTimingDidChange(*declarativeAnimation);
}
}

Expand Down

0 comments on commit a1ad490

Please sign in to comment.