Issue #2486 - Part 1: Initial plumbing and CSSOM support for cascade layers

This commit is contained in:
FranklinDM 2024-07-14 18:54:18 +08:00 • committed by roytam1
commit cac56b8e77
16 changed files with 416 additions and 4 deletions

View file

@ -237,6 +237,16 @@ DOMInterfaces = {
'headerFile': 'nsCSSRules.h', 'headerFile': 'nsCSSRules.h',
}, },
'CSSLayerBlockRule': {
'nativeType': 'mozilla::CSSLayerBlockRule',
'headerFile': 'nsCSSRules.h',
},
'CSSLayerStatementRule': {
'nativeType': 'mozilla::CSSLayerStatementRule',
'headerFile': 'nsCSSRules.h',
},
'CSSLexer': { 'CSSLexer': {
'wrapperCache': False 'wrapperCache': False
}, },

View file

@ -13,6 +13,8 @@ XPIDL_SOURCES += [
'nsIDOMCSSImportRule.idl', 'nsIDOMCSSImportRule.idl',
'nsIDOMCSSKeyframeRule.idl', 'nsIDOMCSSKeyframeRule.idl',
'nsIDOMCSSKeyframesRule.idl', 'nsIDOMCSSKeyframesRule.idl',
'nsIDOMCSSLayerBlockRule.idl',
'nsIDOMCSSLayerStatementRule.idl',
'nsIDOMCSSMediaRule.idl', 'nsIDOMCSSMediaRule.idl',
'nsIDOMCSSMozDocumentRule.idl', 'nsIDOMCSSMozDocumentRule.idl',
'nsIDOMCSSPageRule.idl', 'nsIDOMCSSPageRule.idl',

View file

@ -14,4 +14,5 @@ interface nsIDOMCSSImportRule : nsISupports
readonly attribute DOMString href; readonly attribute DOMString href;
readonly attribute nsIDOMMediaList media; readonly attribute nsIDOMMediaList media;
readonly attribute nsIDOMCSSStyleSheet styleSheet; readonly attribute nsIDOMCSSStyleSheet styleSheet;
readonly attribute DOMString layerName;
}; };

View file

@ -0,0 +1,12 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 "nsIDOMCSSGroupingRule.idl"
[scriptable, uuid(2865c2ba-ae78-4282-8eff-9b7a2d71f9eb)]
interface nsIDOMCSSLayerBlockRule : nsIDOMCSSGroupingRule
{
readonly attribute DOMString name;
};

View file

@ -0,0 +1,11 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 "nsISupports.idl"
[scriptable, uuid(ec215b70-417e-41fa-8d48-8edd6d30aac3)]
interface nsIDOMCSSLayerStatementRule : nsISupports
{
};

View file

@ -44,6 +44,9 @@ interface nsIDOMCSSRule : nsISupports
const unsigned short COUNTER_STYLE_RULE = 11; const unsigned short COUNTER_STYLE_RULE = 11;
const unsigned short SUPPORTS_RULE = 12; const unsigned short SUPPORTS_RULE = 12;
const unsigned short FONT_FEATURE_VALUES_RULE = 14; const unsigned short FONT_FEATURE_VALUES_RULE = 14;
const unsigned short RESERVED1_RULE = 15;
const unsigned short LAYER_BLOCK_RULE = 16;
const unsigned short LAYER_STATEMENT_RULE = 17;
readonly attribute unsigned short type; readonly attribute unsigned short type;
attribute DOMString cssText; attribute DOMString cssText;

View file

@ -15,3 +15,9 @@ interface CSSImportRule : CSSRule {
// be. See <https://bugzilla.mozilla.org/show_bug.cgi?id=1326509>. // be. See <https://bugzilla.mozilla.org/show_bug.cgi?id=1326509>.
[SameObject] readonly attribute CSSStyleSheet? styleSheet; [SameObject] readonly attribute CSSStyleSheet? styleSheet;
}; };
// https://drafts.csswg.org/css-cascade-5/#extensions-to-cssimportrule-interface
partial interface CSSImportRule {
[Pref="layout.css.cascade-layers.enabled"]
readonly attribute DOMString? layerName;
};

View file

@ -0,0 +1,12 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*
* The origin of this IDL file is
* https://drafts.csswg.org/css-cascade-5/#the-csslayerblockrule-interface
*/
[Exposed=Window, Pref="layout.css.cascade-layers.enabled"]
interface CSSLayerBlockRule : CSSGroupingRule {
readonly attribute DOMString name;
};

View file

@ -0,0 +1,14 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*
* The origin of this IDL file is
* https://drafts.csswg.org/css-cascade-5/#the-csslayerstatementrule-interface
*/
[Exposed=Window, Pref="layout.css.cascade-layers.enabled"]
interface CSSLayerStatementRule : CSSRule {
// readonly attribute FrozenArray<CSSOMString> nameList;
[Frozen, Cached, Pure]
readonly attribute sequence<DOMString> nameList;
};

View file

@ -98,6 +98,8 @@ WEBIDL_FILES = [
'CSSImportRule.webidl', 'CSSImportRule.webidl',
'CSSKeyframeRule.webidl', 'CSSKeyframeRule.webidl',
'CSSKeyframesRule.webidl', 'CSSKeyframesRule.webidl',
'CSSLayerBlockRule.webidl',
'CSSLayerStatementRule.webidl',
'CSSLexer.webidl', 'CSSLexer.webidl',
'CSSMediaRule.webidl', 'CSSMediaRule.webidl',
'CSSMozDocumentRule.webidl', 'CSSMozDocumentRule.webidl',

View file

@ -29,6 +29,7 @@ class ImportRule final : public Rule,
{ {
public: public:
ImportRule(nsMediaList* aMedia, const nsString& aURLSpec, ImportRule(nsMediaList* aMedia, const nsString& aURLSpec,
const nsString& aLayerName,
uint32_t aLineNumber, uint32_t aColumnNumber); uint32_t aLineNumber, uint32_t aColumnNumber);
private: private:
// for |Clone| // for |Clone|
@ -65,9 +66,11 @@ public:
// The XPCOM GetHref is fine, since it never fails. // The XPCOM GetHref is fine, since it never fails.
nsMediaList* Media() const { return mMedia; } nsMediaList* Media() const { return mMedia; }
StyleSheet* GetStyleSheet() const; StyleSheet* GetStyleSheet() const;
// The XPCOM GetLayerName is OK
private: private:
nsString mURLSpec; nsString mURLSpec;
nsString mLayerName;
RefPtr<nsMediaList> mMedia; RefPtr<nsMediaList> mMedia;
RefPtr<CSSStyleSheet> mChildSheet; RefPtr<CSSStyleSheet> mChildSheet;
}; };

View file

@ -78,7 +78,10 @@ public:
DOCUMENT_RULE, DOCUMENT_RULE,
SUPPORTS_RULE, SUPPORTS_RULE,
FONT_FEATURE_VALUES_RULE, FONT_FEATURE_VALUES_RULE,
COUNTER_STYLE_RULE COUNTER_STYLE_RULE,
RESERVED1_RULE,
LAYER_BLOCK_RULE,
LAYER_STATEMENT_RULE
}; };
virtual int32_t GetType() const = 0; virtual int32_t GetType() const = 0;

View file

@ -705,6 +705,7 @@ protected:
bool ParseMediaQueryExpression(nsMediaQuery* aQuery); bool ParseMediaQueryExpression(nsMediaQuery* aQuery);
void ProcessImport(const nsString& aURLSpec, void ProcessImport(const nsString& aURLSpec,
nsMediaList* aMedia, nsMediaList* aMedia,
const nsString& aLayerName,
RuleAppendFunc aAppendFunc, RuleAppendFunc aAppendFunc,
void* aProcessData, void* aProcessData,
uint32_t aLineNumber, uint32_t aLineNumber,
@ -3885,19 +3886,24 @@ CSSParserImpl::ParseImportRule(RuleAppendFunc aAppendFunc, void* aData)
NS_ASSERTION(media->Length() != 0, "media list must be nonempty"); NS_ASSERTION(media->Length() != 0, "media list must be nonempty");
} }
ProcessImport(url, media, aAppendFunc, aData, linenum, colnum); // FIXME: Layer functions inside @import declarations are treated as an error.
nsAutoString layerName;
ProcessImport(url, media, layerName, aAppendFunc, aData, linenum, colnum);
return true; return true;
} }
void void
CSSParserImpl::ProcessImport(const nsString& aURLSpec, CSSParserImpl::ProcessImport(const nsString& aURLSpec,
nsMediaList* aMedia, nsMediaList* aMedia,
const nsString& aLayerName,
RuleAppendFunc aAppendFunc, RuleAppendFunc aAppendFunc,
void* aData, void* aData,
uint32_t aLineNumber, uint32_t aLineNumber,
uint32_t aColumnNumber) uint32_t aColumnNumber)
{ {
RefPtr<css::ImportRule> rule = new css::ImportRule(aMedia, aURLSpec, RefPtr<css::ImportRule> rule = new css::ImportRule(aMedia, aURLSpec,
aLayerName,
aLineNumber, aLineNumber,
aColumnNumber); aColumnNumber);
(*aAppendFunc)(rule, aData); (*aAppendFunc)(rule, aData);

View file

@ -36,6 +36,8 @@
#include "mozilla/dom/CSSNamespaceRuleBinding.h" #include "mozilla/dom/CSSNamespaceRuleBinding.h"
#include "mozilla/dom/CSSImportRuleBinding.h" #include "mozilla/dom/CSSImportRuleBinding.h"
#include "mozilla/dom/CSSMediaRuleBinding.h" #include "mozilla/dom/CSSMediaRuleBinding.h"
#include "mozilla/dom/CSSLayerBlockRuleBinding.h"
#include "mozilla/dom/CSSLayerStatementRuleBinding.h"
#include "mozilla/dom/CSSSupportsRuleBinding.h" #include "mozilla/dom/CSSSupportsRuleBinding.h"
#include "mozilla/dom/CSSMozDocumentRuleBinding.h" #include "mozilla/dom/CSSMozDocumentRuleBinding.h"
#include "mozilla/dom/CSSPageRuleBinding.h" #include "mozilla/dom/CSSPageRuleBinding.h"
@ -247,10 +249,12 @@ GroupRuleRuleList::IndexedGetter(uint32_t aIndex, bool& aFound)
// //
ImportRule::ImportRule(nsMediaList* aMedia, const nsString& aURLSpec, ImportRule::ImportRule(nsMediaList* aMedia, const nsString& aURLSpec,
const nsString& aLayerName,
uint32_t aLineNumber, uint32_t aColumnNumber) uint32_t aLineNumber, uint32_t aColumnNumber)
: Rule(aLineNumber, aColumnNumber) : Rule(aLineNumber, aColumnNumber)
, mURLSpec(aURLSpec) , mURLSpec(aURLSpec)
, mMedia(aMedia) , mMedia(aMedia)
, mLayerName(aLayerName)
{ {
MOZ_ASSERT(aMedia); MOZ_ASSERT(aMedia);
// XXXbz This is really silly.... the mMedia here will be replaced // XXXbz This is really silly.... the mMedia here will be replaced
@ -259,8 +263,9 @@ ImportRule::ImportRule(nsMediaList* aMedia, const nsString& aURLSpec,
} }
ImportRule::ImportRule(const ImportRule& aCopy) ImportRule::ImportRule(const ImportRule& aCopy)
: Rule(aCopy), : Rule(aCopy)
mURLSpec(aCopy.mURLSpec) , mURLSpec(aCopy.mURLSpec)
, mLayerName(aCopy.mLayerName)
{ {
// Whether or not an @import rule has a null sheet is a permanent // Whether or not an @import rule has a null sheet is a permanent
// property of that @import rule, since it is null only if the target // property of that @import rule, since it is null only if the target
@ -412,6 +417,13 @@ ImportRule::GetStyleSheet(nsIDOMCSSStyleSheet * *aStyleSheet)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
ImportRule::GetLayerName(nsAString & aLayerName)
{
aLayerName = mLayerName;
return NS_OK;
}
/* virtual */ size_t /* virtual */ size_t
ImportRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const ImportRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
{ {
@ -3351,3 +3363,230 @@ nsCSSCounterStyleRule::WrapObject(JSContext* aCx,
{ {
return CSSCounterStyleRuleBinding::Wrap(aCx, this, aGivenProto); return CSSCounterStyleRuleBinding::Wrap(aCx, this, aGivenProto);
} }
namespace mozilla {
// -------------------------------------------
// LayerStatementRule
//
CSSLayerStatementRule::CSSLayerStatementRule(
const nsTArray<nsString>& aNameList,
uint32_t aLineNumber, uint32_t aColumnNumber)
: Rule(aLineNumber, aColumnNumber)
, mNameList(aNameList)
{
}
CSSLayerStatementRule::CSSLayerStatementRule(const CSSLayerStatementRule& aCopy)
: Rule(aCopy)
, mNameList(aCopy.mNameList)
{
}
CSSLayerStatementRule::~CSSLayerStatementRule()
{
}
NS_IMPL_ADDREF_INHERITED(CSSLayerStatementRule, Rule)
NS_IMPL_RELEASE_INHERITED(CSSLayerStatementRule, Rule)
bool
CSSLayerStatementRule::IsCCLeaf() const
{
// We're not a leaf.
return false;
}
// QueryInterface implementation for CSSLayerStatementRule
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(CSSLayerStatementRule)
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSLayerStatementRule)
NS_INTERFACE_MAP_END_INHERITING(Rule)
NS_IMPL_CYCLE_COLLECTION_CLASS(CSSLayerStatementRule)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CSSLayerStatementRule)
tmp->mNameList.Clear();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSLayerStatementRule, mozilla::css::Rule)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
#ifdef DEBUG
/* virtual */ void
CSSLayerStatementRule::List(FILE* out, int32_t aIndent) const
{
// TODO
}
#endif
/* virtual */ int32_t
CSSLayerStatementRule::GetType() const
{
return Rule::LAYER_STATEMENT_RULE;
}
/* virtual */ already_AddRefed<Rule>
CSSLayerStatementRule::Clone() const
{
RefPtr<Rule> clone = new CSSLayerStatementRule(*this);
return clone.forget();
}
uint16_t
CSSLayerStatementRule::Type() const
{
return nsIDOMCSSRule::LAYER_STATEMENT_RULE;
}
void
CSSLayerStatementRule::GetCssTextImpl(nsAString& aCssText) const
{
aCssText.AssignLiteral("@layer ");
for (uint32_t i = 0, i_end = mNameList.Length(); i != i_end; ++i) {
aCssText.Append(mNameList[i]);
aCssText.Append(',');
if (i != i_end - 1) {
aCssText.Append(' ');
}
}
aCssText.Append(';');
}
void
CSSLayerStatementRule::GetNameList(nsTArray<nsString>& aResult)
{
aResult = mNameList;
}
/* virtual */ size_t
CSSLayerStatementRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
{
return aMallocSizeOf(this);
}
/* virtual */ JSObject*
CSSLayerStatementRule::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto)
{
return CSSLayerStatementRuleBinding::Wrap(aCx, this, aGivenProto);
}
// -------------------------------------------
// LayerBlockRule
//
CSSLayerBlockRule::CSSLayerBlockRule(const nsString& aName,
uint32_t aLineNumber, uint32_t aColumnNumber)
: css::GroupRule(aLineNumber, aColumnNumber)
, mName(aName)
{
}
CSSLayerBlockRule::~CSSLayerBlockRule()
{
}
CSSLayerBlockRule::CSSLayerBlockRule(const CSSLayerBlockRule& aCopy)
: css::GroupRule(aCopy)
, mName(aCopy.mName)
{
}
#ifdef DEBUG
/* virtual */ void
CSSLayerBlockRule::List(FILE* out, int32_t aIndent) const
{
// TODO
}
#endif
/* virtual */ int32_t
CSSLayerBlockRule::GetType() const
{
return Rule::LAYER_BLOCK_RULE;
}
/* virtual */ already_AddRefed<mozilla::css::Rule>
CSSLayerBlockRule::Clone() const
{
RefPtr<css::Rule> clone = new CSSLayerBlockRule(*this);
return clone.forget();
}
/* virtual */ bool
CSSLayerBlockRule::UseForPresentation(nsPresContext* aPresContext,
nsMediaQueryResultCacheKey& aKey)
{
// This will never be reached.
return true;
}
NS_IMPL_ADDREF_INHERITED(CSSLayerBlockRule, css::GroupRule)
NS_IMPL_RELEASE_INHERITED(CSSLayerBlockRule, css::GroupRule)
// QueryInterface implementation for CSSLayerBlockRule
NS_INTERFACE_MAP_BEGIN(CSSLayerBlockRule)
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSGroupingRule)
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSLayerBlockRule)
NS_INTERFACE_MAP_END_INHERITING(GroupRule)
uint16_t
CSSLayerBlockRule::Type() const
{
return nsIDOMCSSRule::LAYER_BLOCK_RULE;
}
void
CSSLayerBlockRule::GetCssTextImpl(nsAString& aCssText) const
{
aCssText.AssignLiteral("@layer ");
aCssText.Append(mName);
css::GroupRule::AppendRulesToCssText(aCssText);
}
// nsIDOMCSSGroupingRule methods
NS_IMETHODIMP
CSSLayerBlockRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
{
return css::GroupRule::GetCssRules(aRuleList);
}
NS_IMETHODIMP
CSSLayerBlockRule::InsertRule(const nsAString & aRule, uint32_t aIndex, uint32_t* _retval)
{
return css::GroupRule::InsertRule(aRule, aIndex, _retval);
}
NS_IMETHODIMP
CSSLayerBlockRule::DeleteRule(uint32_t aIndex)
{
return css::GroupRule::DeleteRule(aIndex);
}
// nsIDOMCSSLayerBlockRule methods
NS_IMETHODIMP
CSSLayerBlockRule::GetName(nsAString& aConditionText)
{
aConditionText.Assign(mName);
return NS_OK;
}
/* virtual */ size_t
CSSLayerBlockRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
{
size_t n = aMallocSizeOf(this);
n += css::GroupRule::SizeOfExcludingThis(aMallocSizeOf);
n += mName.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
return n;
}
/* virtual */ JSObject*
CSSLayerBlockRule::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto)
{
return CSSLayerBlockRuleBinding::Wrap(aCx, this, aGivenProto);
}
} // namespace mozilla

View file

@ -26,6 +26,8 @@
#include "nsIDOMCSSFontFaceRule.h" #include "nsIDOMCSSFontFaceRule.h"
#include "nsIDOMCSSFontFeatureValuesRule.h" #include "nsIDOMCSSFontFeatureValuesRule.h"
#include "nsIDOMCSSGroupingRule.h" #include "nsIDOMCSSGroupingRule.h"
#include "nsIDOMCSSLayerBlockRule.h"
#include "nsIDOMCSSLayerStatementRule.h"
#include "nsIDOMCSSMediaRule.h" #include "nsIDOMCSSMediaRule.h"
#include "nsIDOMCSSMozDocumentRule.h" #include "nsIDOMCSSMozDocumentRule.h"
#include "nsIDOMCSSPageRule.h" #include "nsIDOMCSSPageRule.h"
@ -737,4 +739,87 @@ private:
uint32_t mGeneration; uint32_t mGeneration;
}; };
namespace mozilla {
class CSSLayerStatementRule final : public css::Rule,
public nsIDOMCSSLayerStatementRule
{
public:
CSSLayerStatementRule(const nsTArray<nsString>& aNameList,
uint32_t aLineNumber, uint32_t aColumnNumber);
CSSLayerStatementRule(const CSSLayerStatementRule& aCopy);
// Rule methods
#ifdef DEBUG
virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
#endif
virtual int32_t GetType() const override;
using Rule::GetType;
virtual already_AddRefed<mozilla::css::Rule> Clone() const override;
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(CSSLayerStatementRule, Rule)
NS_DECL_ISUPPORTS_INHERITED
virtual bool IsCCLeaf() const override;
// nsIDOMCSSLayerStatementRule interface
NS_DECL_NSIDOMCSSLAYERSTATEMENTRULE
// WebIDL interface
uint16_t Type() const override;
void GetCssTextImpl(nsAString& aCssText) const override;
void GetNameList(nsTArray<nsString>& aResult);
virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
protected:
virtual ~CSSLayerStatementRule();
nsTArray<nsString> mNameList;
};
class CSSLayerBlockRule final : public css::GroupRule,
public nsIDOMCSSLayerBlockRule
{
public:
CSSLayerBlockRule(const nsString& aName,
uint32_t aLineNumber, uint32_t aColumnNumber);
CSSLayerBlockRule(const CSSLayerBlockRule& aCopy);
// Rule methods
#ifdef DEBUG
virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
#endif
virtual int32_t GetType() const override;
using Rule::GetType;
virtual already_AddRefed<mozilla::css::Rule> Clone() const override;
virtual bool UseForPresentation(nsPresContext* aPresContext,
nsMediaQueryResultCacheKey& aKey) override;
NS_DECL_ISUPPORTS_INHERITED
// nsIDOMCSSGroupingRule interface
NS_DECL_NSIDOMCSSGROUPINGRULE
// nsIDOMCSSLayerBlockRule interface
NS_DECL_NSIDOMCSSLAYERBLOCKRULE
// WebIDL interface
uint16_t Type() const override;
void GetCssTextImpl(nsAString& aCssText) const override;
// Our XPCOM GetName is OK
virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
protected:
virtual ~CSSLayerBlockRule();
nsString mName;
};
} // namespace mozilla
#endif /* !defined(nsCSSRules_h_) */ #endif /* !defined(nsCSSRules_h_) */

View file

@ -2675,6 +2675,9 @@ pref("layout.css.control-characters.visible", false);
// Is support for ResizeObservers enabled? // Is support for ResizeObservers enabled?
pref("layout.css.resizeobserver.enabled", true); pref("layout.css.resizeobserver.enabled", true);
// Is support for cascade layers enabled?
pref("layout.css.cascade-layers.enabled", true);
// pref for which side vertical scrollbars should be on // pref for which side vertical scrollbars should be on
// 0 = end-side in UI direction // 0 = end-side in UI direction
// 1 = end-side in document/content direction // 1 = end-side in document/content direction