Implement CSSStyleSheet::replaceSync (#36586)

Implements the `replaceSync` method on CSSStyleSheet

Testing: Covered by wpt tests. Expectations are updated.

Signed-off-by: webbeef <me@webbeef.org>
This commit is contained in:
webbeef 2025-04-23 08:29:01 -07:00 committed by GitHub
parent 5d3cbc67ee
commit 30fdf48ca6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 47 additions and 162 deletions

View file

@ -93,6 +93,7 @@ pub(crate) fn throw_dom_exception(
Error::NotReadable => DOMErrorName::NotReadableError,
Error::Data => DOMErrorName::DataError,
Error::Operation => DOMErrorName::OperationError,
Error::NotAllowed => DOMErrorName::NotAllowedError,
Error::Type(message) => unsafe {
assert!(!JS_IsExceptionPending(*cx));
throw_type_error(*cx, &message);

View file

@ -24,7 +24,7 @@ use crate::dom::bindings::reflector::{
DomGlobal, reflect_dom_object, reflect_dom_object_with_proto,
};
use crate::dom::bindings::root::{DomRoot, MutNullableDom};
use crate::dom::bindings::str::DOMString;
use crate::dom::bindings::str::{DOMString, USVString};
use crate::dom::cssrulelist::{CSSRuleList, RulesSource};
use crate::dom::element::Element;
use crate::dom::medialist::MediaList;
@ -290,4 +290,32 @@ impl CSSStyleSheetMethods<crate::DomTypeHolder> for CSSStyleSheet {
// > 8. Return -1.
Ok(-1)
}
/// <https://drafts.csswg.org/cssom/#synchronously-replace-the-rules-of-a-cssstylesheet>
fn ReplaceSync(&self, text: USVString) -> Result<(), Error> {
// Step 1. If the constructed flag is not set throw a NotAllowedError
if !self.is_constructed {
return Err(Error::NotAllowed);
}
// Step 2. Let rules be the result of running parse a stylesheets contents from text.
let global = self.global();
let window = global.as_window();
StyleStyleSheet::update_from_str(
&self.style_stylesheet,
&text,
UrlExtraData(window.get_url().get_arc()),
None,
window.css_error_reporter(),
AllowImportRules::No, // Step 3.If rules contains one or more @import rules, remove those rules from rules.
);
// Step 4. Set sheets CSS rules to rules.
// We reset our rule list, which will be initialized properly
// at the next getter access.
self.rulelist.set(None);
Ok(())
}
}

View file

@ -53,6 +53,7 @@ pub(crate) enum DOMErrorName {
NotReadableError,
DataError,
OperationError,
NotAllowedError,
}
impl DOMErrorName {
@ -84,6 +85,7 @@ impl DOMErrorName {
"NotReadableError" => Some(DOMErrorName::NotReadableError),
"DataError" => Some(DOMErrorName::DataError),
"OperationError" => Some(DOMErrorName::OperationError),
"NotAllowedError" => Some(DOMErrorName::NotAllowedError),
_ => None,
}
}
@ -135,6 +137,10 @@ impl DOMException {
DOMErrorName::OperationError => {
"The operation failed for an operation-specific reason."
},
DOMErrorName::NotAllowedError => {
r#"The request is not allowed by the user agent or the platform in the current context,
possibly because the user denied permission."#
},
};
(

View file

@ -59,6 +59,8 @@ pub enum Error {
Data,
/// OperationError DOMException
Operation,
/// NotAllowedError DOMException
NotAllowed,
/// TypeError JavaScript Error
Type(String),

View file

@ -11,6 +11,7 @@ interface CSSStyleSheet : StyleSheet {
[Throws, SameObject] readonly attribute CSSRuleList cssRules;
[Throws] unsigned long insertRule(DOMString rule, optional unsigned long index = 0);
[Throws] undefined deleteRule(unsigned long index);
[Throws] undefined replaceSync(USVString text);
};
dictionary CSSStyleSheetInit {

View file

@ -11,12 +11,6 @@
[@function --foo( --x ) is valid]
expected: FAIL
[@function --foo () is invalid]
expected: FAIL
[@function --foo (--x) is invalid]
expected: FAIL
[@function --foo(--x auto) is valid]
expected: FAIL
@ -113,9 +107,6 @@
[@function --foo(--x <angle>: 10px) is valid]
expected: FAIL
[@function --foo(--x: 10px !important) is invalid]
expected: FAIL
[@function --foo(--x <length>#) is valid]
expected: FAIL
@ -131,30 +122,6 @@
[@function --foo(--x <transform-function>+) is valid]
expected: FAIL
[@function --foo(--x <transform-list>#) is invalid]
expected: FAIL
[@function --foo(--x <transform-list>+) is invalid]
expected: FAIL
[@function --foo(--x *) is invalid]
expected: FAIL
[@function --foo(--x !) is invalid]
expected: FAIL
[@function --foo(--x 50px) is invalid]
expected: FAIL
[@function --foo(--x <length> | auto) is invalid]
expected: FAIL
[@function --foo(--x none | auto) is invalid]
expected: FAIL
[@function --foo(--x <dino>) is invalid]
expected: FAIL
[@function --foo(--x) returns type(*) is valid]
expected: FAIL
@ -173,71 +140,5 @@
[@function --foo(--x) returns type(foo | bar) is valid]
expected: FAIL
[@function --foo(--x) ! is invalid]
expected: FAIL
[@function --foo(--x) length is invalid]
expected: FAIL
[@function --foo(--x) returns is invalid]
expected: FAIL
[@function --foo(--x) returns is invalid]
expected: FAIL
[@function --foo(--x) returns * is invalid]
expected: FAIL
[@function --foo(--x) returns <transform-list># is invalid]
expected: FAIL
[@function --foo(--x) returns <transform-list>+ is invalid]
expected: FAIL
[@function --foo(--x) returns auto | none is invalid]
expected: FAIL
[@function --foo(--x): <length> is invalid]
expected: FAIL
[@function --foo(--x): length is invalid]
expected: FAIL
[@function --foo(--x) returneth <length> is invalid]
expected: FAIL
[@function --foo(--x:1px, --y, --z:2px) is valid]
expected: FAIL
[@function --foo(!) is invalid]
expected: FAIL
[@function --foo(--x: !) is invalid]
expected: FAIL
[@function --foo(--x type(!)) is invalid]
expected: FAIL
[@function --foo(,) is invalid]
expected: FAIL
[@function --foo(,,,) is invalid]
expected: FAIL
[@function --foo(--x, ;) is invalid]
expected: FAIL
[@function --foo(;) is invalid]
expected: FAIL
[@function --foo(\]) is invalid]
expected: FAIL
[@function --foo(, --x\]) is invalid]
expected: FAIL
[@function --foo(--x) ! <length> is invalid]
expected: FAIL
[@function --foo(--x) returns <length>! is invalid]
expected: FAIL

View file

@ -1,33 +1,3 @@
[nested-declarations-cssom.html]
[Trailing declarations]
expected: FAIL
[Mixed declarations]
expected: FAIL
[CSSNestedDeclarations.style]
expected: FAIL
[Nested group rule]
expected: FAIL
[Nested @scope rule]
expected: FAIL
[Inner rule starting with an ident]
expected: FAIL
[Inserting a CSSNestedDeclaration rule into style rule]
expected: FAIL
[Inserting a CSSNestedDeclaration rule into nested group rule]
expected: FAIL
[Attempting to insert a CSSNestedDeclaration rule into top-level @media rule]
expected: FAIL
[Attempting to insert a CSSNestedDeclaration rule, empty block]
expected: FAIL
[Attempting to insert a CSSNestedDeclaration rule, all invalid declarations]
expected: FAIL

View file

@ -1,9 +1,3 @@
[CSSStyleSheet-constructable-baseURL.html]
[Constructing sheet with custom base URL ueses that URL for CSS rules]
expected: FAIL
[Constructing sheet with relative URL adds to the constructor document's base URL]
expected: FAIL
[Constructing sheet with invalid base URL throws a NotAllowedError]
expected: FAIL

View file

@ -1,4 +0,0 @@
[CSSStyleSheet-constructable-disabled-regular-sheet-insertion.html]
[Shouldn't crash / assert when inserting a stylesheet after there are disabled constructable sheets]
expected: FAIL

View file

@ -41,9 +41,6 @@
[Adding non-constructed stylesheet to AdoptedStyleSheets is not allowed when the owner document of the stylesheet and the AdoptedStyleSheets are in different document trees]
expected: FAIL
[CSSStyleSheet.replaceSync replaces stylesheet text synchronously]
expected: FAIL
[CSSStyleSheet.replaceSync correctly updates the style of its adopters synchronously]
expected: FAIL
@ -62,9 +59,6 @@
[CSSStyleSheet.replace ignores @import rule but still loads other rules]
expected: FAIL
[CSSStyleSheet.replaceSync allows, but ignores, import rule inside]
expected: FAIL
[CSSStyleSheet.replace does not reject on failed imports]
expected: FAIL
@ -73,9 +67,3 @@
[Adopting a shadow host's ancestor will empty adoptedStyleSheets if adopting to a different document]
expected: FAIL
[Modifying an adopted stylesheet on a disconnected shadow root should not crash.]
expected: FAIL
[Constructing a sheet with the default base URL uses the constructor document's base URL for CSS rules]
expected: FAIL

View file

@ -1,2 +1,9 @@
[adoptedstylesheets-modify-array-and-sheet.html]
expected: ERROR
[Add the two sheets. Text should be red.]
expected: FAIL
[Flip the two sheet. Still red.]
expected: FAIL
[Modify the color declaration. Should now be green.]
expected: FAIL

View file

@ -395,21 +395,12 @@
[CSSStyleSheet interface: operation replace(USVString)]
expected: FAIL
[CSSStyleSheet interface: operation replaceSync(USVString)]
expected: FAIL
[CSSStyleSheet interface: sheet must inherit property "replace(USVString)" with the proper type]
expected: FAIL
[CSSStyleSheet interface: calling replace(USVString) on sheet with too few arguments must throw TypeError]
expected: FAIL
[CSSStyleSheet interface: sheet must inherit property "replaceSync(USVString)" with the proper type]
expected: FAIL
[CSSStyleSheet interface: calling replaceSync(USVString) on sheet with too few arguments must throw TypeError]
expected: FAIL
[Document interface: attribute adoptedStyleSheets]
expected: FAIL