From a187d5f28fa60a0404dedd4ba8ca4242ac53d570 Mon Sep 17 00:00:00 2001 From: Tim Ledbetter Date: Wed, 26 Feb 2025 12:37:38 +0000 Subject: [PATCH] LibWeb/SVG: Process script element when its text content changes --- Libraries/LibWeb/HTML/Parser/HTMLParser.cpp | 1 + Libraries/LibWeb/SVG/SVGScriptElement.cpp | 20 +++++++++++++++++++ Libraries/LibWeb/SVG/SVGScriptElement.h | 5 +++++ .../SVG/script-element-dynamic-insertion.txt | 1 + .../syntax/parsing/unclosed-svg-script.txt | 6 +++--- .../SVG/script-element-dynamic-insertion.html | 12 +++++++++++ 6 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 Tests/LibWeb/Text/expected/SVG/script-element-dynamic-insertion.txt create mode 100644 Tests/LibWeb/Text/input/SVG/script-element-dynamic-insertion.html diff --git a/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp b/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp index 2e55b80dbe4..c68bb4063a1 100644 --- a/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp +++ b/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp @@ -4308,6 +4308,7 @@ void HTMLParser::process_using_the_rules_for_foreign_content(HTMLToken& token) // If the active speculative HTML parser is null and the user agent supports SVG, then Process the SVG script element according to the SVG rules. [SVG] // FIXME: If the active speculative HTML parser is null + script_element.set_parser_inserted({}); script_element.process_the_script_element(); // Decrement the parser's script nesting level by one. diff --git a/Libraries/LibWeb/SVG/SVGScriptElement.cpp b/Libraries/LibWeb/SVG/SVGScriptElement.cpp index 718de002a10..6b619509ae9 100644 --- a/Libraries/LibWeb/SVG/SVGScriptElement.cpp +++ b/Libraries/LibWeb/SVG/SVGScriptElement.cpp @@ -35,6 +35,24 @@ void SVGScriptElement::visit_edges(Cell::Visitor& visitor) visitor.visit(m_script); } +void SVGScriptElement::inserted() +{ + Base::inserted(); + if (m_parser_inserted) + return; + + process_the_script_element(); +} + +void SVGScriptElement::children_changed(ChildrenChangedMetadata const* metadata) +{ + Base::children_changed(metadata); + if (m_parser_inserted) + return; + + process_the_script_element(); +} + // https://www.w3.org/TR/SVGMobile12/script.html#ScriptContentProcessing void SVGScriptElement::process_the_script_element() { @@ -114,6 +132,8 @@ void SVGScriptElement::process_the_script_element() } else { // Inline script content script_content = child_text_content(); + if (script_content.is_empty()) + return; } // 3. The 'script' element's "already processed" flag is set to true. diff --git a/Libraries/LibWeb/SVG/SVGScriptElement.h b/Libraries/LibWeb/SVG/SVGScriptElement.h index 3815d104a85..941b5a39b40 100644 --- a/Libraries/LibWeb/SVG/SVGScriptElement.h +++ b/Libraries/LibWeb/SVG/SVGScriptElement.h @@ -21,8 +21,12 @@ class SVGScriptElement public: void process_the_script_element(); + void set_parser_inserted(Badge) { m_parser_inserted = true; } void set_source_line_number(Badge, size_t source_line_number) { m_source_line_number = source_line_number; } + virtual void inserted() override; + virtual void children_changed(ChildrenChangedMetadata const*) override; + protected: SVGScriptElement(DOM::Document&, DOM::QualifiedName); @@ -34,6 +38,7 @@ private: virtual void visit_edges(Cell::Visitor&) override; bool m_already_processed { false }; + bool m_parser_inserted { false }; GC::Ptr m_script; diff --git a/Tests/LibWeb/Text/expected/SVG/script-element-dynamic-insertion.txt b/Tests/LibWeb/Text/expected/SVG/script-element-dynamic-insertion.txt new file mode 100644 index 00000000000..25987f890c5 --- /dev/null +++ b/Tests/LibWeb/Text/expected/SVG/script-element-dynamic-insertion.txt @@ -0,0 +1 @@ +SVG script ran: true diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/syntax/parsing/unclosed-svg-script.txt b/Tests/LibWeb/Text/expected/wpt-import/html/syntax/parsing/unclosed-svg-script.txt index 3c683d8b4e3..e0b4d11c311 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/html/syntax/parsing/unclosed-svg-script.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/html/syntax/parsing/unclosed-svg-script.txt @@ -2,10 +2,10 @@ Harness status: OK Found 5 tests -4 Pass -1 Fail +3 Pass +2 Fail Pass SVG scripts with end tag should run Fail SVG scripts without end tag should not run Pass SVG scripts with bogus end tag inside should run -Pass SVG scripts ended by HTML breakout should not run +Fail SVG scripts ended by HTML breakout should not run Pass SVG scripts with self-closing start tag should run \ No newline at end of file diff --git a/Tests/LibWeb/Text/input/SVG/script-element-dynamic-insertion.html b/Tests/LibWeb/Text/input/SVG/script-element-dynamic-insertion.html new file mode 100644 index 00000000000..63976a4b79e --- /dev/null +++ b/Tests/LibWeb/Text/input/SVG/script-element-dynamic-insertion.html @@ -0,0 +1,12 @@ + + +
+