зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1916311 - [css-view-transitions] Initial pass at DOM API internals. r=boris,webidl,smaug
This is still fairly incomplete (i.e. no capturing, etc), but it allows a transition to "start", and then finish (on the next frame always, for now) or timeout, appropriately. I think it's in a reviewable shape, given that. There's one known divergence from the spec, which is described in https://github.com/w3c/csswg-drafts/issues/10822 Differential Revision: https://phabricator.services.mozilla.com/D220843
This commit is contained in:
Родитель
7dbf811c63
Коммит
1b8d105218
|
@ -243,6 +243,7 @@
|
||||||
#include "mozilla/dom/URL.h"
|
#include "mozilla/dom/URL.h"
|
||||||
#include "mozilla/dom/UseCounterMetrics.h"
|
#include "mozilla/dom/UseCounterMetrics.h"
|
||||||
#include "mozilla/dom/UserActivation.h"
|
#include "mozilla/dom/UserActivation.h"
|
||||||
|
#include "mozilla/dom/ViewTransition.h"
|
||||||
#include "mozilla/dom/WakeLockJS.h"
|
#include "mozilla/dom/WakeLockJS.h"
|
||||||
#include "mozilla/dom/WakeLockSentinel.h"
|
#include "mozilla/dom/WakeLockSentinel.h"
|
||||||
#include "mozilla/dom/WindowBinding.h"
|
#include "mozilla/dom/WindowBinding.h"
|
||||||
|
@ -2586,6 +2587,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(Document)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPrototypeDocument)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPrototypeDocument)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMidasCommandManager)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMidasCommandManager)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAll)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAll)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mActiveViewTransition)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocGroup)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocGroup)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFrameRequestManager)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFrameRequestManager)
|
||||||
|
|
||||||
|
@ -2715,6 +2717,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Document)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPrototypeDocument)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPrototypeDocument)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMidasCommandManager)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMidasCommandManager)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mAll)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mAll)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mActiveViewTransition)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mReferrerInfo)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mReferrerInfo)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPreloadReferrerInfo)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPreloadReferrerInfo)
|
||||||
|
|
||||||
|
@ -17782,10 +17785,49 @@ void Document::ClearStaleServoData() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewTransition* Document::StartViewTransition(
|
// https://drafts.csswg.org/css-view-transitions-1/#dom-document-startviewtransition
|
||||||
const Optional<OwningNonNull<ViewTransitionUpdateCallback>>&) {
|
already_AddRefed<ViewTransition> Document::StartViewTransition(
|
||||||
// TODO(emilio): Not yet implemented
|
const Optional<OwningNonNull<ViewTransitionUpdateCallback>>& aCallback) {
|
||||||
return nullptr;
|
// Steps 1-3
|
||||||
|
RefPtr transition = new ViewTransition(
|
||||||
|
*this, aCallback.WasPassed() ? &aCallback.Value() : nullptr);
|
||||||
|
if (Hidden()) {
|
||||||
|
// Step 4:
|
||||||
|
//
|
||||||
|
// If document's visibility state is "hidden", then skip transition with an
|
||||||
|
// "InvalidStateError" DOMException, and return transition.
|
||||||
|
transition->SkipTransition(SkipTransitionReason::DocumentHidden);
|
||||||
|
return transition.forget();
|
||||||
|
}
|
||||||
|
if (mActiveViewTransition) {
|
||||||
|
// Step 5:
|
||||||
|
// If document's active view transition is not null, then skip that view
|
||||||
|
// transition with an "AbortError" DOMException in this's relevant Realm.
|
||||||
|
mActiveViewTransition->SkipTransition(
|
||||||
|
SkipTransitionReason::ClobberedActiveTransition);
|
||||||
|
}
|
||||||
|
// Step 6: Set document's active view transition to transition.
|
||||||
|
mActiveViewTransition = transition;
|
||||||
|
|
||||||
|
if (mPresShell) {
|
||||||
|
if (nsRefreshDriver* rd = mPresShell->GetRefreshDriver()) {
|
||||||
|
rd->EnsureViewTransitionOperationsHappen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Step 7: return transition
|
||||||
|
return transition.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Document::ClearActiveViewTransition() { mActiveViewTransition = nullptr; }
|
||||||
|
|
||||||
|
void Document::PerformPendingViewTransitionOperations() {
|
||||||
|
if (mActiveViewTransition) {
|
||||||
|
mActiveViewTransition->PerformPendingOperations();
|
||||||
|
}
|
||||||
|
EnumerateSubDocuments([](Document& aDoc) {
|
||||||
|
aDoc.PerformPendingViewTransitionOperations();
|
||||||
|
return CallState::Continue;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Selection* Document::GetSelection(ErrorResult& aRv) {
|
Selection* Document::GetSelection(ErrorResult& aRv) {
|
||||||
|
|
|
@ -3818,8 +3818,13 @@ class Document : public nsINode,
|
||||||
MOZ_CAN_RUN_SCRIPT void
|
MOZ_CAN_RUN_SCRIPT void
|
||||||
DetermineProximityToViewportAndNotifyResizeObservers();
|
DetermineProximityToViewportAndNotifyResizeObservers();
|
||||||
|
|
||||||
ViewTransition* StartViewTransition(
|
already_AddRefed<ViewTransition> StartViewTransition(
|
||||||
const Optional<OwningNonNull<ViewTransitionUpdateCallback>>&);
|
const Optional<OwningNonNull<ViewTransitionUpdateCallback>>&);
|
||||||
|
ViewTransition* GetActiveViewTransition() const {
|
||||||
|
return mActiveViewTransition;
|
||||||
|
}
|
||||||
|
void ClearActiveViewTransition();
|
||||||
|
void PerformPendingViewTransitionOperations();
|
||||||
|
|
||||||
// Getter for PermissionDelegateHandler. Performs lazy initialization.
|
// Getter for PermissionDelegateHandler. Performs lazy initialization.
|
||||||
PermissionDelegateHandler* GetPermissionDelegateHandler();
|
PermissionDelegateHandler* GetPermissionDelegateHandler();
|
||||||
|
@ -5359,6 +5364,9 @@ class Document : public nsINode,
|
||||||
|
|
||||||
RefPtr<HTMLAllCollection> mAll;
|
RefPtr<HTMLAllCollection> mAll;
|
||||||
|
|
||||||
|
// https://drafts.csswg.org/css-view-transitions-1/#document-active-view-transition
|
||||||
|
RefPtr<ViewTransition> mActiveViewTransition;
|
||||||
|
|
||||||
nsTHashSet<RefPtr<WorkerDocumentListener>> mWorkerListeners;
|
nsTHashSet<RefPtr<WorkerDocumentListener>> mWorkerListeners;
|
||||||
|
|
||||||
// Pres shell resolution saved before entering fullscreen mode.
|
// Pres shell resolution saved before entering fullscreen mode.
|
||||||
|
|
|
@ -4,11 +4,17 @@
|
||||||
|
|
||||||
#include "ViewTransition.h"
|
#include "ViewTransition.h"
|
||||||
#include "mozilla/dom/Document.h"
|
#include "mozilla/dom/Document.h"
|
||||||
|
#include "mozilla/dom/Promise.h"
|
||||||
|
#include "mozilla/dom/Promise-inl.h"
|
||||||
#include "mozilla/dom/ViewTransitionBinding.h"
|
#include "mozilla/dom/ViewTransitionBinding.h"
|
||||||
|
#include "nsITimer.h"
|
||||||
|
|
||||||
namespace mozilla::dom {
|
namespace mozilla::dom {
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ViewTransition, mDocument)
|
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ViewTransition, mDocument,
|
||||||
|
mUpdateCallback,
|
||||||
|
mUpdateCallbackDonePromise, mReadyPromise,
|
||||||
|
mFinishedPromise)
|
||||||
|
|
||||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ViewTransition)
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ViewTransition)
|
||||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||||
|
@ -20,31 +26,297 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(ViewTransition)
|
||||||
|
|
||||||
ViewTransition::ViewTransition(Document& aDoc,
|
ViewTransition::ViewTransition(Document& aDoc,
|
||||||
ViewTransitionUpdateCallback* aCb)
|
ViewTransitionUpdateCallback* aCb)
|
||||||
: mDocument(&aDoc) {}
|
: mDocument(&aDoc), mUpdateCallback(aCb) {}
|
||||||
|
|
||||||
ViewTransition::~ViewTransition() = default;
|
ViewTransition::~ViewTransition() { ClearTimeoutTimer(); }
|
||||||
|
|
||||||
nsISupports* ViewTransition::GetParentObject() const {
|
nsIGlobalObject* ViewTransition::GetParentObject() const {
|
||||||
return ToSupports(mDocument.get());
|
return mDocument ? mDocument->GetParentObject() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Promise* ViewTransition::UpdateCallbackDone() {
|
Promise* ViewTransition::GetUpdateCallbackDone(ErrorResult& aRv) {
|
||||||
// TODO(emilio): Not yet implemented.
|
if (!mUpdateCallbackDonePromise) {
|
||||||
return nullptr;
|
mUpdateCallbackDonePromise = Promise::Create(GetParentObject(), aRv);
|
||||||
|
}
|
||||||
|
return mUpdateCallbackDonePromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
Promise* ViewTransition::Ready() {
|
Promise* ViewTransition::GetReady(ErrorResult& aRv) {
|
||||||
// TODO(emilio): Not yet implemented.
|
if (!mReadyPromise) {
|
||||||
return nullptr;
|
mReadyPromise = Promise::Create(GetParentObject(), aRv);
|
||||||
|
}
|
||||||
|
return mReadyPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
Promise* ViewTransition::Finished() {
|
Promise* ViewTransition::GetFinished(ErrorResult& aRv) {
|
||||||
// TODO(emilio): Not yet implemented.
|
if (!mFinishedPromise) {
|
||||||
return nullptr;
|
mFinishedPromise = Promise::Create(GetParentObject(), aRv);
|
||||||
|
}
|
||||||
|
return mFinishedPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewTransition::SkipTransition() {
|
void ViewTransition::CallUpdateCallbackIgnoringErrors(CallIfDone aCallIfDone) {
|
||||||
// TODO(emilio): Not yet implemented.
|
if (aCallIfDone == CallIfDone::No && mPhase == Phase::Done) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
CallUpdateCallback(IgnoreErrors());
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://drafts.csswg.org/css-view-transitions-1/#call-the-update-callback
|
||||||
|
void ViewTransition::CallUpdateCallback(ErrorResult& aRv) {
|
||||||
|
MOZ_ASSERT(mDocument);
|
||||||
|
// Step 1: Assert: transition's phase is "done", or before
|
||||||
|
// "update-callback-called".
|
||||||
|
MOZ_ASSERT(mPhase == Phase::Done ||
|
||||||
|
UnderlyingValue(mPhase) <
|
||||||
|
UnderlyingValue(Phase::UpdateCallbackCalled));
|
||||||
|
|
||||||
|
// Step 5: If transition's phase is not "done", then set transition's phase
|
||||||
|
// to "update-callback-called".
|
||||||
|
//
|
||||||
|
// NOTE(emilio): This is swapped with the spec because the spec is broken,
|
||||||
|
// see https://github.com/w3c/csswg-drafts/issues/10822
|
||||||
|
if (mPhase != Phase::Done) {
|
||||||
|
mPhase = Phase::UpdateCallbackCalled;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 2: Let callbackPromise be null.
|
||||||
|
RefPtr<Promise> callbackPromise;
|
||||||
|
if (!mUpdateCallback) {
|
||||||
|
// Step 3: If transition's update callback is null, then set callbackPromise
|
||||||
|
// to a promise resolved with undefined, in transition’s relevant Realm.
|
||||||
|
callbackPromise =
|
||||||
|
Promise::CreateResolvedWithUndefined(GetParentObject(), aRv);
|
||||||
|
} else {
|
||||||
|
// Step 4: Otherwise set callbackPromise to the result of invoking
|
||||||
|
// transition’s update callback. MOZ_KnownLive because the callback can only
|
||||||
|
// go away when we get CCd.
|
||||||
|
callbackPromise = MOZ_KnownLive(mUpdateCallback)->Call(aRv);
|
||||||
|
}
|
||||||
|
if (aRv.Failed()) {
|
||||||
|
// TODO(emilio): Do we need extra error handling here?
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MOZ_ASSERT(callbackPromise);
|
||||||
|
// Step 8: React to callbackPromise with fulfillSteps and rejectSteps.
|
||||||
|
callbackPromise->AddCallbacksWithCycleCollectedArgs(
|
||||||
|
[](JSContext*, JS::Handle<JS::Value>, ErrorResult& aRv,
|
||||||
|
ViewTransition* aVt) {
|
||||||
|
// Step 6: Let fulfillSteps be to following steps:
|
||||||
|
if (Promise* ucd = aVt->GetUpdateCallbackDone(aRv)) {
|
||||||
|
// 6.1: Resolve transition's update callback done promise with
|
||||||
|
// undefined.
|
||||||
|
ucd->MaybeResolveWithUndefined();
|
||||||
|
}
|
||||||
|
if (aVt->mPhase == Phase::Done) {
|
||||||
|
// "Skip a transition" step 8. We need to resolve "finished" after
|
||||||
|
// update-callback-done.
|
||||||
|
if (Promise* finished = aVt->GetFinished(aRv)) {
|
||||||
|
finished->MaybeResolveWithUndefined();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
aVt->Activate();
|
||||||
|
},
|
||||||
|
[](JSContext*, JS::Handle<JS::Value> aReason, ErrorResult& aRv,
|
||||||
|
ViewTransition* aVt) {
|
||||||
|
// Step 7: Let rejectSteps be to following steps:
|
||||||
|
if (Promise* ucd = aVt->GetUpdateCallbackDone(aRv)) {
|
||||||
|
// 7.1: Reject transition's update callback done promise with reason.
|
||||||
|
ucd->MaybeReject(aReason);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 7.2: If transition's phase is "done", then return.
|
||||||
|
if (aVt->mPhase == Phase::Done) {
|
||||||
|
// "Skip a transition" step 8. We need to resolve "finished" after
|
||||||
|
// update-callback-done.
|
||||||
|
if (Promise* finished = aVt->GetFinished(aRv)) {
|
||||||
|
finished->MaybeReject(aReason);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 7.3: Mark as handled transition's ready promise.
|
||||||
|
if (Promise* ready = aVt->GetReady(aRv)) {
|
||||||
|
MOZ_ALWAYS_TRUE(ready->SetAnyPromiseIsHandled());
|
||||||
|
}
|
||||||
|
aVt->SkipTransition(SkipTransitionReason::UpdateCallbackRejected,
|
||||||
|
aReason);
|
||||||
|
},
|
||||||
|
RefPtr(this));
|
||||||
|
|
||||||
|
// Step 9: To skip a transition after a timeout, the user agent may perform
|
||||||
|
// the following steps in parallel:
|
||||||
|
MOZ_ASSERT(!mTimeoutTimer);
|
||||||
|
ClearTimeoutTimer(); // Be safe just in case.
|
||||||
|
mTimeoutTimer = NS_NewTimer();
|
||||||
|
mTimeoutTimer->InitWithNamedFuncCallback(
|
||||||
|
TimeoutCallback, this, StaticPrefs::dom_viewTransitions_timeout_ms(),
|
||||||
|
nsITimer::TYPE_ONE_SHOT, "ViewTransition::TimeoutCallback");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewTransition::ClearTimeoutTimer() {
|
||||||
|
if (mTimeoutTimer) {
|
||||||
|
mTimeoutTimer->Cancel();
|
||||||
|
mTimeoutTimer = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewTransition::TimeoutCallback(nsITimer* aTimer, void* aClosure) {
|
||||||
|
RefPtr vt = static_cast<ViewTransition*>(aClosure);
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(aTimer == vt->mTimeoutTimer);
|
||||||
|
vt->Timeout();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewTransition::Timeout() {
|
||||||
|
ClearTimeoutTimer();
|
||||||
|
if (mPhase != Phase::Done && mDocument) {
|
||||||
|
SkipTransition(SkipTransitionReason::Timeout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://drafts.csswg.org/css-view-transitions-1/#activate-view-transition
|
||||||
|
void ViewTransition::Activate() {
|
||||||
|
// Step 1: If transition's phase is "done", then return.
|
||||||
|
if (mPhase == Phase::Done) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(emilio): Steps 2-7.
|
||||||
|
|
||||||
|
// Step 8: Set transition's phase to "animating".
|
||||||
|
mPhase = Phase::Animating;
|
||||||
|
// Step 9: Resolve transition's ready promise.
|
||||||
|
if (Promise* ready = GetReady(IgnoreErrors())) {
|
||||||
|
ready->MaybeResolveWithUndefined();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://drafts.csswg.org/css-view-transitions/#perform-pending-transition-operations
|
||||||
|
void ViewTransition::PerformPendingOperations() {
|
||||||
|
MOZ_ASSERT(mDocument);
|
||||||
|
MOZ_ASSERT(mDocument->GetActiveViewTransition() == this);
|
||||||
|
|
||||||
|
switch (mPhase) {
|
||||||
|
case Phase::PendingCapture:
|
||||||
|
return Setup();
|
||||||
|
case Phase::Animating:
|
||||||
|
return HandleFrame();
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://drafts.csswg.org/css-view-transitions/#setup-view-transition
|
||||||
|
void ViewTransition::Setup() {
|
||||||
|
// TODO(emilio): Steps 1-3: Capture old state.
|
||||||
|
//
|
||||||
|
// Step 4: Queue a global task on the DOM manipulation task source, given
|
||||||
|
// transition's relevant global object, to perform the following steps:
|
||||||
|
// 4.1: If transition's phase is "done", then abort these steps. That is
|
||||||
|
// achieved via CallIfDone::No.
|
||||||
|
// 4.2: call the update callback.
|
||||||
|
mDocument->Dispatch(NewRunnableMethod<CallIfDone>(
|
||||||
|
"ViewTransition::CallUpdateCallbackFromSetup", this,
|
||||||
|
&ViewTransition::CallUpdateCallbackIgnoringErrors, CallIfDone::No));
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://drafts.csswg.org/css-view-transitions-1/#handle-transition-frame
|
||||||
|
void ViewTransition::HandleFrame() {
|
||||||
|
// TODO(emilio): Steps 1-3: Compute active animations.
|
||||||
|
bool hasActiveAnimations = false;
|
||||||
|
// Step 4: If hasActiveAnimations is false:
|
||||||
|
if (!hasActiveAnimations) {
|
||||||
|
// 4.1: Set transition's phase to "done".
|
||||||
|
mPhase = Phase::Done;
|
||||||
|
// 4.2: Clear view transition transition.
|
||||||
|
ClearActiveTransition();
|
||||||
|
// 4.3: Resolve transition's finished promise.
|
||||||
|
if (Promise* finished = GetFinished(IgnoreErrors())) {
|
||||||
|
finished->MaybeResolveWithUndefined();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// TODO(emilio): Steps 5-6 (check CB size, update pseudo styles).
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://drafts.csswg.org/css-view-transitions-1/#clear-view-transition
|
||||||
|
void ViewTransition::ClearActiveTransition() {
|
||||||
|
// Steps 1-2
|
||||||
|
MOZ_ASSERT(mDocument);
|
||||||
|
MOZ_ASSERT(mDocument->GetActiveViewTransition() == this);
|
||||||
|
|
||||||
|
// TODO(emilio): Step 3 (clear named elements)
|
||||||
|
// TODO(emilio): Step 4 (clear show transition tree flag)
|
||||||
|
mDocument->ClearActiveViewTransition();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewTransition::SkipTransition(SkipTransitionReason aReason) {
|
||||||
|
SkipTransition(aReason, JS::UndefinedHandleValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://drafts.csswg.org/css-view-transitions-1/#skip-the-view-transition
|
||||||
|
// https://drafts.csswg.org/css-view-transitions-1/#dom-viewtransition-skiptransition
|
||||||
|
void ViewTransition::SkipTransition(
|
||||||
|
SkipTransitionReason aReason,
|
||||||
|
JS::Handle<JS::Value> aUpdateCallbackRejectReason) {
|
||||||
|
MOZ_ASSERT(mDocument);
|
||||||
|
MOZ_ASSERT_IF(aReason != SkipTransitionReason::JS, mPhase != Phase::Done);
|
||||||
|
MOZ_ASSERT_IF(aReason != SkipTransitionReason::UpdateCallbackRejected,
|
||||||
|
aUpdateCallbackRejectReason == JS::UndefinedHandleValue);
|
||||||
|
if (mPhase == Phase::Done) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Step 3: If transition's phase is before "update-callback-called", then
|
||||||
|
// queue a global task on the DOM manipulation task source, given
|
||||||
|
// transition’s relevant global object, to call the update callback of
|
||||||
|
// transition.
|
||||||
|
if (UnderlyingValue(mPhase) < UnderlyingValue(Phase::UpdateCallbackCalled)) {
|
||||||
|
mDocument->Dispatch(NewRunnableMethod<CallIfDone>(
|
||||||
|
"ViewTransition::CallUpdateCallbackFromSkip", this,
|
||||||
|
&ViewTransition::CallUpdateCallbackIgnoringErrors, CallIfDone::Yes));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 4: Set rendering suppression for view transitions to false.
|
||||||
|
// TODO(emilio): We don't have that flag yet.
|
||||||
|
|
||||||
|
// Step 5: If document's active view transition is transition, Clear view
|
||||||
|
// transition transition.
|
||||||
|
if (mDocument->GetActiveViewTransition() == this) {
|
||||||
|
ClearActiveTransition();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 6: Set transition's phase to "done".
|
||||||
|
mPhase = Phase::Done;
|
||||||
|
|
||||||
|
// Step 7: Reject transition's ready promise with reason.
|
||||||
|
if (Promise* readyPromise = GetReady(IgnoreErrors())) {
|
||||||
|
switch (aReason) {
|
||||||
|
case SkipTransitionReason::JS:
|
||||||
|
readyPromise->MaybeRejectWithAbortError(
|
||||||
|
"Skipped ViewTransition due to skipTransition() call");
|
||||||
|
break;
|
||||||
|
case SkipTransitionReason::ClobberedActiveTransition:
|
||||||
|
readyPromise->MaybeRejectWithAbortError(
|
||||||
|
"Skipped ViewTransition due to another transition starting");
|
||||||
|
break;
|
||||||
|
case SkipTransitionReason::DocumentHidden:
|
||||||
|
readyPromise->MaybeRejectWithAbortError(
|
||||||
|
"Skipped ViewTransition due to document being hidden");
|
||||||
|
break;
|
||||||
|
case SkipTransitionReason::Timeout:
|
||||||
|
readyPromise->MaybeRejectWithAbortError(
|
||||||
|
"Skipped ViewTransition due to timeout");
|
||||||
|
break;
|
||||||
|
case SkipTransitionReason::UpdateCallbackRejected:
|
||||||
|
readyPromise->MaybeReject(aUpdateCallbackRejectReason);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 8: Resolve transition's finished promise with the result of reacting
|
||||||
|
// to transition's update callback done promise.
|
||||||
|
//
|
||||||
|
// This is done in CallUpdateCallback()
|
||||||
}
|
}
|
||||||
|
|
||||||
JSObject* ViewTransition::WrapObject(JSContext* aCx,
|
JSObject* ViewTransition::WrapObject(JSContext* aCx,
|
||||||
|
|
|
@ -7,32 +7,85 @@
|
||||||
|
|
||||||
#include "nsWrapperCache.h"
|
#include "nsWrapperCache.h"
|
||||||
|
|
||||||
namespace mozilla::dom {
|
class nsIGlobalObject;
|
||||||
|
class nsITimer;
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
|
||||||
|
class ErrorResult;
|
||||||
|
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
class Promise;
|
|
||||||
class Document;
|
class Document;
|
||||||
|
class Promise;
|
||||||
class ViewTransitionUpdateCallback;
|
class ViewTransitionUpdateCallback;
|
||||||
|
|
||||||
|
enum class SkipTransitionReason : uint8_t {
|
||||||
|
JS,
|
||||||
|
DocumentHidden,
|
||||||
|
ClobberedActiveTransition,
|
||||||
|
Timeout,
|
||||||
|
UpdateCallbackRejected,
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://drafts.csswg.org/css-view-transitions-1/#viewtransition-phase
|
||||||
|
enum class ViewTransitionPhase : uint8_t {
|
||||||
|
PendingCapture = 0,
|
||||||
|
UpdateCallbackCalled,
|
||||||
|
Animating,
|
||||||
|
Done,
|
||||||
|
};
|
||||||
|
|
||||||
class ViewTransition final : public nsISupports, public nsWrapperCache {
|
class ViewTransition final : public nsISupports, public nsWrapperCache {
|
||||||
public:
|
public:
|
||||||
|
using Phase = ViewTransitionPhase;
|
||||||
|
|
||||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||||
NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(ViewTransition)
|
NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(ViewTransition)
|
||||||
|
|
||||||
ViewTransition(Document&, ViewTransitionUpdateCallback*);
|
ViewTransition(Document&, ViewTransitionUpdateCallback*);
|
||||||
|
|
||||||
Promise* UpdateCallbackDone();
|
Promise* GetUpdateCallbackDone(ErrorResult&);
|
||||||
Promise* Ready();
|
Promise* GetReady(ErrorResult&);
|
||||||
Promise* Finished();
|
Promise* GetFinished(ErrorResult&);
|
||||||
void SkipTransition();
|
|
||||||
|
|
||||||
nsISupports* GetParentObject() const;
|
void SkipTransition(SkipTransitionReason = SkipTransitionReason::JS);
|
||||||
|
void PerformPendingOperations();
|
||||||
|
|
||||||
|
nsIGlobalObject* GetParentObject() const;
|
||||||
JSObject* WrapObject(JSContext*, JS::Handle<JSObject*> aGivenProto) override;
|
JSObject* WrapObject(JSContext*, JS::Handle<JSObject*> aGivenProto) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
enum class CallIfDone : bool { No, Yes };
|
||||||
|
MOZ_CAN_RUN_SCRIPT void CallUpdateCallbackIgnoringErrors(CallIfDone);
|
||||||
|
MOZ_CAN_RUN_SCRIPT void CallUpdateCallback(ErrorResult&);
|
||||||
|
void Activate();
|
||||||
|
|
||||||
|
void ClearActiveTransition();
|
||||||
|
void Timeout();
|
||||||
|
void Setup();
|
||||||
|
void HandleFrame();
|
||||||
|
void SkipTransition(SkipTransitionReason, JS::Handle<JS::Value>);
|
||||||
|
void ClearTimeoutTimer();
|
||||||
|
|
||||||
~ViewTransition();
|
~ViewTransition();
|
||||||
|
|
||||||
|
// Stored for the whole lifetime of the object (until CC).
|
||||||
RefPtr<Document> mDocument;
|
RefPtr<Document> mDocument;
|
||||||
|
RefPtr<ViewTransitionUpdateCallback> mUpdateCallback;
|
||||||
|
|
||||||
|
// Allocated lazily, but same object once allocated (again until CC).
|
||||||
|
RefPtr<Promise> mUpdateCallbackDonePromise;
|
||||||
|
RefPtr<Promise> mReadyPromise;
|
||||||
|
RefPtr<Promise> mFinishedPromise;
|
||||||
|
|
||||||
|
static void TimeoutCallback(nsITimer*, void*);
|
||||||
|
RefPtr<nsITimer> mTimeoutTimer;
|
||||||
|
|
||||||
|
Phase mPhase = Phase::PendingCapture;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mozilla::dom
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
|
|
||||||
[Exposed=Window, Pref="dom.viewTransitions.enabled"]
|
[Exposed=Window, Pref="dom.viewTransitions.enabled"]
|
||||||
interface ViewTransition {
|
interface ViewTransition {
|
||||||
readonly attribute Promise<undefined> updateCallbackDone;
|
[Throws] readonly attribute Promise<undefined> updateCallbackDone;
|
||||||
readonly attribute Promise<undefined> ready;
|
[Throws] readonly attribute Promise<undefined> ready;
|
||||||
readonly attribute Promise<undefined> finished;
|
[Throws] readonly attribute Promise<undefined> finished;
|
||||||
undefined skipTransition();
|
undefined skipTransition();
|
||||||
};
|
};
|
||||||
|
|
|
@ -1364,6 +1364,7 @@ nsRefreshDriver::nsRefreshDriver(nsPresContext* aPresContext)
|
||||||
mResizeSuppressed(false),
|
mResizeSuppressed(false),
|
||||||
mNeedToUpdateIntersectionObservations(false),
|
mNeedToUpdateIntersectionObservations(false),
|
||||||
mNeedToUpdateResizeObservers(false),
|
mNeedToUpdateResizeObservers(false),
|
||||||
|
mNeedToUpdateViewTransitions(false),
|
||||||
mNeedToRunFrameRequestCallbacks(false),
|
mNeedToRunFrameRequestCallbacks(false),
|
||||||
mNeedToUpdateAnimations(false),
|
mNeedToUpdateAnimations(false),
|
||||||
mMightNeedMediaQueryListenerUpdate(false),
|
mMightNeedMediaQueryListenerUpdate(false),
|
||||||
|
@ -1965,6 +1966,9 @@ auto nsRefreshDriver::GetReasonsToTick() const -> TickReasons {
|
||||||
if (mNeedToUpdateResizeObservers) {
|
if (mNeedToUpdateResizeObservers) {
|
||||||
reasons |= TickReasons::eNeedsToNotifyResizeObservers;
|
reasons |= TickReasons::eNeedsToNotifyResizeObservers;
|
||||||
}
|
}
|
||||||
|
if (mNeedToUpdateViewTransitions) {
|
||||||
|
reasons |= TickReasons::eNeedsToUpdateViewTransitions;
|
||||||
|
}
|
||||||
if (mNeedToUpdateAnimations) {
|
if (mNeedToUpdateAnimations) {
|
||||||
reasons |= TickReasons::eNeedsToUpdateAnimations;
|
reasons |= TickReasons::eNeedsToUpdateAnimations;
|
||||||
}
|
}
|
||||||
|
@ -2014,6 +2018,9 @@ void nsRefreshDriver::AppendTickReasonsToString(TickReasons aReasons,
|
||||||
if (aReasons & TickReasons::eNeedsToNotifyResizeObservers) {
|
if (aReasons & TickReasons::eNeedsToNotifyResizeObservers) {
|
||||||
aStr.AppendLiteral(" NeedsToNotifyResizeObservers");
|
aStr.AppendLiteral(" NeedsToNotifyResizeObservers");
|
||||||
}
|
}
|
||||||
|
if (aReasons & TickReasons::eNeedsToUpdateViewTransitions) {
|
||||||
|
aStr.AppendLiteral(" NeedsToUpdateViewTransitions");
|
||||||
|
}
|
||||||
if (aReasons & TickReasons::eNeedsToUpdateAnimations) {
|
if (aReasons & TickReasons::eNeedsToUpdateAnimations) {
|
||||||
aStr.AppendLiteral(" NeedsToUpdateAnimations");
|
aStr.AppendLiteral(" NeedsToUpdateAnimations");
|
||||||
}
|
}
|
||||||
|
@ -2236,6 +2243,15 @@ void nsRefreshDriver::RunFullscreenSteps() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nsRefreshDriver::PerformPendingViewTransitionOperations() {
|
||||||
|
if (!mNeedToUpdateViewTransitions) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mNeedToUpdateViewTransitions = false;
|
||||||
|
AUTO_PROFILER_LABEL_RELEVANT_FOR_JS("View Transitions", LAYOUT);
|
||||||
|
mPresContext->Document()->PerformPendingViewTransitionOperations();
|
||||||
|
}
|
||||||
|
|
||||||
void nsRefreshDriver::UpdateIntersectionObservations(TimeStamp aNowTime) {
|
void nsRefreshDriver::UpdateIntersectionObservations(TimeStamp aNowTime) {
|
||||||
AUTO_PROFILER_LABEL_RELEVANT_FOR_JS("Compute intersections", LAYOUT);
|
AUTO_PROFILER_LABEL_RELEVANT_FOR_JS("Compute intersections", LAYOUT);
|
||||||
mPresContext->Document()->UpdateIntersections(aNowTime);
|
mPresContext->Document()->UpdateIntersections(aNowTime);
|
||||||
|
@ -2799,7 +2815,13 @@ void nsRefreshDriver::Tick(VsyncId aId, TimeStamp aNowTime,
|
||||||
return StopTimer();
|
return StopTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 17. For each doc of docs, run the update intersection observations
|
// TODO(emilio): Step 17, focus fix-up should happen here.
|
||||||
|
|
||||||
|
// Step 18: For each doc of docs, perform pending transition operations for
|
||||||
|
// doc.
|
||||||
|
PerformPendingViewTransitionOperations();
|
||||||
|
|
||||||
|
// Step 19. For each doc of docs, run the update intersection observations
|
||||||
// steps for doc.
|
// steps for doc.
|
||||||
UpdateIntersectionObservations(aNowTime);
|
UpdateIntersectionObservations(aNowTime);
|
||||||
|
|
||||||
|
|
|
@ -406,6 +406,11 @@ class nsRefreshDriver final : public mozilla::layers::TransactionIdAllocator,
|
||||||
mNeedToUpdateResizeObservers = true;
|
mNeedToUpdateResizeObservers = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EnsureViewTransitionOperationsHappen() {
|
||||||
|
EnsureTimerStarted();
|
||||||
|
mNeedToUpdateViewTransitions = true;
|
||||||
|
}
|
||||||
|
|
||||||
void EnsureAnimationUpdate() {
|
void EnsureAnimationUpdate() {
|
||||||
EnsureTimerStarted();
|
EnsureTimerStarted();
|
||||||
mNeedToUpdateAnimations = true;
|
mNeedToUpdateAnimations = true;
|
||||||
|
@ -442,6 +447,7 @@ class nsRefreshDriver final : public mozilla::layers::TransactionIdAllocator,
|
||||||
eRootNeedsMoreTicksForUserInput = 1 << 9,
|
eRootNeedsMoreTicksForUserInput = 1 << 9,
|
||||||
eNeedsToUpdateAnimations = 1 << 10,
|
eNeedsToUpdateAnimations = 1 << 10,
|
||||||
eNeedsToRunFrameRequestCallbacks = 1 << 11,
|
eNeedsToRunFrameRequestCallbacks = 1 << 11,
|
||||||
|
eNeedsToUpdateViewTransitions = 1 << 12,
|
||||||
};
|
};
|
||||||
|
|
||||||
void AddForceNotifyContentfulPaintPresContext(nsPresContext* aPresContext);
|
void AddForceNotifyContentfulPaintPresContext(nsPresContext* aPresContext);
|
||||||
|
@ -495,6 +501,7 @@ class nsRefreshDriver final : public mozilla::layers::TransactionIdAllocator,
|
||||||
mozilla::TimeStamp aNowTime);
|
mozilla::TimeStamp aNowTime);
|
||||||
void UpdateIntersectionObservations(mozilla::TimeStamp aNowTime);
|
void UpdateIntersectionObservations(mozilla::TimeStamp aNowTime);
|
||||||
void UpdateRelevancyOfContentVisibilityAutoFrames();
|
void UpdateRelevancyOfContentVisibilityAutoFrames();
|
||||||
|
void PerformPendingViewTransitionOperations();
|
||||||
MOZ_CAN_RUN_SCRIPT void
|
MOZ_CAN_RUN_SCRIPT void
|
||||||
DetermineProximityToViewportAndNotifyResizeObservers();
|
DetermineProximityToViewportAndNotifyResizeObservers();
|
||||||
void MaybeIncreaseMeasuredTicksSinceLoading();
|
void MaybeIncreaseMeasuredTicksSinceLoading();
|
||||||
|
@ -638,10 +645,13 @@ class nsRefreshDriver final : public mozilla::layers::TransactionIdAllocator,
|
||||||
// all our documents.
|
// all our documents.
|
||||||
bool mNeedToUpdateIntersectionObservations : 1;
|
bool mNeedToUpdateIntersectionObservations : 1;
|
||||||
|
|
||||||
// True if we need to flush in order to update intersection observations in
|
// True if we need to flush in order to update resize observations in all
|
||||||
// all our documents.
|
// our documents.
|
||||||
bool mNeedToUpdateResizeObservers : 1;
|
bool mNeedToUpdateResizeObservers : 1;
|
||||||
|
|
||||||
|
// True if we may need to perform pending view transition operations.
|
||||||
|
bool mNeedToUpdateViewTransitions : 1;
|
||||||
|
|
||||||
// True if we may need to run any frame callback.
|
// True if we may need to run any frame callback.
|
||||||
bool mNeedToRunFrameRequestCallbacks : 1;
|
bool mNeedToRunFrameRequestCallbacks : 1;
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,7 @@ struct EnumTypeFitsWithin
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the underlying value of an enum, but typesafe.
|
* Get the underlying value of an enum, but typesafe.
|
||||||
|
* TODO: Replace with std::to_underlying when available.
|
||||||
*
|
*
|
||||||
* example:
|
* example:
|
||||||
*
|
*
|
||||||
|
|
|
@ -4460,6 +4460,14 @@
|
||||||
mirror: always
|
mirror: always
|
||||||
rust: true
|
rust: true
|
||||||
|
|
||||||
|
# Timeout for view transitions.
|
||||||
|
# TODO(emilio): Figure out the right time-out, Blink uses between 4 and 15
|
||||||
|
# seconds.
|
||||||
|
- name: dom.viewTransitions.timeout-ms
|
||||||
|
type: uint32_t
|
||||||
|
value: 10000
|
||||||
|
mirror: always
|
||||||
|
|
||||||
# Is support for WebVR APIs enabled?
|
# Is support for WebVR APIs enabled?
|
||||||
# Disabled everywhere, but not removed.
|
# Disabled everywhere, but not removed.
|
||||||
- name: dom.vr.enabled
|
- name: dom.vr.enabled
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[active-view-transition-on-non-root.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +1,2 @@
|
||||||
[active-view-transition-type-on-non-root.html]
|
[active-view-transition-type-on-non-root.html]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[backdrop-filter-captured.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[dialog-in-rtl-iframe.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[document-element-detached-crash.html]
|
|
||||||
expected: TIMEOUT
|
|
|
@ -1,3 +1,4 @@
|
||||||
[duplicate-tag-rejects-capture.html]
|
[duplicate-tag-rejects-capture.html]
|
||||||
|
expected: [ERROR, OK]
|
||||||
[Two different elements with the same name in the old DOM should skip the transition]
|
[Two different elements with the same name in the old DOM should skip the transition]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
[element-stops-grouping-after-animation.html]
|
[element-stops-grouping-after-animation.html]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
[event-pseudo-name.html]
|
[event-pseudo-name.html]
|
||||||
|
expected: TIMEOUT
|
||||||
[verifies pseudo name includes a tag]
|
[verifies pseudo name includes a tag]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[fractional-translation-from-position.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[fractional-translation-from-transform.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +1,2 @@
|
||||||
[fragmented-during-transition-skips.html]
|
[fragmented-during-transition-skips.html]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
[hit-test-unpainted-element.html]
|
[hit-test-unpainted-element.html]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
[hit-test-unrelated-element.html]
|
[hit-test-unrelated-element.html]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[iframe-new-has-scrollbar.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[iframe-old-has-scrollbar.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[iframe-transition-destroyed-document-crash.html]
|
|
||||||
expected: TIMEOUT
|
|
|
@ -1,2 +0,0 @@
|
||||||
[iframe-transition.sub.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[list-style-position-style-change-crash.html]
|
|
||||||
expected: TIMEOUT
|
|
|
@ -1,2 +0,0 @@
|
||||||
[massive-element-below-viewport-partially-onscreen-new.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[massive-element-below-viewport-partially-onscreen-old.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +1,5 @@
|
||||||
[massive-element-left-of-viewport-partially-onscreen-new.html]
|
[massive-element-left-of-viewport-partially-onscreen-new.html]
|
||||||
expected: FAIL
|
# Might need meta viewport.
|
||||||
|
expected:
|
||||||
|
if os == "android": FAIL
|
||||||
|
PASS
|
||||||
|
|
|
@ -1,2 +1,5 @@
|
||||||
[massive-element-left-of-viewport-partially-onscreen-old.html]
|
[massive-element-left-of-viewport-partially-onscreen-old.html]
|
||||||
expected: FAIL
|
# Might need meta viewport.
|
||||||
|
expected:
|
||||||
|
if os == "android": FAIL
|
||||||
|
PASS
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[massive-element-right-of-viewport-partially-onscreen-new.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[massive-element-right-of-viewport-partially-onscreen-old.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[named-element-with-fix-pos-child-new.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[named-element-with-fix-pos-child-old.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,4 +1,5 @@
|
||||||
[pageswap-ctor.html]
|
[pageswap-ctor.html]
|
||||||
|
expected: ERROR
|
||||||
[Constructing pageswap event]
|
[Constructing pageswap event]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[new-and-old-sizes-match.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[new-content-from-root-display-none.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +1,5 @@
|
||||||
[new-content-has-scrollbars.html]
|
[new-content-has-scrollbars.html]
|
||||||
expected: FAIL
|
# Might depend on classic (non-overlay) scrollbars
|
||||||
|
expected:
|
||||||
|
if os == "android": FAIL
|
||||||
|
PASS
|
||||||
|
|
|
@ -1,3 +1,2 @@
|
||||||
[no-crash-set-exception.html]
|
[no-crash-set-exception.html]
|
||||||
[An exception thrown during a transition shouldn't crash.]
|
expected: [OK, ERROR]
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
[no-crash-view-transition-in-massive-iframe.html]
|
[no-crash-view-transition-in-massive-iframe.html]
|
||||||
|
expected: TIMEOUT
|
||||||
[startViewTransition in massive iframe shouldn't crash.]
|
[startViewTransition in massive iframe shouldn't crash.]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[no-root-capture.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[no-white-flash-before-activation.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[nothing-captured.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,5 +0,0 @@
|
||||||
[only-child-on-root-element-with-view-transition.html]
|
|
||||||
expected:
|
|
||||||
if not fission and (os == "linux") and debug: [OK, CRASH]
|
|
||||||
[:only-child is not supported on view-transition]
|
|
||||||
expected: FAIL
|
|
|
@ -1,3 +0,0 @@
|
||||||
[only-child-view-transition.html]
|
|
||||||
[:only-child is not supported on view-transition]
|
|
||||||
expected: FAIL
|
|
|
@ -1,3 +0,0 @@
|
||||||
[paused-animation-at-end.html]
|
|
||||||
[view transition is not over if animations are paused]
|
|
||||||
expected: FAIL
|
|
|
@ -1,5 +1,6 @@
|
||||||
[pseudo-computed-style-stays-in-sync-with-new-element.html]
|
[pseudo-computed-style-stays-in-sync-with-new-element.html]
|
||||||
expected:
|
expected:
|
||||||
if (os == "android") and fission: [OK, TIMEOUT]
|
if (os == "android") and fission: [OK, TIMEOUT]
|
||||||
|
ERROR
|
||||||
[computed style on pseudo-element stays in sync with the DOM element]
|
[computed style on pseudo-element stays in sync with the DOM element]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
[pseudo-get-computed-style.html]
|
[pseudo-get-computed-style.html]
|
||||||
|
expected: ERROR
|
||||||
[position property of pseudo elements]
|
[position property of pseudo elements]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
||||||
[properties of pseudo elements outside of transition]
|
[properties of pseudo elements outside of transition]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[properties of pseudo elements outside of transition]
|
[properties of pseudo elements outside of transition]
|
||||||
expected: FAIL
|
expected: NOTRUN
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[ready_resolves_after_dom_before_raf.html]
|
|
||||||
expected:
|
|
||||||
if not fission and (os == "linux") and debug: [OK, CRASH]
|
|
||||||
[updateCallbackDone resolves, then ready resolves with no rAF in between]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[rotated-cat-off-top-edge.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[rtl-with-scrollbar.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[scroller-child-abspos.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[scroller-child.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[scroller.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[shadow-part-with-name-overridden-by-important.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,5 +1,6 @@
|
||||||
[style-inheritance.html]
|
[style-inheritance.html]
|
||||||
expected:
|
expected:
|
||||||
if not fission and (os == "linux") and debug: [OK, CRASH]
|
if not fission and (os == "linux") and debug: [OK, CRASH]
|
||||||
|
ERROR
|
||||||
[style inheritance of pseudo elements]
|
[style inheritance of pseudo elements]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
|
@ -1,3 +1,2 @@
|
||||||
[synchronous-callback-skipped-before-run.html]
|
[synchronous-callback-skipped-before-run.html]
|
||||||
[finished promise should be resolved if skipTransition() is invoked before a synchronous updateCallbackDone callback is dispatched]
|
expected: ERROR
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[transition-in-empty-iframe.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,9 +1,10 @@
|
||||||
[transition-in-hidden-page.html]
|
[transition-in-hidden-page.html]
|
||||||
|
expected: [TIMEOUT, ERROR]
|
||||||
[A view transition should be immediately skipped if started when document is hidden]
|
[A view transition should be immediately skipped if started when document is hidden]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[A view transition should be skipped when a document becomes hidden while processing update callback]
|
[A view transition should be skipped when a document becomes hidden while processing update callback]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
||||||
[A view transition should be skipped when a document becomes hidden while animating]
|
[A view transition should be skipped when a document becomes hidden while animating]
|
||||||
expected: FAIL
|
expected: NOTRUN
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
[transition-skipped-after-animation-started.html]
|
[transition-skipped-after-animation-started.html]
|
||||||
expected:
|
expected: TIMEOUT
|
||||||
if (os == "android") and fission: [TIMEOUT, OK]
|
|
||||||
[skipTransition() after animations have started running should resolve finished promise]
|
[skipTransition() after animations have started running should resolve finished promise]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
[transition-skipped-from-invalid-callback.html]
|
[transition-skipped-from-invalid-callback.html]
|
||||||
expected:
|
expected: TIMEOUT
|
||||||
if (os == "android") and fission: [OK, TIMEOUT]
|
|
||||||
[transition skipped because callback has invalid syntax]
|
[transition skipped because callback has invalid syntax]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
[unset-and-initial-view-transition-name.html]
|
[unset-and-initial-view-transition-name.html]
|
||||||
expected:
|
expected: TIMEOUT
|
||||||
if (os == "android") and fission: [OK, TIMEOUT]
|
|
||||||
[validates that view-transition-name: unset or initial are ignored]
|
[validates that view-transition-name: unset or initial are ignored]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
[view-transition-name-on-removed-element.html]
|
[view-transition-name-on-removed-element.html]
|
||||||
|
expected: TIMEOUT
|
||||||
[view-transition-name on an element removed by script should not be visited when discovering named elements]
|
[view-transition-name on an element removed by script should not be visited when discovering named elements]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
[view-transition-name-removed-mid-transition.html]
|
[view-transition-name-removed-mid-transition.html]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
[view-transition-types-match-early-mutation.html]
|
[view-transition-types-match-early-mutation.html]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
[view-transition-types-match-early.html]
|
[view-transition-types-match-early.html]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
[view-transition-types-match-late-mutation.html]
|
[view-transition-types-match-late-mutation.html]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
[view-transition-types-matches.html]
|
[view-transition-types-matches.html]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
[view-transition-types-mutable.html]
|
[view-transition-types-mutable.html]
|
||||||
|
expected: ERROR
|
||||||
[ViewTransition.types is a ViewTransitionTypeSet]
|
[ViewTransition.types is a ViewTransitionTypeSet]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
[view-transition-types-removed.html]
|
[view-transition-types-removed.html]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
[view-transition-types-reserved-mutation.html]
|
[view-transition-types-reserved-mutation.html]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
[view-transition-types-reserved.html]
|
[view-transition-types-reserved.html]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
[view-transition-types-stay.html]
|
[view-transition-types-stay.html]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
[web-animation-pseudo-incorrect-name.html]
|
[web-animation-pseudo-incorrect-name.html]
|
||||||
|
expected: ERROR
|
||||||
[animation created with incorrect name]
|
[animation created with incorrect name]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
[web-animations-api-parse-pseudo-argument.html?first-pseudo=::view-transition-group(first )]
|
[web-animations-api-parse-pseudo-argument.html?first-pseudo=::view-transition-group(first )]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
||||||
[web-animations-api-parse-pseudo-argument.html?first-pseudo=::view-transition-group(first)]
|
[web-animations-api-parse-pseudo-argument.html?first-pseudo=::view-transition-group(first)]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
||||||
[web-animations-api-parse-pseudo-argument.html?first-pseudo=::view-transition-group( first )]
|
[web-animations-api-parse-pseudo-argument.html?first-pseudo=::view-transition-group( first )]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
||||||
[web-animations-api-parse-pseudo-argument.html?first-pseudo=::view-transition-group(first]
|
[web-animations-api-parse-pseudo-argument.html?first-pseudo=::view-transition-group(first]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
||||||
[web-animations-api-parse-pseudo-argument.html?first-pseudo=::view-transition-group( first]
|
[web-animations-api-parse-pseudo-argument.html?first-pseudo=::view-transition-group( first]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
||||||
[web-animations-api-parse-pseudo-argument.html?first-pseudo=::view-transition-group( first)]
|
[web-animations-api-parse-pseudo-argument.html?first-pseudo=::view-transition-group( first)]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
[web-animations-api.html]
|
[web-animations-api.html]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
[window-resize-aborts-transition.html]
|
[window-resize-aborts-transition.html]
|
||||||
|
expected: [ERROR, TIMEOUT]
|
||||||
[View transitions: Resizing viewport skips the transition]
|
[View transitions: Resizing viewport skips the transition]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
Загрузка…
Ссылка в новой задаче