LibWeb: Add ad-hoc method for serializing CDATASection nodes to string

Previously, CDATASection nodes were being serialized as if they were
text, which meant they were missing their start and end delimiters.
Occurrences of the '&', '<' and '>' characters were also being replaced
with their entity names.
This commit is contained in:
Tim Ledbetter 2024-02-18 14:27:25 +00:00 committed by Andreas Kling
parent 70b9cddc48
commit 1a249f9d85
Notes: sideshowbarker 2024-07-17 06:40:35 +09:00

View File

@ -161,6 +161,7 @@ static WebIDL::ExceptionOr<String> serialize_text(DOM::Text const& text, Require
static WebIDL::ExceptionOr<String> serialize_document_fragment(DOM::DocumentFragment const& document_fragment, Optional<FlyString>& namespace_, HashMap<FlyString, Vector<Optional<FlyString>>>& namespace_prefix_map, u64& prefix_index, RequireWellFormed require_well_formed); static WebIDL::ExceptionOr<String> serialize_document_fragment(DOM::DocumentFragment const& document_fragment, Optional<FlyString>& namespace_, HashMap<FlyString, Vector<Optional<FlyString>>>& namespace_prefix_map, u64& prefix_index, RequireWellFormed require_well_formed);
static WebIDL::ExceptionOr<String> serialize_document_type(DOM::DocumentType const& document_type, RequireWellFormed require_well_formed); static WebIDL::ExceptionOr<String> serialize_document_type(DOM::DocumentType const& document_type, RequireWellFormed require_well_formed);
static WebIDL::ExceptionOr<String> serialize_processing_instruction(DOM::ProcessingInstruction const& processing_instruction, RequireWellFormed require_well_formed); static WebIDL::ExceptionOr<String> serialize_processing_instruction(DOM::ProcessingInstruction const& processing_instruction, RequireWellFormed require_well_formed);
static WebIDL::ExceptionOr<String> serialize_cdata_section(DOM::CDATASection const& cdata_section, RequireWellFormed require_well_formed);
// https://w3c.github.io/DOM-Parsing/#dfn-xml-serialization-algorithm // https://w3c.github.io/DOM-Parsing/#dfn-xml-serialization-algorithm
WebIDL::ExceptionOr<String> serialize_node_to_xml_string_impl(JS::NonnullGCPtr<DOM::Node const> root, Optional<FlyString>& namespace_, HashMap<FlyString, Vector<Optional<FlyString>>>& namespace_prefix_map, u64& prefix_index, RequireWellFormed require_well_formed) WebIDL::ExceptionOr<String> serialize_node_to_xml_string_impl(JS::NonnullGCPtr<DOM::Node const> root, Optional<FlyString>& namespace_, HashMap<FlyString, Vector<Optional<FlyString>>>& namespace_prefix_map, u64& prefix_index, RequireWellFormed require_well_formed)
@ -194,7 +195,7 @@ WebIDL::ExceptionOr<String> serialize_node_to_xml_string_impl(JS::NonnullGCPtr<D
return serialize_comment(static_cast<DOM::Comment const&>(*root), require_well_formed); return serialize_comment(static_cast<DOM::Comment const&>(*root), require_well_formed);
} }
if (is<DOM::Text>(*root) || is<DOM::CDATASection>(*root)) { if (is<DOM::Text>(*root)) {
// -> Text // -> Text
// Run the algorithm for XML serializing a Text node node. // Run the algorithm for XML serializing a Text node node.
return serialize_text(static_cast<DOM::Text const&>(*root), require_well_formed); return serialize_text(static_cast<DOM::Text const&>(*root), require_well_formed);
@ -218,6 +219,12 @@ WebIDL::ExceptionOr<String> serialize_node_to_xml_string_impl(JS::NonnullGCPtr<D
return serialize_processing_instruction(static_cast<DOM::ProcessingInstruction const&>(*root), require_well_formed); return serialize_processing_instruction(static_cast<DOM::ProcessingInstruction const&>(*root), require_well_formed);
} }
if (is<DOM::CDATASection>(*root)) {
// Note: Serialization of CDATASection nodes is not mentioned in the specification, but treating CDATASection nodes as
// text leads to incorrect serialization.
return serialize_cdata_section(static_cast<DOM::CDATASection const&>(*root), require_well_formed);
}
if (is<DOM::Attr>(*root)) { if (is<DOM::Attr>(*root)) {
// -> An Attr object // -> An Attr object
// Return an empty string. // Return an empty string.
@ -898,4 +905,18 @@ static WebIDL::ExceptionOr<String> serialize_processing_instruction(DOM::Process
return MUST(markup.to_string()); return MUST(markup.to_string());
} }
// FIXME: This is ad-hoc
static WebIDL::ExceptionOr<String> serialize_cdata_section(DOM::CDATASection const& cdata_section, RequireWellFormed require_well_formed)
{
if (require_well_formed == RequireWellFormed::Yes && cdata_section.data().contains("]]>"sv))
return WebIDL::InvalidStateError::create(cdata_section.realm(), "CDATA section data contains a CDATA section end delimiter"_fly_string);
StringBuilder markup;
markup.append("<![CDATA["sv);
markup.append(cdata_section.data());
markup.append("]]>"sv);
return MUST(markup.to_string());
}
} }