mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 17:17:44 +00:00
LibWeb: Make Node.textContent more spec compliant
The current implementation felt a bit ad-hoc and notably allowed textContent to operate on all node types. It also only returned the child text content of the Node instead of the descendant text content.
This commit is contained in:
parent
d36838d050
commit
5e61382849
4 changed files with 40 additions and 14 deletions
|
@ -98,22 +98,45 @@ const HTML::HTMLElement* Node::enclosing_html_element_with_attribute(const FlySt
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
String Node::text_content() const
|
||||
// https://dom.spec.whatwg.org/#concept-descendant-text-content
|
||||
String Node::descendant_text_content() const
|
||||
{
|
||||
StringBuilder builder;
|
||||
for (auto* child = first_child(); child; child = child->next_sibling()) {
|
||||
builder.append(child->text_content());
|
||||
}
|
||||
for_each_in_subtree_of_type<Text>([&](auto& text_node) {
|
||||
builder.append(text_node.data());
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
return builder.to_string();
|
||||
}
|
||||
|
||||
void Node::set_text_content(const String& content)
|
||||
// https://dom.spec.whatwg.org/#dom-node-textcontent
|
||||
String Node::text_content() const
|
||||
{
|
||||
if (is_text()) {
|
||||
verify_cast<Text>(this)->set_data(content);
|
||||
if (is<DocumentFragment>(this) || is<Element>(this))
|
||||
return descendant_text_content();
|
||||
else if (is<CharacterData>(this))
|
||||
return verify_cast<CharacterData>(this)->data();
|
||||
|
||||
// FIXME: Else if this is an Attr node, return this's value.
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#ref-for-dom-node-textcontent%E2%91%A0
|
||||
void Node::set_text_content(String const& content)
|
||||
{
|
||||
if (is<DocumentFragment>(this) || is<Element>(this)) {
|
||||
string_replace_all(content);
|
||||
} else if (is<CharacterData>(this)) {
|
||||
// FIXME: CharacterData::set_data is not spec compliant. Make this match the spec when set_data becomes spec compliant.
|
||||
// Do note that this will make this function able to throw an exception.
|
||||
|
||||
auto* character_data_node = verify_cast<CharacterData>(this);
|
||||
character_data_node->set_data(content);
|
||||
} else {
|
||||
remove_all_children();
|
||||
append_child(document().create_text_node(content));
|
||||
// FIXME: Else if this is an Attr node, set an existing attribute value with this and the given value.
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
set_needs_style_update(true);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue