summaryrefslogtreecommitdiff
path: root/Source/WebCore/dom/TreeWalker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/dom/TreeWalker.cpp')
-rw-r--r--Source/WebCore/dom/TreeWalker.cpp208
1 files changed, 76 insertions, 132 deletions
diff --git a/Source/WebCore/dom/TreeWalker.cpp b/Source/WebCore/dom/TreeWalker.cpp
index 172bc41ad..79e7b16ba 100644
--- a/Source/WebCore/dom/TreeWalker.cpp
+++ b/Source/WebCore/dom/TreeWalker.cpp
@@ -25,59 +25,51 @@
#include "config.h"
#include "TreeWalker.h"
-#include "ExceptionCode.h"
#include "ContainerNode.h"
#include "NodeTraversal.h"
+#include <runtime/JSCJSValueInlines.h>
namespace WebCore {
-TreeWalker::TreeWalker(PassRefPtr<Node> rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> filter, bool expandEntityReferences)
- : NodeIteratorBase(rootNode, whatToShow, filter, expandEntityReferences)
+TreeWalker::TreeWalker(Node& rootNode, unsigned long whatToShow, RefPtr<NodeFilter>&& filter)
+ : NodeIteratorBase(rootNode, whatToShow, WTFMove(filter))
, m_current(root())
{
}
-void TreeWalker::setCurrentNode(PassRefPtr<Node> node, ExceptionCode& ec)
+void TreeWalker::setCurrentNode(Node& node)
{
- if (!node) {
- ec = NOT_SUPPORTED_ERR;
- return;
- }
m_current = node;
}
-inline Node* TreeWalker::setCurrent(PassRefPtr<Node> node)
+inline Node* TreeWalker::setCurrent(Ref<Node>&& node)
{
- m_current = node;
- return m_current.get();
+ m_current = WTFMove(node);
+ return m_current.ptr();
}
-Node* TreeWalker::parentNode(JSC::ExecState* state)
+Node* TreeWalker::parentNode()
{
- RefPtr<Node> node = m_current;
- while (node != root()) {
+ RefPtr<Node> node = m_current.ptr();
+ while (node != &root()) {
node = node->parentNode();
if (!node)
- return 0;
- short acceptNodeResult = acceptNode(state, node.get());
- if (state && state->hadException())
- return 0;
+ return nullptr;
+ short acceptNodeResult = acceptNode(node.get());
if (acceptNodeResult == NodeFilter::FILTER_ACCEPT)
- return setCurrent(node.release());
+ return setCurrent(node.releaseNonNull());
}
- return 0;
+ return nullptr;
}
-Node* TreeWalker::firstChild(JSC::ExecState* state)
+Node* TreeWalker::firstChild()
{
for (RefPtr<Node> node = m_current->firstChild(); node; ) {
- short acceptNodeResult = acceptNode(state, node.get());
- if (state && state->hadException())
- return 0;
+ short acceptNodeResult = acceptNode(node.get());
switch (acceptNodeResult) {
case NodeFilter::FILTER_ACCEPT:
- m_current = node.release();
- return m_current.get();
+ m_current = node.releaseNonNull();
+ return m_current.ptr();
case NodeFilter::FILTER_SKIP:
if (node->firstChild()) {
node = node->firstChild();
@@ -93,24 +85,22 @@ Node* TreeWalker::firstChild(JSC::ExecState* state)
break;
}
ContainerNode* parent = node->parentNode();
- if (!parent || parent == root() || parent == m_current)
- return 0;
+ if (!parent || parent == &root() || parent == m_current.ptr())
+ return nullptr;
node = parent;
} while (node);
}
- return 0;
+ return nullptr;
}
-Node* TreeWalker::lastChild(JSC::ExecState* state)
+Node* TreeWalker::lastChild()
{
for (RefPtr<Node> node = m_current->lastChild(); node; ) {
- short acceptNodeResult = acceptNode(state, node.get());
- if (state && state->hadException())
- return 0;
+ short acceptNodeResult = acceptNode(node.get());
switch (acceptNodeResult) {
case NodeFilter::FILTER_ACCEPT:
- m_current = node.release();
- return m_current.get();
+ m_current = node.releaseNonNull();
+ return m_current.ptr();
case NodeFilter::FILTER_SKIP:
if (node->lastChild()) {
node = node->lastChild();
@@ -126,152 +116,106 @@ Node* TreeWalker::lastChild(JSC::ExecState* state)
break;
}
ContainerNode* parent = node->parentNode();
- if (!parent || parent == root() || parent == m_current)
- return 0;
+ if (!parent || parent == &root() || parent == m_current.ptr())
+ return nullptr;
node = parent;
} while (node);
}
- return 0;
+ return nullptr;
}
-Node* TreeWalker::previousSibling(JSC::ExecState* state)
+template<TreeWalker::SiblingTraversalType type> Node* TreeWalker::traverseSiblings()
{
- RefPtr<Node> node = m_current;
- if (node == root())
- return 0;
- while (1) {
- for (RefPtr<Node> sibling = node->previousSibling(); sibling; ) {
- short acceptNodeResult = acceptNode(state, sibling.get());
- if (state && state->hadException())
- return 0;
- switch (acceptNodeResult) {
- case NodeFilter::FILTER_ACCEPT:
- m_current = sibling.release();
- return m_current.get();
- case NodeFilter::FILTER_SKIP:
- if (sibling->lastChild()) {
- sibling = sibling->lastChild();
- node = sibling;
- continue;
- }
- break;
- case NodeFilter::FILTER_REJECT:
- break;
+ RefPtr<Node> node = m_current.ptr();
+ if (node == &root())
+ return nullptr;
+
+ auto isNext = type == SiblingTraversalType::Next;
+ while (true) {
+ for (RefPtr<Node> sibling = isNext ? node->nextSibling() : node->previousSibling(); sibling; ) {
+ short acceptNodeResult = acceptNode(sibling.get());
+ if (acceptNodeResult == NodeFilter::FILTER_ACCEPT) {
+ m_current = sibling.releaseNonNull();
+ return m_current.ptr();
}
- sibling = sibling->previousSibling();
+ node = sibling;
+ sibling = isNext ? sibling->firstChild() : sibling->lastChild();
+ if (acceptNodeResult == NodeFilter::FILTER_REJECT || !sibling)
+ sibling = isNext ? node->nextSibling() : node->previousSibling();
}
node = node->parentNode();
- if (!node || node == root())
- return 0;
- short acceptNodeResult = acceptNode(state, node.get());
- if (state && state->hadException())
- return 0;
+ if (!node || node == &root())
+ return nullptr;
+ short acceptNodeResult = acceptNode(node.get());
if (acceptNodeResult == NodeFilter::FILTER_ACCEPT)
- return 0;
+ return nullptr;
}
}
-Node* TreeWalker::nextSibling(JSC::ExecState* state)
+Node* TreeWalker::previousSibling()
{
- RefPtr<Node> node = m_current;
- if (node == root())
- return 0;
- while (1) {
- for (RefPtr<Node> sibling = node->nextSibling(); sibling; ) {
- short acceptNodeResult = acceptNode(state, sibling.get());
- if (state && state->hadException())
- return 0;
- switch (acceptNodeResult) {
- case NodeFilter::FILTER_ACCEPT:
- m_current = sibling.release();
- return m_current.get();
- case NodeFilter::FILTER_SKIP:
- if (sibling->firstChild()) {
- sibling = sibling->firstChild();
- node = sibling;
- continue;
- }
- break;
- case NodeFilter::FILTER_REJECT:
- break;
- }
- sibling = sibling->nextSibling();
- }
- node = node->parentNode();
- if (!node || node == root())
- return 0;
- short acceptNodeResult = acceptNode(state, node.get());
- if (state && state->hadException())
- return 0;
- if (acceptNodeResult == NodeFilter::FILTER_ACCEPT)
- return 0;
- }
+ return traverseSiblings<SiblingTraversalType::Previous>();
+}
+
+Node* TreeWalker::nextSibling()
+{
+ return traverseSiblings<SiblingTraversalType::Next>();
}
-Node* TreeWalker::previousNode(JSC::ExecState* state)
+Node* TreeWalker::previousNode()
{
- RefPtr<Node> node = m_current;
- while (node != root()) {
+ RefPtr<Node> node = m_current.ptr();
+ while (node != &root()) {
while (Node* previousSibling = node->previousSibling()) {
node = previousSibling;
- short acceptNodeResult = acceptNode(state, node.get());
- if (state && state->hadException())
- return 0;
+ short acceptNodeResult = acceptNode(node.get());
if (acceptNodeResult == NodeFilter::FILTER_REJECT)
continue;
while (Node* lastChild = node->lastChild()) {
node = lastChild;
- acceptNodeResult = acceptNode(state, node.get());
- if (state && state->hadException())
- return 0;
+ acceptNodeResult = acceptNode(node.get());
if (acceptNodeResult == NodeFilter::FILTER_REJECT)
break;
}
if (acceptNodeResult == NodeFilter::FILTER_ACCEPT) {
- m_current = node.release();
- return m_current.get();
+ m_current = node.releaseNonNull();
+ return m_current.ptr();
}
}
- if (node == root())
- return 0;
+ if (node == &root())
+ return nullptr;
ContainerNode* parent = node->parentNode();
if (!parent)
- return 0;
+ return nullptr;
node = parent;
- short acceptNodeResult = acceptNode(state, node.get());
- if (state && state->hadException())
- return 0;
+ short acceptNodeResult = acceptNode(node.get());
if (acceptNodeResult == NodeFilter::FILTER_ACCEPT)
- return setCurrent(node.release());
+ return setCurrent(node.releaseNonNull());
}
- return 0;
+ return nullptr;
}
-Node* TreeWalker::nextNode(JSC::ExecState* state)
+Node* TreeWalker::nextNode()
{
- RefPtr<Node> node = m_current;
+ RefPtr<Node> node = m_current.ptr();
Children:
while (Node* firstChild = node->firstChild()) {
node = firstChild;
- short acceptNodeResult = acceptNode(state, node.get());
- if (state && state->hadException())
- return 0;
+ short acceptNodeResult = acceptNode(node.get());
if (acceptNodeResult == NodeFilter::FILTER_ACCEPT)
- return setCurrent(node.release());
+ return setCurrent(node.releaseNonNull());
if (acceptNodeResult == NodeFilter::FILTER_REJECT)
break;
}
- while (Node* nextSibling = NodeTraversal::nextSkippingChildren(node.get(), root())) {
+ while (Node* nextSibling = NodeTraversal::nextSkippingChildren(*node, &root())) {
node = nextSibling;
- short acceptNodeResult = acceptNode(state, node.get());
- if (state && state->hadException())
- return 0;
+ short acceptNodeResult = acceptNode(node.get());
if (acceptNodeResult == NodeFilter::FILTER_ACCEPT)
- return setCurrent(node.release());
+ return setCurrent(node.releaseNonNull());
if (acceptNodeResult == NodeFilter::FILTER_SKIP)
goto Children;
}
- return 0;
+ return nullptr;
}
} // namespace WebCore