diff --git a/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp b/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp index 75e03e388c..ecff5b9118 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp @@ -25,6 +25,31 @@ bool CSSRuleList::is_supported_property_index(u32 index) const return index < m_rules.size(); } +// https://drafts.csswg.org/cssom/#insert-a-css-rule +DOM::ExceptionOr CSSRuleList::insert_a_css_rule(NonnullRefPtr rule, u32 index) +{ + // 1. Set length to the number of items in list. + auto length = m_rules.size(); + + // 2. If index is greater than length, then throw an IndexSizeError exception. + if (index > length) + return DOM::IndexSizeError::create("CSS rule index out of bounds."); + + // NOTE: These steps don't apply since we're receiving a parsed rule. + // 3. Set new rule to the results of performing parse a CSS rule on argument rule. + // 4. If new rule is a syntax error, throw a SyntaxError exception. + + // FIXME: 5. If new rule cannot be inserted into list at the zero-index position index due to constraints specified by CSS, then throw a HierarchyRequestError exception. [CSS21] + + // FIXME: 6. If new rule is an @namespace at-rule, and list contains anything other than @import at-rules, and @namespace at-rules, throw an InvalidStateError exception. + + // 7. Insert new rule into list at the zero-indexed position index. + m_rules.insert(index, move(rule)); + + // 8. Return index. + return index; +} + // https://drafts.csswg.org/cssom/#remove-a-css-rule DOM::ExceptionOr CSSRuleList::remove_a_css_rule(u32 index) { diff --git a/Userland/Libraries/LibWeb/CSS/CSSRuleList.h b/Userland/Libraries/LibWeb/CSS/CSSRuleList.h index 4ea6430270..c91c721720 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSRuleList.h +++ b/Userland/Libraries/LibWeb/CSS/CSSRuleList.h @@ -48,6 +48,7 @@ public: bool is_supported_property_index(u32 index) const; DOM::ExceptionOr remove_a_css_rule(u32 index); + DOM::ExceptionOr insert_a_css_rule(NonnullRefPtr, u32 index); private: explicit CSSRuleList(NonnullRefPtrVector&&); diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp index 262b058d82..b85bbe13ab 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp @@ -5,6 +5,7 @@ */ #include +#include #include namespace Web::CSS { @@ -25,17 +26,17 @@ DOM::ExceptionOr CSSStyleSheet::insert_rule(StringView rule, unsigned // FIXME: 2. If the disallow modification flag is set, throw a NotAllowedError DOMException. - // Let parsed rule be the return value of invoking parse a rule with rule. + // 3. Let parsed rule be the return value of invoking parse a rule with rule. + auto parsed_rule = parse_css_rule(CSS::ParsingContext {}, rule); - // If parsed rule is a syntax error, return parsed rule. + // 4. If parsed rule is a syntax error, return parsed rule. + if (!parsed_rule) + return DOM::SyntaxError::create("Unable to parse CSS rule."); - // If parsed rule is an @import rule, and the constructed flag is set, throw a SyntaxError DOMException. + // FIXME: 5. If parsed rule is an @import rule, and the constructed flag is set, throw a SyntaxError DOMException. - // Return the result of invoking insert a CSS rule rule in the CSS rules at index. - - (void)index; - (void)rule; - TODO(); + // 6. Return the result of invoking insert a CSS rule rule in the CSS rules at index. + return m_rules->insert_a_css_rule(parsed_rule.release_nonnull(), index); } // https://drafts.csswg.org/cssom/#dom-cssstylesheet-deleterule diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 7ecde84f51..b1eb35e4dc 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -3298,6 +3298,12 @@ RefPtr parse_css_value(CSS::ParsingContext const& context, Stri return parser.parse_as_css_value(property_id); } +RefPtr parse_css_rule(CSS::ParsingContext const& context, StringView css_text) +{ + CSS::Parser parser(context, css_text); + return parser.parse_as_rule(); +} + Optional parse_selector(CSS::ParsingContext const& context, StringView const& selector_text) { CSS::Parser parser(context, selector_text); diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h index 9c357947ec..0e5823caa6 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h @@ -235,6 +235,7 @@ RefPtr parse_css(CSS::ParsingContext const&, StringView cons RefPtr parse_css_declaration(CSS::ParsingContext const&, StringView const&); RefPtr parse_css_value(CSS::ParsingContext const&, StringView const&, CSS::PropertyID property_id = CSS::PropertyID::Invalid); Optional parse_selector(CSS::ParsingContext const&, StringView const&); +RefPtr parse_css_rule(CSS::ParsingContext const&, StringView); RefPtr parse_html_length(DOM::Document const&, StringView const&);