Skip to content

Commit f289eeb

Browse files
committed
Bug 1744292 - Implement @Custom-Media queries. r=firefox-style-system-reviewers,layout-reviewers,webidl,smaug,dshin
Unfortunately the existing WPT test coverage is rather lacking so we need to fix that before enabling. Differential Revision: https://phabricator.services.mozilla.com/D270675
1 parent de5612d commit f289eeb

33 files changed

+773
-211
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2+
/* This Source Code Form is subject to the terms of the Mozilla Public
3+
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
4+
* You can obtain one at http://mozilla.org/MPL/2.0/.
5+
*
6+
* The origin of this IDL file is
7+
* https://drafts.csswg.org/cssom/#the-cssmediarule-interface
8+
* https://drafts.csswg.org/css-conditional/#the-cssmediarule-interface
9+
*/
10+
11+
typedef (MediaList or boolean) CustomMediaQuery;
12+
13+
// https://drafts.csswg.org/mediaqueries-5/#csscustommediarule
14+
[Exposed=Window, Pref="layout.css.custom-media.enabled"]
15+
interface CSSCustomMediaRule : CSSRule {
16+
readonly attribute UTF8String name;
17+
readonly attribute CustomMediaQuery query;
18+
};

dom/webidl/moz.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,7 @@ WEBIDL_FILES = [
493493
"CSSConditionRule.webidl",
494494
"CSSContainerRule.webidl",
495495
"CSSCounterStyleRule.webidl",
496+
"CSSCustomMediaRule.webidl",
496497
"CSSFontFaceRule.webidl",
497498
"CSSFontFeatureValuesRule.webidl",
498499
"CSSFontPaletteValuesRule.webidl",

layout/inspector/InspectorUtils.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,7 @@ static uint32_t CollectAtRules(ServoCSSRuleList& aRuleList,
573573
(void)aResult.AppendElement(OwningNonNull(*rule), fallible);
574574
break;
575575
}
576+
case StyleCssRuleType::CustomMedia:
576577
case StyleCssRuleType::Style:
577578
case StyleCssRuleType::Import:
578579
case StyleCssRuleType::Document:

layout/inspector/ServoStyleRuleMap.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ void ServoStyleRuleMap::RuleRemoved(StyleSheet& aStyleSheet,
9696
mTable.Clear();
9797
break;
9898
}
99+
case StyleCssRuleType::CustomMedia:
99100
case StyleCssRuleType::LayerStatement:
100101
case StyleCssRuleType::FontFace:
101102
case StyleCssRuleType::Page:
@@ -162,6 +163,7 @@ void ServoStyleRuleMap::FillTableFromRule(css::Rule& aRule) {
162163
}
163164
break;
164165
}
166+
case StyleCssRuleType::CustomMedia:
165167
case StyleCssRuleType::LayerStatement:
166168
case StyleCssRuleType::FontFace:
167169
case StyleCssRuleType::Page:
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2+
/* vim: set ts=2 et sw=2 tw=80: */
3+
/* This Source Code Form is subject to the terms of the Mozilla Public
4+
* License, v. 2.0. If a copy of the MPL was not distributed with this
5+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6+
7+
#include "mozilla/dom/CSSCustomMediaRule.h"
8+
9+
#include "mozilla/DeclarationBlock.h"
10+
#include "mozilla/ServoBindings.h"
11+
#include "mozilla/dom/CSSCustomMediaRuleBinding.h"
12+
#include "mozilla/dom/CSSCustomMediaRuleBindingFwd.h"
13+
#include "mozilla/dom/MediaList.h"
14+
15+
namespace mozilla::dom {
16+
17+
CSSCustomMediaRule::CSSCustomMediaRule(RefPtr<StyleCustomMediaRule> aRawRule,
18+
StyleSheet* aSheet,
19+
css::Rule* aParentRule, uint32_t aLine,
20+
uint32_t aColumn)
21+
: css::Rule(aSheet, aParentRule, aLine, aColumn),
22+
mRawRule(std::move(aRawRule)) {}
23+
24+
CSSCustomMediaRule::~CSSCustomMediaRule() {
25+
if (mMediaList) {
26+
mMediaList->SetStyleSheet(nullptr);
27+
}
28+
}
29+
30+
NS_IMPL_ADDREF_INHERITED(CSSCustomMediaRule, Rule)
31+
NS_IMPL_RELEASE_INHERITED(CSSCustomMediaRule, Rule)
32+
33+
NS_IMPL_CYCLE_COLLECTION_CLASS(CSSCustomMediaRule)
34+
35+
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CSSCustomMediaRule)
36+
NS_INTERFACE_MAP_END_INHERITING(Rule)
37+
38+
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(CSSCustomMediaRule, css::Rule)
39+
if (tmp->mMediaList) {
40+
tmp->mMediaList->SetStyleSheet(nullptr);
41+
tmp->mMediaList = nullptr;
42+
}
43+
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
44+
45+
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSCustomMediaRule, css::Rule)
46+
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMediaList)
47+
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
48+
49+
bool CSSCustomMediaRule::IsCCLeaf() const {
50+
return Rule::IsCCLeaf() && !mMediaList;
51+
}
52+
53+
/* virtual */
54+
void CSSCustomMediaRule::DropSheetReference() {
55+
if (mMediaList) {
56+
mMediaList->SetStyleSheet(nullptr);
57+
}
58+
Rule::DropSheetReference();
59+
}
60+
61+
void CSSCustomMediaRule::SetRawAfterClone(RefPtr<StyleCustomMediaRule> aRaw) {
62+
mRawRule = std::move(aRaw);
63+
if (mMediaList) {
64+
mMediaList->SetRawAfterClone(
65+
Servo_CustomMediaRule_GetCondition(mRawRule, nullptr).Consume());
66+
mMediaList->SetStyleSheet(nullptr);
67+
mMediaList->SetStyleSheet(GetStyleSheet());
68+
}
69+
}
70+
71+
// WebIDL interfaces
72+
StyleCssRuleType CSSCustomMediaRule::Type() const {
73+
return StyleCssRuleType::CustomMedia;
74+
}
75+
76+
// CSSRule implementation
77+
78+
void CSSCustomMediaRule::GetCssText(nsACString& aCssText) const {
79+
Servo_CustomMediaRule_GetCssText(mRawRule, &aCssText);
80+
}
81+
82+
void CSSCustomMediaRule::GetName(nsACString& aName) const {
83+
auto* name = Servo_CustomMediaRule_GetName(mRawRule);
84+
name->ToUTF8String(aName);
85+
}
86+
87+
void CSSCustomMediaRule::GetQuery(OwningCustomMediaQuery& aQuery) {
88+
if (mMediaList) {
89+
aQuery.SetAsMediaList() = mMediaList;
90+
return;
91+
}
92+
bool value = false;
93+
RefPtr rawMediaList =
94+
Servo_CustomMediaRule_GetCondition(mRawRule, &value).Consume();
95+
if (!rawMediaList) {
96+
aQuery.SetAsBoolean() = value;
97+
return;
98+
}
99+
100+
mMediaList = new MediaList(rawMediaList.forget());
101+
mMediaList->SetStyleSheet(GetStyleSheet());
102+
aQuery.SetAsMediaList() = mMediaList;
103+
}
104+
105+
size_t CSSCustomMediaRule::SizeOfIncludingThis(
106+
MallocSizeOf aMallocSizeOf) const {
107+
// TODO Implement this!
108+
return aMallocSizeOf(this);
109+
}
110+
111+
#ifdef DEBUG
112+
void CSSCustomMediaRule::List(FILE* out, int32_t aIndent) const {
113+
nsAutoCString str;
114+
for (int32_t i = 0; i < aIndent; i++) {
115+
str.AppendLiteral(" ");
116+
}
117+
Servo_CustomMediaRule_Debug(mRawRule, &str);
118+
fprintf_stderr(out, "%s\n", str.get());
119+
}
120+
#endif
121+
122+
JSObject* CSSCustomMediaRule::WrapObject(JSContext* aCx,
123+
JS::Handle<JSObject*> aGivenProto) {
124+
return CSSCustomMediaRule_Binding::Wrap(aCx, this, aGivenProto);
125+
}
126+
127+
} // namespace mozilla::dom

layout/style/CSSCustomMediaRule.h

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2+
/* vim: set ts=2 et sw=2 tw=80: */
3+
/* This Source Code Form is subject to the terms of the Mozilla Public
4+
* License, v. 2.0. If a copy of the MPL was not distributed with this
5+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6+
7+
#ifndef mozilla_dom_CSSCustomMediaRule_h
8+
#define mozilla_dom_CSSCustomMediaRule_h
9+
10+
#include "mozilla/ServoBindingTypes.h"
11+
#include "mozilla/css/Rule.h"
12+
#include "mozilla/dom/CSSCustomMediaRuleBindingFwd.h"
13+
14+
namespace mozilla::dom {
15+
16+
class CSSCustomMediaRule final : public css::Rule {
17+
public:
18+
CSSCustomMediaRule(RefPtr<StyleCustomMediaRule> aRawRule, StyleSheet* aSheet,
19+
css::Rule* aParentRule, uint32_t aLine, uint32_t aColumn);
20+
21+
NS_DECL_ISUPPORTS_INHERITED
22+
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(CSSCustomMediaRule, css::Rule)
23+
24+
void DropSheetReference() final;
25+
bool IsCCLeaf() const final;
26+
27+
StyleCustomMediaRule* Raw() const { return mRawRule; }
28+
void SetRawAfterClone(RefPtr<StyleCustomMediaRule>);
29+
30+
// WebIDL interfaces
31+
StyleCssRuleType Type() const final;
32+
void GetCssText(nsACString& aCssText) const final;
33+
34+
void GetName(nsACString&) const;
35+
void GetQuery(OwningCustomMediaQuery&);
36+
37+
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const final;
38+
39+
#ifdef DEBUG
40+
void List(FILE* out = stdout, int32_t aIndent = 0) const final;
41+
#endif
42+
43+
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) final;
44+
45+
private:
46+
~CSSCustomMediaRule();
47+
48+
RefPtr<StyleCustomMediaRule> mRawRule;
49+
RefPtr<dom::MediaList> mMediaList;
50+
};
51+
52+
} // namespace mozilla::dom
53+
54+
#endif // mozilla_dom_CSSCustomMediaRule_h

layout/style/ServoBindingTypes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ UNLOCKED_RULE_TYPE(Namespace)
126126
UNLOCKED_RULE_TYPE(Margin)
127127
UNLOCKED_RULE_TYPE(Container)
128128
UNLOCKED_RULE_TYPE(Media)
129+
UNLOCKED_RULE_TYPE(CustomMedia)
129130
UNLOCKED_RULE_TYPE(Supports)
130131
UNLOCKED_RULE_TYPE(Document)
131132
UNLOCKED_RULE_TYPE(FontFeatureValues)

layout/style/ServoBindings.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ GROUP_RULE_FUNCS_UNLOCKED(Media)
7979
GROUP_RULE_FUNCS_UNLOCKED(Document)
8080
BASIC_RULE_FUNCS_UNLOCKED(Namespace)
8181
BASIC_RULE_FUNCS_UNLOCKED(Margin)
82+
BASIC_RULE_FUNCS_UNLOCKED(CustomMedia)
8283
GROUP_RULE_FUNCS_LOCKED(Page)
8384
BASIC_RULE_FUNCS_UNLOCKED(Property)
8485
GROUP_RULE_FUNCS_UNLOCKED(Supports)

layout/style/ServoCSSRuleList.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "mozilla/StyleSheet.h"
1313
#include "mozilla/dom/CSSContainerRule.h"
1414
#include "mozilla/dom/CSSCounterStyleRule.h"
15+
#include "mozilla/dom/CSSCustomMediaRule.h"
1516
#include "mozilla/dom/CSSFontFaceRule.h"
1617
#include "mozilla/dom/CSSFontFeatureValuesRule.h"
1718
#include "mozilla/dom/CSSFontPaletteValuesRule.h"
@@ -107,6 +108,7 @@ css::Rule* ServoCSSRuleList::GetRule(uint32_t aIndex) {
107108
CASE_RULE_UNLOCKED(StartingStyle, StartingStyle)
108109
CASE_RULE_LOCKED(PositionTry, PositionTry)
109110
CASE_RULE_LOCKED(NestedDeclarations, NestedDeclarations)
111+
CASE_RULE_UNLOCKED(CustomMedia, CustomMedia)
110112
#undef CASE_RULE_LOCKED
111113
#undef CASE_RULE_UNLOCKED
112114
#undef CASE_RULE_WITH_PREFIX
@@ -286,6 +288,7 @@ void ServoCSSRuleList::SetRawContents(RefPtr<StyleLockedCssRules> aNewRules,
286288
RULE_CASE_UNLOCKED(StartingStyle, StartingStyle)
287289
RULE_CASE_LOCKED(PositionTry, PositionTry)
288290
RULE_CASE_LOCKED(NestedDeclarations, NestedDeclarations)
291+
RULE_CASE_UNLOCKED(CustomMedia, CustomMedia)
289292
case StyleCssRuleType::Keyframe:
290293
MOZ_ASSERT_UNREACHABLE("keyframe rule cannot be here");
291294
break;

layout/style/ServoStyleConstsInlines.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ template struct StyleStrong<StyleLockedStyleRule>;
4444
template struct StyleStrong<StyleLockedImportRule>;
4545
template struct StyleStrong<StyleLockedKeyframesRule>;
4646
template struct StyleStrong<StyleMediaRule>;
47+
template struct StyleStrong<StyleCustomMediaRule>;
4748
template struct StyleStrong<StyleDocumentRule>;
4849
template struct StyleStrong<StyleNamespaceRule>;
4950
template struct StyleStrong<StyleMarginRule>;

0 commit comments

Comments
 (0)