commit bc7603ab3124559c99756c09b2713699504a673d parent 4d5c12d5fb2e029a888eac10ff3c84acbb5c3a0b Author: Emilio Cobos Álvarez <emilio@crisal.io> Date: Wed, 26 Nov 2025 08:28:29 +0000 Bug 2001878 - Implement :active-view-transition-type and co. r=firefox-style-system-reviewers,view-transitions-reviewers,webidl,smaug,boris The test change is needed to avoid ERROR status due to the previous transition getting skipped when starting a new one. The rest is somewhat straight-forward. Differential Revision: https://phabricator.services.mozilla.com/D273740 Diffstat:
30 files changed, 278 insertions(+), 82 deletions(-)
diff --git a/dom/base/Document.cpp b/dom/base/Document.cpp @@ -285,6 +285,7 @@ #include "mozilla/net/NeckoChannelParams.h" #include "mozilla/net/RequestContextService.h" #include "nsAboutProtocolUtils.h" +#include "nsAtom.h" #include "nsAttrValue.h" #include "nsAttrValueInlines.h" #include "nsBaseHashtable.h" @@ -18791,10 +18792,27 @@ void Document::ClearStaleServoData() { // https://drafts.csswg.org/css-view-transitions-1/#dom-document-startviewtransition already_AddRefed<ViewTransition> Document::StartViewTransition( - const Optional<OwningNonNull<ViewTransitionUpdateCallback>>& aCallback) { + const ViewTransitionUpdateCallbackOrStartViewTransitionOptions& aOptions) { // Steps 1-3 - RefPtr transition = new ViewTransition( - *this, aCallback.WasPassed() ? &aCallback.Value() : nullptr); + + nsTArray<RefPtr<nsAtom>> types; + ViewTransitionUpdateCallback* cb = nullptr; + if (aOptions.IsViewTransitionUpdateCallback()) { + cb = &aOptions.GetAsViewTransitionUpdateCallback(); + } else { + MOZ_ASSERT(aOptions.IsStartViewTransitionOptions()); + const auto& options = aOptions.GetAsStartViewTransitionOptions(); + cb = options.mUpdate.get(); + if (!options.mTypes.IsNull()) { + const auto& optionsTypes = options.mTypes.Value(); + types.SetCapacity(optionsTypes.Length()); + for (const auto& type : optionsTypes) { + // TODO(emilio): should probably de-duplicate here. + types.AppendElement(NS_AtomizeMainThread(type)); + } + } + } + RefPtr transition = new ViewTransition(*this, cb, std::move(types)); if (Hidden()) { // Step 4: // diff --git a/dom/base/Document.h b/dom/base/Document.h @@ -288,7 +288,7 @@ class TrustedHTMLOrString; class OwningTrustedHTMLOrString; enum class ViewportFitType : uint8_t; class ViewTransition; -class ViewTransitionUpdateCallback; +class ViewTransitionUpdateCallbackOrStartViewTransitionOptions; class WakeLockSentinel; class WindowContext; class WindowGlobalChild; @@ -4065,7 +4065,7 @@ class Document : public nsINode, DetermineProximityToViewportAndNotifyResizeObservers(); already_AddRefed<ViewTransition> StartViewTransition( - const Optional<OwningNonNull<ViewTransitionUpdateCallback>>&); + const ViewTransitionUpdateCallbackOrStartViewTransitionOptions&); ViewTransition* GetActiveViewTransition() const { return mActiveViewTransition; } diff --git a/dom/tests/mochitest/general/test_interfaces.js b/dom/tests/mochitest/general/test_interfaces.js @@ -1609,6 +1609,8 @@ let interfaceNamesInGlobalScope = [ // IMPORTANT: Do not change this list without review from a DOM peer! { name: "ViewTransition", insecureContext: true }, // IMPORTANT: Do not change this list without review from a DOM peer! + { name: "ViewTransitionTypeSet", insecureContext: true }, + // IMPORTANT: Do not change this list without review from a DOM peer! { name: "VisualViewport", insecureContext: true }, // IMPORTANT: Do not change this list without review from a DOM peer! { name: "WGSLLanguageFeatures", earlyBetaOrEarlier: true }, diff --git a/dom/view-transitions/ViewTransition.cpp b/dom/view-transitions/ViewTransition.cpp @@ -18,6 +18,7 @@ #include "mozilla/dom/DocumentTimeline.h" #include "mozilla/dom/Promise-inl.h" #include "mozilla/dom/ViewTransitionBinding.h" +#include "mozilla/dom/ViewTransitionTypeSet.h" #include "mozilla/image/WebRenderImageProvider.h" #include "mozilla/layers/RenderRootStateManager.h" #include "mozilla/layers/WebRenderBridgeChild.h" @@ -245,7 +246,7 @@ static inline void ImplCycleCollectionTraverse( NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ViewTransition, mDocument, mUpdateCallback, mUpdateCallbackDonePromise, mReadyPromise, - mFinishedPromise, mNamedElements, + mFinishedPromise, mNamedElements, mTypes, mSnapshotContainingBlock) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ViewTransition) @@ -257,8 +258,9 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(ViewTransition) NS_IMPL_CYCLE_COLLECTING_RELEASE(ViewTransition) ViewTransition::ViewTransition(Document& aDoc, - ViewTransitionUpdateCallback* aCb) - : mDocument(&aDoc), mUpdateCallback(aCb) {} + ViewTransitionUpdateCallback* aCb, + TypeList&& aTypeList) + : mDocument(&aDoc), mUpdateCallback(aCb), mTypeList(std::move(aTypeList)) {} ViewTransition::~ViewTransition() { ClearTimeoutTimer(); } @@ -2013,4 +2015,15 @@ Maybe<nsRect> ViewTransition::GetNewActiveRect(nsAtom* aName) const { return el->mNewActiveRect; } +ViewTransitionTypeSet* ViewTransition::Types() { + if (!mTypes) { + mTypes = new ViewTransitionTypeSet(*this); + for (const auto& type : mTypeList) { + ViewTransitionTypeSet_Binding::SetlikeHelpers::Add( + mTypes, nsDependentAtomString(type), IgnoreErrors()); + } + } + return mTypes; +} + }; // namespace mozilla::dom diff --git a/dom/view-transitions/ViewTransition.h b/dom/view-transitions/ViewTransition.h @@ -34,6 +34,7 @@ class IpcResourceUpdateQueue; namespace dom { +class ViewTransitionTypeSet; extern LazyLogModule gViewTransitionsLog; #define VT_LOG(...) \ @@ -79,15 +80,19 @@ enum class ViewTransitionPhase : uint8_t { class ViewTransition final : public nsISupports, public nsWrapperCache { public: using Phase = ViewTransitionPhase; + using TypeList = nsTArray<RefPtr<nsAtom>>; NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(ViewTransition) - ViewTransition(Document&, ViewTransitionUpdateCallback*); + ViewTransition(Document&, ViewTransitionUpdateCallback*, TypeList&&); Promise* GetUpdateCallbackDone(ErrorResult&); Promise* GetReady(ErrorResult&); Promise* GetFinished(ErrorResult&); + ViewTransitionTypeSet* Types(); + const TypeList& GetTypeList() const { return mTypeList; } + TypeList& GetTypeList() { return mTypeList; } void SkipTransition(SkipTransitionReason = SkipTransitionReason::JS); MOZ_CAN_RUN_SCRIPT void PerformPendingOperations(); @@ -213,6 +218,9 @@ class ViewTransition final : public nsISupports, public nsWrapperCache { RefPtr<Promise> mReadyPromise; RefPtr<Promise> mFinishedPromise; + TypeList mTypeList; + RefPtr<ViewTransitionTypeSet> mTypes; + static void TimeoutCallback(nsITimer*, void*); RefPtr<nsITimer> mTimeoutTimer; diff --git a/dom/view-transitions/ViewTransitionTypeSet.cpp b/dom/view-transitions/ViewTransitionTypeSet.cpp @@ -0,0 +1,72 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/dom/ViewTransitionTypeSet.h" + +#include "mozilla/ErrorResult.h" +#include "mozilla/dom/ViewTransition.h" +#include "mozilla/dom/ViewTransitionBinding.h" +#include "nsISupportsImpl.h" + +namespace mozilla::dom { + +using namespace ViewTransitionTypeSet_Binding; + +// Only needed for refcounted objects. +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ViewTransitionTypeSet, mTransition) +NS_IMPL_CYCLE_COLLECTING_ADDREF(ViewTransitionTypeSet) +NS_IMPL_CYCLE_COLLECTING_RELEASE(ViewTransitionTypeSet) +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ViewTransitionTypeSet) + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY + NS_INTERFACE_MAP_ENTRY(nsISupports) +NS_INTERFACE_MAP_END + +ViewTransitionTypeSet::ViewTransitionTypeSet(ViewTransition& aVt) + : mTransition(&aVt) {} + +ViewTransitionTypeSet::~ViewTransitionTypeSet() = default; + +nsISupports* ViewTransitionTypeSet::GetParentObject() const { + return mTransition.get(); +} + +ViewTransitionTypeSet* ViewTransitionTypeSet::Add(const nsAString& aValue, + ErrorResult& aRv) { + if (SetlikeHelpers::Has(this, aValue, aRv) || aRv.Failed()) { + return this; + } + SetlikeHelpers::Add(this, aValue, aRv); + if (aRv.Failed()) { + return this; + } + RefPtr atom = NS_AtomizeMainThread(aValue); + MOZ_ASSERT(!mTransition->GetTypeList().Contains(atom)); + mTransition->GetTypeList().AppendElement(std::move(atom)); + return this; +} +void ViewTransitionTypeSet::Clear(ErrorResult& aRv) { + SetlikeHelpers::Clear(this, aRv); + if (aRv.Failed()) { + return; + } + mTransition->GetTypeList().Clear(); +} +bool ViewTransitionTypeSet::Delete(const nsAString& aValue, ErrorResult& aRv) { + if (!SetlikeHelpers::Delete(this, aValue, aRv) || aRv.Failed()) { + return false; + } + RefPtr atom = NS_AtomizeMainThread(aValue); + MOZ_ASSERT(mTransition->GetTypeList().Contains(atom)); + mTransition->GetTypeList().RemoveElement(atom); + return true; +} + +JSObject* ViewTransitionTypeSet::WrapObject(JSContext* aCx, + JS::Handle<JSObject*> aGivenProto) { + return ViewTransitionTypeSet_Binding::Wrap(aCx, this, aGivenProto); +} + +} // namespace mozilla::dom diff --git a/dom/view-transitions/ViewTransitionTypeSet.h b/dom/view-transitions/ViewTransitionTypeSet.h @@ -0,0 +1,46 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef DOM_VIEWTRANSITIONTYPESET_H_ +#define DOM_VIEWTRANSITIONTYPESET_H_ + +#include "nsCycleCollectionParticipant.h" +#include "nsWrapperCache.h" + +namespace mozilla { +class ErrorResult; +namespace dom { + +class ViewTransition; + +class ViewTransitionTypeSet final : public nsISupports, public nsWrapperCache { + public: + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(ViewTransitionTypeSet) + + public: + explicit ViewTransitionTypeSet(ViewTransition&); + + MOZ_CAN_RUN_SCRIPT ViewTransitionTypeSet* Add(const nsAString&, ErrorResult&); + MOZ_CAN_RUN_SCRIPT void Clear(ErrorResult&); + MOZ_CAN_RUN_SCRIPT bool Delete(const nsAString&, ErrorResult&); + + protected: + ~ViewTransitionTypeSet(); + + public: + nsISupports* GetParentObject() const; + + JSObject* WrapObject(JSContext* aCx, + JS::Handle<JSObject*> aGivenProto) override; + + RefPtr<ViewTransition> mTransition; +}; + +} // namespace dom +} // namespace mozilla + +#endif // DOM_VIEWTRANSITIONTYPESET_H_ diff --git a/dom/view-transitions/moz.build b/dom/view-transitions/moz.build @@ -9,10 +9,12 @@ with Files("*"): EXPORTS.mozilla.dom += [ "ViewTransition.h", + "ViewTransitionTypeSet.h", ] UNIFIED_SOURCES += [ "ViewTransition.cpp", + "ViewTransitionTypeSet.cpp", ] include("/ipc/chromium/chromium-config.mozbuild") diff --git a/dom/webidl/Document.webidl b/dom/webidl/Document.webidl @@ -764,17 +764,23 @@ partial interface Document { readonly attribute FragmentDirective fragmentDirective; }; -// https://drafts.csswg.org/css-view-transitions-1/#additions-to-document-api + +callback ViewTransitionUpdateCallback = Promise<any> (); +dictionary StartViewTransitionOptions { + ViewTransitionUpdateCallback? update = null; + sequence<DOMString>? types = null; +}; + +// https://drafts.csswg.org/css-view-transitions-2/#idl-index partial interface Document { [Pref="dom.viewTransitions.enabled"] - ViewTransition startViewTransition(optional ViewTransitionUpdateCallback updateCallback); + ViewTransition startViewTransition( + optional (ViewTransitionUpdateCallback or StartViewTransitionOptions) callbackOptions = {} + ); [Pref="dom.viewTransitions.enabled"] readonly attribute ViewTransition? activeViewTransition; }; -// https://github.com/w3c/csswg-drafts/pull/10767 for the name divergence in the spec -callback ViewTransitionUpdateCallback = Promise<any> (); - // https://wicg.github.io/sanitizer-api/#sanitizer-api partial interface Document { [Throws, Pref="dom.security.sanitizer.enabled"] diff --git a/dom/webidl/ViewTransition.webidl b/dom/webidl/ViewTransition.webidl @@ -2,13 +2,31 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/ * - * https://drafts.csswg.org/css-view-transitions-1/#the-domtransition-interface + * https://drafts.csswg.org/css-view-transitions-2/#the-domtransition-interface + * https://drafts.csswg.org/css-view-transitions-2/#viewtransitiontypeset */ [Exposed=Window, Pref="dom.viewTransitions.enabled"] +interface ViewTransitionTypeSet { + setlike<DOMString>; +}; + +// Setlike methods that need to be overridden to keep the contents in sync with +// the C++ version, see bug 1799890 and bug 1822927. +partial interface ViewTransitionTypeSet { + [Throws] + ViewTransitionTypeSet add(DOMString type); + [Throws] + undefined clear(); + [Throws] + boolean delete(DOMString type); +}; + +[Exposed=Window, Pref="dom.viewTransitions.enabled"] interface ViewTransition { [Throws] readonly attribute Promise<undefined> updateCallbackDone; [Throws] readonly attribute Promise<undefined> ready; [Throws] readonly attribute Promise<undefined> finished; undefined skipTransition(); + [SameObject] readonly attribute ViewTransitionTypeSet types; }; diff --git a/layout/style/GeckoBindings.cpp b/layout/style/GeckoBindings.cpp @@ -804,6 +804,39 @@ bool Gecko_MatchViewTransitionClass( return vt->MatchClassList(name, *aPtNameAndClassSelector); } +static bool IsValidViewTransitionType(nsAtom* aName) { + nsDependentAtomString str(aName); + return !StringBeginsWith(str, u"-ua-"_ns, + nsASCIICaseInsensitiveStringComparator) && + !str.LowerCaseEqualsASCII("none"); +} + +bool Gecko_HasActiveViewTransitionTypes( + const mozilla::dom::Document* aDoc, + const nsTArray<StyleCustomIdent>* aNames) { + MOZ_ASSERT(aDoc); + MOZ_ASSERT(aNames); + const ViewTransition* vt = aDoc->GetActiveViewTransition(); + if (!vt) { + return false; + } + const auto& typeList = vt->GetTypeList(); + if (typeList.IsEmpty()) { + return false; + } + for (const auto& name : *aNames) { + if (typeList.Contains(name.AsAtom())) { + // NOTE(emilio): This IsValidViewTransitionType() check is not in the spec + // and is rather weird, but matches other browsers for now, see: + // https://github.com/w3c/csswg-drafts/issues/13141 + if (IsValidViewTransitionType(name.AsAtom())) { + return true; + } + } + } + return false; +} + nsAtom* Gecko_GetXMLLangValue(const Element* aElement) { const nsAttrValue* attr = aElement->GetParsedAttr(nsGkAtoms::lang, kNameSpaceID_XML); diff --git a/layout/style/GeckoBindings.h b/layout/style/GeckoBindings.h @@ -147,6 +147,8 @@ const mozilla::PreferenceSheet::Prefs* Gecko_GetPrefSheetPrefs( bool Gecko_IsTableBorderNonzero(const mozilla::dom::Element* element); bool Gecko_IsSelectListBox(const mozilla::dom::Element* element); +bool Gecko_HasActiveViewTransitionTypes( + const mozilla::dom::Document*, const nsTArray<mozilla::StyleCustomIdent>*); // Attributes. #define SERVO_DECLARE_ELEMENT_ATTR_MATCHING_FUNCTIONS(prefix_, implementor_) \ diff --git a/layout/style/ServoBindings.toml b/layout/style/ServoBindings.toml @@ -373,6 +373,7 @@ cbindgen-types = [ { gecko = "StyleAppearance", servo = "crate::values::specified::Appearance" }, { gecko = "StyleAspectRatio", servo = "crate::values::computed::position::AspectRatio" }, { gecko = "StyleAtom", servo = "crate::Atom" }, + { gecko = "StyleCustomIdent", servo = "crate::values::CustomIdent" }, { gecko = "StyleComputedFontStretchRange", servo = "crate::font_face::ComputedFontStretchRange" }, { gecko = "StyleComputedFontStyleDescriptor", servo = "crate::font_face::ComputedFontStyleDescriptor" }, { gecko = "StyleComputedFontWeightRange", servo = "crate::font_face::ComputedFontWeightRange" }, diff --git a/servo/components/style/gecko/selector_parser.rs b/servo/components/style/gecko/selector_parser.rs @@ -10,7 +10,7 @@ use crate::properties::ComputedValues; use crate::selector_parser::{Direction, HorizontalDirection, SelectorParser}; use crate::str::starts_with_ignore_ascii_case; use crate::string_cache::{Atom, Namespace, WeakAtom, WeakNamespace}; -use crate::values::{AtomIdent, AtomString, CSSInteger}; +use crate::values::{AtomIdent, AtomString, CSSInteger, CustomIdent}; use cssparser::{BasicParseError, BasicParseErrorKind, Parser}; use cssparser::{CowRcStr, SourceLocation, ToCss, Token}; use dom::{DocumentState, ElementState, HEADING_LEVEL_OFFSET}; @@ -89,6 +89,9 @@ macro_rules! pseudo_class_name { CustomState(CustomState), /// The `:heading` & `:heading()` pseudo-classes. Heading(HeadingSelectorData), + /// The :active-view-transition-type() pseudo-class: + /// https://drafts.csswg.org/css-view-transitions-2/#the-active-view-transition-type-pseudo + ActiveViewTransitionType(ThinVec<CustomIdent>), /// The non-standard `:-moz-locale-dir` pseudo-class. MozLocaleDir(Direction), } @@ -125,6 +128,18 @@ impl ToCss for NonTSPseudoClass { dir.to_css(&mut CssWriter::new(dest))?; return dest.write_char(')') }, + NonTSPseudoClass::ActiveViewTransitionType(ref types) => { + dest.write_str(":active-view-transition-type(")?; + let mut first = true; + for ty in types.iter() { + if !first { + dest.write_str(", ")?; + } + first = false; + ty.to_css(&mut CssWriter::new(dest))?; + } + return dest.write_char(')') + }, NonTSPseudoClass::Heading(ref levels) => { dest.write_str(":heading")?; if levels.0.is_empty() { @@ -191,6 +206,7 @@ impl NonTSPseudoClass { NonTSPseudoClass::CustomState(_) | NonTSPseudoClass::Heading(_) | NonTSPseudoClass::Lang(_) | + NonTSPseudoClass::ActiveViewTransitionType(_) | NonTSPseudoClass::Dir(_) => false, } } @@ -201,7 +217,7 @@ impl NonTSPseudoClass { /// Returns whether the pseudo-class is enabled in content sheets. #[inline] fn is_enabled_in_content(&self) -> bool { - if matches!(*self, Self::ActiveViewTransition) { + if matches!(*self, Self::ActiveViewTransition | Self::ActiveViewTransitionType(..)) { return static_prefs::pref!("dom.viewTransitions.enabled"); } if matches!(*self, Self::Heading(..)) { @@ -226,6 +242,7 @@ impl NonTSPseudoClass { $(NonTSPseudoClass::$name => flag!($state),)* NonTSPseudoClass::Dir(ref dir) => dir.element_state(), NonTSPseudoClass::Heading(..) => ElementState::HEADING_LEVEL_BITS, + NonTSPseudoClass::ActiveViewTransitionType(..) => ElementState::ACTIVE_VIEW_TRANSITION, NonTSPseudoClass::MozLocaleDir(..) | NonTSPseudoClass::CustomState(..) | NonTSPseudoClass::Lang(..) => ElementState::empty(), @@ -514,6 +531,13 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> { } NonTSPseudoClass::Heading(HeadingSelectorData(result.into())) }, + "active-view-transition-type" => { + let result = parser.parse_comma_separated(|input| CustomIdent::parse(input, &[]))?; + if result.is_empty() { + return Err(parser.new_custom_error(StyleParseErrorKind::UnspecifiedError)); + } + NonTSPseudoClass::ActiveViewTransitionType(result.into()) + }, "-moz-locale-dir" => { NonTSPseudoClass::MozLocaleDir(Direction::parse(parser)?) }, diff --git a/servo/components/style/gecko/wrapper.rs b/servo/components/style/gecko/wrapper.rs @@ -2064,6 +2064,11 @@ impl<'le> ::selectors::Element for GeckoElement<'le> { self.state().intersects(pseudo_class.state_flag()) }, NonTSPseudoClass::Dir(ref dir) => self.state().intersects(dir.element_state()), + NonTSPseudoClass::ActiveViewTransitionType(ref types) => { + self.state().intersects(pseudo_class.state_flag()) && unsafe { + bindings::Gecko_HasActiveViewTransitionTypes(self.as_node().owner_doc().0, types) + } + }, NonTSPseudoClass::AnyLink => self.is_link(), NonTSPseudoClass::Link => { self.is_link() && context.visited_handling().matches_unvisited() diff --git a/servo/components/style/selector_map.rs b/servo/components/style/selector_map.rs @@ -52,6 +52,7 @@ const RARE_PSEUDO_CLASS_STATES: ElementState = ElementState::from_bits_retain( | ElementState::FOCUSRING.bits() | ElementState::TOPMOST_MODAL.bits() | ElementState::SUPPRESS_FOR_PRINT_SELECTION.bits() + | ElementState::ACTIVE_VIEW_TRANSITION.bits() | ElementState::HEADING_LEVEL_BITS.bits(), ); diff --git a/testing/web-platform/meta/css/css-shadow-parts/pseudo-classes-after-part.html.ini b/testing/web-platform/meta/css/css-shadow-parts/pseudo-classes-after-part.html.ini @@ -16,6 +16,3 @@ ["::part(mypart):xr-overlay" should be a valid selector] expected: FAIL - - ["::part(mypart):active-view-transition-type(mytype)" should be a valid selector] - expected: FAIL diff --git a/testing/web-platform/meta/css/css-view-transitions/idlharness.html.ini b/testing/web-platform/meta/css/css-view-transitions/idlharness.html.ini @@ -2,9 +2,6 @@ [ViewTransition interface: attribute types] expected: FAIL - [ViewTransition interface: document.startViewTransition() must inherit property "types" with the proper type] - expected: FAIL - [CSSViewTransitionRule interface: existence and properties of interface object] expected: FAIL @@ -41,27 +38,6 @@ [CSSViewTransitionRule interface: sheet.cssRules[0\] must inherit property "types" with the proper type] expected: FAIL - [ViewTransitionTypeSet interface: existence and properties of interface object] - expected: FAIL - - [ViewTransitionTypeSet interface object length] - expected: FAIL - - [ViewTransitionTypeSet interface object name] - expected: FAIL - - [ViewTransitionTypeSet interface: existence and properties of interface prototype object] - expected: FAIL - - [ViewTransitionTypeSet interface: existence and properties of interface prototype object's "constructor" property] - expected: FAIL - - [ViewTransitionTypeSet interface: existence and properties of interface prototype object's @@unscopables property] - expected: FAIL - - [ViewTransitionTypeSet interface: setlike<DOMString>] - expected: FAIL - [ViewTransition interface: attribute transitionRoot] expected: FAIL diff --git a/testing/web-platform/meta/css/css-view-transitions/view-transition-types-match-early-mutation.html.ini b/testing/web-platform/meta/css/css-view-transitions/view-transition-types-match-early-mutation.html.ini @@ -1,2 +0,0 @@ -[view-transition-types-match-early-mutation.html] - expected: TIMEOUT diff --git a/testing/web-platform/meta/css/css-view-transitions/view-transition-types-match-early.html.ini b/testing/web-platform/meta/css/css-view-transitions/view-transition-types-match-early.html.ini @@ -1,2 +0,0 @@ -[view-transition-types-match-early.html] - expected: TIMEOUT diff --git a/testing/web-platform/meta/css/css-view-transitions/view-transition-types-match-late-mutation.html.ini b/testing/web-platform/meta/css/css-view-transitions/view-transition-types-match-late-mutation.html.ini @@ -1,2 +0,0 @@ -[view-transition-types-match-late-mutation.html] - expected: TIMEOUT diff --git a/testing/web-platform/meta/css/css-view-transitions/view-transition-types-matches-case-sensitive.html.ini b/testing/web-platform/meta/css/css-view-transitions/view-transition-types-matches-case-sensitive.html.ini @@ -1,2 +0,0 @@ -[view-transition-types-matches-case-sensitive.html] - expected: TIMEOUT diff --git a/testing/web-platform/meta/css/css-view-transitions/view-transition-types-matches.html.ini b/testing/web-platform/meta/css/css-view-transitions/view-transition-types-matches.html.ini @@ -1,2 +0,0 @@ -[view-transition-types-matches.html] - expected: TIMEOUT diff --git a/testing/web-platform/meta/css/css-view-transitions/view-transition-types-mutable-no-document-element-crashtest.html.ini b/testing/web-platform/meta/css/css-view-transitions/view-transition-types-mutable-no-document-element-crashtest.html.ini @@ -1,5 +1,2 @@ [view-transition-types-mutable-no-document-element-crashtest.html] - expected: - [OK, ERROR] - [ViewTransitionTypeSet should not crash when documentElement is null] - expected: FAIL + expected: [OK, ERROR] diff --git a/testing/web-platform/meta/css/css-view-transitions/view-transition-types-mutable.html.ini b/testing/web-platform/meta/css/css-view-transitions/view-transition-types-mutable.html.ini @@ -1,10 +0,0 @@ -[view-transition-types-mutable.html] - expected: ERROR - [ViewTransition.types is a ViewTransitionTypeSet] - expected: FAIL - - [ViewTransitionTypeSet behaves like an ordinary Set of strings] - expected: FAIL - - [ViewTransitionTypeSet should reflect its members for a non-active transition] - expected: FAIL diff --git a/testing/web-platform/meta/css/css-view-transitions/view-transition-types-removed.html.ini b/testing/web-platform/meta/css/css-view-transitions/view-transition-types-removed.html.ini @@ -1,2 +0,0 @@ -[view-transition-types-removed.html] - expected: TIMEOUT diff --git a/testing/web-platform/meta/css/css-view-transitions/view-transition-types-reserved-mutation.html.ini b/testing/web-platform/meta/css/css-view-transitions/view-transition-types-reserved-mutation.html.ini @@ -1,2 +0,0 @@ -[view-transition-types-reserved-mutation.html] - expected: TIMEOUT diff --git a/testing/web-platform/meta/css/css-view-transitions/view-transition-types-reserved.html.ini b/testing/web-platform/meta/css/css-view-transitions/view-transition-types-reserved.html.ini @@ -1,2 +0,0 @@ -[view-transition-types-reserved.html] - expected: TIMEOUT diff --git a/testing/web-platform/meta/css/css-view-transitions/view-transition-types-stay.html.ini b/testing/web-platform/meta/css/css-view-transitions/view-transition-types-stay.html.ini @@ -1,2 +0,0 @@ -[view-transition-types-stay.html] - expected: TIMEOUT diff --git a/testing/web-platform/tests/css/css-view-transitions/view-transition-types-mutable.html b/testing/web-platform/tests/css/css-view-transitions/view-transition-types-mutable.html @@ -4,16 +4,18 @@ <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <script> - - test(() => { + promise_test(async () => { assert_implements(document.startViewTransition); - const { types } = document.startViewTransition(); - assert_true(types instanceof ViewTransitionTypeSet); + let transition = document.startViewTransition(); + assert_true(transition.types instanceof ViewTransitionTypeSet); + await transition.finished; }, "ViewTransition.types is a ViewTransitionTypeSet"); - test(() => { + promise_test(async () => { assert_implements(document.startViewTransition); - const { types } = document.startViewTransition(); + let transition = document.startViewTransition(); + let types = transition.types; + assert_equals(types, transition.types, "Should return the same object"); types.add("a"); types.add("b"); assert_array_equals([...types], ["a", "b"]); @@ -27,6 +29,7 @@ types.add(""); types.add("123"); assert_array_equals([...types], ["a", ".", "", "123"]); + await transition.finished; }, "ViewTransitionTypeSet behaves like an ordinary Set of strings"); promise_test(async () => {