Add basic support for enumerating computed styles (#31499)

* Add basic support for enumerating computed styles

The old code was so broken, it was enumerating the style attribute
instead of the computed styles.

So this patch implements a basic enumeration, but not including custom
properties whose computed value is not the guaranteed-invalid value.

* Feedback
This commit is contained in:
Oriol Brufau 2024-03-06 22:43:06 +01:00 committed by GitHub
parent 6283146829
commit ea38d8ad6f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 175 additions and 224 deletions

View file

@ -2,8 +2,11 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::cmp::Ordering;
use dom_struct::dom_struct;
use html5ever::local_name;
use lazy_static::lazy_static;
use servo_arc::Arc;
use servo_url::ServoUrl;
use style::attr::AttrValue;
@ -342,9 +345,44 @@ impl CSSStyleDeclaration {
}
}
lazy_static! {
static ref ENABLED_LONGHAND_PROPERTIES: Vec<LonghandId> = {
// The 'all' shorthand contains all the enabled longhands with 2 exceptions:
// 'direction' and 'unicode-bidi', so these must be added afterward.
let mut enabled_longhands: Vec<LonghandId> = ShorthandId::All.longhands().collect();
if PropertyId::Longhand(LonghandId::Direction).enabled_for_all_content() {
enabled_longhands.push(LonghandId::Direction);
}
if PropertyId::Longhand(LonghandId::UnicodeBidi).enabled_for_all_content() {
enabled_longhands.push(LonghandId::UnicodeBidi);
}
// Sort lexicographically, but with vendor-prefixed properties after standard ones.
enabled_longhands.sort_unstable_by(|a, b| {
let a = a.name();
let b = b.name();
let is_a_vendor_prefixed = a.starts_with("-");
let is_b_vendor_prefixed = b.starts_with("-");
if is_a_vendor_prefixed == is_b_vendor_prefixed {
a.partial_cmp(b).unwrap()
} else if is_b_vendor_prefixed {
Ordering::Less
} else {
Ordering::Greater
}
});
enabled_longhands
};
}
impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-length
fn Length(&self) -> u32 {
if self.readonly {
// Readonly style declarations are used for getComputedStyle.
// TODO: include custom properties whose computed value is not the guaranteed-invalid value.
return ENABLED_LONGHAND_PROPERTIES.len() as u32;
}
self.owner.with_block(|pdb| pdb.declarations().len() as u32)
}
@ -364,6 +402,10 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertypriority
fn GetPropertyPriority(&self, property: DOMString) -> DOMString {
if self.readonly {
// Readonly style declarations are used for getComputedStyle.
return DOMString::new();
}
let id = match PropertyId::parse_enabled_for_all_content(&property) {
Ok(id) => id,
Err(..) => return DOMString::new(),
@ -432,6 +474,12 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
// https://dev.w3.org/csswg/cssom/#the-cssstyledeclaration-interface
fn IndexedGetter(&self, index: u32) -> Option<DOMString> {
if self.readonly {
// Readonly style declarations are used for getComputedStyle.
// TODO: include custom properties whose computed value is not the guaranteed-invalid value.
let longhand = ENABLED_LONGHAND_PROPERTIES.get(index as usize)?;
return Some(DOMString::from(longhand.name()));
}
self.owner.with_block(|pdb| {
let declaration = pdb.declarations().get(index as usize)?;
Some(DOMString::from(declaration.id().name()))
@ -440,6 +488,10 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
// https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-csstext
fn CssText(&self) -> DOMString {
if self.readonly {
// Readonly style declarations are used for getComputedStyle.
return DOMString::new();
}
self.owner.with_block(|pdb| {
let mut serialization = String::new();
pdb.to_css(&mut serialization).unwrap();

View file

@ -0,0 +1,3 @@
[all-prop-initial-xml.html]
[height]
expected: FAIL

View file

@ -1,2 +1,30 @@
[all-prop-revert-layer.html]
expected: TIMEOUT
[margin-top]
expected: FAIL
[margin-right]
expected: FAIL
[margin-bottom]
expected: FAIL
[margin-left]
expected: FAIL
[padding-top]
expected: FAIL
[padding-right]
expected: FAIL
[padding-bottom]
expected: FAIL
[padding-left]
expected: FAIL
[width]
expected: FAIL
[height]
expected: FAIL

View file

@ -0,0 +1,6 @@
[all-prop-revert-noop.html?include=3]
[input]
expected: FAIL
[textarea]
expected: FAIL

View file

@ -1,90 +0,0 @@
[getComputedStyle-listing.html]
[border-block-end-color]
expected: FAIL
[border-block-end-style]
expected: FAIL
[border-block-end-width]
expected: FAIL
[border-block-start-color]
expected: FAIL
[border-block-start-style]
expected: FAIL
[border-block-start-width]
expected: FAIL
[border-inline-end-color]
expected: FAIL
[border-inline-end-style]
expected: FAIL
[border-inline-end-width]
expected: FAIL
[border-inline-start-color]
expected: FAIL
[border-inline-start-style]
expected: FAIL
[border-inline-start-width]
expected: FAIL
[inset-block-start]
expected: FAIL
[inset-block-end]
expected: FAIL
[inset-inline-start]
expected: FAIL
[inset-inline-end]
expected: FAIL
[margin-block-start]
expected: FAIL
[margin-block-end]
expected: FAIL
[margin-inline-start]
expected: FAIL
[margin-inline-end]
expected: FAIL
[padding-block-start]
expected: FAIL
[padding-block-end]
expected: FAIL
[padding-inline-start]
expected: FAIL
[padding-inline-end]
expected: FAIL
[block-size]
expected: FAIL
[inline-size]
expected: FAIL
[max-block-size]
expected: FAIL
[max-inline-size]
expected: FAIL
[min-block-size]
expected: FAIL
[min-inline-size]
expected: FAIL

View file

@ -0,0 +1,2 @@
[compute-kind-widget-no-fallback-props-001.html]
expected: FAIL

View file

@ -1,3 +0,0 @@
[cssstyledeclaration-csstext-all-shorthand.html]
['all' shorthand with all longhands]
expected: FAIL

View file

@ -1,4 +0,0 @@
[cssstyledeclaration-csstext.html]
[cssText on computed style declaration returns the empty string]
expected: FAIL

View file

@ -0,0 +1,3 @@
[cssstyledeclaration-custom-properties.html]
[Custom properties are included in computed style]
expected: FAIL

View file

@ -6,3 +6,5 @@
[getComputedStyle returns no style for element in non-rendered iframe (display: none)]
expected: FAIL
[getComputedStyle returns no style for detached element]
expected: FAIL

View file

@ -1,12 +0,0 @@
[getComputedStyle-getter-v-properties.tentative.html]
[margin-top]
expected: FAIL
[font-size]
expected: FAIL
[max-width]
expected: FAIL
[width]
expected: FAIL

View file

@ -1,4 +0,0 @@
[getComputedStyle-logical-enumeration.html]
[Logical properties in enumeration of computed style]
expected: FAIL

View file

@ -13,3 +13,30 @@
[This pseudo-element should parse: ::highlight( n\\61me )]
expected: FAIL
[This pseudo-element should not parse: ::before(test)]
expected: FAIL
[This pseudo-element should not parse: ::highlight]
expected: FAIL
[This pseudo-element should not parse: ::highlight(]
expected: FAIL
[This pseudo-element should not parse: ::highlight()]
expected: FAIL
[This pseudo-element should not parse: ::highlight(1)]
expected: FAIL
[This pseudo-element should not parse: ::highlight($)]
expected: FAIL
[This pseudo-element should not parse: ::highlight (name)]
expected: FAIL
[This pseudo-element should not parse: ::highlight(name)a]
expected: FAIL
[This pseudo-element should not parse: ::view-transition-group(*)]
expected: FAIL

View file

@ -1,2 +1,12 @@
[all-prop-revert-layer.html]
expected: TIMEOUT
[block-size]
expected: FAIL
[inline-size]
expected: FAIL
[width]
expected: FAIL
[height]
expected: FAIL

View file

@ -0,0 +1,6 @@
[all-prop-revert-noop.html?include=3]
[input]
expected: FAIL
[textarea]
expected: FAIL

View file

@ -1,90 +0,0 @@
[getComputedStyle-listing.html]
[border-block-end-color]
expected: FAIL
[border-block-end-style]
expected: FAIL
[border-block-end-width]
expected: FAIL
[border-block-start-color]
expected: FAIL
[border-block-start-style]
expected: FAIL
[border-block-start-width]
expected: FAIL
[border-inline-end-color]
expected: FAIL
[border-inline-end-style]
expected: FAIL
[border-inline-end-width]
expected: FAIL
[border-inline-start-color]
expected: FAIL
[border-inline-start-style]
expected: FAIL
[border-inline-start-width]
expected: FAIL
[inset-block-start]
expected: FAIL
[inset-block-end]
expected: FAIL
[inset-inline-start]
expected: FAIL
[inset-inline-end]
expected: FAIL
[margin-block-start]
expected: FAIL
[margin-block-end]
expected: FAIL
[margin-inline-start]
expected: FAIL
[margin-inline-end]
expected: FAIL
[padding-block-start]
expected: FAIL
[padding-block-end]
expected: FAIL
[padding-inline-start]
expected: FAIL
[padding-inline-end]
expected: FAIL
[block-size]
expected: FAIL
[inline-size]
expected: FAIL
[max-block-size]
expected: FAIL
[max-inline-size]
expected: FAIL
[min-block-size]
expected: FAIL
[min-inline-size]
expected: FAIL

View file

@ -0,0 +1,2 @@
[compute-kind-widget-no-fallback-props-001.html]
expected: FAIL

View file

@ -1,3 +0,0 @@
[cssstyledeclaration-csstext.html]
[cssText on computed style declaration returns the empty string]
expected: FAIL

View file

@ -0,0 +1,3 @@
[cssstyledeclaration-custom-properties.html]
[Custom properties are included in computed style]
expected: FAIL

View file

@ -6,3 +6,5 @@
[getComputedStyle returns no style for element in non-rendered iframe (display: none)]
expected: FAIL
[getComputedStyle returns no style for detached element]
expected: FAIL

View file

@ -1,12 +0,0 @@
[getComputedStyle-getter-v-properties.tentative.html]
[margin-top]
expected: FAIL
[font-size]
expected: FAIL
[max-width]
expected: FAIL
[width]
expected: FAIL

View file

@ -1,4 +0,0 @@
[getComputedStyle-logical-enumeration.html]
[Logical properties in enumeration of computed style]
expected: FAIL

View file

@ -13,3 +13,30 @@
[This pseudo-element should parse: ::highlight( n\\61me )]
expected: FAIL
[This pseudo-element should not parse: ::before(test)]
expected: FAIL
[This pseudo-element should not parse: ::highlight]
expected: FAIL
[This pseudo-element should not parse: ::highlight(]
expected: FAIL
[This pseudo-element should not parse: ::highlight()]
expected: FAIL
[This pseudo-element should not parse: ::highlight(1)]
expected: FAIL
[This pseudo-element should not parse: ::highlight($)]
expected: FAIL
[This pseudo-element should not parse: ::highlight (name)]
expected: FAIL
[This pseudo-element should not parse: ::highlight(name)a]
expected: FAIL
[This pseudo-element should not parse: ::view-transition-group(*)]
expected: FAIL