LibWeb/SVG: Process script element when its text content changes

This commit is contained in:
Tim Ledbetter 2025-02-26 12:37:38 +00:00 committed by Jelle Raaijmakers
commit a187d5f28f
Notes: github-actions[bot] 2025-02-26 15:09:59 +00:00
6 changed files with 42 additions and 3 deletions

View file

@ -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] // 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 // FIXME: If the active speculative HTML parser is null
script_element.set_parser_inserted({});
script_element.process_the_script_element(); script_element.process_the_script_element();
// Decrement the parser's script nesting level by one. // Decrement the parser's script nesting level by one.

View file

@ -35,6 +35,24 @@ void SVGScriptElement::visit_edges(Cell::Visitor& visitor)
visitor.visit(m_script); 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 // https://www.w3.org/TR/SVGMobile12/script.html#ScriptContentProcessing
void SVGScriptElement::process_the_script_element() void SVGScriptElement::process_the_script_element()
{ {
@ -114,6 +132,8 @@ void SVGScriptElement::process_the_script_element()
} else { } else {
// Inline script content // Inline script content
script_content = child_text_content(); script_content = child_text_content();
if (script_content.is_empty())
return;
} }
// 3. The 'script' element's "already processed" flag is set to true. // 3. The 'script' element's "already processed" flag is set to true.

View file

@ -21,8 +21,12 @@ class SVGScriptElement
public: public:
void process_the_script_element(); void process_the_script_element();
void set_parser_inserted(Badge<HTML::HTMLParser>) { m_parser_inserted = true; }
void set_source_line_number(Badge<HTML::HTMLParser>, size_t source_line_number) { m_source_line_number = source_line_number; } void set_source_line_number(Badge<HTML::HTMLParser>, size_t source_line_number) { m_source_line_number = source_line_number; }
virtual void inserted() override;
virtual void children_changed(ChildrenChangedMetadata const*) override;
protected: protected:
SVGScriptElement(DOM::Document&, DOM::QualifiedName); SVGScriptElement(DOM::Document&, DOM::QualifiedName);
@ -34,6 +38,7 @@ private:
virtual void visit_edges(Cell::Visitor&) override; virtual void visit_edges(Cell::Visitor&) override;
bool m_already_processed { false }; bool m_already_processed { false };
bool m_parser_inserted { false };
GC::Ptr<HTML::ClassicScript> m_script; GC::Ptr<HTML::ClassicScript> m_script;

View file

@ -0,0 +1 @@
SVG script ran: true

View file

@ -2,10 +2,10 @@ Harness status: OK
Found 5 tests Found 5 tests
4 Pass 3 Pass
1 Fail 2 Fail
Pass SVG scripts with end tag should run Pass SVG scripts with end tag should run
Fail SVG scripts without end tag should not run Fail SVG scripts without end tag should not run
Pass SVG scripts with bogus end tag inside should 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 Pass SVG scripts with self-closing start tag should run

View file

@ -0,0 +1,12 @@
<!DOCTYPE html>
<script src="../include.js"></script>
<div id="script-container"></div>
<script>
let scriptRan = false;
test(() => {
let script = document.createElementNS("http://www.w3.org/2000/svg", "script");
script.textContent = `scriptRan = true;`;
document.getElementById('script-container').appendChild(script);
println(`SVG script ran: ${scriptRan}`);
});
</script>