RefPtr<Text> Text::replaceWholeText(const String& newText, ExceptionCode&) { // Remove all adjacent text nodes, and replace the contents of this one. // Protect startText and endText against mutation event handlers removing the last ref RefPtr<Text> startText = const_cast<Text*>(earliestLogicallyAdjacentTextNode(this)); RefPtr<Text> endText = const_cast<Text*>(latestLogicallyAdjacentTextNode(this)); RefPtr<Text> protectedThis(this); // Mutation event handlers could cause our last ref to go away RefPtr<ContainerNode> parent = parentNode(); // Protect against mutation handlers moving this node during traversal for (RefPtr<Node> n = startText; n && n != this && n->isTextNode() && n->parentNode() == parent;) { RefPtr<Node> nodeToRemove(n.release()); n = nodeToRemove->nextSibling(); parent->removeChild(nodeToRemove.get(), IGNORE_EXCEPTION); } if (this != endText) { Node* onePastEndText = endText->nextSibling(); for (RefPtr<Node> n = nextSibling(); n && n != onePastEndText && n->isTextNode() && n->parentNode() == parent;) { RefPtr<Node> nodeToRemove(n.release()); n = nodeToRemove->nextSibling(); parent->removeChild(nodeToRemove.get(), IGNORE_EXCEPTION); } } if (newText.isEmpty()) { if (parent && parentNode() == parent) parent->removeChild(this, IGNORE_EXCEPTION); return 0; } setData(newText, IGNORE_EXCEPTION); return protectedThis.release(); }
String Text::wholeText() const { const Text* startText = earliestLogicallyAdjacentTextNode(this); const Text* endText = latestLogicallyAdjacentTextNode(this); Node* onePastEndText = endText->nextSibling(); unsigned resultLength = 0; for (const Node* n = startText; n != onePastEndText; n = n->nextSibling()) { if (!n->isTextNode()) continue; const String& data = toText(n)->data(); if (std::numeric_limits<unsigned>::max() - data.length() < resultLength) CRASH(); resultLength += data.length(); } StringBuilder result; result.reserveCapacity(resultLength); for (const Node* n = startText; n != onePastEndText; n = n->nextSibling()) { if (!n->isTextNode()) continue; result.append(toText(n)->data()); } ASSERT(result.length() == resultLength); return result.toString(); }
String Text::wholeText() const { const Text* startText = earliestLogicallyAdjacentTextNode(this); const Text* endText = latestLogicallyAdjacentTextNode(this); Node* onePastEndText = endText->nextSibling(); unsigned resultLength = 0; for (const Node* n = startText; n != onePastEndText; n = n->nextSibling()) { if (!n->isTextNode()) continue; const Text* t = static_cast<const Text*>(n); const String& data = t->data(); resultLength += data.length(); } UChar* resultData; String result = String::createUninitialized(resultLength, resultData); UChar* p = resultData; for (const Node* n = startText; n != onePastEndText; n = n->nextSibling()) { if (!n->isTextNode()) continue; const Text* t = static_cast<const Text*>(n); const String& data = t->data(); unsigned dataLength = data.length(); memcpy(p, data.characters(), dataLength * sizeof(UChar)); p += dataLength; } ASSERT(p == resultData + resultLength); return result; }
String Text::wholeText() const { const Text* startText = earliestLogicallyAdjacentTextNode(this); const Text* endText = latestLogicallyAdjacentTextNode(this); Node* onePastEndText = endText->nextSibling(); Checked<unsigned> resultLength = 0; for (const Node* n = startText; n != onePastEndText; n = n->nextSibling()) { if (!n->isTextNode()) continue; const Text* t = static_cast<const Text*>(n); const String& data = t->data(); resultLength += data.length(); } StringBuilder result; result.reserveCapacity(resultLength.unsafeGet()); for (const Node* n = startText; n != onePastEndText; n = n->nextSibling()) { if (!n->isTextNode()) continue; const Text* t = static_cast<const Text*>(n); result.append(t->data()); } ASSERT(result.length() == resultLength.unsafeGet()); return result.toString(); }
String Text::wholeText() const { const Text* startText = earliestLogicallyAdjacentTextNode(this); const Text* endText = latestLogicallyAdjacentTextNode(this); const Node* onePastEndText = TextNodeTraversal::nextSibling(endText); StringBuilder result; for (const Text* text = startText; text != onePastEndText; text = TextNodeTraversal::nextSibling(text)) result.append(text->data()); return result.toString(); }
String Text::wholeText() const { const Text* startText = earliestLogicallyAdjacentTextNode(this); const Text* endText = latestLogicallyAdjacentTextNode(this); Vector<UChar> result; Node* onePastEndText = endText->nextSibling(); for (const Node* n = startText; n != onePastEndText; n = n->nextSibling()) { if (!n->isTextNode()) continue; const Text* t = static_cast<const Text*>(n); const String& data = t->data(); result.append(data.characters(), data.length()); } return String::adopt(result); }