Bug 1787173 - Improve CSS OM for CSSContainerRule. r=nchevobbe

This implements https://github.com/w3c/csswg-drafts/pull/7293, pending a
spec resolution, so landing test as tentative for now, but the change
makes sense.

Differential Revision: https://phabricator.services.mozilla.com/D155602
This commit is contained in:
Emilio Cobos Álvarez 2022-08-26 10:31:38 +00:00
parent 520b9862fc
commit 44438f746a
8 changed files with 81 additions and 4 deletions

View file

@ -10,5 +10,6 @@
// https://drafts.csswg.org/css-contain-3/#the-csscontainerrule-interface
[Exposed=Window, Pref="layout.css.container-queries.enabled"]
interface CSSContainerRule : CSSConditionRule {
readonly attribute UTF8String containerName;
readonly attribute UTF8String containerQuery;
};

View file

@ -55,6 +55,14 @@ void CSSContainerRule::GetCssText(nsACString& aCssText) const {
Servo_ContainerRule_GetCssText(mRawRule, &aCssText);
}
void CSSContainerRule::GetContainerName(nsACString& aName) const {
Servo_ContainerRule_GetContainerName(mRawRule, &aName);
}
void CSSContainerRule::GetContainerQuery(nsACString& aQuery) const {
Servo_ContainerRule_GetContainerQuery(mRawRule, &aQuery);
}
void CSSContainerRule::SetRawAfterClone(RefPtr<RawServoContainerRule> aRaw) {
mRawRule = std::move(aRaw);

View file

@ -32,6 +32,9 @@ class CSSContainerRule final : public css::ConditionRule {
void GetCssText(nsACString& aCssText) const final;
void GetConditionText(nsACString& aConditionText) final;
void GetContainerName(nsACString&) const;
void GetContainerQuery(nsACString&) const;
size_t SizeOfIncludingThis(MallocSizeOf) const override;
JSObject* WrapObject(JSContext* aCx,

View file

@ -47,6 +47,11 @@ impl ContainerRule {
&self.condition.condition
}
/// Returns the query name filter.
pub fn container_name(&self) -> &ContainerName {
&self.condition.name
}
/// Measure heap usage.
#[cfg(feature = "gecko")]
pub fn size_of(&self, guard: &SharedRwLockReadGuard, ops: &mut MallocSizeOfOps) -> usize {
@ -88,10 +93,12 @@ impl ToCssWithGuard for ContainerRule {
}
/// A container condition and filter, combined.
#[derive(Debug, ToShmem)]
#[derive(Debug, ToShmem, ToCss)]
pub struct ContainerCondition {
#[css(skip_if = "ContainerName::is_none")]
name: ContainerName,
condition: QueryCondition,
#[css(skip)]
flags: FeatureFlags,
}

View file

@ -2966,12 +2966,35 @@ pub extern "C" fn Servo_SupportsRule_GetConditionText(
pub extern "C" fn Servo_ContainerRule_GetConditionText(
rule: &RawServoContainerRule,
result: &mut nsACString,
) {
read_locked_arc(rule, |rule: &ContainerRule| {
rule.condition.to_css(&mut CssWriter::new(result)).unwrap();
})
}
#[no_mangle]
pub extern "C" fn Servo_ContainerRule_GetContainerQuery(
rule: &RawServoContainerRule,
result: &mut nsACString,
) {
read_locked_arc(rule, |rule: &ContainerRule| {
rule.query_condition().to_css(&mut CssWriter::new(result)).unwrap();
})
}
#[no_mangle]
pub extern "C" fn Servo_ContainerRule_GetContainerName(
rule: &RawServoContainerRule,
result: &mut nsACString,
) {
read_locked_arc(rule, |rule: &ContainerRule| {
let name = rule.container_name();
if !name.is_none() {
name.to_css(&mut CssWriter::new(result)).unwrap();
}
})
}
#[no_mangle]
pub extern "C" fn Servo_MozDocumentRule_GetConditionText(
rule: &RawServoMozDocumentRule,

View file

@ -1,2 +1,2 @@
prefs: [layout.css.constructable-stylesheets.enabled:true]
prefs: [layout.css.constructable-stylesheets.enabled:true,layout.css.container-queries.enabled:true]
leak-threshold: [default:51200]

View file

@ -36,7 +36,7 @@
assert_equals(rules[0].cssRules.length, 2);
assert_equals(rules[0].conditionText, "(width = 100px)");
assert_equals(rules[0].cssRules[0].conditionText, "(inline-size > 200px)");
assert_equals(rules[0].cssRules[0].conditionText, "\\!-name (inline-size > 200px)");
}, "Serialization of conditionText");
test(() => {

View file

@ -0,0 +1,35 @@
<!doctype html>
<meta charset="utf-8">
<title>CSSContainerRule</title>
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
<link rel="author" title="Mozilla" href="https://mozilla.org">
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#the-csscontainerrule-interface">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<style id="sheet"></style>
<script>
const kTests = [
{
rule: "@container name (min-width: 100px) {}",
name: "name",
query: "(min-width: 100px)",
},
{
rule: "@container (min-width: 100px) {}",
name: "",
query: "(min-width: 100px)",
},
];
const sheet = document.getElementById("sheet").sheet;
for (let { rule, name, query } of kTests) {
test(function() {
sheet.insertRule(rule, 0);
let r = sheet.cssRules[0];
assert_true(r instanceof CSSContainerRule);
assert_equals(r.containerName, name, "containerName");
assert_equals(r.containerQuery, query, "containerQuery");
assert_equals(r.conditionText, name ? `${name} ${query}` : query, "conditionText");
}, rule)
}
</script>