diff --git a/Tests/LibWeb/Text/expected/css/CSSStyleSheet-replaceSync.txt b/Tests/LibWeb/Text/expected/css/CSSStyleSheet-replaceSync.txt new file mode 100644 index 00000000000..cc7d3b5e3fa --- /dev/null +++ b/Tests/LibWeb/Text/expected/css/CSSStyleSheet-replaceSync.txt @@ -0,0 +1,8 @@ +Exception thrown when calling replaceSync() on non-constructed stylesheet: NotAllowedError +Number of CSS rules after replaceSync(): 2 +Rule: .test { font-size: 14px; } +Rule: .test2 { font-size: 16px; } +cssRules returns the same object before and after replaceSync(): true +@import rule should be not appear below: +Rule: .test { padding: 100px; } +Calling replaceSync() while the disallow modification flag set throws: NotAllowedError diff --git a/Tests/LibWeb/Text/input/css/CSSStyleSheet-replaceSync.html b/Tests/LibWeb/Text/input/css/CSSStyleSheet-replaceSync.html new file mode 100644 index 00000000000..1933014b5eb --- /dev/null +++ b/Tests/LibWeb/Text/input/css/CSSStyleSheet-replaceSync.html @@ -0,0 +1,57 @@ + + + + diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp index 13f3604a863..3d5d43f4df0 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp @@ -230,6 +230,33 @@ JS::NonnullGCPtr CSSStyleSheet::replace(String text) return promise; } +// https://drafts.csswg.org/cssom/#dom-cssstylesheet-replacesync +WebIDL::ExceptionOr CSSStyleSheet::replace_sync(StringView text) +{ + // 1. If the constructed flag is not set, or the disallow modification flag is set, throw a NotAllowedError DOMException. + if (!constructed()) + return WebIDL::NotAllowedError::create(realm(), "Can't call replaceSync() on non-constructed stylesheets"_fly_string); + if (disallow_modification()) + return WebIDL::NotAllowedError::create(realm(), "Can't call replaceSync() on non-modifiable stylesheets"_fly_string); + + // 2. Let rules be the result of running parse a stylesheet’s contents from text. + auto context = m_style_sheet_list ? CSS::Parser::ParsingContext { m_style_sheet_list->document() } : CSS::Parser::ParsingContext { realm() }; + auto* parsed_stylesheet = parse_css_stylesheet(context, text); + auto& rules = parsed_stylesheet->rules(); + + // 3. If rules contains one or more @import rules, remove those rules from rules. + JS::MarkedVector> rules_without_import(realm().heap()); + for (auto rule : rules) { + if (rule->type() != CSSRule::Type::Import) + rules_without_import.append(rule); + } + + // 4.Set sheet’s CSS rules to rules. + m_rules->set_rules({}, rules_without_import); + + return {}; +} + // https://www.w3.org/TR/cssom/#dom-cssstylesheet-removerule WebIDL::ExceptionOr CSSStyleSheet::remove_rule(unsigned index) { diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h index 236db5d6b20..b47181e1d6e 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h @@ -53,6 +53,7 @@ public: WebIDL::ExceptionOr delete_rule(unsigned index); JS::NonnullGCPtr replace(String text); + WebIDL::ExceptionOr replace_sync(StringView text); void for_each_effective_style_rule(Function const& callback) const; // Returns whether the match state of any media queries changed after evaluation. diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.idl b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.idl index cdf2450ae78..cd424853ad4 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.idl +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.idl @@ -14,7 +14,7 @@ interface CSSStyleSheet : StyleSheet { undefined deleteRule(unsigned long index); Promise replace(USVString text); - // FIXME: undefined replaceSync(USVString text); + undefined replaceSync(USVString text); // https://drafts.csswg.org/cssom/#legacy-css-style-sheet-members [SameObject, ImplementedAs=css_rules] readonly attribute CSSRuleList rules;