From 6176bd62d9b768fac966d30f5275f3fcd4b99003 Mon Sep 17 00:00:00 2001 From: Moonchild Date: Wed, 3 Apr 2024 13:59:06 +0200 Subject: [PATCH] Issue #2490 - Part 12: Convert CSSStyleRule to WebIDL. The .style PutForwards bit is coming along for the ride here, aligning us with the behavior of Blink and Gecko. --- dom/base/nsDOMClassInfo.cpp | 17 ------ dom/base/nsDOMClassInfoClasses.h | 1 - dom/base/nsWrapperCache.h | 2 - dom/bindings/Bindings.conf | 4 ++ dom/webidl/CSSStyleRule.webidl | 14 +++++ dom/webidl/LegacyQueryInterface.webidl | 1 + dom/webidl/moz.build | 1 + .../file_crosscompartment_weakmap.html | 1 - .../test_crosscompartment_weakmap.html | 8 --- layout/style/BindingStyleRule.cpp | 18 ++++++ layout/style/BindingStyleRule.h | 60 +++++++++++++++++++ layout/style/StyleRule.cpp | 35 +++++------ layout/style/StyleRule.h | 7 +-- layout/style/moz.build | 13 +++- layout/style/nsICSSStyleRuleDOMWrapper.h | 5 ++ 15 files changed, 132 insertions(+), 55 deletions(-) create mode 100644 dom/webidl/CSSStyleRule.webidl create mode 100644 layout/style/BindingStyleRule.cpp create mode 100644 layout/style/BindingStyleRule.h diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index 3b5a5a1f17..18115dbba2 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -80,7 +80,6 @@ #include "nsIDOMCSSSupportsRule.h" #include "nsIDOMCSSCounterStyleRule.h" #include "nsIDOMCSSPageRule.h" -#include "nsIDOMCSSStyleRule.h" #include "nsIDOMXULCommandDispatcher.h" #include "nsIControllers.h" #ifdef MOZ_XUL @@ -188,9 +187,6 @@ static nsDOMClassInfoData sClassInfoData[] = { // Misc Core related classes // CSS classes - NS_DEFINE_CLASSINFO_DATA(CSSStyleRule, nsCSSRuleSH, - DOM_DEFAULT_SCRIPTABLE_FLAGS | - nsIXPCScriptable::WANT_PRECREATE) NS_DEFINE_CLASSINFO_DATA(CSSMediaRule, nsCSSRuleSH, DOM_DEFAULT_SCRIPTABLE_FLAGS | nsIXPCScriptable::WANT_PRECREATE) @@ -516,11 +512,6 @@ nsDOMClassInfo::Init() DOM_CLASSINFO_MAP_ENTRY(nsIDOMDOMConstructor) DOM_CLASSINFO_MAP_END - DOM_CLASSINFO_MAP_BEGIN(CSSStyleRule, nsIDOMCSSStyleRule) - DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSRule) - DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSStyleRule) - DOM_CLASSINFO_MAP_END - DOM_CLASSINFO_MAP_BEGIN(CSSMediaRule, nsIDOMCSSMediaRule) DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSRule) DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSMediaRule) @@ -2000,14 +1991,6 @@ nsCSSRuleSH::PreCreate(nsISupports *nativeObj, JSContext *cx, return NS_ERROR_UNEXPECTED; } css::Rule* cssRule = rule->GetCSSRule(); - if (!cssRule) { - // A DOMCSSStyleRule whose actual underlying rule has gone away. There - // isn't much a caller can do with this thing anyway, and only chrome code - // can get its hands on it to start with, so just wrap in the current - // global. - *parentObj = globalObj; - return NS_OK; - } nsIDocument* doc = cssRule->GetDocument(); if (!doc) { *parentObj = globalObj; diff --git a/dom/base/nsDOMClassInfoClasses.h b/dom/base/nsDOMClassInfoClasses.h index 90dbb32a72..ff3e57f60c 100644 --- a/dom/base/nsDOMClassInfoClasses.h +++ b/dom/base/nsDOMClassInfoClasses.h @@ -8,7 +8,6 @@ DOMCI_CLASS(DOMPrototype) DOMCI_CLASS(DOMConstructor) // CSS classes -DOMCI_CLASS(CSSStyleRule) DOMCI_CLASS(CSSMediaRule) // XUL classes diff --git a/dom/base/nsWrapperCache.h b/dom/base/nsWrapperCache.h index eb366e8baa..df83a8f234 100644 --- a/dom/base/nsWrapperCache.h +++ b/dom/base/nsWrapperCache.h @@ -19,7 +19,6 @@ class TabChildGlobal; class ProcessGlobal; } // namespace dom namespace css { -class StyleRule; class MediaRule; class DocumentRule; } // namespace css @@ -291,7 +290,6 @@ private: friend class SandboxPrivate; friend class nsInProcessTabChildGlobal; friend class nsWindowRoot; - friend class mozilla::css::StyleRule; friend class mozilla::css::MediaRule; friend class mozilla::css::DocumentRule; friend class mozilla::CSSSupportsRule; diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index 08387439c7..5c91365834 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -223,6 +223,10 @@ DOMInterfaces = { 'nativeType': 'nsICSSDeclaration' }, +'CSSStyleRule': { + 'nativeType': 'mozilla::BindingStyleRule', +}, + 'CSSStyleSheet': { 'nativeType': 'mozilla::StyleSheet', 'binaryNames': { 'ownerRule': 'DOMOwnerRule' }, diff --git a/dom/webidl/CSSStyleRule.webidl b/dom/webidl/CSSStyleRule.webidl new file mode 100644 index 0000000000..571bd6a57f --- /dev/null +++ b/dom/webidl/CSSStyleRule.webidl @@ -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/cssom/#the-cssstylerule-interface + */ + +// https://drafts.csswg.org/cssom/#the-cssstylerule-interface +interface CSSStyleRule : CSSRule { + attribute DOMString selectorText; + [SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style; +}; diff --git a/dom/webidl/LegacyQueryInterface.webidl b/dom/webidl/LegacyQueryInterface.webidl index 96048b03ca..41bbd025ff 100644 --- a/dom/webidl/LegacyQueryInterface.webidl +++ b/dom/webidl/LegacyQueryInterface.webidl @@ -26,6 +26,7 @@ Comment implements LegacyQueryInterface; Crypto implements LegacyQueryInterface; CSSPrimitiveValue implements LegacyQueryInterface; CSSStyleDeclaration implements LegacyQueryInterface; +CSSStyleRule implements LegacyQueryInterface; CSSValueList implements LegacyQueryInterface; DOMImplementation implements LegacyQueryInterface; DOMParser implements LegacyQueryInterface; diff --git a/dom/webidl/moz.build b/dom/webidl/moz.build index 820af99089..3f20beac79 100644 --- a/dom/webidl/moz.build +++ b/dom/webidl/moz.build @@ -98,6 +98,7 @@ WEBIDL_FILES = [ 'CSSRule.webidl', 'CSSRuleList.webidl', 'CSSStyleDeclaration.webidl', + 'CSSStyleRule.webidl', 'CSSStyleSheet.webidl', 'CSSTransition.webidl', 'CSSValue.webidl', diff --git a/js/xpconnect/tests/mochitest/file_crosscompartment_weakmap.html b/js/xpconnect/tests/mochitest/file_crosscompartment_weakmap.html index b25cdb2f90..127c479ebe 100644 --- a/js/xpconnect/tests/mochitest/file_crosscompartment_weakmap.html +++ b/js/xpconnect/tests/mochitest/file_crosscompartment_weakmap.html @@ -1,7 +1,6 @@ - Test Cross-Compartment DOM WeakMaps diff --git a/js/xpconnect/tests/mochitest/test_crosscompartment_weakmap.html b/js/xpconnect/tests/mochitest/test_crosscompartment_weakmap.html index e50b1f1bd8..54658d17bc 100644 --- a/js/xpconnect/tests/mochitest/test_crosscompartment_weakmap.html +++ b/js/xpconnect/tests/mochitest/test_crosscompartment_weakmap.html @@ -15,14 +15,6 @@ function setup() { var item = window.frames[0].document.querySelector("body"); my_map.set(item, "success_string"); - - var rule_fail = false; - try { - my_map.set(window.frames[0].document.styleSheets[0].cssRules[0], 1); - } catch (e) { - rule_fail = true; - } - ok(rule_fail, "Using rule as a weak map key across compartments should produce an exception because it can't be wrapper preserved."); } function runTest() { diff --git a/layout/style/BindingStyleRule.cpp b/layout/style/BindingStyleRule.cpp new file mode 100644 index 0000000000..9cdbc46cdd --- /dev/null +++ b/layout/style/BindingStyleRule.cpp @@ -0,0 +1,18 @@ +/* -*- Mode: C++; 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 "mozilla/BindingStyleRule.h" +#include "mozilla/dom/CSSStyleRuleBinding.h" + +namespace mozilla { + +/* virtual */ JSObject* +BindingStyleRule::WrapObject(JSContext* aCx, + JS::Handle aGivenProto) +{ + return dom::CSSStyleRuleBinding::Wrap(aCx, this, aGivenProto); +} + +} // namespace mozilla diff --git a/layout/style/BindingStyleRule.h b/layout/style/BindingStyleRule.h new file mode 100644 index 0000000000..e371bc1149 --- /dev/null +++ b/layout/style/BindingStyleRule.h @@ -0,0 +1,60 @@ +/* -*- Mode: C++; 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/. */ + +#ifndef mozilla_BindingStyleRule_h__ +#define mozilla_BindingStyleRule_h__ + +#include "nscore.h" +#include "nsStringGlue.h" +#include "mozilla/css/Rule.h" + +/** + * Superclass for mozilla::css::StyleRule, for use from bindings code. + */ + +class nsICSSDeclaration; + +namespace mozilla { + +class BindingStyleRule : public css::Rule +{ +protected: + BindingStyleRule(uint32_t aLineNumber, uint32_t aColumnNumber) + : css::Rule(aLineNumber, aColumnNumber) + { + } + BindingStyleRule(const BindingStyleRule& aCopy) + : css::Rule(aCopy) + { + } + virtual ~BindingStyleRule() {} + +public: + // This is pure virtual because we have no members, and are an abstract class + // to start with. The fact that we have to have this declaration at all is + // kinda dumb. :( + virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) + const override MOZ_MUST_OVERRIDE = 0; + + // Likewise for this one. We have to override our superclass, but don't + // really need to do anything in this method. + virtual bool IsCCLeaf() const override MOZ_MUST_OVERRIDE = 0; + + // WebIDL API + // For GetSelectorText/SetSelectorText, we purposefully use a signature that + // matches the nsIDOMCSSStyleRule one for now, so subclasses can just + // implement both at once. The actual implementations must never return + // anything other than NS_OK; + NS_IMETHOD GetSelectorText(nsAString& aSelectorText) = 0; + NS_IMETHOD SetSelectorText(const nsAString& aSelectorText) = 0; + virtual nsICSSDeclaration* Style() = 0; + + virtual JSObject* WrapObject(JSContext* aCx, + JS::Handle aGivenProto) override; +}; + +} // namespace mozilla + +#endif // mozilla_BindingStyleRule_h__ diff --git a/layout/style/StyleRule.cpp b/layout/style/StyleRule.cpp index cf5952a650..97a17d2871 100644 --- a/layout/style/StyleRule.cpp +++ b/layout/style/StyleRule.cpp @@ -15,6 +15,7 @@ #include "mozilla/MemoryReporting.h" #include "mozilla/css/GroupRule.h" #include "mozilla/css/Declaration.h" +#include "mozilla/dom/CSSStyleRuleBinding.h" #include "nsIDocument.h" #include "nsIAtom.h" #include "nsString.h" @@ -26,7 +27,6 @@ #include "nsCSSPseudoClasses.h" #include "nsCSSAnonBoxes.h" #include "nsTArray.h" -#include "nsDOMClassInfoID.h" #include "nsContentUtils.h" #include "nsError.h" #include "mozAutoDocUpdate.h" @@ -1235,13 +1235,18 @@ StyleRule::Type() const NS_IMETHODIMP StyleRule::GetStyle(nsIDOMCSSStyleDeclaration** aStyle) +{ + NS_ADDREF(*aStyle = Style()); + return NS_OK; +} + +nsICSSDeclaration* +StyleRule::Style() { if (!mDOMDeclaration) { mDOMDeclaration.reset(new DOMCSSDeclarationImpl(this)); } - *aStyle = mDOMDeclaration.get(); - NS_ADDREF(*aStyle); - return NS_OK; + return mDOMDeclaration.get(); } NS_IMETHODIMP @@ -1256,11 +1261,10 @@ StyleRule::StyleRule(nsCSSSelectorList* aSelector, Declaration* aDeclaration, uint32_t aLineNumber, uint32_t aColumnNumber) - : Rule(aLineNumber, aColumnNumber), - mSelector(aSelector), - mDeclaration(aDeclaration) + : BindingStyleRule(aLineNumber, aColumnNumber) + , mSelector(aSelector) + , mDeclaration(aDeclaration) { - SetIsNotDOMBinding(); NS_PRECONDITION(aDeclaration, "must have a declaration"); mDeclaration->SetOwningRule(this); @@ -1268,11 +1272,10 @@ StyleRule::StyleRule(nsCSSSelectorList* aSelector, // for |Clone| StyleRule::StyleRule(const StyleRule& aCopy) - : Rule(aCopy), - mSelector(aCopy.mSelector ? aCopy.mSelector->Clone() : nullptr), - mDeclaration(new Declaration(*aCopy.mDeclaration)) + : BindingStyleRule(aCopy) + , mSelector(aCopy.mSelector ? aCopy.mSelector->Clone() : nullptr) + , mDeclaration(new Declaration(*aCopy.mDeclaration)) { - SetIsNotDOMBinding(); mDeclaration->SetOwningRule(this); // rest is constructed lazily on existing data } @@ -1301,7 +1304,6 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(StyleRule) else NS_INTERFACE_MAP_ENTRY(nsICSSStyleRuleDOMWrapper) NS_INTERFACE_MAP_ENTRY(nsIDOMCSSStyleRule) - NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSStyleRule) NS_INTERFACE_MAP_END_INHERITING(Rule) NS_IMPL_ADDREF_INHERITED(StyleRule, Rule) @@ -1496,12 +1498,5 @@ StyleRule::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const return n; } -/* virtual */ JSObject* -StyleRule::WrapObject(JSContext* aCx, JS::Handle aGivenProto) -{ - NS_NOTREACHED("We called SetIsNotDOMBinding() in our constructor"); - return nullptr; -} - } // namespace css } // namespace mozilla diff --git a/layout/style/StyleRule.h b/layout/style/StyleRule.h index 55ec693a38..ba10542c78 100644 --- a/layout/style/StyleRule.h +++ b/layout/style/StyleRule.h @@ -14,7 +14,7 @@ #include "mozilla/Attributes.h" #include "mozilla/MemoryReporting.h" #include "mozilla/UniquePtr.h" -#include "mozilla/css/Rule.h" +#include "mozilla/BindingStyleRule.h" #include "nsString.h" #include "nsCOMPtr.h" @@ -325,7 +325,7 @@ namespace css { class Declaration; -class StyleRule final : public Rule +class StyleRule final : public BindingStyleRule , public nsICSSStyleRuleDOMWrapper { public: @@ -350,6 +350,7 @@ public: // WebIDL interface uint16_t Type() const override; void GetCssTextImpl(nsAString& aCssText) const override; + virtual nsICSSDeclaration* Style() override; // null for style attribute nsCSSSelectorList* Selector() { return mSelector; } @@ -369,8 +370,6 @@ public: virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override; - virtual JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; - private: ~StyleRule(); diff --git a/layout/style/moz.build b/layout/style/moz.build index 7239526aa8..1212a92d10 100644 --- a/layout/style/moz.build +++ b/layout/style/moz.build @@ -74,6 +74,7 @@ EXPORTS += [ EXPORTS.mozilla += [ 'AnimationCollection.h', + 'BindingStyleRule.h', 'CSSEnabledState.h', 'CSSStyleSheet.h', 'CSSVariableDeclarations.h', @@ -177,10 +178,18 @@ UNIFIED_SOURCES += [ 'SVGAttrAnimationRuleProcessor.cpp', ] -# nsCSSRuleProcessor.cpp needs to be built separately because it uses plarena.h. -# nsLayoutStylesheetCache.cpp needs to be built separately because it uses +# - BindingStyleRule.cpp doesn't necessarily need to be built separately, +# however, it may shift unified build boundaries, causing +# the Unified CPP containing it to include nsStyleCoord.cpp, which +# includes, via nsStyleCoord.h, , which ends up including +# , which fails in much the way described in +# . +# - nsCSSRuleProcessor.cpp needs to be built separately because it uses +# plarena.h. +# - nsLayoutStylesheetCache.cpp needs to be built separately because it uses # nsExceptionHandler.h, which includes windows.h. SOURCES += [ + 'BindingStyleRule.cpp', 'nsCSSRuleProcessor.cpp', 'nsLayoutStylesheetCache.cpp', ] diff --git a/layout/style/nsICSSStyleRuleDOMWrapper.h b/layout/style/nsICSSStyleRuleDOMWrapper.h index 038cca0868..f2a3b6ccc9 100644 --- a/layout/style/nsICSSStyleRuleDOMWrapper.h +++ b/layout/style/nsICSSStyleRuleDOMWrapper.h @@ -18,6 +18,11 @@ #define NS_ICSS_STYLE_RULE_DOM_WRAPPER_IID \ {0xcee1bbb6, 0x0a32, 0x4cf3, {0x8d, 0x42, 0xba, 0x39, 0x38, 0xe9, 0xec, 0xaa}} +namespace mozilla { +namespace css { +class StyleRule; +} // namespace css +} // namespace mozilla class nsICSSStyleRuleDOMWrapper : public nsIDOMCSSStyleRule { public: