diff options
Diffstat (limited to 'layout/style')
45 files changed, 693 insertions, 341 deletions
diff --git a/layout/style/CSSPageRule.cpp b/layout/style/CSSPageRule.cpp index 04d064b362..fb7dcbc38b 100644 --- a/layout/style/CSSPageRule.cpp +++ b/layout/style/CSSPageRule.cpp @@ -94,20 +94,20 @@ CSSPageRuleDeclaration::GetParsingEnvironment( CSSPageRule::CSSPageRule(RefPtr<StyleLockedPageRule> aRawRule, StyleSheet* aSheet, css::Rule* aParentRule, uint32_t aLine, uint32_t aColumn) - : css::Rule(aSheet, aParentRule, aLine, aColumn), + : css::GroupRule(aSheet, aParentRule, aLine, aColumn), mRawRule(std::move(aRawRule)), mDecls(Servo_PageRule_GetStyle(mRawRule).Consume()) {} -NS_IMPL_ADDREF_INHERITED(CSSPageRule, css::Rule) -NS_IMPL_RELEASE_INHERITED(CSSPageRule, css::Rule) +NS_IMPL_ADDREF_INHERITED(CSSPageRule, css::GroupRule) +NS_IMPL_RELEASE_INHERITED(CSSPageRule, css::GroupRule) // QueryInterface implementation for PageRule NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CSSPageRule) -NS_INTERFACE_MAP_END_INHERITING(css::Rule) +NS_INTERFACE_MAP_END_INHERITING(css::GroupRule) NS_IMPL_CYCLE_COLLECTION_CLASS(CSSPageRule) -NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(CSSPageRule, css::Rule) +NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(CSSPageRule, css::GroupRule) // Keep this in sync with IsCCLeaf. // Trace the wrapper for our declaration. This just expands out @@ -124,14 +124,14 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CSSPageRule) // Note that this has to happen before unlinking css::Rule. tmp->UnlinkDeclarationWrapper(tmp->mDecls); tmp->mDecls.mDecls->SetOwningRule(nullptr); -NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(css::Rule) +NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(css::GroupRule) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSPageRule, css::Rule) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSPageRule, css::GroupRule) // Keep this in sync with IsCCLeaf. NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END bool CSSPageRule::IsCCLeaf() const { - if (!Rule::IsCCLeaf()) { + if (!GroupRule::IsCCLeaf()) { return false; } @@ -147,7 +147,7 @@ StyleCssRuleType CSSPageRule::Type() const { return StyleCssRuleType::Page; } size_t CSSPageRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const { // TODO Implement this! - return aMallocSizeOf(this); + return GroupRule::SizeOfExcludingThis(aMallocSizeOf) + aMallocSizeOf(this); } #ifdef DEBUG @@ -188,6 +188,10 @@ void CSSPageRule::SetSelectorText(const nsACString& aSelectorText) { } } +already_AddRefed<StyleLockedCssRules> CSSPageRule::GetOrCreateRawRules() { + return Servo_PageRule_GetRules(mRawRule).Consume(); +} + nsICSSDeclaration* CSSPageRule::Style() { return &mDecls; } JSObject* CSSPageRule::WrapObject(JSContext* aCx, diff --git a/layout/style/CSSPageRule.h b/layout/style/CSSPageRule.h index 705d526bdf..904f94d2c0 100644 --- a/layout/style/CSSPageRule.h +++ b/layout/style/CSSPageRule.h @@ -7,7 +7,7 @@ #ifndef mozilla_dom_CSSPageRule_h #define mozilla_dom_CSSPageRule_h -#include "mozilla/css/Rule.h" +#include "mozilla/css/GroupRule.h" #include "mozilla/ServoBindingTypes.h" #include "nsDOMCSSDeclaration.h" @@ -53,13 +53,14 @@ class CSSPageRuleDeclaration final : public nsDOMCSSDeclaration { RefPtr<DeclarationBlock> mDecls; }; -class CSSPageRule final : public css::Rule { +class CSSPageRule final : public css::GroupRule { public: CSSPageRule(RefPtr<StyleLockedPageRule> aRawRule, StyleSheet* aSheet, css::Rule* aParentRule, uint32_t aLine, uint32_t aColumn); NS_DECL_ISUPPORTS_INHERITED - NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(CSSPageRule, css::Rule) + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(CSSPageRule, + css::GroupRule) bool IsCCLeaf() const final; @@ -76,6 +77,8 @@ class CSSPageRule final : public css::Rule { size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const final; + already_AddRefed<StyleLockedCssRules> GetOrCreateRawRules() final; + #ifdef DEBUG void List(FILE* out = stdout, int32_t aIndent = 0) const final; #endif diff --git a/layout/style/CSSScopeRule.cpp b/layout/style/CSSScopeRule.cpp new file mode 100644 index 0000000000..18047a582b --- /dev/null +++ b/layout/style/CSSScopeRule.cpp @@ -0,0 +1,66 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/CSSScopeRule.h" +#include "mozilla/dom/CSSScopeRuleBinding.h" +#include "mozilla/ServoBindings.h" + +namespace mozilla::dom { + +CSSScopeRule::CSSScopeRule(RefPtr<StyleScopeRule> aRawRule, StyleSheet* aSheet, + css::Rule* aParentRule, uint32_t aLine, + uint32_t aColumn) + : css::GroupRule(aSheet, aParentRule, aLine, aColumn), + mRawRule(std::move(aRawRule)) {} + +NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(CSSScopeRule, css::GroupRule) + +// QueryInterface implementation for SupportsRule + +#ifdef DEBUG +void CSSScopeRule::List(FILE* out, int32_t aIndent) const { + nsAutoCString str; + for (int32_t i = 0; i < aIndent; i++) { + str.AppendLiteral(" "); + } + Servo_ScopeRule_Debug(mRawRule, &str); + fprintf_stderr(out, "%s\n", str.get()); +} +#endif + +StyleCssRuleType CSSScopeRule::Type() const { return StyleCssRuleType::Scope; } + +already_AddRefed<StyleLockedCssRules> CSSScopeRule::GetOrCreateRawRules() { + return Servo_ScopeRule_GetRules(mRawRule).Consume(); +} + +void CSSScopeRule::SetRawAfterClone(RefPtr<StyleScopeRule> aRaw) { + mRawRule = std::move(aRaw); + css::GroupRule::DidSetRawAfterClone(); +} + +void CSSScopeRule::GetCssText(nsACString& aCssText) const { + Servo_ScopeRule_GetCssText(mRawRule.get(), &aCssText); +} + +void CSSScopeRule::GetStart(nsACString& aStart) const { + Servo_ScopeRule_GetStart(mRawRule.get(), &aStart); +} + +void CSSScopeRule::GetEnd(nsACString& aEnd) const { + Servo_ScopeRule_GetEnd(mRawRule.get(), &aEnd); +} + +size_t CSSScopeRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const { + return aMallocSizeOf(this); +} + +JSObject* CSSScopeRule::WrapObject(JSContext* aCx, + JS::Handle<JSObject*> aGivenProto) { + return CSSScopeRule_Binding::Wrap(aCx, this, aGivenProto); +} + +} // namespace mozilla::dom diff --git a/layout/style/CSSScopeRule.h b/layout/style/CSSScopeRule.h new file mode 100644 index 0000000000..2cb1fa7e40 --- /dev/null +++ b/layout/style/CSSScopeRule.h @@ -0,0 +1,49 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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 CSSScopeRule_h___ +#define CSSScopeRule_h___ + +#include "mozilla/css/GroupRule.h" +#include "mozilla/ServoBindingTypes.h" + +namespace mozilla::dom { + +class CSSScopeRule final : public css::GroupRule { + public: + CSSScopeRule(RefPtr<StyleScopeRule> aRawRule, StyleSheet* aSheet, + css::Rule* aParentRule, uint32_t aLine, uint32_t aColumn); + + NS_DECL_ISUPPORTS_INHERITED + +#ifdef DEBUG + void List(FILE* out = stdout, int32_t aIndent = 0) const final; +#endif + + StyleScopeRule* Raw() const { return mRawRule; } + void SetRawAfterClone(RefPtr<StyleScopeRule>); + + already_AddRefed<StyleLockedCssRules> GetOrCreateRawRules() final; + + // WebIDL interface + StyleCssRuleType Type() const final; + void GetCssText(nsACString& aCssText) const final; + + void GetStart(nsACString& aStart) const; + void GetEnd(nsACString& aEnd) const; + + size_t SizeOfIncludingThis(MallocSizeOf) const override; + JSObject* WrapObject(JSContext*, JS::Handle<JSObject*>) override; + + private: + ~CSSScopeRule() = default; + + RefPtr<StyleScopeRule> mRawRule; +}; + +} // namespace mozilla::dom + +#endif diff --git a/layout/style/CSSStartingStyleRule.cpp b/layout/style/CSSStartingStyleRule.cpp new file mode 100644 index 0000000000..5c5ec311c9 --- /dev/null +++ b/layout/style/CSSStartingStyleRule.cpp @@ -0,0 +1,47 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/CSSStartingStyleRule.h" +#include "mozilla/dom/CSSStartingStyleRuleBinding.h" +#include "mozilla/ServoBindings.h" + +namespace mozilla::dom { + +NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(CSSStartingStyleRule, + css::GroupRule) + +// QueryInterface implementation for SupportsRule + +#ifdef DEBUG +void CSSStartingStyleRule::List(FILE* out, int32_t aIndent) const { + nsAutoCString str; + for (int32_t i = 0; i < aIndent; i++) { + str.AppendLiteral(" "); + } + Servo_StartingStyleRule_Debug(mRawRule, &str); + fprintf_stderr(out, "%s\n", str.get()); +} +#endif + +StyleCssRuleType CSSStartingStyleRule::Type() const { + return StyleCssRuleType::StartingStyle; +} + +already_AddRefed<StyleLockedCssRules> +CSSStartingStyleRule::GetOrCreateRawRules() { + return Servo_StartingStyleRule_GetRules(mRawRule).Consume(); +} + +void CSSStartingStyleRule::GetCssText(nsACString& aCssText) const { + Servo_StartingStyleRule_GetCssText(mRawRule.get(), &aCssText); +} + +JSObject* CSSStartingStyleRule::WrapObject(JSContext* aCx, + JS::Handle<JSObject*> aGivenProto) { + return CSSStartingStyleRule_Binding::Wrap(aCx, this, aGivenProto); +} + +} // namespace mozilla::dom diff --git a/layout/style/CSSStartingStyleRule.h b/layout/style/CSSStartingStyleRule.h new file mode 100644 index 0000000000..9ecccf505c --- /dev/null +++ b/layout/style/CSSStartingStyleRule.h @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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 CSSStaringStyleRule_h___ +#define CSSStaringStyleRule_h___ + +#include "mozilla/css/GroupRule.h" +#include "mozilla/ServoBindingTypes.h" + +namespace mozilla::dom { + +class CSSStartingStyleRule final : public css::GroupRule { + public: + CSSStartingStyleRule(RefPtr<StyleStartingStyleRule> aRawRule, + StyleSheet* aSheet, css::Rule* aParentRule, + uint32_t aLine, uint32_t aColumn) + : css::GroupRule(aSheet, aParentRule, aLine, aColumn), + mRawRule(std::move(aRawRule)) {} + + NS_DECL_ISUPPORTS_INHERITED + +#ifdef DEBUG + void List(FILE* out = stdout, int32_t aIndent = 0) const final; +#endif + + StyleStartingStyleRule* Raw() const { return mRawRule; } + void SetRawAfterClone(RefPtr<StyleStartingStyleRule> aRaw) { + mRawRule = std::move(aRaw); + css::GroupRule::DidSetRawAfterClone(); + } + + already_AddRefed<StyleLockedCssRules> GetOrCreateRawRules() final; + + // WebIDL interface + StyleCssRuleType Type() const final; + void GetCssText(nsACString& aCssText) const final; + + size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override { + return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf); + } + JSObject* WrapObject(JSContext*, JS::Handle<JSObject*>) override; + + private: + ~CSSStartingStyleRule() = default; + + RefPtr<StyleStartingStyleRule> mRawRule; +}; + +} // namespace mozilla::dom + +#endif diff --git a/layout/style/FontFaceImpl.cpp b/layout/style/FontFaceImpl.cpp index 9d1f7c8c5b..5650b62afd 100644 --- a/layout/style/FontFaceImpl.cpp +++ b/layout/style/FontFaceImpl.cpp @@ -675,25 +675,40 @@ bool FontFaceImpl::IsInFontFaceSet(FontFaceSetImpl* aFontFaceSet) const { void FontFaceImpl::AddFontFaceSet(FontFaceSetImpl* aFontFaceSet) { MOZ_ASSERT(!IsInFontFaceSet(aFontFaceSet)); - if (mFontFaceSet == aFontFaceSet) { - mInFontFaceSet = true; + auto doAddFontFaceSet = [&]() { + if (mFontFaceSet == aFontFaceSet) { + mInFontFaceSet = true; + } else { + mOtherFontFaceSets.AppendElement(aFontFaceSet); + } + }; + + if (mUserFontEntry) { + AutoWriteLock lock(mUserFontEntry->Lock()); + doAddFontFaceSet(); } else { - mOtherFontFaceSets.AppendElement(aFontFaceSet); + doAddFontFaceSet(); } } void FontFaceImpl::RemoveFontFaceSet(FontFaceSetImpl* aFontFaceSet) { MOZ_ASSERT(IsInFontFaceSet(aFontFaceSet)); - if (mFontFaceSet == aFontFaceSet) { - mInFontFaceSet = false; - } else { - mOtherFontFaceSets.RemoveElement(aFontFaceSet); - } + auto doRemoveFontFaceSet = [&]() { + if (mFontFaceSet == aFontFaceSet) { + mInFontFaceSet = false; + } else { + mOtherFontFaceSets.RemoveElement(aFontFaceSet); + } + }; - // The caller should be holding a strong reference to the FontFaceSetImpl. if (mUserFontEntry) { - mUserFontEntry->CheckUserFontSet(); + AutoWriteLock lock(mUserFontEntry->Lock()); + doRemoveFontFaceSet(); + // The caller should be holding a strong reference to the FontFaceSetImpl. + mUserFontEntry->CheckUserFontSetLocked(); + } else { + doRemoveFontFaceSet(); } } @@ -736,7 +751,7 @@ void FontFaceImpl::Entry::SetLoadState(UserFontLoadState aLoadState) { nsTArray<RefPtr<FontFaceImpl>> fontFaces; { - MutexAutoLock lock(mMutex); + AutoReadLock lock(mLock); fontFaces.SetCapacity(mFontFaces.Length()); for (FontFaceImpl* f : mFontFaces) { fontFaces.AppendElement(f); @@ -758,7 +773,7 @@ void FontFaceImpl::Entry::SetLoadState(UserFontLoadState aLoadState) { /* virtual */ void FontFaceImpl::Entry::GetUserFontSets( nsTArray<RefPtr<gfxUserFontSet>>& aResult) { - MutexAutoLock lock(mMutex); + AutoReadLock lock(mLock); aResult.Clear(); @@ -783,7 +798,7 @@ void FontFaceImpl::Entry::GetUserFontSets( /* virtual */ already_AddRefed<gfxUserFontSet> FontFaceImpl::Entry::GetUserFontSet() const { - MutexAutoLock lock(mMutex); + AutoReadLock lock(mLock); if (mFontSet) { return do_AddRef(mFontSet); } @@ -816,7 +831,7 @@ void FontFaceImpl::Entry::CheckUserFontSetLocked() { } void FontFaceImpl::Entry::FindFontFaceOwners(nsTHashSet<FontFace*>& aOwners) { - MutexAutoLock lock(mMutex); + AutoReadLock lock(mLock); for (FontFaceImpl* f : mFontFaces) { if (FontFace* owner = f->GetOwner()) { aOwners.Insert(owner); @@ -825,13 +840,13 @@ void FontFaceImpl::Entry::FindFontFaceOwners(nsTHashSet<FontFace*>& aOwners) { } void FontFaceImpl::Entry::AddFontFace(FontFaceImpl* aFontFace) { - MutexAutoLock lock(mMutex); + AutoWriteLock lock(mLock); mFontFaces.AppendElement(aFontFace); CheckUserFontSetLocked(); } void FontFaceImpl::Entry::RemoveFontFace(FontFaceImpl* aFontFace) { - MutexAutoLock lock(mMutex); + AutoWriteLock lock(mLock); mFontFaces.RemoveElement(aFontFace); CheckUserFontSetLocked(); } diff --git a/layout/style/FontFaceImpl.h b/layout/style/FontFaceImpl.h index 70c06609e9..7f1279a248 100644 --- a/layout/style/FontFaceImpl.h +++ b/layout/style/FontFaceImpl.h @@ -10,7 +10,7 @@ #include "mozilla/dom/FontFaceBinding.h" #include "mozilla/FontPropertyTypes.h" #include "mozilla/Maybe.h" -#include "mozilla/Mutex.h" +#include "mozilla/RWLock.h" #include "mozilla/ServoStyleConsts.h" #include "gfxUserFontSet.h" #include "nsCSSPropertyID.h" @@ -50,21 +50,15 @@ class FontFaceImpl final { Entry(gfxUserFontSet* aFontSet, nsTArray<gfxFontFaceSrc>&& aFontFaceSrcList, gfxUserFontAttributes&& aAttr) : gfxUserFontEntry(std::move(aFontFaceSrcList), std::move(aAttr)), - mMutex("FontFaceImpl::Entry::mMutex"), mFontSet(aFontSet) {} void SetLoadState(UserFontLoadState aLoadState) override; void GetUserFontSets(nsTArray<RefPtr<gfxUserFontSet>>& aResult) override; already_AddRefed<gfxUserFontSet> GetUserFontSet() const override; - void CheckUserFontSet() { - MutexAutoLock lock(mMutex); - CheckUserFontSetLocked(); - } - #ifdef DEBUG bool HasUserFontSet(gfxUserFontSet* aFontSet) const { - MutexAutoLock lock(mMutex); + AutoReadLock lock(mLock); return mFontSet == aFontSet; } #endif @@ -73,19 +67,19 @@ class FontFaceImpl final { void RemoveFontFace(FontFaceImpl* aOwner); void FindFontFaceOwners(nsTHashSet<FontFace*>& aOwners); - protected: - void CheckUserFontSetLocked() MOZ_REQUIRES(mMutex); + RWLock& Lock() const MOZ_RETURN_CAPABILITY(mLock) { return mLock; } - mutable Mutex mMutex; + protected: + void CheckUserFontSetLocked() MOZ_REQUIRES(mLock); // Font set which owns this entry; - gfxUserFontSet* MOZ_NON_OWNING_REF mFontSet MOZ_GUARDED_BY(mMutex); + gfxUserFontSet* MOZ_NON_OWNING_REF mFontSet MOZ_GUARDED_BY(mLock); // The FontFace objects that use this user font entry. We need to store // an array of these, not just a single pointer, since the user font // cache can return the same entry for different FontFaces that have // the same descriptor values and come from the same origin. - AutoTArray<FontFaceImpl*, 1> mFontFaces MOZ_GUARDED_BY(mMutex); + AutoTArray<FontFaceImpl*, 1> mFontFaces MOZ_GUARDED_BY(mLock); }; #ifdef DEBUG diff --git a/layout/style/FontFaceSetDocumentImpl.cpp b/layout/style/FontFaceSetDocumentImpl.cpp index 33f7404c7c..cd1d5959d2 100644 --- a/layout/style/FontFaceSetDocumentImpl.cpp +++ b/layout/style/FontFaceSetDocumentImpl.cpp @@ -496,7 +496,7 @@ bool FontFaceSetDocumentImpl::UpdateRules( } if (modified) { - IncrementGeneration(true); + IncrementGenerationLocked(true); mHasLoadingFontFacesIsDirty = true; CheckLoadingStarted(); CheckLoadingFinished(); diff --git a/layout/style/FontFaceSetImpl.cpp b/layout/style/FontFaceSetImpl.cpp index 7383842a41..5dabf25d38 100644 --- a/layout/style/FontFaceSetImpl.cpp +++ b/layout/style/FontFaceSetImpl.cpp @@ -70,8 +70,7 @@ using namespace mozilla::dom; NS_IMPL_ISUPPORTS0(FontFaceSetImpl) FontFaceSetImpl::FontFaceSetImpl(FontFaceSet* aOwner) - : mMutex("mozilla::dom::FontFaceSetImpl"), - mOwner(aOwner), + : mOwner(aOwner), mStatus(FontFaceSetLoadStatus::Loaded), mNonRuleFacesDirty(false), mHasLoadingFontFaces(false), @@ -891,7 +890,7 @@ void FontFaceSetImpl::OnLoadingFinished() { void FontFaceSetImpl::RefreshStandardFontLoadPrincipal() { RecursiveMutexAutoLock lock(mMutex); mAllowedFontLoads.Clear(); - IncrementGeneration(false); + IncrementGenerationLocked(false); } // -- gfxUserFontSet diff --git a/layout/style/FontFaceSetImpl.h b/layout/style/FontFaceSetImpl.h index 6f245c6599..dd412dd721 100644 --- a/layout/style/FontFaceSetImpl.h +++ b/layout/style/FontFaceSetImpl.h @@ -92,9 +92,10 @@ class FontFaceSetImpl : public nsISupports, public gfxUserFontSet { virtual void DispatchToOwningThread(const char* aName, std::function<void()>&& aFunc) = 0; - // Called by nsFontFaceLoader when the loader has completed normally. + // Called by nsFontFaceLoader when the loader has completed normally, + // or by gfxUserFontSet if it cancels the loader. // It's removed from the mLoaders set. - virtual void RemoveLoader(nsFontFaceLoader* aLoader); + void RemoveLoader(nsFontFaceLoader* aLoader) override; virtual bool UpdateRules(const nsTArray<nsFontFaceRuleContainer>& aRules) { MOZ_ASSERT_UNREACHABLE("Not implemented!"); @@ -247,8 +248,6 @@ class FontFaceSetImpl : public nsISupports, public gfxUserFontSet { virtual TimeStamp GetNavigationStartTimeStamp() = 0; - mutable RecursiveMutex mMutex; - FontFaceSet* MOZ_NON_OWNING_REF mOwner MOZ_GUARDED_BY(mMutex); // The document's node principal, which is the principal font loads for diff --git a/layout/style/FontFaceSetWorkerImpl.cpp b/layout/style/FontFaceSetWorkerImpl.cpp index 015c9e5b18..7fbfbf0d95 100644 --- a/layout/style/FontFaceSetWorkerImpl.cpp +++ b/layout/style/FontFaceSetWorkerImpl.cpp @@ -227,7 +227,7 @@ void FontFaceSetWorkerImpl::FlushUserFontSet() { } if (modified) { - IncrementGeneration(true); + IncrementGenerationLocked(true); mHasLoadingFontFacesIsDirty = true; CheckLoadingStarted(); CheckLoadingFinished(); diff --git a/layout/style/GenerateServoCSSPropList.py b/layout/style/GenerateServoCSSPropList.py index 0e9678ac5c..4dba1f0a8f 100644 --- a/layout/style/GenerateServoCSSPropList.py +++ b/layout/style/GenerateServoCSSPropList.py @@ -30,7 +30,7 @@ def generate_data(output, template): ) # Add all relevant files into the dependencies of the generated file. - DEP_EXTS = [".py", ".rs", ".zip"] + DEP_EXTS = [".py", ".rs"] deps = set() for path, dirs, files in os.walk(SERVO_PROP_BASE): for file in files: diff --git a/layout/style/ImageLoader.cpp b/layout/style/ImageLoader.cpp index 2ae1822b02..1a59a5bcf3 100644 --- a/layout/style/ImageLoader.cpp +++ b/layout/style/ImageLoader.cpp @@ -565,6 +565,16 @@ static void InvalidateImages(nsIFrame* aFrame, imgIRequest* aRequest, } } } +#ifdef XP_MACOSX + else if (aFrame->HasAnyStateBits(NS_FRAME_IN_POPUP)) { + // On macOS popups are painted with fallback rendering so they don't have + // webrender user data to tell us if the frame was painted last time, so we + // just have to invalidate always. Bug 1754796 tracks making popups on macOS + // use webrender. (On other platforms tooltips type popups are still + // rendered with fallback, but we don't expect them to have images.) + invalidateFrame = true; + } +#endif // Update ancestor rendering observers (-moz-element etc) // diff --git a/layout/style/PreferenceSheet.cpp b/layout/style/PreferenceSheet.cpp index a206209885..eb752b2789 100644 --- a/layout/style/PreferenceSheet.cpp +++ b/layout/style/PreferenceSheet.cpp @@ -205,7 +205,7 @@ void PreferenceSheet::Prefs::Load(bool aIsChrome) { // as those are the colors exposed to the user in the colors dialog. mMustUseLightColorSet = mUsePrefColors && !mUseDocumentColors; #ifdef XP_WIN - if (mUseAccessibilityTheme) { + if (mUseAccessibilityTheme && (mIsChrome || !mUseDocumentColors)) { // Windows overrides the light colors with the HCM colors when HCM is // active, so make sure to always use the light system colors in that case, // and also make sure that we always use the light color set for the same diff --git a/layout/style/Rule.cpp b/layout/style/Rule.cpp index 0a7de42789..4b0f783bd9 100644 --- a/layout/style/Rule.cpp +++ b/layout/style/Rule.cpp @@ -106,7 +106,9 @@ void Rule::AssertParentRuleType() { type == StyleCssRuleType::Supports || type == StyleCssRuleType::Keyframes || type == StyleCssRuleType::LayerBlock || - type == StyleCssRuleType::Container); + type == StyleCssRuleType::Container || + type == StyleCssRuleType::Scope || + type == StyleCssRuleType::StartingStyle); } } #endif diff --git a/layout/style/ServoBindingTypes.h b/layout/style/ServoBindingTypes.h index fe4f96cf0b..b081a4981b 100644 --- a/layout/style/ServoBindingTypes.h +++ b/layout/style/ServoBindingTypes.h @@ -129,6 +129,8 @@ UNLOCKED_RULE_TYPE(Supports) UNLOCKED_RULE_TYPE(Document) UNLOCKED_RULE_TYPE(FontFeatureValues) UNLOCKED_RULE_TYPE(FontPaletteValues) +UNLOCKED_RULE_TYPE(Scope) +UNLOCKED_RULE_TYPE(StartingStyle) SERVO_ARC_TYPE(AnimationValue, mozilla::StyleAnimationValue) SERVO_ARC_TYPE(ComputedStyle, mozilla::ComputedStyle) diff --git a/layout/style/ServoBindings.h b/layout/style/ServoBindings.h index 6f19006512..52538cafb8 100644 --- a/layout/style/ServoBindings.h +++ b/layout/style/ServoBindings.h @@ -77,7 +77,7 @@ BASIC_RULE_FUNCS_LOCKED(Keyframes) GROUP_RULE_FUNCS_UNLOCKED(Media) GROUP_RULE_FUNCS_UNLOCKED(Document) BASIC_RULE_FUNCS_UNLOCKED(Namespace) -BASIC_RULE_FUNCS_LOCKED(Page) +GROUP_RULE_FUNCS_LOCKED(Page) BASIC_RULE_FUNCS_UNLOCKED(Property) GROUP_RULE_FUNCS_UNLOCKED(Supports) GROUP_RULE_FUNCS_UNLOCKED(LayerBlock) @@ -87,6 +87,8 @@ BASIC_RULE_FUNCS_UNLOCKED(FontPaletteValues) BASIC_RULE_FUNCS_LOCKED(FontFace) BASIC_RULE_FUNCS_LOCKED(CounterStyle) GROUP_RULE_FUNCS_UNLOCKED(Container) +GROUP_RULE_FUNCS_UNLOCKED(Scope) +GROUP_RULE_FUNCS_UNLOCKED(StartingStyle) #undef GROUP_RULE_FUNCS_LOCKED #undef GROUP_RULE_FUNCS_UNLOCKED diff --git a/layout/style/ServoBindings.toml b/layout/style/ServoBindings.toml index 20e1ca4116..67fd902e2b 100644 --- a/layout/style/ServoBindings.toml +++ b/layout/style/ServoBindings.toml @@ -515,6 +515,9 @@ cbindgen-types = [ { gecko = "StyleBasicShape", servo = "crate::values::computed::basic_shape::BasicShape" }, { gecko = "StyleGenericInsetRect", servo = "crate::values::generics::basic_shape::InsetRect" }, { gecko = "StyleInsetRect", servo = "crate::values::computed::basic_shape::InsetRect" }, + { gecko = "StyleShape", servo = "crate::values::computed::basic_shape::Shape" }, + { gecko = "StyleShapeCommand", servo = "crate::values::computed::basic_shape::ShapeCommand" }, + { gecko = "StyleGenericShapeCommand", servo = "crate::values::generics::basic_shape::ShapeCommand" }, { gecko = "StyleArcSlice", servo = "style_traits::arc_slice::ArcSlice" }, { gecko = "StyleForgottenArcSlicePtr", servo = "style_traits::arc_slice::ForgottenArcSlicePtr" }, { gecko = "StyleOwnedSlice", servo = "style_traits::owned_slice::OwnedSlice" }, diff --git a/layout/style/ServoCSSRuleList.cpp b/layout/style/ServoCSSRuleList.cpp index 6fcdfdd4b5..133a962256 100644 --- a/layout/style/ServoCSSRuleList.cpp +++ b/layout/style/ServoCSSRuleList.cpp @@ -22,6 +22,8 @@ #include "mozilla/dom/CSSNamespaceRule.h" #include "mozilla/dom/CSSPageRule.h" #include "mozilla/dom/CSSPropertyRule.h" +#include "mozilla/dom/CSSScopeRule.h" +#include "mozilla/dom/CSSStartingStyleRule.h" #include "mozilla/dom/CSSStyleRule.h" #include "mozilla/dom/CSSSupportsRule.h" #include "mozilla/IntegerRange.h" @@ -98,6 +100,8 @@ css::Rule* ServoCSSRuleList::GetRule(uint32_t aIndex) { CASE_RULE_UNLOCKED(LayerBlock, LayerBlock) CASE_RULE_UNLOCKED(LayerStatement, LayerStatement) CASE_RULE_UNLOCKED(Container, Container) + CASE_RULE_UNLOCKED(Scope, Scope) + CASE_RULE_UNLOCKED(StartingStyle, StartingStyle) #undef CASE_RULE_LOCKED #undef CASE_RULE_UNLOCKED #undef CASE_RULE_WITH_PREFIX @@ -208,12 +212,21 @@ nsresult ServoCSSRuleList::InsertRule(const nsACString& aRule, } StyleCssRuleType type; uint32_t containingTypes = 0; + Maybe<StyleCssRuleType> parseRelativeRuleType; for (css::Rule* rule = mParentRule; rule; rule = rule->GetParentRule()) { - containingTypes |= (1 << uint32_t(rule->Type())); + const auto ruleType = rule->Type(); + containingTypes |= (1 << uint32_t(ruleType)); + if (parseRelativeRuleType.isNothing() && + (ruleType == StyleCssRuleType::Style || + ruleType == StyleCssRuleType::Scope)) { + // Only the closest applicable type to this rule matters. + parseRelativeRuleType = Some(ruleType); + } } nsresult rv = Servo_CssRules_InsertRule( mRawRules, mStyleSheet->RawContents(), &aRule, aIndex, containingTypes, - loader, allowImportRules, mStyleSheet, &type); + parseRelativeRuleType.ptrOr(nullptr), loader, allowImportRules, + mStyleSheet, &type); NS_ENSURE_SUCCESS(rv, rv); mRules.InsertElementAt(aIndex, uintptr_t(type)); return rv; @@ -276,6 +289,8 @@ void ServoCSSRuleList::SetRawContents(RefPtr<StyleLockedCssRules> aNewRules, RULE_CASE_UNLOCKED(LayerBlock, LayerBlock) RULE_CASE_UNLOCKED(LayerStatement, LayerStatement) RULE_CASE_UNLOCKED(Container, Container) + RULE_CASE_UNLOCKED(Scope, Scope) + RULE_CASE_UNLOCKED(StartingStyle, StartingStyle) case StyleCssRuleType::Keyframe: MOZ_ASSERT_UNREACHABLE("keyframe rule cannot be here"); break; diff --git a/layout/style/ServoElementSnapshot.cpp b/layout/style/ServoElementSnapshot.cpp index e0ef2849f9..a5251d9349 100644 --- a/layout/style/ServoElementSnapshot.cpp +++ b/layout/style/ServoElementSnapshot.cpp @@ -82,4 +82,11 @@ void ServoElementSnapshot::AddAttrs(const Element& aElement, } } +void ServoElementSnapshot::AddCustomStates(Element& aElement) { + if (mContains & Flags::CustomState) { + return; + } + mCustomStates = aElement.EnsureCustomStates().Clone(); + mContains |= Flags::CustomState; +} } // namespace mozilla diff --git a/layout/style/ServoElementSnapshot.h b/layout/style/ServoElementSnapshot.h index b702975c4b..5a86b4c13d 100644 --- a/layout/style/ServoElementSnapshot.h +++ b/layout/style/ServoElementSnapshot.h @@ -33,6 +33,7 @@ enum class ServoElementSnapshotFlags : uint8_t { Id = 1 << 2, MaybeClass = 1 << 3, OtherPseudoClassState = 1 << 4, + CustomState = 1 << 5, }; MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(ServoElementSnapshotFlags) @@ -89,6 +90,11 @@ class ServoElementSnapshot { void AddAttrs(const Element&, int32_t aNameSpaceID, nsAtom* aAttribute); /** + * Captures the given element custom states. + */ + void AddCustomStates(Element&); + + /** * Captures some other pseudo-class matching state not included in * ElementState. */ @@ -155,6 +161,7 @@ class ServoElementSnapshot { // snapshots. nsTArray<AttrArray::InternalAttr> mAttrs; nsTArray<RefPtr<nsAtom>> mChangedAttrNames; + nsTArray<RefPtr<nsAtom>> mCustomStates; nsAttrValue mClass; ServoStateType mState; Flags mContains; diff --git a/layout/style/ServoStyleConstsForwards.h b/layout/style/ServoStyleConstsForwards.h index 65128e1377..5bf87d8330 100644 --- a/layout/style/ServoStyleConstsForwards.h +++ b/layout/style/ServoStyleConstsForwards.h @@ -83,7 +83,7 @@ struct PropertyStyleAnimationValuePair; using ComputedKeyframeValues = nsTArray<PropertyStyleAnimationValuePair>; class ComputedStyle; -enum LogicalAxis : uint8_t; +enum class LogicalAxis : uint8_t; class SeenPtrs; class SharedFontList; class StyleSheet; @@ -100,7 +100,7 @@ struct ComputedTiming; struct URLExtraData; enum HalfCorner : uint8_t; -enum LogicalSide : uint8_t; +enum class LogicalSide : uint8_t; enum class PseudoStyleType : uint8_t; enum class OriginFlags : uint8_t; enum class UseBoxSizing : uint8_t; diff --git a/layout/style/ServoStyleConstsInlines.h b/layout/style/ServoStyleConstsInlines.h index 1985e8fbeb..5a86e4ccd0 100644 --- a/layout/style/ServoStyleConstsInlines.h +++ b/layout/style/ServoStyleConstsInlines.h @@ -53,6 +53,8 @@ template struct StyleStrong<StyleFontPaletteValuesRule>; template struct StyleStrong<StyleLockedFontFaceRule>; template struct StyleStrong<StyleLockedCounterStyleRule>; template struct StyleStrong<StyleContainerRule>; +template struct StyleStrong<StyleScopeRule>; +template struct StyleStrong<StyleStartingStyleRule>; template <typename T> inline void StyleOwnedSlice<T>::Clear() { @@ -697,9 +699,12 @@ CSSCoord StyleCalcLengthPercentage::ResolveToCSSPixels(CSSCoord aBasis) const { return Servo_ResolveCalcLengthPercentage(this, aBasis); } -nscoord StyleCalcLengthPercentage::Resolve(nscoord aBasis) const { - return detail::DefaultLengthToAppUnits( - ResolveToCSSPixels(CSSPixel::FromAppUnits(aBasis))); +template <typename Rounder> +nscoord StyleCalcLengthPercentage::Resolve(nscoord aBasis, + Rounder aRounder) const { + static_assert(std::is_same_v<decltype(aRounder(1.0f)), nscoord>); + CSSCoord result = ResolveToCSSPixels(CSSPixel::FromAppUnits(aBasis)); + return aRounder(result * AppUnitsPerCSSPixel()); } template <> @@ -724,11 +729,10 @@ CSSCoord LengthPercentage::ResolveToCSSPixelsWith(T aPercentageGetter) const { return ResolveToCSSPixels(aPercentageGetter()); } -template <typename T, typename PercentRounder> -nscoord LengthPercentage::Resolve(T aPercentageGetter, - PercentRounder aPercentRounder) const { +template <typename T, typename Rounder> +nscoord LengthPercentage::Resolve(T aPercentageGetter, Rounder aRounder) const { static_assert(std::is_same_v<decltype(aPercentageGetter()), nscoord>); - static_assert(std::is_same_v<decltype(aPercentRounder(1.0f)), nscoord>); + static_assert(std::is_same_v<decltype(aRounder(1.0f)), nscoord>); if (ConvertsToLength()) { return ToLength(); } @@ -737,9 +741,9 @@ nscoord LengthPercentage::Resolve(T aPercentageGetter, } nscoord basis = aPercentageGetter(); if (IsPercentage()) { - return aPercentRounder(basis * AsPercentage()._0); + return aRounder(basis * AsPercentage()._0); } - return AsCalc().Resolve(basis); + return AsCalc().Resolve(basis, aRounder); } nscoord LengthPercentage::Resolve(nscoord aPercentageBasis) const { @@ -752,11 +756,10 @@ nscoord LengthPercentage::Resolve(T aPercentageGetter) const { return Resolve(aPercentageGetter, detail::DefaultPercentLengthToAppUnits); } -template <typename PercentRounder> +template <typename Rounder> nscoord LengthPercentage::Resolve(nscoord aPercentageBasis, - PercentRounder aPercentRounder) const { - return Resolve([aPercentageBasis] { return aPercentageBasis; }, - aPercentRounder); + Rounder aRounder) const { + return Resolve([aPercentageBasis] { return aPercentageBasis; }, aRounder); } void LengthPercentage::ScaleLengthsBy(float aScale) { @@ -1201,6 +1204,20 @@ inline nsRect StyleZoom::Unzoom(const nsRect& aValue) const { UnzoomCoord(aValue.Width()), UnzoomCoord(aValue.Height())); } +template <> +inline gfx::Point StyleCoordinatePair<StyleCSSFloat>::ToGfxPoint( + const CSSSize* aBasis) const { + return gfx::Point(x, y); +} + +template <> +inline gfx::Point StyleCoordinatePair<LengthPercentage>::ToGfxPoint( + const CSSSize* aBasis) const { + MOZ_ASSERT(aBasis); + return gfx::Point(x.ResolveToCSSPixels(aBasis->Width()), + y.ResolveToCSSPixels(aBasis->Height())); +} + } // namespace mozilla #endif diff --git a/layout/style/ServoStyleSet.cpp b/layout/style/ServoStyleSet.cpp index cfc38849b8..91231af2b0 100644 --- a/layout/style/ServoStyleSet.cpp +++ b/layout/style/ServoStyleSet.cpp @@ -41,7 +41,9 @@ #include "mozilla/dom/CSSNamespaceRule.h" #include "mozilla/dom/CSSPageRule.h" #include "mozilla/dom/CSSPropertyRule.h" +#include "mozilla/dom/CSSScopeRule.h" #include "mozilla/dom/CSSSupportsRule.h" +#include "mozilla/dom/CSSStartingStyleRule.h" #include "mozilla/dom/FontFaceSet.h" #include "mozilla/dom/Element.h" #include "mozilla/dom/ElementInlines.h" @@ -1002,6 +1004,8 @@ void ServoStyleSet::RuleChangedInternal(StyleSheet& aSheet, css::Rule& aRule, CASE_FOR(LayerBlock, LayerBlock) CASE_FOR(LayerStatement, LayerStatement) CASE_FOR(Container, Container) + CASE_FOR(Scope, Scope) + CASE_FOR(StartingStyle, StartingStyle) // @namespace can only be inserted / removed when there are only other // @namespace and @import rules, and can't be mutated. case StyleCssRuleType::Namespace: @@ -1394,6 +1398,13 @@ void ServoStyleSet::MaybeInvalidateRelativeSelectorClassDependency( mRawData.get(), &aElement, &aSnapshots); } +void ServoStyleSet::MaybeInvalidateRelativeSelectorCustomStateDependency( + const Element& aElement, nsAtom* state, + const ServoElementSnapshotTable& aSnapshots) { + Servo_StyleSet_MaybeInvalidateRelativeSelectorCustomStateDependency( + mRawData.get(), &aElement, state, &aSnapshots); +} + void ServoStyleSet::MaybeInvalidateRelativeSelectorAttributeDependency( const Element& aElement, nsAtom* aAttribute, const ServoElementSnapshotTable& aSnapshots) { @@ -1465,6 +1476,12 @@ bool ServoStyleSet::HasNthOfStateDependency(const Element& aElement, aState.GetInternalValue()); } +bool ServoStyleSet::HasNthOfCustomStateDependency(const Element& aElement, + nsAtom* aState) const { + return Servo_StyleSet_HasNthOfCustomStateDependency(mRawData.get(), &aElement, + aState); +} + void ServoStyleSet::RestyleSiblingsForNthOf(const Element& aElement, uint32_t aFlags) const { Servo_StyleSet_RestyleSiblingsForNthOf(&aElement, aFlags); diff --git a/layout/style/ServoStyleSet.h b/layout/style/ServoStyleSet.h index eee6cba0f7..f3159c97ec 100644 --- a/layout/style/ServoStyleSet.h +++ b/layout/style/ServoStyleSet.h @@ -477,6 +477,14 @@ class ServoStyleSet { const dom::Element&, const ServoElementSnapshotTable& aSnapshots); /** + * Maybe invalidate if a modification to a Custom State might require us to + * restyle the relative selector it refers to. + */ + void MaybeInvalidateRelativeSelectorCustomStateDependency( + const dom::Element&, nsAtom* state, + const ServoElementSnapshotTable& aSnapshots); + + /** * Maybe invalidate if a modification to an ID might require us to restyle * the relative selector it refers to. */ @@ -550,6 +558,12 @@ class ServoStyleSet { bool HasNthOfStateDependency(const dom::Element&, dom::ElementState) const; /** + * Returns true if a change in Custom State on an element might require + * us to restyle the element's siblings. + */ + bool HasNthOfCustomStateDependency(const dom::Element&, nsAtom*) const; + + /** * Restyle this element's siblings in order to propagate any potential change * in :nth-child(of) styling. */ diff --git a/layout/style/SharedSubResourceCache.h b/layout/style/SharedSubResourceCache.h index 32919b8863..896eacbcb5 100644 --- a/layout/style/SharedSubResourceCache.h +++ b/layout/style/SharedSubResourceCache.h @@ -58,6 +58,9 @@ struct SharedSubResourceCacheLoadingValueBase { virtual void SetLoadCompleted() = 0; virtual void Cancel() = 0; + // Return the next sub-resource which has the same key. + Derived* GetNextSubResource() { return mNext; } + ~SharedSubResourceCacheLoadingValueBase() { // Do this iteratively to avoid blowing up the stack. RefPtr<Derived> next = std::move(mNext); diff --git a/layout/style/moz.build b/layout/style/moz.build index a14ab6a7ac..b77fa34983 100644 --- a/layout/style/moz.build +++ b/layout/style/moz.build @@ -56,6 +56,7 @@ EXPORTS += [ "nsCSSValue.h", "nsDOMCSSAttrDeclaration.h", "nsDOMCSSDeclaration.h", + "nsFontFaceLoader.h", "nsICSSDeclaration.h", "nsICSSLoaderObserver.h", "nsStyleAutoArray.h", @@ -143,6 +144,8 @@ EXPORTS.mozilla.dom += [ "CSSPageRule.h", "CSSPropertyRule.h", "CSSRuleList.h", + "CSSScopeRule.h", + "CSSStartingStyleRule.h", "CSSStyleRule.h", "CSSSupportsRule.h", "CSSValue.h", @@ -194,6 +197,8 @@ UNIFIED_SOURCES += [ "CSSPageRule.cpp", "CSSPropertyRule.cpp", "CSSRuleList.cpp", + "CSSScopeRule.cpp", + "CSSStartingStyleRule.cpp", "CSSStyleRule.cpp", "CSSSupportsRule.cpp", "DeclarationBlock.cpp", diff --git a/layout/style/nsCSSPseudoElementList.h b/layout/style/nsCSSPseudoElementList.h index 9514dd6c4b..7492523c58 100644 --- a/layout/style/nsCSSPseudoElementList.h +++ b/layout/style/nsCSSPseudoElementList.h @@ -51,6 +51,7 @@ CSS_PSEUDO_ELEMENT(highlight, ":highlight", 0) CSS_PSEUDO_ELEMENT(selection, ":selection", CSS_PSEUDO_ELEMENT_CONTAINS_ELEMENTS) +CSS_PSEUDO_ELEMENT(targetText, ":target-text", 0) // XXXbz should we really allow random content to style these? Maybe // use our flags to prevent that? CSS_PSEUDO_ELEMENT(mozFocusInner, ":-moz-focus-inner", 0) diff --git a/layout/style/nsCSSPseudoElements.h b/layout/style/nsCSSPseudoElements.h index 9866fbfb7e..baeee9d4de 100644 --- a/layout/style/nsCSSPseudoElements.h +++ b/layout/style/nsCSSPseudoElements.h @@ -130,6 +130,8 @@ class nsCSSPseudoElements { switch (aType) { case Type::highlight: return mozilla::StaticPrefs::dom_customHighlightAPI_enabled(); + case Type::targetText: + return mozilla::StaticPrefs::dom_text_fragments_enabled(); case Type::sliderTrack: case Type::sliderThumb: case Type::sliderFill: diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index d40d4bc801..5b71ec54bf 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -1358,11 +1358,28 @@ already_AddRefed<nsROCSSPrimitiveValue> nsComputedDOMStyle::MatrixToCSSValue( /* Create a value to hold our result. */ RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; - val->SetString(resultString); return val.forget(); } +already_AddRefed<nsROCSSPrimitiveValue> nsComputedDOMStyle::AppUnitsToCSSValue( + nscoord aAppUnits) { + return PixelsToCSSValue(CSSPixel::FromAppUnits(aAppUnits)); +} + +already_AddRefed<nsROCSSPrimitiveValue> nsComputedDOMStyle::PixelsToCSSValue( + float aPixels) { + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; + SetValueToPixels(val, aPixels); + return val.forget(); +} + +void nsComputedDOMStyle::SetValueToPixels(nsROCSSPrimitiveValue* aValue, + float aPixels) { + MOZ_ASSERT(mComputedStyle); + aValue->SetPixels(mComputedStyle->EffectiveZoom().Unzoom(aPixels)); +} + already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetMozOsxFontSmoothing() { if (nsContentUtils::ShouldResistFingerprinting( mPresShell->GetPresContext()->GetDocShell(), @@ -1614,9 +1631,7 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::GetGridTemplateColumnsRows( // Add any leading implicit tracks. if (serializeImplicit) { for (uint32_t i = 0; i < numLeadingImplicitTracks; ++i) { - RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; - val->SetAppUnits(trackSizes[i]); - valueList->AppendCSSValue(val.forget()); + valueList->AppendCSSValue(AppUnitsToCSSValue(trackSizes[i])); } } @@ -1652,8 +1667,7 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::GetGridTemplateColumnsRows( for (uint32_t i = 0; i < repeatStart; i++) { AppendGridLineNames(valueList, aTrackInfo.mResolvedLineNames[i]); RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; - val->SetAppUnits(*trackSizeIter++); - valueList->AppendCSSValue(val.forget()); + valueList->AppendCSSValue(AppUnitsToCSSValue(*trackSizeIter++)); } auto lineNameIter = aTrackInfo.mResolvedLineNames.cbegin() + repeatStart; // Write the track names at the start of the repeat, including the names @@ -1666,9 +1680,7 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::GetGridTemplateColumnsRows( // track). const nscoord firstRepeatTrackSize = (!aTrackInfo.mRemovedRepeatTracks[0]) ? *trackSizeIter++ : 0; - RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; - val->SetAppUnits(firstRepeatTrackSize); - valueList->AppendCSSValue(val.forget()); + valueList->AppendCSSValue(AppUnitsToCSSValue(firstRepeatTrackSize)); } // Write the line names and track sizes inside the repeat, checking for // removed tracks (size 0). @@ -1688,9 +1700,7 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::GetGridTemplateColumnsRows( trackSizeIter != explicitTrackSizeEnd); const nscoord repeatTrackSize = (!aTrackInfo.mRemovedRepeatTracks[i]) ? *trackSizeIter++ : 0; - RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; - val->SetAppUnits(repeatTrackSize); - valueList->AppendCSSValue(val.forget()); + valueList->AppendCSSValue(AppUnitsToCSSValue(repeatTrackSize)); } // The resolved line names include a single repetition of the auto-repeat // line names. Skip over those. @@ -1698,9 +1708,7 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::GetGridTemplateColumnsRows( // Write out any more tracks after the repeat. while (trackSizeIter != explicitTrackSizeEnd) { AppendGridLineNames(valueList, *lineNameIter++); - RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; - val->SetAppUnits(*trackSizeIter++); - valueList->AppendCSSValue(val.forget()); + valueList->AppendCSSValue(AppUnitsToCSSValue(*trackSizeIter++)); } // Write the final trailing line name. AppendGridLineNames(valueList, *lineNameIter++); @@ -1711,18 +1719,15 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::GetGridTemplateColumnsRows( if (i == numExplicitTracks) { break; } - RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; - val->SetAppUnits(trackSizes[i + numLeadingImplicitTracks]); - valueList->AppendCSSValue(val.forget()); + valueList->AppendCSSValue( + AppUnitsToCSSValue(trackSizes[i + numLeadingImplicitTracks])); } } // Add any trailing implicit tracks. if (serializeImplicit) { for (uint32_t i = numLeadingImplicitTracks + numExplicitTracks; i < numSizes; ++i) { - RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; - val->SetAppUnits(trackSizes[i]); - valueList->AppendCSSValue(val.forget()); + valueList->AppendCSSValue(AppUnitsToCSSValue(trackSizes[i])); } } @@ -1787,15 +1792,9 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetPaddingRight() { already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBorderSpacing() { RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false); - RefPtr<nsROCSSPrimitiveValue> xSpacing = new nsROCSSPrimitiveValue; - RefPtr<nsROCSSPrimitiveValue> ySpacing = new nsROCSSPrimitiveValue; - const nsStyleTableBorder* border = StyleTableBorder(); - xSpacing->SetAppUnits(border->mBorderSpacingCol); - ySpacing->SetAppUnits(border->mBorderSpacingRow); - - valueList->AppendCSSValue(xSpacing.forget()); - valueList->AppendCSSValue(ySpacing.forget()); + valueList->AppendCSSValue(AppUnitsToCSSValue(border->mBorderSpacingCol)); + valueList->AppendCSSValue(AppUnitsToCSSValue(border->mBorderSpacingRow)); return valueList.forget(); } @@ -1833,32 +1832,26 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetMarginRight() { } already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetHeight() { - RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; - if (mInnerFrame && !IsNonReplacedInline(mInnerFrame)) { AssertFlushedPendingReflows(); - nsMargin adjustedValues = GetAdjustedValuesForBoxSizing(); - val->SetAppUnits(mInnerFrame->GetContentRect().height + - adjustedValues.TopBottom()); - } else { - SetValueToSize(val, StylePosition()->mHeight); + const nsMargin adjustedValues = GetAdjustedValuesForBoxSizing(); + return AppUnitsToCSSValue(mInnerFrame->GetContentRect().height + + adjustedValues.TopBottom()); } - + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; + SetValueToSize(val, StylePosition()->mHeight); return val.forget(); } already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetWidth() { - RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; - if (mInnerFrame && !IsNonReplacedInline(mInnerFrame)) { AssertFlushedPendingReflows(); nsMargin adjustedValues = GetAdjustedValuesForBoxSizing(); - val->SetAppUnits(mInnerFrame->GetContentRect().width + - adjustedValues.LeftRight()); - } else { - SetValueToSize(val, StylePosition()->mWidth); + return AppUnitsToCSSValue(mInnerFrame->GetContentRect().width + + adjustedValues.LeftRight()); } - + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; + SetValueToSize(val, StylePosition()->mWidth); return val.forget(); } @@ -1968,14 +1961,13 @@ static_assert(eSideTop == 0 && eSideRight == 1 && eSideBottom == 2 && already_AddRefed<CSSValue> nsComputedDOMStyle::GetNonStaticPositionOffset( mozilla::Side aSide, bool aResolveAuto, PercentageBaseGetter aWidthGetter, PercentageBaseGetter aHeightGetter) { - RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; - const nsStylePosition* positionData = StylePosition(); int32_t sign = 1; LengthPercentageOrAuto coord = positionData->mOffset.Get(aSide); if (coord.IsAuto()) { if (!aResolveAuto) { + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetString("auto"); return val.forget(); } @@ -1983,14 +1975,12 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::GetNonStaticPositionOffset( sign = -1; } if (!coord.IsLengthPercentage()) { - val->SetPixels(0.0f); - return val.forget(); + return PixelsToCSSValue(0.0f); } - auto& lp = coord.AsLengthPercentage(); + const auto& lp = coord.AsLengthPercentage(); if (lp.ConvertsToLength()) { - val->SetPixels(sign * lp.ToLengthInCSSPixels()); - return val.forget(); + return PixelsToCSSValue(sign * lp.ToLengthInCSSPixels()); } PercentageBaseGetter baseGetter = (aSide == eSideLeft || aSide == eSideRight) @@ -1998,12 +1988,10 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::GetNonStaticPositionOffset( : aHeightGetter; nscoord percentageBase; if (!(this->*baseGetter)(percentageBase)) { - val->SetPixels(0.0f); - return val.forget(); + return PixelsToCSSValue(0.0f); } nscoord result = lp.Resolve(percentageBase); - val->SetAppUnits(sign * result); - return val.forget(); + return AppUnitsToCSSValue(sign * result); } already_AddRefed<CSSValue> nsComputedDOMStyle::GetAbsoluteOffset( @@ -2013,9 +2001,7 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::GetAbsoluteOffset( const auto& oppositeCoord = offset.Get(NS_OPPOSITE_SIDE(aSide)); if (coord.IsAuto() || oppositeCoord.IsAuto()) { - RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; - val->SetAppUnits(GetUsedAbsoluteOffset(aSide)); - return val.forget(); + return AppUnitsToCSSValue(GetUsedAbsoluteOffset(aSide)); } return GetNonStaticPositionOffset( @@ -2096,23 +2082,18 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::GetStaticOffset( already_AddRefed<CSSValue> nsComputedDOMStyle::GetPaddingWidthFor( mozilla::Side aSide) { - RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; - - auto& padding = StylePadding()->mPadding.Get(aSide); + const auto& padding = StylePadding()->mPadding.Get(aSide); if (!mInnerFrame || !PaddingNeedsUsedValue(padding, *mComputedStyle)) { + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; SetValueToLengthPercentage(val, padding, true); - } else { - AssertFlushedPendingReflows(); - val->SetAppUnits(mInnerFrame->GetUsedPadding().Side(aSide)); + return val.forget(); } - - return val.forget(); + AssertFlushedPendingReflows(); + return AppUnitsToCSSValue(mInnerFrame->GetUsedPadding().Side(aSide)); } already_AddRefed<CSSValue> nsComputedDOMStyle::GetBorderWidthFor( mozilla::Side aSide) { - RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; - nscoord width; if (mInnerFrame && mComputedStyle->StyleDisplay()->HasAppearance()) { AssertFlushedPendingReflows(); @@ -2120,29 +2101,23 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::GetBorderWidthFor( } else { width = StyleBorder()->GetComputedBorderWidth(aSide); } - val->SetAppUnits(width); - - return val.forget(); + return AppUnitsToCSSValue(width); } already_AddRefed<CSSValue> nsComputedDOMStyle::GetMarginFor(Side aSide) { - RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; - - auto& margin = StyleMargin()->mMargin.Get(aSide); + const auto& margin = StyleMargin()->mMargin.Get(aSide); if (!mInnerFrame || margin.ConvertsToLength()) { + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; SetValueToLengthPercentageOrAuto(val, margin, false); - } else { - AssertFlushedPendingReflows(); - - // For tables, GetUsedMargin always returns an empty margin, so we - // should read the margin from the table wrapper frame instead. - val->SetAppUnits(mOuterFrame->GetUsedMargin().Side(aSide)); - NS_ASSERTION(mOuterFrame == mInnerFrame || - mInnerFrame->GetUsedMargin() == nsMargin(0, 0, 0, 0), - "Inner tables must have zero margins"); + return val.forget(); } - - return val.forget(); + AssertFlushedPendingReflows(); + // For tables, GetUsedMargin always returns an empty margin, so we + // should read the margin from the table wrapper frame instead. + NS_ASSERTION( + mOuterFrame == mInnerFrame || mInnerFrame->GetUsedMargin() == nsMargin(), + "Inner tables must have zero margins"); + return AppUnitsToCSSValue(mOuterFrame->GetUsedMargin().Side(aSide)); } static void SetValueToExtremumLength(nsROCSSPrimitiveValue* aValue, @@ -2223,7 +2198,7 @@ void nsComputedDOMStyle::SetValueToLengthPercentage( if (aClampNegativeCalc) { length = std::max(float(length), 0.0f); } - return aValue->SetPixels(length); + return SetValueToPixels(aValue, length); } if (aLength.ConvertsToPercentage()) { float result = aLength.ToPercentage(); diff --git a/layout/style/nsComputedDOMStyle.h b/layout/style/nsComputedDOMStyle.h index 4f135a3aca..d1f3458030 100644 --- a/layout/style/nsComputedDOMStyle.h +++ b/layout/style/nsComputedDOMStyle.h @@ -148,6 +148,10 @@ class nsComputedDOMStyle final : public nsDOMCSSDeclaration, NS_DECL_NSIMUTATIONOBSERVER_PARENTCHAINCHANGED private: + already_AddRefed<nsROCSSPrimitiveValue> AppUnitsToCSSValue(nscoord); + already_AddRefed<nsROCSSPrimitiveValue> PixelsToCSSValue(float); + void SetValueToPixels(nsROCSSPrimitiveValue*, float); + void GetPropertyValue(const nsCSSPropertyID aPropID, const nsACString& aMaybeCustomPropertyNme, nsACString& aValue); diff --git a/layout/style/nsMediaFeatures.cpp b/layout/style/nsMediaFeatures.cpp index f888c127d4..fbdde4102d 100644 --- a/layout/style/nsMediaFeatures.cpp +++ b/layout/style/nsMediaFeatures.cpp @@ -336,18 +336,20 @@ StyleDynamicRange Gecko_MediaFeatures_DynamicRange(const Document* aDocument) { StyleDynamicRange Gecko_MediaFeatures_VideoDynamicRange( const Document* aDocument) { - if (aDocument->ShouldResistFingerprinting(RFPTarget::CSSVideoDynamicRange)) { + if (aDocument->ShouldResistFingerprinting(RFPTarget::CSSVideoDynamicRange) || + !StaticPrefs::layout_css_video_dynamic_range_allows_high()) { return StyleDynamicRange::Standard; } // video-dynamic-range: high has 3 requirements: // 1) high peak brightness // 2) high contrast ratio // 3) color depth > 24 - // We check the color depth requirement before asking the LookAndFeel - // if it is HDR capable. + + // As a proxy for those requirements, return 'High' if the screen associated + // with the device context claims to be HDR capable. if (nsDeviceContext* dx = GetDeviceContextFor(aDocument)) { - if (dx->GetDepth() > 24 && - LookAndFeel::GetInt(LookAndFeel::IntID::VideoDynamicRange)) { + if (dx->GetScreenIsHDR()) { + // bjw return StyleDynamicRange::High; } } diff --git a/layout/style/nsROCSSPrimitiveValue.cpp b/layout/style/nsROCSSPrimitiveValue.cpp index 84911d209b..3b31a14dd2 100644 --- a/layout/style/nsROCSSPrimitiveValue.cpp +++ b/layout/style/nsROCSSPrimitiveValue.cpp @@ -102,20 +102,12 @@ void nsROCSSPrimitiveValue::SetDegree(float aValue) { mType = CSS_DEG; } -void nsROCSSPrimitiveValue::SetAppUnits(nscoord aValue) { - SetPixels(nsPresContext::AppUnitsToFloatCSSPixels(aValue)); -} - void nsROCSSPrimitiveValue::SetPixels(float aValue) { Reset(); mValue.mFloat = aValue; mType = CSS_PX; } -void nsROCSSPrimitiveValue::SetAppUnits(float aValue) { - SetAppUnits(NSToCoordRound(aValue)); -} - void nsROCSSPrimitiveValue::SetString(const nsACString& aString) { Reset(); mValue.mString = ToNewUnicode(aString, mozilla::fallible); diff --git a/layout/style/nsROCSSPrimitiveValue.h b/layout/style/nsROCSSPrimitiveValue.h index d782a23469..79e6fd6a10 100644 --- a/layout/style/nsROCSSPrimitiveValue.h +++ b/layout/style/nsROCSSPrimitiveValue.h @@ -48,8 +48,6 @@ class nsROCSSPrimitiveValue final : public mozilla::dom::CSSValue { void SetPercent(float aValue); void SetDegree(float aValue); void SetPixels(float aValue); - void SetAppUnits(nscoord aValue); - void SetAppUnits(float aValue); void SetString(const nsACString& aString); void SetString(const nsAString& aString); diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index 39f5b1a760..e46566d471 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -3536,7 +3536,7 @@ static nscoord Resolve(const StyleContainIntrinsicSize& aSize, } MOZ_ASSERT(aSize.HasAuto()); if (const auto* element = Element::FromNodeOrNull(aFrame.GetContent())) { - Maybe<float> lastSize = aAxis == eLogicalAxisBlock + Maybe<float> lastSize = aAxis == LogicalAxis::Block ? element->GetLastRememberedBSize() : element->GetLastRememberedISize(); if (lastSize && aFrame.HidesContent()) { @@ -3556,7 +3556,7 @@ Maybe<nscoord> ContainSizeAxes::ContainIntrinsicBSize( } const StyleContainIntrinsicSize& bSize = aFrame.StylePosition()->ContainIntrinsicBSize(aFrame.GetWritingMode()); - return Some(Resolve(bSize, aNoneValue, aFrame, eLogicalAxisBlock)); + return Some(Resolve(bSize, aNoneValue, aFrame, LogicalAxis::Block)); } Maybe<nscoord> ContainSizeAxes::ContainIntrinsicISize( @@ -3566,7 +3566,7 @@ Maybe<nscoord> ContainSizeAxes::ContainIntrinsicISize( } const StyleContainIntrinsicSize& iSize = aFrame.StylePosition()->ContainIntrinsicISize(aFrame.GetWritingMode()); - return Some(Resolve(iSize, aNoneValue, aFrame, eLogicalAxisInline)); + return Some(Resolve(iSize, aNoneValue, aFrame, LogicalAxis::Inline)); } nsSize ContainSizeAxes::ContainSize(const nsSize& aUncontainedSize, diff --git a/layout/style/res/forms.css b/layout/style/res/forms.css index 587534e9f3..044d460ad4 100644 --- a/layout/style/res/forms.css +++ b/layout/style/res/forms.css @@ -73,6 +73,8 @@ fieldset { label { cursor: default; + /* If you add declarations here, consider whether the select > label and file + * input label need them as well. */ } /* Default inputs, text inputs, and selects */ @@ -281,6 +283,7 @@ select > button { select > label { display: inline-block; overflow: clip; + cursor: unset; } option[label]::before { @@ -627,6 +630,7 @@ input[type=file] > label { min-inline-size: 12em; text-align: match-parent; + cursor: unset; color: unset; font-size: unset; letter-spacing: unset; diff --git a/layout/style/res/html.css b/layout/style/res/html.css index ff58ecd4d1..18dd1c4855 100644 --- a/layout/style/res/html.css +++ b/layout/style/res/html.css @@ -765,7 +765,7 @@ video > .caption-box { * The pseudo element won't inherit CSS styles from its direct parent, `::cue` * would actually inherit styles from video because it's video's pseudo element. * Therefore, we have to explicitly set some styles which are already defined - * in its parent element in vtt.jsm. + * in its parent element in vtt.sys.mjs. */ ::cue { color: rgba(255, 255, 255, 1); @@ -816,15 +816,21 @@ dialog::backdrop { background: rgba(0, 0, 0, 0.1); } +/* https://html.spec.whatwg.org/#the-marquee-element-2 */ marquee { - inline-size: -moz-available; display: inline-block; + text-align: initial; + overflow: hidden !important; + + /* See https://github.com/whatwg/html/issues/10249 */ + inline-size: -moz-available; vertical-align: text-bottom; - text-align: start; + white-space: nowrap; } marquee:is([direction="up"], [direction="down"]) { block-size: 200px; + white-space: unset; } /* Ruby */ diff --git a/layout/style/test/chrome/chrome-only-media-queries.js b/layout/style/test/chrome/chrome-only-media-queries.js index aaf313a526..d17976149b 100644 --- a/layout/style/test/chrome/chrome-only-media-queries.js +++ b/layout/style/test/chrome/chrome-only-media-queries.js @@ -31,4 +31,5 @@ const CHROME_ONLY_QUERIES = [ "(-moz-gtk-theme-family: adwaita)", "(-moz-gtk-theme-family: breeze)", "(-moz-gtk-theme-family: yaru)", + "(forced-colors: requested)", ]; diff --git a/layout/style/test/mochitest.toml b/layout/style/test/mochitest.toml index 54ad9736f2..cc5f26708f 100644 --- a/layout/style/test/mochitest.toml +++ b/layout/style/test/mochitest.toml @@ -6,16 +6,13 @@ prefs = [ "gfx.font_loader.delay=0", "layout.css.container-queries.enabled=true", "layout.css.individual-transform.enabled=true", - "layout.css.motion-path-ray.enabled=true", - "layout.css.motion-path-basic-shapes.enabled=true", - "layout.css.motion-path-coord-box.enabled=true", - "layout.css.motion-path-offset-position.enabled=true", "layout.css.motion-path-url.enabled=true", "layout.css.backdrop-filter.enabled=true", "layout.css.fit-content-function.enabled=true", "layout.css.scroll-driven-animations.enabled=true", "layout.css.animation-composition.enabled=true", "layout.css.basic-shape-rect.enabled=true", + "layout.css.basic-shape-shape.enabled=true", "layout.css.basic-shape-xywh.enabled=true", "layout.css.transform-box-content-stroke.enabled=true", "layout.css.transition-behavior.enabled=true", diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js index 2e8b4c71a3..c63d65926e 100644 --- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -1035,6 +1035,36 @@ if (IsCSSPropertyPrefEnabled("layout.css.basic-shape-rect.enabled")) { ); } +var basicShapeShapeValues = []; +var basicShapeShapeValuesWithFillRule = []; +if (IsCSSPropertyPrefEnabled("layout.css.basic-shape-shape.enabled")) { + basicShapeShapeValuesWithFillRule.push( + "shape(evenodd from 0px 0px, line to 10px 10px)", + "shape(nonzero from 0px 0px, line to 10px 10px)" + ); + + basicShapeShapeValues.push( + "shape(from 0px 0%, line to 10px 10%)", + "shape(from 10px 10px, move by 10px 5px, line by 20px 40%, close)", + "shape(from 10px 10px, hline by 10px, vline to 5rem)", + "shape(from 10px 10px, vline by 5%, hline to 1vw)", + "shape(from 10px 10px, curve to 50px 20px via 10rem 1%)", + "shape(from 10px 10px, smooth to 50px 20px via 10rem 1%)", + "shape(from 10% 1rem, arc to 50px 1pt of 20% cw large rotate 25deg)" + ); + + // It's fine to include this for properties which don't support shape(), + // e.g. shape-outside, because they must reject these values. + basicShapeInvalidValues.push( + "shape()", + "shape(evenodd, from 0px 0px)", + "shape(from 0px 0px line to 10px 10px)", + "shape(from 0px 0px)", + "shape(close)", + "shape(nonzero, close)" + ); +} + if (/* mozGradientsEnabled */ true) { // Maybe one day :( // Extend gradient lists with valid/invalid moz-prefixed expressions: @@ -6841,6 +6871,130 @@ var gCSSProperties = { "left 10px top", ], }, + offset: { + domProp: "offset", + inherited: false, + type: CSS_TYPE_TRUE_SHORTHAND, + subproperties: [ + "offset-path", + "offset-distance", + "offset-rotate", + "offset-anchor", + "offset-position", + ], + initial_values: ["none"], + other_values: [ + "none 30deg reverse", + "none 50px reverse 30deg", + "none calc(10px + 20%) auto", + "none reverse", + "none / left center", + "path('M 0 0 H 1') -200% auto", + "path('M 0 0 H 1') -200%", + "path('M 0 0 H 1') 50px", + "path('M 0 0 H 1') auto", + "path('M 0 0 H 1') reverse 30deg 50px", + "path('M 0 0 H 1')", + "path('m 20 0 h 100') -7rad 8px / auto", + "path('m 0 30 v 100') -7rad 8px / left top", + "path('m 0 0 h 100') -7rad 8px", + "path('M 0 0 H 100') 100px 0deg", + "top right / top left", + "top right ray(45deg closest-side)", + "50% 50% ray(0rad farthest-side)", + ], + invalid_values: [ + "100px 0deg path('m 0 0 h 100')", + "30deg", + "auto 30deg 100px", + "auto / none", + "none /", + "none / 100px 20px 30deg", + "path('M 20 30 A 60 70 80') bottom", + "path('M 20 30 A 60 70 80') bottom top", + "path('M 20 30 A 60 70 80') 100px 200px", + "path('M 20 30 A 60 70 80') reverse auto", + "path('M 20 30 A 60 70 80') reverse 10px 30deg", + "path('M 20 30 A 60 70 80') /", + ], + }, + "offset-anchor": { + domProp: "offsetAnchor", + inherited: false, + type: CSS_TYPE_LONGHAND, + initial_values: ["auto"], + other_values: [ + "left bottom", + "center center", + "calc(20% + 10px) center", + "right 30em", + "10px 20%", + "left -10px top -20%", + "right 10% bottom 20em", + ], + invalid_values: ["none", "10deg", "left 10% top"], + }, + "offset-distance": { + domProp: "offsetDistance", + inherited: false, + type: CSS_TYPE_LONGHAND, + initial_values: ["0"], + other_values: ["10px", "10%", "190%", "-280%", "calc(30px + 40%)"], + invalid_values: ["none", "45deg"], + }, + "offset-path": { + domProp: "offsetPath", + inherited: false, + type: CSS_TYPE_LONGHAND, + initial_values: ["none"], + other_values: [ + "ray(0deg)", + "ray(45deg closest-side)", + "ray(0rad farthest-side)", + "ray(0.5turn closest-corner contain)", + "ray(200grad farthest-corner)", + "ray(sides 180deg)", + "ray(contain farthest-side 180deg)", + "ray(calc(180deg - 45deg) farthest-side)", + "ray(0deg at center center)", + "ray(at 10% 10% 1rad)", + ] + .concat(pathValues.other_values) + .concat(basicShapeOtherValues) + .concat(basicShapeXywhRectValues) + .concat(basicShapeShapeValues), + invalid_values: [ + "path('')", + "ray(closest-side)", + "ray(0deg, closest-side)", + "ray(contain 0deg closest-side contain)", + ].concat(pathValues.invalid_values), + }, + "offset-position": { + domProp: "offsetPosition", + inherited: false, + type: CSS_TYPE_LONGHAND, + initial_values: ["normal"], + other_values: [ + "auto", + "left bottom", + "center center", + "calc(20% + 10px) center", + "right 30em", + "10px 20%", + "left -10px top -20%", + "right 10% bottom 20em", + ], + invalid_values: ["none", "10deg", "left 10% top"], + }, + "offset-rotate": { + domProp: "offsetRotate", + inherited: false, + type: CSS_TYPE_LONGHAND, + initial_values: ["auto"], + other_values: ["reverse", "0deg", "0rad reverse", "-45deg", "5turn auto"], + invalid_values: ["none", "10px", "reverse 0deg reverse", "reverse auto"], + }, opacity: { domProp: "opacity", inherited: false, @@ -8827,7 +8981,9 @@ var gCSSProperties = { .concat(basicShapeSVGBoxValues) .concat(basicShapeOtherValues) .concat(basicShapeOtherValuesWithFillRule) - .concat(basicShapeXywhRectValues), + .concat(basicShapeXywhRectValues) + .concat(basicShapeShapeValues) + .concat(basicShapeShapeValuesWithFillRule), invalid_values: [ "path(nonzero)", "path(abs, 'M 10 10 L 10 10 z')", @@ -13409,158 +13565,10 @@ gCSSProperties["scrollbar-width"] = { invalid_values: ["1px"], }; -gCSSProperties["offset"] = { - domProp: "offset", - inherited: false, - type: CSS_TYPE_TRUE_SHORTHAND, - subproperties: [ - "offset-path", - "offset-distance", - "offset-rotate", - "offset-anchor", - ], - initial_values: ["none"], - other_values: [ - "none 30deg reverse", - "none 50px reverse 30deg", - "none calc(10px + 20%) auto", - "none reverse", - "none / left center", - "path('M 0 0 H 1') -200% auto", - "path('M 0 0 H 1') -200%", - "path('M 0 0 H 1') 50px", - "path('M 0 0 H 1') auto", - "path('M 0 0 H 1') reverse 30deg 50px", - "path('M 0 0 H 1')", - "path('m 20 0 h 100') -7rad 8px / auto", - "path('m 0 30 v 100') -7rad 8px / left top", - "path('m 0 0 h 100') -7rad 8px", - "path('M 0 0 H 100') 100px 0deg", - ], - invalid_values: [ - "100px 0deg path('m 0 0 h 100')", - "30deg", - "auto 30deg 100px", - "auto / none", - "none /", - "none / 100px 20px 30deg", - "path('M 20 30 A 60 70 80') bottom", - "path('M 20 30 A 60 70 80') bottom top", - "path('M 20 30 A 60 70 80') 100px 200px", - "path('M 20 30 A 60 70 80') reverse auto", - "path('M 20 30 A 60 70 80') reverse 10px 30deg", - "path('M 20 30 A 60 70 80') /", - ], -}; - -gCSSProperties["offset-path"] = { - domProp: "offsetPath", - inherited: false, - type: CSS_TYPE_LONGHAND, - initial_values: ["none"], - other_values: [...pathValues.other_values], - invalid_values: ["path('')"].concat(pathValues.invalid_values), -}; - -if (IsCSSPropertyPrefEnabled("layout.css.motion-path-ray.enabled")) { - gCSSProperties["offset-path"]["other_values"].push( - "ray(0deg)", - "ray(45deg closest-side)", - "ray(0rad farthest-side)", - "ray(0.5turn closest-corner contain)", - "ray(200grad farthest-corner)", - "ray(sides 180deg)", - "ray(contain farthest-side 180deg)", - "ray(calc(180deg - 45deg) farthest-side)", - "ray(0deg at center center)", - "ray(at 10% 10% 1rad)" - ); - - gCSSProperties["offset-path"]["invalid_values"].push( - "ray(closest-side)", - "ray(0deg, closest-side)", - "ray(contain 0deg closest-side contain)" - ); -} - -if (IsCSSPropertyPrefEnabled("layout.css.motion-path-basic-shapes.enabled")) { - gCSSProperties["offset-path"]["other_values"].push( - ...basicShapeOtherValues, - ...basicShapeXywhRectValues - ); -} - if (IsCSSPropertyPrefEnabled("layout.css.motion-path-url.enabled")) { gCSSProperties["offset-path"]["other_values"].push("url(#svgPath)"); } -gCSSProperties["offset-distance"] = { - domProp: "offsetDistance", - inherited: false, - type: CSS_TYPE_LONGHAND, - initial_values: ["0"], - other_values: ["10px", "10%", "190%", "-280%", "calc(30px + 40%)"], - invalid_values: ["none", "45deg"], -}; - -gCSSProperties["offset-rotate"] = { - domProp: "offsetRotate", - inherited: false, - type: CSS_TYPE_LONGHAND, - initial_values: ["auto"], - other_values: ["reverse", "0deg", "0rad reverse", "-45deg", "5turn auto"], - invalid_values: ["none", "10px", "reverse 0deg reverse", "reverse auto"], -}; - -gCSSProperties["offset-anchor"] = { - domProp: "offsetAnchor", - inherited: false, - type: CSS_TYPE_LONGHAND, - initial_values: ["auto"], - other_values: [ - "left bottom", - "center center", - "calc(20% + 10px) center", - "right 30em", - "10px 20%", - "left -10px top -20%", - "right 10% bottom 20em", - ], - invalid_values: ["none", "10deg", "left 10% top"], -}; - -if ( - IsCSSPropertyPrefEnabled("layout.css.motion-path-offset-position.enabled") -) { - gCSSProperties["offset"]["subproperties"].push("offset-position"); - gCSSProperties["offset"]["other_values"].push("top right / top left"); - - if (IsCSSPropertyPrefEnabled("layout.css.motion-path-ray.enabled")) { - gCSSProperties["offset"]["other_values"].push( - "top right ray(45deg closest-side)", - "50% 50% ray(0rad farthest-side)" - ); - } - - gCSSProperties["offset-position"] = { - domProp: "offsetPosition", - inherited: false, - type: CSS_TYPE_LONGHAND, - initial_values: ["normal"], - other_values: [ - "auto", - "left bottom", - "center center", - "calc(20% + 10px) center", - "right 30em", - "10px 20%", - "left -10px top -20%", - "right 10% bottom 20em", - ], - invalid_values: ["none", "10deg", "left 10% top"], - }; -} - { let linear_function_other_values = [ "linear(0, 1)", diff --git a/layout/style/test/test_hover_quirk.html b/layout/style/test/test_hover_quirk.html index 61e19f2a60..7a78185178 100644 --- a/layout/style/test/test_hover_quirk.html +++ b/layout/style/test/test_hover_quirk.html @@ -54,6 +54,18 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=783213 #dynamic-test:hover > * { background: rgb(0, 255, 0); } + + #dynamic-test-2 :is(button,input,a){ + background-color:yellow !important; + } + + #dynamic-test-2 :is(button,input,a):hover{ + background-color:lime !important; + } + + #dynamic-test-2 :is(button,input):focus{ + background-color:skyblue !important; + } </style> <script src="/tests/SimpleTest/SimpleTest.js"></script> <script src="/tests/SimpleTest/EventUtils.js"></script> @@ -97,6 +109,21 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=783213 is(getComputedStyle(document.getElementById('should-be-green-on-hover')).backgroundColor, "rgb(0, 255, 0)", "Dynamic change should invalidate properly"); + + synthesizeMouseAtCenter(document.getElementById('button'), {type: "mousemove"}); + is(getComputedStyle(document.getElementById('button')).backgroundColor, + "rgb(0, 255, 0)", + "Button hover should be green"); + + synthesizeMouseAtCenter(document.getElementById('input'), {type: "mousemove"}); + is(getComputedStyle(document.getElementById('input')).backgroundColor, + "rgb(0, 255, 0)", + "Input hover should be green"); + + synthesizeMouseAtCenter(document.getElementById('link-2'), {type: "mousemove"}); + is(getComputedStyle(document.getElementById('link-2')).backgroundColor, + "rgb(0, 255, 0)", + "Link hover should be green"); SimpleTest.finish(); }); </script> @@ -113,6 +140,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=783213 <a id="link" href="#">Link<span class="child"></span></a><br> <div id="div" class="parent">Div <span><span class="child"></span></span></div><br> </div> + <div id="dynamic-test-2"> + <button id="button">Button</button> + <input id="input" value="Input"> + <a id="link-2"href="">Link</a> + </div> <pre id="test"></pre> </body> </html> diff --git a/layout/style/test/test_non_content_accessible_pseudos.html b/layout/style/test/test_non_content_accessible_pseudos.html index 81493b1a4a..5f2d15d6a2 100644 --- a/layout/style/test/test_non_content_accessible_pseudos.html +++ b/layout/style/test/test_non_content_accessible_pseudos.html @@ -30,7 +30,6 @@ const NON_CONTENT_ACCESIBLE_PSEUDOS = [ ":-moz-dir-attr-rtl", ":-moz-dir-attr-like-auto", ":-moz-autofill-preview", - ":-moz-lwtheme", ":-moz-is-html", ":-moz-locale-dir(rtl)", ":-moz-locale-dir(ltr)", diff --git a/layout/style/test/test_selectors.html b/layout/style/test/test_selectors.html index d688139d3c..684e9d6524 100644 --- a/layout/style/test/test_selectors.html +++ b/layout/style/test/test_selectors.html @@ -1077,7 +1077,6 @@ function runTests() { test_balanced_unparseable(":dir"); // Test chrome-only -moz-lwtheme - test_balanced_unparseable(":-moz-lwtheme"); test_balanced_unparseable(":-moz-broken"); test_balanced_unparseable(":-moz-tree-row(selected)"); diff --git a/layout/style/test/test_style_struct_copy_constructors.html b/layout/style/test/test_style_struct_copy_constructors.html index 95f727a58d..bce5a4e32c 100644 --- a/layout/style/test/test_style_struct_copy_constructors.html +++ b/layout/style/test/test_style_struct_copy_constructors.html @@ -64,6 +64,12 @@ for (var prop in gCSSProperties) { } /** Test using inheritance **/ + +// TODO(bug 1887221): Zoom right now doesn't apply to explicitly inherited +// values, so remove it to get consistent results. +gRule1.style.removeProperty("zoom"); +gRule2.style.removeProperty("zoom"); + for (var prop in gCSSProperties) { var info = gCSSProperties[prop]; if (info.inherited && !("subproperties" in info)) { @@ -79,14 +85,6 @@ for (var prop in gCSSProperties) { } } -for (var prop in gCSSProperties) { - var info = gCSSProperties[prop]; - if (!("subproperties" in info)) { - gRule1.style.removeProperty(prop); - gRule2.style.removeProperty(prop); - } -} - </script> </pre> </body> |