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;