From 8cfef678c8f8f21cc34eb0491f76dbd413ad32d5 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Fri, 13 Jan 2017 10:41:03 -0500 Subject: [PATCH] Bug 851892 part 9. Add a CSSRule Web IDL interface. r=peterv,heycam Note that this explicitly drops CSSRule.UNKNOWN_RULE. --- dom/bindings/Bindings.conf | 6 ++- dom/webidl/CSSRule.webidl | 52 ++++++++++++++++++++++++++ dom/webidl/CSSStyleDeclaration.webidl | 2 - dom/webidl/CSSStyleSheet.webidl | 2 - dom/webidl/StyleRuleChangeEvent.webidl | 2 - dom/webidl/StyleSheet.webidl | 2 - dom/webidl/moz.build | 1 + layout/style/CSSRuleList.h | 5 ++- layout/style/CSSStyleSheet.cpp | 6 +-- layout/style/CSSStyleSheet.h | 2 +- layout/style/Rule.h | 19 ++++++++++ layout/style/ServoCSSRuleList.cpp | 7 +--- layout/style/ServoCSSRuleList.h | 2 +- layout/style/ServoStyleSheet.cpp | 3 +- layout/style/ServoStyleSheet.h | 3 +- layout/style/StyleSheet.h | 6 ++- layout/style/nsCSSRules.cpp | 31 ++++++++++++++- 17 files changed, 125 insertions(+), 26 deletions(-) create mode 100644 dom/webidl/CSSRule.webidl diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index a30617fdb40b..7f5f27ee2b6c 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -204,6 +204,11 @@ DOMInterfaces = { 'nativeType': 'nsROCSSPrimitiveValue', }, +'CSSRule': { + 'hasXPConnectImpls': True, + 'nativeType': 'mozilla::css::Rule' +}, + 'CSSStyleDeclaration': { 'nativeType': 'nsICSSDeclaration' }, @@ -1660,7 +1665,6 @@ def addExternalIface(iface, nativeType=None, headerFile=None, addExternalIface('ApplicationCache', nativeType='nsIDOMOfflineResourceList') addExternalIface('Counter') -addExternalIface('CSSRule') addExternalIface('RTCDataChannel', nativeType='nsIDOMDataChannel') addExternalIface('HitRegionOptions', nativeType='nsISupports') addExternalIface('imgINotificationObserver', nativeType='imgINotificationObserver') diff --git a/dom/webidl/CSSRule.webidl b/dom/webidl/CSSRule.webidl new file mode 100644 index 000000000000..6c4dac2e6280 --- /dev/null +++ b/dom/webidl/CSSRule.webidl @@ -0,0 +1,52 @@ +/* -*- 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-cssrule-interface + * https://drafts.csswg.org/css-animations/#interface-cssrule + * https://drafts.csswg.org/css-counter-styles-3/#extentions-to-cssrule-interface + * https://drafts.csswg.org/css-conditional-3/#extentions-to-cssrule-interface + * https://drafts.csswg.org/css-fonts-3/#om-fontfeaturevalues + */ + +// https://drafts.csswg.org/cssom/#the-cssrule-interface +interface CSSRule { + + const unsigned short STYLE_RULE = 1; + const unsigned short CHARSET_RULE = 2; // historical + const unsigned short IMPORT_RULE = 3; + const unsigned short MEDIA_RULE = 4; + const unsigned short FONT_FACE_RULE = 5; + const unsigned short PAGE_RULE = 6; + // FIXME: We don't support MARGIN_RULE yet. + // XXXbz Should we expose the constant anyway? + // const unsigned short MARGIN_RULE = 9; + const unsigned short NAMESPACE_RULE = 10; + readonly attribute unsigned short type; + attribute DOMString cssText; + readonly attribute CSSRule? parentRule; + readonly attribute CSSStyleSheet? parentStyleSheet; +}; + +// https://drafts.csswg.org/css-animations/#interface-cssrule +partial interface CSSRule { + const unsigned short KEYFRAMES_RULE = 7; + const unsigned short KEYFRAME_RULE = 8; +}; + +// https://drafts.csswg.org/css-counter-styles-3/#extentions-to-cssrule-interface +partial interface CSSRule { + const unsigned short COUNTER_STYLE_RULE = 11; +}; + +// https://drafts.csswg.org/css-conditional-3/#extentions-to-cssrule-interface +partial interface CSSRule { + const unsigned short SUPPORTS_RULE = 12; +}; + +// https://drafts.csswg.org/css-fonts-3/#om-fontfeaturevalues +partial interface CSSRule { + const unsigned short FONT_FEATURE_VALUES_RULE = 14; +}; diff --git a/dom/webidl/CSSStyleDeclaration.webidl b/dom/webidl/CSSStyleDeclaration.webidl index d9b2511ded8c..0c95d6c9f5c3 100644 --- a/dom/webidl/CSSStyleDeclaration.webidl +++ b/dom/webidl/CSSStyleDeclaration.webidl @@ -7,8 +7,6 @@ * http://dev.w3.org/csswg/cssom/ */ -interface CSSRule; - interface CSSStyleDeclaration { [SetterThrows] attribute DOMString cssText; diff --git a/dom/webidl/CSSStyleSheet.webidl b/dom/webidl/CSSStyleSheet.webidl index 48fb89db1252..f51b89cd184f 100644 --- a/dom/webidl/CSSStyleSheet.webidl +++ b/dom/webidl/CSSStyleSheet.webidl @@ -7,8 +7,6 @@ * http://dev.w3.org/csswg/cssom/ */ -interface CSSRule; - enum CSSStyleSheetParsingMode { "author", "user", diff --git a/dom/webidl/StyleRuleChangeEvent.webidl b/dom/webidl/StyleRuleChangeEvent.webidl index 0b783366ba59..ef35bae6486c 100644 --- a/dom/webidl/StyleRuleChangeEvent.webidl +++ b/dom/webidl/StyleRuleChangeEvent.webidl @@ -3,8 +3,6 @@ * 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/. */ -interface CSSRule; - [ChromeOnly, Constructor(DOMString type, optional StyleRuleChangeEventInit eventInitDict)] interface StyleRuleChangeEvent : Event { diff --git a/dom/webidl/StyleSheet.webidl b/dom/webidl/StyleSheet.webidl index 71a8ccd8f470..26c2fbb999bd 100644 --- a/dom/webidl/StyleSheet.webidl +++ b/dom/webidl/StyleSheet.webidl @@ -7,8 +7,6 @@ * http://dev.w3.org/csswg/cssom/ */ -interface CSSRule; - interface StyleSheet { [Constant] readonly attribute DOMString type; diff --git a/dom/webidl/moz.build b/dom/webidl/moz.build index 4238276a6ab3..83ffd095cb26 100644 --- a/dom/webidl/moz.build +++ b/dom/webidl/moz.build @@ -92,6 +92,7 @@ WEBIDL_FILES = [ 'CSSLexer.webidl', 'CSSPrimitiveValue.webidl', 'CSSPseudoElement.webidl', + 'CSSRule.webidl', 'CSSRuleList.webidl', 'CSSStyleDeclaration.webidl', 'CSSStyleSheet.webidl', diff --git a/layout/style/CSSRuleList.h b/layout/style/CSSRuleList.h index f056d111520f..f1001fdb4b9f 100644 --- a/layout/style/CSSRuleList.h +++ b/layout/style/CSSRuleList.h @@ -7,6 +7,7 @@ #define mozilla_dom_CSSRuleList_h #include "mozilla/StyleSheetInlines.h" +#include "mozilla/css/Rule.h" #include "nsIDOMCSSRule.h" #include "nsIDOMCSSRuleList.h" #include "nsWrapperCache.h" @@ -45,13 +46,13 @@ public: } // WebIDL API - nsIDOMCSSRule* Item(uint32_t aIndex) + css::Rule* Item(uint32_t aIndex) { bool unused; return IndexedGetter(aIndex, unused); } - virtual nsIDOMCSSRule* IndexedGetter(uint32_t aIndex, bool& aFound) = 0; + virtual css::Rule* IndexedGetter(uint32_t aIndex, bool& aFound) = 0; virtual uint32_t Length() = 0; protected: diff --git a/layout/style/CSSStyleSheet.cpp b/layout/style/CSSStyleSheet.cpp index 4f26527e252c..4af47860b085 100644 --- a/layout/style/CSSStyleSheet.cpp +++ b/layout/style/CSSStyleSheet.cpp @@ -61,7 +61,7 @@ public: virtual CSSStyleSheet* GetParentObject() override; - virtual nsIDOMCSSRule* + virtual css::Rule* IndexedGetter(uint32_t aIndex, bool& aFound) override; virtual uint32_t Length() override; @@ -101,7 +101,7 @@ CSSRuleListImpl::Length() return AssertedCast(mStyleSheet->StyleRuleCount()); } -nsIDOMCSSRule* +css::Rule* CSSRuleListImpl::IndexedGetter(uint32_t aIndex, bool& aFound) { aFound = false; @@ -875,7 +875,7 @@ CSSStyleSheet::RegisterNamespaceRule(css::Rule* aRule) return NS_OK; } -nsIDOMCSSRule* +css::Rule* CSSStyleSheet::GetDOMOwnerRule() const { return mOwnerRule; diff --git a/layout/style/CSSStyleSheet.h b/layout/style/CSSStyleSheet.h index 4d2b52cbe645..a17f610520b7 100644 --- a/layout/style/CSSStyleSheet.h +++ b/layout/style/CSSStyleSheet.h @@ -194,7 +194,7 @@ public: // Can't be inline because we can't include ImportRule here. And can't be // called GetOwnerRule because that would be ambiguous with the ImportRule // version. - nsIDOMCSSRule* GetDOMOwnerRule() const final; + css::Rule* GetDOMOwnerRule() const final; void WillDirty(); void DidDirty(); diff --git a/layout/style/Rule.h b/layout/style/Rule.h index 5ec846794b8c..37446d6459c8 100644 --- a/layout/style/Rule.h +++ b/layout/style/Rule.h @@ -115,6 +115,11 @@ public: // WebIDL interface, aka helpers for nsIDOMCSSRule implementation. virtual uint16_t Type() const = 0; virtual void GetCssTextImpl(nsAString& aCssText) const = 0; + // XPCOM GetCssText is OK, since it never throws. + // XPCOM SetCssText is OK, since it never throws. + Rule* GetParentRule() const; + StyleSheet* GetParentStyleSheet() const { return GetStyleSheet(); } + nsIDocument* GetParentObject() const { return GetDocument(); } protected: // This is sometimes null (e.g., for style attributes). @@ -131,4 +136,18 @@ protected: } // namespace css } // namespace mozilla +// Specialization of the bindings UnwrapArg setup for css::Rule, so we can avoid +// adding an IID to css::Rule. This can go away once all css::Rule subclasses +// are on WebIDL bindings. + +#include "js/TypeDecls.h" + +namespace mozilla { +namespace dom { +template <> +nsresult +UnwrapArg(JS::Handle src, css::Rule** ppArg); +} // namepace dom +} // namespace mozilla + #endif /* mozilla_css_Rule_h___ */ diff --git a/layout/style/ServoCSSRuleList.cpp b/layout/style/ServoCSSRuleList.cpp index 42d411b802ac..7f7c07a6b481 100644 --- a/layout/style/ServoCSSRuleList.cpp +++ b/layout/style/ServoCSSRuleList.cpp @@ -79,7 +79,7 @@ ServoCSSRuleList::GetRule(uint32_t aIndex) return CastToPtr(rule); } -nsIDOMCSSRule* +css::Rule* ServoCSSRuleList::IndexedGetter(uint32_t aIndex, bool& aFound) { if (aIndex >= mRules.Length()) { @@ -87,10 +87,7 @@ ServoCSSRuleList::IndexedGetter(uint32_t aIndex, bool& aFound) return nullptr; } aFound = true; - if (css::Rule* rule = GetRule(aIndex)) { - return rule; - } - return nullptr; + return GetRule(aIndex); } template diff --git a/layout/style/ServoCSSRuleList.h b/layout/style/ServoCSSRuleList.h index 56a8583c4fcf..fcc18190e2e7 100644 --- a/layout/style/ServoCSSRuleList.h +++ b/layout/style/ServoCSSRuleList.h @@ -30,7 +30,7 @@ public: ServoStyleSheet* GetParentObject() final { return mStyleSheet; } - nsIDOMCSSRule* IndexedGetter(uint32_t aIndex, bool& aFound) final; + css::Rule* IndexedGetter(uint32_t aIndex, bool& aFound) final; uint32_t Length() final { return mRules.Length(); } void DropReference(); diff --git a/layout/style/ServoStyleSheet.cpp b/layout/style/ServoStyleSheet.cpp index 7a96485d4b08..61b270e372d1 100644 --- a/layout/style/ServoStyleSheet.cpp +++ b/layout/style/ServoStyleSheet.cpp @@ -145,9 +145,10 @@ ServoStyleSheet::List(FILE* aOut, int32_t aIndex) const } #endif -nsIDOMCSSRule* +css::Rule* ServoStyleSheet::GetDOMOwnerRule() const { + NS_ERROR("stylo: Don't know how to get DOM owner rule for ServoStyleSheet"); return nullptr; } diff --git a/layout/style/ServoStyleSheet.h b/layout/style/ServoStyleSheet.h index 7d82bdcc25f2..ed2bf23b0214 100644 --- a/layout/style/ServoStyleSheet.h +++ b/layout/style/ServoStyleSheet.h @@ -20,6 +20,7 @@ class ServoCSSRuleList; namespace css { class Loader; +class Rule; } /** @@ -73,7 +74,7 @@ public: // Can't be inline because we can't include ImportRule here. And can't be // called GetOwnerRule because that would be ambiguous with the ImportRule // version. - nsIDOMCSSRule* GetDOMOwnerRule() const final; + css::Rule* GetDOMOwnerRule() const final; void WillDirty() {} void DidDirty() {} diff --git a/layout/style/StyleSheet.h b/layout/style/StyleSheet.h index b12200c75fd5..d231caf20c2b 100644 --- a/layout/style/StyleSheet.h +++ b/layout/style/StyleSheet.h @@ -33,6 +33,10 @@ class CSSRuleList; class SRIMetadata; } // namespace dom +namespace css { +class Rule; +} + /** * Superclass for data common to CSSStyleSheet and ServoStyleSheet. */ @@ -148,7 +152,7 @@ public: // The XPCOM SetDisabled is fine for WebIDL. // WebIDL CSSStyleSheet API - virtual nsIDOMCSSRule* GetDOMOwnerRule() const = 0; + virtual css::Rule* GetDOMOwnerRule() const = 0; dom::CSSRuleList* GetCssRules(nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv); uint32_t InsertRule(const nsAString& aRule, uint32_t aIndex, diff --git a/layout/style/nsCSSRules.cpp b/layout/style/nsCSSRules.cpp index 35ba9906edee..b009ea19b660 100644 --- a/layout/style/nsCSSRules.cpp +++ b/layout/style/nsCSSRules.cpp @@ -43,6 +43,27 @@ using namespace mozilla::dom; // base class for all rule types in a CSS style sheet +// Temporary code that can go away once all css::Rules are on WebIDL bindings. +#include "xpcpublic.h" +namespace mozilla { +namespace dom { +template<> +nsresult +UnwrapArg(JS::Handle src, css::Rule** ppArg) +{ + MOZ_ASSERT(NS_IsMainThread()); + nsCOMPtr rule = + do_QueryInterface(xpc::UnwrapReflectorToISupports(src)); + if (!rule) { + return NS_NOINTERFACE; + } + *ppArg = rule->GetCSSRule(); + NS_ADDREF(*ppArg); + return NS_OK; +} +} // namespace dom +} // namespace mozilla + namespace mozilla { namespace css { @@ -110,6 +131,12 @@ Rule::GetCssText(nsAString& aCssText) return NS_OK; } +Rule* +Rule::GetParentRule() const +{ + return mParentRule; +} + // ------------------------------- // Style Rule List for group rules // @@ -121,7 +148,7 @@ public: virtual CSSStyleSheet* GetParentObject() override; - virtual nsIDOMCSSRule* + virtual Rule* IndexedGetter(uint32_t aIndex, bool& aFound) override; virtual uint32_t Length() override; @@ -166,7 +193,7 @@ GroupRuleRuleList::Length() return AssertedCast(mGroupRule->StyleRuleCount()); } -nsIDOMCSSRule* +Rule* GroupRuleRuleList::IndexedGetter(uint32_t aIndex, bool& aFound) { aFound = false;