Bug 1918402 - Implement more of view transition's "capture the new state". r=view-transitions-reviewers,boris

This should be enough to start setting up the pseudo-element tree.

Differential Revision: https://phabricator.services.mozilla.com/D226362
This commit is contained in:
Emilio Cobos Álvarez 2024-10-23 19:41:36 +00:00
parent 36ca90eead
commit 75c58cac53
2 changed files with 69 additions and 4 deletions

View File

@ -260,7 +260,24 @@ void ViewTransition::Activate() {
return;
}
// TODO(emilio): Steps 2-7.
// TODO(emilio): Step 2: Set rendering suppression for view transitions to
// false.
// Step 3: If transition's initial snapshot containing block size is not
// equal to the snapshot containing block size, then skip the view transition
// for transition, and return.
if (mInitialSnapshotContainingBlockSize !=
SnapshotContainingBlockRect().Size()) {
return SkipTransition(SkipTransitionReason::Resize);
}
// Step 4: Capture the new state for transition.
if (auto skipReason = CaptureNewState()) {
// If failure is returned, then skip the view transition for transition...
return SkipTransition(*skipReason);
}
// TODO(emilio): Steps 5-7:
// Step 8: Set transition's phase to "animating".
mPhase = Phase::Animating;
@ -373,7 +390,8 @@ Maybe<SkipTransitionReason> ViewTransition::CaptureOldState() {
}
if (!usedTransitionNames.EnsureInserted(name)) {
// If usedTransitionNames contains transitionName, then return failure.
result.emplace(SkipTransitionReason::DuplicateTransitionName);
result.emplace(
SkipTransitionReason::DuplicateTransitionNameCapturingOldState);
return false;
}
// TODO: Set element's captured in a view transition to true.
@ -401,6 +419,42 @@ Maybe<SkipTransitionReason> ViewTransition::CaptureOldState() {
return result;
}
// https://drafts.csswg.org/css-view-transitions-1/#capture-the-new-state
Maybe<SkipTransitionReason> ViewTransition::CaptureNewState() {
nsTHashSet<nsAtom*> usedTransitionNames;
Maybe<SkipTransitionReason> result;
ForEachFrame(mDocument, [&](nsIFrame* aFrame) {
// As a fast path we check for v-t-n first.
auto* name = DocumentScopedTransitionNameFor(aFrame);
if (!name) {
return true;
}
if (aFrame->IsHiddenByContentVisibilityOnAnyAncestor()) {
// If any flat tree ancestor of this element skips its contents, then
// continue.
return true;
}
if (aFrame->GetPrevContinuation() || aFrame->GetNextContinuation()) {
// If element has more than one box fragment, then continue.
return true;
}
if (!usedTransitionNames.EnsureInserted(name)) {
result.emplace(
SkipTransitionReason::DuplicateTransitionNameCapturingNewState);
return false;
}
auto& capturedElement = mNamedElements.LookupOrInsertWith(name, [&] {
// TODO(emilio): See if we need to store something different here (rather
// than the properties of the new element). Maybe identity / null / etc?
return MakeUnique<CapturedElement>(aFrame,
mInitialSnapshotContainingBlockSize);
});
capturedElement->mNewElement = aFrame->GetContent()->AsElement();
return true;
});
return result;
}
// https://drafts.csswg.org/css-view-transitions/#setup-view-transition
void ViewTransition::Setup() {
// Step 2: Capture the old state for transition.
@ -518,10 +572,18 @@ void ViewTransition::SkipTransition(
readyPromise->MaybeRejectWithAbortError(
"Skipped ViewTransition due to timeout");
break;
case SkipTransitionReason::DuplicateTransitionName:
case SkipTransitionReason::DuplicateTransitionNameCapturingOldState:
readyPromise->MaybeRejectWithInvalidStateError(
"Duplicate view-transition-name value while capturing old state");
break;
case SkipTransitionReason::DuplicateTransitionNameCapturingNewState:
readyPromise->MaybeRejectWithInvalidStateError(
"Duplicate view-transition-name value while capturing new state");
break;
case SkipTransitionReason::Resize:
readyPromise->MaybeRejectWithInvalidStateError(
"Skipped view transition due to viewport resize");
break;
case SkipTransitionReason::UpdateCallbackRejected:
readyPromise->MaybeReject(aUpdateCallbackRejectReason);
break;

View File

@ -28,7 +28,9 @@ enum class SkipTransitionReason : uint8_t {
ClobberedActiveTransition,
Timeout,
UpdateCallbackRejected,
DuplicateTransitionName,
DuplicateTransitionNameCapturingOldState,
DuplicateTransitionNameCapturingNewState,
Resize,
};
// https://drafts.csswg.org/css-view-transitions-1/#viewtransition-phase
@ -70,6 +72,7 @@ class ViewTransition final : public nsISupports, public nsWrapperCache {
void Timeout();
void Setup();
[[nodiscard]] Maybe<SkipTransitionReason> CaptureOldState();
[[nodiscard]] Maybe<SkipTransitionReason> CaptureNewState();
void ClearNamedElements();
void HandleFrame();
void SkipTransition(SkipTransitionReason, JS::Handle<JS::Value>);