summaryrefslogtreecommitdiffstats
path: root/WebCore/dom/TreeWalker.cpp
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2008-10-21 07:00:00 -0700
committerThe Android Open Source Project <initial-contribution@android.com>2008-10-21 07:00:00 -0700
commit9364f22aed35e1a1e9d07c121510f80be3ab0502 (patch)
treed49911209b132da58d838efa852daf28d516df21 /WebCore/dom/TreeWalker.cpp
parent87eb0cb35bad8784770ebc807e6c982432e47107 (diff)
downloadexternal_webkit-9364f22aed35e1a1e9d07c121510f80be3ab0502.zip
external_webkit-9364f22aed35e1a1e9d07c121510f80be3ab0502.tar.gz
external_webkit-9364f22aed35e1a1e9d07c121510f80be3ab0502.tar.bz2
Initial Contribution
Diffstat (limited to 'WebCore/dom/TreeWalker.cpp')
-rw-r--r--WebCore/dom/TreeWalker.cpp258
1 files changed, 59 insertions, 199 deletions
diff --git a/WebCore/dom/TreeWalker.cpp b/WebCore/dom/TreeWalker.cpp
index 09c1c95..ffa8ae7 100644
--- a/WebCore/dom/TreeWalker.cpp
+++ b/WebCore/dom/TreeWalker.cpp
@@ -1,9 +1,11 @@
-/*
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* Copyright (C) 2000 Frederik Holljen (frederik.holljen@hig.no)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
* Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
- * Copyright (C) 2004, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -30,17 +32,15 @@
#include "NodeFilter.h"
#include <wtf/PassRefPtr.h>
-using namespace KJS;
-
namespace WebCore {
-TreeWalker::TreeWalker(PassRefPtr<Node> rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> filter, bool expandEntityReferences)
+TreeWalker::TreeWalker(Node* rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> filter, bool expandEntityReferences)
: Traversal(rootNode, whatToShow, filter, expandEntityReferences)
- , m_current(root())
+ , m_current(rootNode)
{
}
-void TreeWalker::setCurrentNode(PassRefPtr<Node> node, ExceptionCode& ec)
+void TreeWalker::setCurrentNode(Node* node, ExceptionCode& ec)
{
if (!node) {
ec = NOT_SUPPORTED_ERR;
@@ -49,237 +49,97 @@ void TreeWalker::setCurrentNode(PassRefPtr<Node> node, ExceptionCode& ec)
m_current = node;
}
-inline Node* TreeWalker::setCurrent(PassRefPtr<Node> node)
+void TreeWalker::setCurrentNode(Node* node)
{
- m_current = node;
- return m_current.get();
+ ASSERT(node);
+ int dummy;
+ setCurrentNode(node, dummy);
}
-Node* TreeWalker::parentNode(JSValue*& exception)
+Node* TreeWalker::parentNode()
{
- exception = 0;
- RefPtr<Node> node = m_current;
- while (node != root()) {
- node = node->parentNode();
- if (!node)
- return 0;
- short acceptNodeResult = acceptNode(node.get(), exception);
- if (exception)
- return 0;
- if (acceptNodeResult == NodeFilter::FILTER_ACCEPT)
- return setCurrent(node.release());
+ for (Node* node = currentNode()->parentNode(); node && (node == root() || node->isDescendantOf(root())); node = node->parentNode()) {
+ if (acceptNode(node) == NodeFilter::FILTER_ACCEPT) {
+ setCurrentNode(node);
+ return node;
+ }
}
return 0;
}
-Node* TreeWalker::firstChild(JSValue*& exception)
+Node* TreeWalker::firstChild()
{
- exception = 0;
- for (RefPtr<Node> node = m_current->firstChild(); node; ) {
- short acceptNodeResult = acceptNode(node.get(), exception);
- if (exception)
- return 0;
- switch (acceptNodeResult) {
- case NodeFilter::FILTER_ACCEPT:
- m_current = node.release();
- return m_current.get();
- case NodeFilter::FILTER_SKIP:
- if (node->firstChild()) {
- node = node->firstChild();
- continue;
- }
- break;
- case NodeFilter::FILTER_REJECT:
- break;
+ for (Node* node = currentNode()->firstChild(); node && (node == root() || node->isDescendantOf(root())); node = node->nextSibling()) {
+ if (acceptNode(node) == NodeFilter::FILTER_ACCEPT) {
+ setCurrentNode(node);
+ return node;
}
- do {
- if (node->nextSibling()) {
- node = node->nextSibling();
- break;
- }
- Node* parent = node->parentNode();
- if (!parent || parent == root() || parent == m_current)
- return 0;
- node = parent;
- } while (node);
}
return 0;
}
-Node* TreeWalker::lastChild(JSValue*& exception)
+Node* TreeWalker::lastChild()
{
- exception = 0;
- for (RefPtr<Node> node = m_current->lastChild(); node; ) {
- short acceptNodeResult = acceptNode(node.get(), exception);
- if (exception)
- return 0;
- switch (acceptNodeResult) {
- case NodeFilter::FILTER_ACCEPT:
- m_current = node.release();
- return m_current.get();
- case NodeFilter::FILTER_SKIP:
- if (node->lastChild()) {
- node = node->lastChild();
- continue;
- }
- break;
- case NodeFilter::FILTER_REJECT:
- break;
+ for (Node* node = currentNode()->lastChild(); node && (node == root() || node->isDescendantOf(root())); node = node->previousSibling()) {
+ if (acceptNode(node) == NodeFilter::FILTER_ACCEPT) {
+ setCurrentNode(node);
+ return node;
}
- do {
- if (node->previousSibling()) {
- node = node->previousSibling();
- break;
- }
- Node* parent = node->parentNode();
- if (!parent || parent == root() || parent == m_current)
- return 0;
- node = parent;
- } while (node);
}
return 0;
}
-Node* TreeWalker::previousSibling(JSValue*& exception)
+Node* TreeWalker::previousSibling()
{
- exception = 0;
- RefPtr<Node> node = m_current;
- if (node == root())
- return 0;
- while (1) {
- for (RefPtr<Node> sibling = node->previousSibling(); sibling; ) {
- short acceptNodeResult = acceptNode(sibling.get(), exception);
- if (exception)
- 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();
- continue;
- }
- break;
- case NodeFilter::FILTER_REJECT:
- break;
- }
- sibling = sibling->previousSibling();
+ for (Node* node = currentNode()->previousSibling(); node && (node == root() || node->isDescendantOf(root())); node = node->previousSibling()) {
+ if (acceptNode(node) == NodeFilter::FILTER_ACCEPT) {
+ setCurrentNode(node);
+ return node;
}
- node = node->parentNode();
- if (!node || node == root())
- return 0;
- short acceptNodeResult = acceptNode(node.get(), exception);
- if (exception)
- return 0;
- if (acceptNodeResult == NodeFilter::FILTER_ACCEPT)
- return 0;
}
+ return 0;
}
-Node* TreeWalker::nextSibling(JSValue*& exception)
+Node* TreeWalker::nextSibling()
{
- exception = 0;
- RefPtr<Node> node = m_current;
- if (node == root())
- return 0;
- while (1) {
- for (RefPtr<Node> sibling = node->nextSibling(); sibling; ) {
- short acceptNodeResult = acceptNode(sibling.get(), exception);
- if (exception)
- 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();
- continue;
- }
- break;
- case NodeFilter::FILTER_REJECT:
- break;
- }
- sibling = sibling->nextSibling();
+ for (Node* node = currentNode()->nextSibling(); node && (node == root() || node->isDescendantOf(root())); node = node->nextSibling()) {
+ if (acceptNode(node) == NodeFilter::FILTER_ACCEPT) {
+ setCurrentNode(node);
+ return node;
}
- node = node->parentNode();
- if (!node || node == root())
- return 0;
- short acceptNodeResult = acceptNode(node.get(), exception);
- if (exception)
- return 0;
- if (acceptNodeResult == NodeFilter::FILTER_ACCEPT)
- return 0;
}
+ return 0;
}
-Node* TreeWalker::previousNode(JSValue*& exception)
+Node* TreeWalker::previousNode()
{
- exception = 0;
- RefPtr<Node> node = m_current;
- while (node != root()) {
- while (Node* previousSibling = node->previousSibling()) {
- node = previousSibling;
- short acceptNodeResult = acceptNode(node.get(), exception);
- if (exception)
- return 0;
- if (acceptNodeResult == NodeFilter::FILTER_REJECT)
- continue;
- while (Node* lastChild = node->lastChild()) {
- node = lastChild;
- acceptNodeResult = acceptNode(node.get(), exception);
- if (exception)
- return 0;
- if (acceptNodeResult == NodeFilter::FILTER_ACCEPT)
- continue;
- }
- if (acceptNodeResult == NodeFilter::FILTER_ACCEPT) {
- m_current = node.release();
- return m_current.get();
- }
+ for (Node* node = currentNode()->traversePreviousNode(); node && (node == root() || node->isDescendantOf(root())); node = node->traversePreviousNode()) {
+ if (acceptNode(node) == NodeFilter::FILTER_ACCEPT && !ancestorRejected(node)) {
+ setCurrentNode(node);
+ return node;
}
- if (node == root())
- return 0;
- Node* parent = node->parentNode();
- if (!parent)
- return 0;
- node = parent;
- short acceptNodeResult = acceptNode(node.get(), exception);
- if (exception)
- return 0;
- if (acceptNodeResult == NodeFilter::FILTER_ACCEPT)
- return setCurrent(node.release());
}
return 0;
}
-Node* TreeWalker::nextNode(JSValue*& exception)
+Node* TreeWalker::nextNode()
{
- exception = 0;
- RefPtr<Node> node = m_current;
-Children:
- while (Node* firstChild = node->firstChild()) {
- node = firstChild;
- short acceptNodeResult = acceptNode(node.get(), exception);
- if (exception)
- return 0;
- if (acceptNodeResult == NodeFilter::FILTER_ACCEPT)
- return setCurrent(node.release());
- if (acceptNodeResult == NodeFilter::FILTER_REJECT)
- break;
- }
- while (Node* nextSibling = node->traverseNextSibling(root())) {
- node = nextSibling;
- short acceptNodeResult = acceptNode(node.get(), exception);
- if (exception)
- return 0;
- if (acceptNodeResult == NodeFilter::FILTER_ACCEPT)
- return setCurrent(node.release());
- if (acceptNodeResult == NodeFilter::FILTER_SKIP)
- goto Children;
+ for (Node* node = currentNode()->traverseNextNode(); node && (node == root() || node->isDescendantOf(root())); node = node->traverseNextNode()) {
+ if (acceptNode(node) == NodeFilter::FILTER_ACCEPT && !ancestorRejected(node)) {
+ setCurrentNode(node);
+ return node;
+ }
}
return 0;
}
+bool TreeWalker::ancestorRejected(const Node* node) const
+{
+ for (Node* a = node->parentNode(); a && a != root(); a = a->parentNode()) {
+ if (acceptNode(a) == NodeFilter::FILTER_REJECT)
+ return true;
+ }
+ return false;
+}
+
} // namespace WebCore