Bug 1960473 - Update content relevancy only once per tick. r=fredw
Otherwise we can end up with dirty frames at the end of a flush. This
doesn't fix bug 1958522 (I think we need either height: fit-content to
work, or IntersectionObserver.scrollMargin). But matches the HTML spec:
> The intent of this step is for the initial viewport proximity
> determination, which takes effect immediately, to be reflected in the
> style and layout calculation which is carried out in a previous step of
> this loop. Proximity determinations other than the initial one take
> effect at the next rendering opportunity.
Differential Revision: https://phabricator.services.mozilla.com/D245489
This commit is contained in:
@@ -4452,7 +4452,8 @@ void PresShell::NotifyFontFaceSetOnRefresh() {
|
||||
|
||||
void PresShell::DoFlushPendingNotifications(FlushType aType) {
|
||||
// by default, flush animations if aType >= FlushType::Style
|
||||
mozilla::ChangesToFlush flush(aType, aType >= FlushType::Style);
|
||||
mozilla::ChangesToFlush flush(aType, aType >= FlushType::Style,
|
||||
aType >= FlushType::Layout);
|
||||
FlushPendingNotifications(flush);
|
||||
}
|
||||
|
||||
@@ -4502,10 +4503,10 @@ void PresShell::DoFlushPendingNotifications(mozilla::ChangesToFlush aFlush) {
|
||||
*/
|
||||
FlushType flushType = aFlush.mFlushType;
|
||||
|
||||
// If this is a layout flush, first update the relevancy of any content
|
||||
// of elements with `content-visibility: auto` so that the values
|
||||
// returned from script queries are up-to-date.
|
||||
if (flushType >= mozilla::FlushType::Layout) {
|
||||
if (aFlush.mUpdateRelevancy) {
|
||||
// If needed, first update the relevancy of any content of elements with
|
||||
// `content-visibility: auto` so that the values returned from e.g. script
|
||||
// queries are up-to-date.
|
||||
UpdateRelevancyOfContentVisibilityAutoFrames();
|
||||
}
|
||||
|
||||
@@ -9868,8 +9869,9 @@ void PresShell::WillPaint() {
|
||||
// reflow being interspersed. Note that we _do_ allow this to be
|
||||
// interruptible; if we can't do all the reflows it's better to flicker a bit
|
||||
// than to freeze up.
|
||||
FlushPendingNotifications(
|
||||
ChangesToFlush(FlushType::InterruptibleLayout, false));
|
||||
FlushPendingNotifications(ChangesToFlush(FlushType::InterruptibleLayout,
|
||||
/* aFlushAnimations = */ false,
|
||||
/* aUpdateRelevancy = */ false));
|
||||
}
|
||||
|
||||
void PresShell::DidPaintWindow() {
|
||||
@@ -12578,13 +12580,15 @@ PresShell::ProximityToViewportResult PresShell::DetermineProximityToViewport() {
|
||||
DOMIntersectionObserver::IsForProximityToViewport::Yes)
|
||||
.Intersects();
|
||||
element->SetVisibleForContentVisibility(intersects);
|
||||
if (oldVisibility.isNothing() || *oldVisibility != intersects) {
|
||||
frame->UpdateIsRelevantContent(ContentRelevancyReason::Visible);
|
||||
}
|
||||
|
||||
// 14.2.3.3
|
||||
if (checkForInitialDetermination && intersects) {
|
||||
// Initial determination happens sync, otherwise on the next rendering
|
||||
// opportunity.
|
||||
frame->UpdateIsRelevantContent(ContentRelevancyReason::Visible);
|
||||
result.mHadInitialDetermination = true;
|
||||
} else if (oldVisibility.isNothing() || *oldVisibility != intersects) {
|
||||
ScheduleContentRelevancyUpdate(ContentRelevancyReason::Visible);
|
||||
}
|
||||
}
|
||||
if (nsPresContext* presContext = GetPresContext()) {
|
||||
|
||||
Reference in New Issue
Block a user