LibWeb: Implement Text.wholeText

This getter returns the concatenation of the data of the contiguous
Text nodes of `this` (being this plus its siblings) in tree order.
This commit is contained in:
Ángel Carias 2024-07-19 13:57:24 -06:00 committed by Tim Ledbetter
parent 7dacd6be89
commit 69da6a0ce4
Notes: github-actions[bot] 2024-07-20 17:03:45 +00:00
5 changed files with 76 additions and 1 deletions

View File

@ -0,0 +1,6 @@
Text node A with no siblings: A
Text node B with previous sibling A: AB
Text node B with previous sibling A and next sibling C: ABC
CDATA section D with no siblings: D
CDATA section E with previous sibling D: DE
CDATA section E with previous sibling D and next sibling F: DEF

View File

@ -0,0 +1,36 @@
<!DOCTYPE html>
<script src="../include.js"></script>
<script>
test(() => {
// HTML Text Nodes
const fragment = document.createDocumentFragment();
const firstNode = document.createTextNode("A");
fragment.appendChild(firstNode);
println(`Text node ${firstNode.data} with no siblings: ${firstNode.wholeText}`);
const secondNode = document.createTextNode("B");
fragment.appendChild(secondNode);
println(`Text node ${secondNode.data} with previous sibling ${secondNode.previousSibling.data}: ${secondNode.wholeText}`);
const thirdNode = document.createTextNode("C");
fragment.appendChild(thirdNode);
println(`Text node ${secondNode.data} with previous sibling ${secondNode.previousSibling.data} and next sibling ${secondNode.nextSibling.data}: ${secondNode.wholeText}`);
// XML CDATA Sections
const xmlDoc = new DOMParser().parseFromString("<root></root>", "application/xml");
const xmlFrag = xmlDoc.querySelector("root");
const firstSection = xmlDoc.createCDATASection("D");
xmlFrag.appendChild(firstSection);
println(`CDATA section ${firstSection.data} with no siblings: ${firstSection.wholeText}`);
const secondSection = xmlDoc.createCDATASection("E");
xmlFrag.appendChild(secondSection);
println(`CDATA section ${secondSection.data} with previous sibling ${secondSection.previousSibling.data}: ${secondSection.wholeText}`);
const thirdSection = xmlDoc.createCDATASection("F");
xmlFrag.appendChild(thirdSection);
println(`CDATA section ${secondSection.data} with previous sibling ${secondSection.previousSibling.data} and next sibling ${secondSection.nextSibling.data}: ${secondSection.wholeText}`);
});
</script>

View File

@ -117,4 +117,36 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Text>> Text::split_text(size_t offset)
return new_node;
}
// https://dom.spec.whatwg.org/#dom-text-wholetext
String Text::whole_text()
{
// https://dom.spec.whatwg.org/#contiguous-text-nodes
// The contiguous Text nodes of a node node are node, nodes previous sibling Text node, if any, and its contiguous
// Text nodes, and nodes next sibling Text node, if any, and its contiguous Text nodes, avoiding any duplicates.
Vector<Text*> nodes;
nodes.append(this);
auto* current_node = previous_sibling();
while (current_node && (current_node->is_text() || current_node->is_cdata_section())) {
nodes.append(static_cast<Text*>(current_node));
current_node = current_node->previous_sibling();
}
// Reverse nodes so they are in tree order
nodes.reverse();
current_node = next_sibling();
while (current_node && (current_node->is_text() || current_node->is_cdata_section())) {
nodes.append(static_cast<Text*>(current_node));
current_node = current_node->next_sibling();
}
StringBuilder builder;
for (auto const& text_node : nodes)
builder.append(text_node->data());
return MUST(builder.to_string());
}
}

View File

@ -43,6 +43,7 @@ public:
EditableTextNodeOwner* editable_text_node_owner();
WebIDL::ExceptionOr<JS::NonnullGCPtr<Text>> split_text(size_t offset);
String whole_text();
bool is_password_input() const { return m_is_password_input; }
void set_is_password_input(Badge<HTML::HTMLInputElement>, bool b) { m_is_password_input = b; }

View File

@ -8,7 +8,7 @@ interface Text : CharacterData {
constructor(optional DOMString data = "");
[NewObject] Text splitText(unsigned long offset);
[FIXME] readonly attribute DOMString wholeText;
readonly attribute DOMString wholeText;
};
Text includes Slottable;