[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.15-1-40151-g37bb677
kocienda
kocienda at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 08:38:09 UTC 2009
The following commit has been merged in the debian/unstable branch:
commit f6ea03efc9d9af982ab8e9e6cd95a9e010654587
Author: kocienda <kocienda at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Tue May 4 22:38:00 2004 +0000
WebCore:
Reviewed by Hyatt
Implemented DOM traversal objects, NodeIterator and TreeWalker.
* WebCore-combined.exp: Regenerate
* WebCore.exp: Export DOMNodeFilter protocol
* khtml/dom/dom2_traversal.cpp: Completed half-done implementation pulled from KDE tree.
* khtml/dom/dom2_traversal.h: Ditto.
* khtml/dom/dom_doc.cpp:
(DOM::Document::createNodeIterator): Ditto.
(DOM::Document::createTreeWalker): Ditto.
* khtml/dom/dom_doc.h: Ditto.
* khtml/ecma/kjs_dom.cpp:
(DOMDocumentProtoFunc::tryCall): Fix cases that create traversal objects.
* khtml/ecma/kjs_traversal.cpp:
(DOMNodeIterator::getValueProperty): Add referenceNode and pointerBeforeReferenceNode
properties to node interator.
(DOMTreeWalkerProtoFunc::tryCall): Fix typo where DOMTreeWalker::PreviousNode case called previousSibling function.
(JSNodeFilterCondition::JSNodeFilterCondition): Implement JS glue class for node filter conditions.
(JSNodeFilterCondition::acceptNode): Ditto.
* khtml/ecma/kjs_traversal.h:
(KJS::DOMNodeIterator::): Add ReferenceNode and PointerBeforeReferenceNode constants.
* khtml/ecma/kjs_traversal.lut.h:
(KJS::): Regenerated
* khtml/xml/dom2_traversalimpl.cpp: Completed half-done implementation pulled from KDE tree.
* khtml/xml/dom2_traversalimpl.h: Ditto.
* khtml/xml/dom_docimpl.cpp:
(DocumentImpl::createNodeIterator): Ditto.
(DocumentImpl::createTreeWalker): Ditto.
* khtml/xml/dom_docimpl.h: Ditto.
* khtml/xml/dom_nodeimpl.cpp:
(NodeImpl::checkAddChild): Patched due to change in isAncestor function. This was the one pre-existing caller.
(NodeImpl::isAncestor): Changed so that it does not return true for itself: node->isAncestor(node) now returns false.
* khtml/xml/dom_nodeimpl.h: Made isAncestor const.
* kwq/DOM.mm: Implemented obj-c glue for traversal objects.
* kwq/DOMInternal.h: Ditto.
* kwq/DOMTraversal.h: Ditto.
WebKit:
Reviewed by Hyatt
* DOM.subproj/DOMTraversal.h: File coppied from WebCore
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@6535 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index ece2764..97b61d1 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,43 @@
+2004-05-04 Ken Kocienda <kocienda at apple.com>
+
+ Reviewed by Hyatt
+
+ Implemented DOM traversal objects, NodeIterator and TreeWalker.
+
+ * WebCore-combined.exp: Regenerate
+ * WebCore.exp: Export DOMNodeFilter protocol
+ * khtml/dom/dom2_traversal.cpp: Completed half-done implementation pulled from KDE tree.
+ * khtml/dom/dom2_traversal.h: Ditto.
+ * khtml/dom/dom_doc.cpp:
+ (DOM::Document::createNodeIterator): Ditto.
+ (DOM::Document::createTreeWalker): Ditto.
+ * khtml/dom/dom_doc.h: Ditto.
+ * khtml/ecma/kjs_dom.cpp:
+ (DOMDocumentProtoFunc::tryCall): Fix cases that create traversal objects.
+ * khtml/ecma/kjs_traversal.cpp:
+ (DOMNodeIterator::getValueProperty): Add referenceNode and pointerBeforeReferenceNode
+ properties to node interator.
+ (DOMTreeWalkerProtoFunc::tryCall): Fix typo where DOMTreeWalker::PreviousNode case called previousSibling function.
+ (JSNodeFilterCondition::JSNodeFilterCondition): Implement JS glue class for node filter conditions.
+ (JSNodeFilterCondition::acceptNode): Ditto.
+ * khtml/ecma/kjs_traversal.h:
+ (KJS::DOMNodeIterator::): Add ReferenceNode and PointerBeforeReferenceNode constants.
+ * khtml/ecma/kjs_traversal.lut.h:
+ (KJS::): Regenerated
+ * khtml/xml/dom2_traversalimpl.cpp: Completed half-done implementation pulled from KDE tree.
+ * khtml/xml/dom2_traversalimpl.h: Ditto.
+ * khtml/xml/dom_docimpl.cpp:
+ (DocumentImpl::createNodeIterator): Ditto.
+ (DocumentImpl::createTreeWalker): Ditto.
+ * khtml/xml/dom_docimpl.h: Ditto.
+ * khtml/xml/dom_nodeimpl.cpp:
+ (NodeImpl::checkAddChild): Patched due to change in isAncestor function. This was the one pre-existing caller.
+ (NodeImpl::isAncestor): Changed so that it does not return true for itself: node->isAncestor(node) now returns false.
+ * khtml/xml/dom_nodeimpl.h: Made isAncestor const.
+ * kwq/DOM.mm: Implemented obj-c glue for traversal objects.
+ * kwq/DOMInternal.h: Ditto.
+ * kwq/DOMTraversal.h: Ditto.
+
2004-05-04 Darin Adler <darin at apple.com>
Reviewed by Ken.
diff --git a/WebCore/WebCore.exp b/WebCore/WebCore.exp
index ec5626f..0a0e4c6 100644
--- a/WebCore/WebCore.exp
+++ b/WebCore/WebCore.exp
@@ -1,5 +1,6 @@
.objc_class_name_DOMImplementation
.objc_class_name_DOMNode
+.objc_class_name_DOMNodeFilter
.objc_class_name_DOMNodeList
.objc_class_name_DOMNamedNodeMap
.objc_class_name_DOMCharacterData
diff --git a/WebCore/WebCore.pbproj/project.pbxproj b/WebCore/WebCore.pbproj/project.pbxproj
index 7871e3f..e55eb4b 100644
--- a/WebCore/WebCore.pbproj/project.pbxproj
+++ b/WebCore/WebCore.pbproj/project.pbxproj
@@ -865,7 +865,7 @@
isa = PBXShellScriptBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "if [ -f ../Tools/Scripts/embed-into-alex ]; then sh ../Tools/Scripts/embed-into-alex; fi";
+ shellScript = "#if [ -f ../Tools/Scripts/embed-into-alex ]; then sh ../Tools/Scripts/embed-into-alex; fi";
};
//250
//251
diff --git a/WebCore/khtml/dom/dom2_traversal.cpp b/WebCore/khtml/dom/dom2_traversal.cpp
index 4ad0b0f..ce15be8 100644
--- a/WebCore/khtml/dom/dom2_traversal.cpp
+++ b/WebCore/khtml/dom/dom2_traversal.cpp
@@ -20,360 +20,330 @@
*
*/
+#include "dom/dom2_traversal.h"
+
#include "dom/dom_exception.h"
#include "dom/dom_string.h"
#include "xml/dom2_traversalimpl.h"
-using namespace DOM;
-
-
-NodeIterator::NodeIterator()
-{
- impl = 0;
-}
-
-NodeIterator::NodeIterator(const NodeIterator &other)
-{
- impl = other.impl;
- if (impl) impl->ref();
-}
+namespace DOM {
-NodeIterator::NodeIterator(NodeIteratorImpl *i)
-{
- impl = i;
- if (impl) impl->ref();
-}
-
-NodeIterator &NodeIterator::operator = (const NodeIterator &other)
-{
- if ( impl != other.impl ) {
- if (impl) impl->deref();
- impl = other.impl;
- if (impl) impl->ref();
- }
- return *this;
-}
-
-NodeIterator::~NodeIterator()
-{
- if (impl) impl->deref();
-}
+// --------------------------------------------------------------
-Node NodeIterator::root()
+short NodeFilterCondition::acceptNode(const Node &) const
{
- if (impl) return impl->root();
- return 0;
+ return NodeFilter::FILTER_ACCEPT;
}
-unsigned long NodeIterator::whatToShow()
-{
- if (impl) return impl->whatToShow();
- return 0;
-}
+// --------------------------------------------------------------
-NodeFilter NodeIterator::filter()
+NodeFilter::NodeFilter() : impl(0)
{
- if (impl) return impl->filter();
- return 0;
}
-bool NodeIterator::expandEntityReferences()
+NodeFilter::NodeFilter(NodeFilterCondition *condition)
{
- if (impl) return impl->expandEntityReferences();
- return 0;
+ impl = new NodeFilterImpl(condition);
+ impl->ref();
}
-Node NodeIterator::nextNode( )
+NodeFilter::NodeFilter(const NodeFilter &other)
{
- if (!impl)
- throw DOMException(DOMException::INVALID_STATE_ERR);
-
- int exceptioncode = 0;
- NodeImpl *r = impl->nextNode(exceptioncode);
- if (exceptioncode)
- throw DOMException(exceptioncode);
- return r;
+ impl = other.impl;
+ if (impl)
+ impl->ref();
}
-Node NodeIterator::previousNode( )
+NodeFilter::NodeFilter(NodeFilterImpl *i)
{
- if (!impl)
- throw DOMException(DOMException::INVALID_STATE_ERR);
-
- int exceptioncode = 0;
- NodeImpl *r = impl->previousNode(exceptioncode);
- if (exceptioncode)
- throw DOMException(exceptioncode);
- return r;
+ impl = i;
+ if (impl)
+ impl->ref();
}
-void NodeIterator::detach()
+NodeFilter &NodeFilter::operator=(const NodeFilter &other)
{
- if (!impl)
- throw DOMException(DOMException::INVALID_STATE_ERR);
+ if (impl == other.impl)
+ return *this;
+
+ NodeFilterImpl *old = impl;
+ impl = other.impl;
+ if (impl)
+ impl->ref();
+ if (old)
+ old->deref();
- int exceptioncode = 0;
- impl->detach(exceptioncode);
- if (exceptioncode)
- throw DOMException(exceptioncode);
+ return *this;
}
-NodeIteratorImpl *NodeIterator::handle() const
+NodeFilter::~NodeFilter()
{
- return impl;
+ if (impl)
+ impl->deref();
}
-bool NodeIterator::isNull() const
+short NodeFilter::acceptNode(const Node &node) const
{
- return (impl == 0);
+ if (impl)
+ return impl->acceptNode(node.handle());
+ return FILTER_ACCEPT;
}
-// -----------------------------------------------------------
+// --------------------------------------------------------------
-NodeFilter::NodeFilter()
+NodeIterator::NodeIterator()
{
impl = 0;
}
-NodeFilter::NodeFilter(const NodeFilter &other)
+NodeIterator::NodeIterator(const NodeIterator &other)
{
impl = other.impl;
- if (impl) impl->ref();
+ if (impl)
+ impl->ref();
}
-NodeFilter::NodeFilter(NodeFilterImpl *i)
+NodeIterator::NodeIterator(NodeIteratorImpl *i)
{
impl = i;
- if (impl) impl->ref();
+ if (impl)
+ impl->ref();
}
-NodeFilter &NodeFilter::operator = (const NodeFilter &other)
+NodeIterator &NodeIterator::operator=(const NodeIterator &other)
{
- if ( impl != other.impl ) {
- if (impl) impl->deref();
- impl = other.impl;
- if (impl) impl->ref();
- }
+ if (impl == other.impl)
+ return *this;
+
+ NodeIteratorImpl *old = impl;
+ impl = other.impl;
+ if (impl)
+ impl->ref();
+ if (old)
+ old->deref();
+
return *this;
}
-NodeFilter::~NodeFilter()
+NodeIterator::~NodeIterator()
{
- if (impl) impl->deref();
+ if (impl)
+ impl->deref();
}
-short NodeFilter::acceptNode(const Node &n)
+Node NodeIterator::root() const
{
- if (impl) return impl->acceptNode(n);
+ if (impl)
+ return impl->root();
return 0;
}
-void NodeFilter::setCustomNodeFilter(CustomNodeFilter *custom)
+unsigned long NodeIterator::whatToShow() const
{
- if (impl) impl->setCustomNodeFilter(custom);
-}
-
-CustomNodeFilter *NodeFilter::customNodeFilter()
-{
- if (impl) return impl->customNodeFilter();
+ if (impl)
+ return impl->whatToShow();
return 0;
}
-NodeFilterImpl *NodeFilter::handle() const
+NodeFilter NodeIterator::filter() const
{
- return impl;
+ if (impl)
+ return impl->filter();
+ return NodeFilter();
}
-bool NodeFilter::isNull() const
+bool NodeIterator::expandEntityReferences() const
{
- return (impl == 0);
+ if (impl)
+ return impl->expandEntityReferences();
+ return 0;
}
-NodeFilter NodeFilter::createCustom(CustomNodeFilter *custom)
+Node NodeIterator::nextNode()
{
- NodeFilterImpl *i = new NodeFilterImpl();
- i->setCustomNodeFilter(custom);
- return i;
-}
+ if (!impl)
+ throw DOMException(DOMException::INVALID_STATE_ERR);
-// --------------------------------------------------------------
-CustomNodeFilter::CustomNodeFilter()
-{
- impl = 0;
+ int exceptioncode = 0;
+ NodeImpl *result = impl->nextNode(exceptioncode);
+ if (exceptioncode)
+ throw DOMException(exceptioncode);
+ return result;
}
-CustomNodeFilter::~CustomNodeFilter()
+Node NodeIterator::previousNode()
{
+ if (!impl)
+ throw DOMException(DOMException::INVALID_STATE_ERR);
+
+ int exceptioncode = 0;
+ NodeImpl *result = impl->previousNode(exceptioncode);
+ if (exceptioncode)
+ throw DOMException(exceptioncode);
+ return result;
}
-short CustomNodeFilter::acceptNode (const Node &/*n*/)
+void NodeIterator::detach()
{
- return NodeFilter::FILTER_ACCEPT;
+ if (!impl)
+ throw DOMException(DOMException::INVALID_STATE_ERR);
+
+ int exceptioncode = 0;
+ impl->detach(exceptioncode);
+ if (exceptioncode)
+ throw DOMException(exceptioncode);
}
-bool CustomNodeFilter::isNull()
+Node NodeIterator::referenceNode() const
{
- return false;
+ if (!impl)
+ throw DOMException(DOMException::INVALID_STATE_ERR);
+
+ return impl->referenceNode();
}
-DOMString CustomNodeFilter::customNodeFilterType()
+bool NodeIterator::pointerBeforeReferenceNode() const
{
- return "";
+ if (!impl)
+ throw DOMException(DOMException::INVALID_STATE_ERR);
+
+ return impl->pointerBeforeReferenceNode();
}
// --------------------------------------------------------------
-TreeWalker::TreeWalker() {
+TreeWalker::TreeWalker()
+{
impl = 0;
}
-TreeWalker::TreeWalker(const TreeWalker &other) {
+TreeWalker::TreeWalker(const TreeWalker &other)
+{
impl = other.impl;
- if (impl) impl->ref();
+ if (impl)
+ impl->ref();
}
TreeWalker::TreeWalker(TreeWalkerImpl *i)
{
impl = i;
- if (impl) impl->ref();
+ if (impl)
+ impl->ref();
}
-TreeWalker & TreeWalker::operator = (const TreeWalker &other)
+TreeWalker &TreeWalker::operator=(const TreeWalker &other)
{
- if ( impl != other.impl ) {
- if (impl) impl->deref();
- impl = other.impl;
- if (impl) impl->ref();
- }
+ if (impl == other.impl)
+ return *this;
+
+ TreeWalkerImpl *old = impl;
+ impl = other.impl;
+ if (impl)
+ impl->ref();
+ if (old)
+ old->deref();
return *this;
}
TreeWalker::~TreeWalker()
{
- if (impl) impl->deref();
+ if (impl)
+ impl->deref();
}
-Node TreeWalker::root()
+Node TreeWalker::root() const
{
- if (impl) return impl->getRoot();
+ if (impl)
+ return impl->root();
return 0;
}
-unsigned long TreeWalker::whatToShow()
+unsigned long TreeWalker::whatToShow() const
{
- if (impl) return impl->getWhatToShow();
+ if (impl)
+ return impl->whatToShow();
return 0;
}
-NodeFilter TreeWalker::filter()
+NodeFilter TreeWalker::filter() const
{
- if (impl) return impl->getFilter();
- return 0;
+ if (impl)
+ return impl->filter();
+ return NodeFilter();
}
-bool TreeWalker::expandEntityReferences()
+bool TreeWalker::expandEntityReferences() const
{
- if (impl) return impl->getExpandEntityReferences();
+ if (impl) return impl->expandEntityReferences();
return false;
}
-Node TreeWalker::currentNode()
+Node TreeWalker::currentNode() const
{
- if (impl) return impl->getCurrentNode();
+ if (impl)
+ return impl->currentNode();
return 0;
}
-void TreeWalker::setCurrentNode(const Node _currentNode)
+void TreeWalker::setCurrentNode(const Node &node)
{
- if (impl) impl->setCurrentNode(_currentNode);
+ if (impl) {
+ int exceptioncode = 0;
+ impl->setCurrentNode(node.handle(), exceptioncode);
+ if (exceptioncode)
+ throw DOMException(exceptioncode);
+ }
}
Node TreeWalker::parentNode()
{
- if (impl) return impl->parentNode();
+ if (impl)
+ return impl->parentNode();
return 0;
}
Node TreeWalker::firstChild()
{
- if (impl) return impl->firstChild();
+ if (impl)
+ return impl->firstChild();
return 0;
}
Node TreeWalker::lastChild()
{
- if (impl) return impl->lastChild();
+ if (impl)
+ return impl->lastChild();
return 0;
}
Node TreeWalker::previousSibling()
{
- if (impl) return impl->previousSibling();
+ if (impl)
+ return impl->previousSibling();
return 0;
}
Node TreeWalker::nextSibling()
{
- if (impl) return impl->nextSibling();
+ if (impl)
+ return impl->nextSibling();
return 0;
}
Node TreeWalker::previousNode()
{
- if (impl) return impl->previousNode();
+ if (impl)
+ return impl->previousNode();
return 0;
}
Node TreeWalker::nextNode()
{
- if (impl) return impl->nextNode();
+ if (impl)
+ return impl->nextNode();
return 0;
}
-TreeWalkerImpl *TreeWalker::handle() const
-{
- return impl;
-}
-
-bool TreeWalker::isNull() const
-{
- return (impl == 0);
-}
-
-// -----------------------------------------------------------------------
-
-/*DocumentTraversal::DocumentTraversal()
-{
-}
-
-DocumentTraversal::DocumentTraversal(const DocumentTraversal &other)
-{
-}
-
-DocumentTraversal &DocumentTraversal::operator = (const DocumentTraversal &other)
-{
- DocumentTraversal::operator = (other);
- return *this;
-}
-
-DocumentTraversal::~DocumentTraversal()
-{
-}
-
-NodeIterator DocumentTraversal::createNodeIterator( const Node &root, long whatToShow,
- const NodeFilter &filter,
- bool entityReferenceExpansion )
-{
- return NodeIterator();
-}
-
-TreeWalker DocumentTraversal::createTreeWalker( const Node &root, long whatToShow,
- const NodeFilter &filter,
- bool entityReferenceExpansion )
-{
- return TreeWalker();
-}
-
-*/
+} // namespace DOM
diff --git a/WebCore/khtml/dom/dom2_traversal.h b/WebCore/khtml/dom/dom2_traversal.h
index 704d3d6..7670653 100644
--- a/WebCore/khtml/dom/dom2_traversal.h
+++ b/WebCore/khtml/dom/dom2_traversal.h
@@ -31,135 +31,22 @@
namespace DOM {
+
class Node;
-class NodeFilter;
class NodeImpl;
-class NodeIteratorImpl;
class NodeFilterImpl;
+class NodeIteratorImpl;
class TreeWalkerImpl;
-class CustomNodeFilter;
-class CustomNodeFilterImpl;
-/**
- * NodeIterators are used to step through a set of nodes, e.g. the set
- * of nodes in a NodeList, the document subtree governed by a
- * particular node, the results of a query, or any other set of nodes.
- * The set of nodes to be iterated is determined by the implementation
- * of the NodeIterator. DOM Level 2 specifies a single NodeIterator
- * implementation for document-order traversal of a document subtree.
- * Instances of these iterators are created by calling
- * DocumentTraversal.createNodeIterator().
- *
- * Any Iterator that returns nodes may implement the <code>
- * NodeIterator </code> interface. Users and vendor libraries may also
- * choose to create Iterators that implement the <code> NodeIterator
- * </code> interface.
- *
- */
-class NodeIterator
+class NodeFilterCondition : public DomShared
{
- friend class NodeIteratorImpl;
- friend class Document;
public:
- NodeIterator();
- NodeIterator(const NodeIterator &other);
-
- NodeIterator & operator = (const NodeIterator &other);
-
- ~NodeIterator();
-
- /**
- * The root node of the NodeIterator, as specified when it was created.
- */
- Node root();
-
- /**
- * This attribute determines which node types are presented via the
- * iterator. The available set of constants is defined in the NodeFilter
- * interface. Nodes not accepted by whatToShow will be skipped, but their
- * children may still be considered. Note that this skip takes precedence
- * over the filter, if any.
- */
- unsigned long whatToShow();
-
- /**
- * The NodeFilter used to screen nodes.
- */
- NodeFilter filter();
-
- /**
- * The value of this flag determines whether the children of entity
- * reference nodes are visible to the iterator. If false, they and
- * their descendents will be rejected. Note that this rejection takes
- * precedence over whatToShow and the filter. Also note that this is
- * currently the only situation where NodeIterators may reject a complete
- * subtree rather than skipping individual nodes.
- *
- * To produce a view of the document that has entity references expanded
- * and does not expose the entity reference node itself, use the whatToShow
- * flags to hide the entity reference node and set expandEntityReferences to
- * true when creating the iterator. To produce a view of the document that
- * has entity reference nodes but no entity expansion, use the whatToShow
- * flags to show the entity reference node and set expandEntityReferences to
- * false.
- */
- bool expandEntityReferences();
-
- /**
- * Returns the next node in the set and advances the position of
- * the Iterator in the set. After a NodeIterator is created, the
- * first call to nextNode() returns the first node in the set.
- *
- * @return The next <code> Node </code> in the set being iterated
- * over, or <code> null </code> if there are no more members in
- * that set.
- *
- * @exception Exceptions from user code
- * Any exceptions raised by a user-written Filter will propagate
- * through.
- *
- */
- Node nextNode();
-
- /**
- * Returns the previous node in the set and moves the position of
- * the Iterator backwards in the set.
- *
- * @return The previous <code> Node </code> in the set being
- * iterated over, or <code> null </code> if there are no more
- * members in that set.
- *
- * @exception Exceptions from user code
- * Any exceptions raised by a user-written Filter will propagate
- * through.
- *
- */
- Node previousNode();
-
- /**
- * Detaches the NodeIterator from the set which it iterated over,
- * releasing any computational resources and placing the iterator in the
- * INVALID state. After detach has been invoked, calls to nextNode or
- * previousNode will raise the exception INVALID_STATE_ERR.
- */
- void detach();
-
- /**
- * @internal
- * not part of the DOM
- */
- NodeIteratorImpl *handle() const;
- bool isNull() const;
-
-protected:
- NodeIteratorImpl *impl;
- NodeIterator(NodeIteratorImpl *i);
+ virtual short acceptNode(const Node &) const;
};
-
/**
* Filters are objects that know how to "filter out" nodes. If an
- * Iterator or <code> TreeWalker </code> is given a filter, before it
+ * Iterator or TreeWalker is given a filter, before it
* returns the next node, it applies the filter. If the filter says to
* accept the node, the Iterator returns it; otherwise, the Iterator
* looks for the next node and pretends that the node that was
@@ -175,31 +62,27 @@ protected:
* with a number of different kinds of Iterators, encouraging code
* reuse.
*
- * To create your own cutsom NodeFilter, define a subclass of
+ * To create your own custom NodeFilter, define a subclass of
* CustomNodeFilter which overrides the acceptNode() method and assign
* an instance of it to the NodeFilter. For more details see the
* CustomNodeFilter class
*/
class NodeFilter
{
- friend class NodeIterator;
- friend class NodeIteratorImpl;
- friend class TreeWalker;
- friend class TreeWalkerImpl;
- friend class NodeFilterImpl;
public:
NodeFilter();
+ NodeFilter(NodeFilterCondition *);
+ NodeFilter(NodeFilterImpl *);
NodeFilter(const NodeFilter &other);
+ NodeFilter &operator=(const NodeFilter &other);
+ ~NodeFilter();
- virtual NodeFilter & operator = (const NodeFilter &other);
-
- virtual ~NodeFilter();
/**
* The following constants are returned by the acceptNode()
* method:
*
*/
- enum AcceptCode {
+ enum {
FILTER_ACCEPT = 1,
FILTER_REJECT = 2,
FILTER_SKIP = 3
@@ -212,7 +95,7 @@ public:
* to the value of NodeType for the equivalent node type.
*
*/
- enum ShowCode {
+ enum {
SHOW_ALL = 0xFFFFFFFF,
SHOW_ELEMENT = 0x00000001,
SHOW_ATTRIBUTE = 0x00000002,
@@ -242,87 +125,141 @@ public:
* href="#Traversal-NodeFilter-acceptNode-constants"> above </a> .
*
*/
- virtual short acceptNode (const Node &n);
+ short acceptNode(const Node &) const;
- /**
- * @internal
- * not part of the DOM
- */
- virtual NodeFilterImpl *handle() const;
- virtual bool isNull() const;
-
- void setCustomNodeFilter(CustomNodeFilter *custom);
- CustomNodeFilter *customNodeFilter();
- static NodeFilter createCustom(CustomNodeFilter *custom);
+ NodeFilterImpl *handle() const { return impl; }
+ bool isNull() const { return impl == 0; }
-protected:
- NodeFilter(NodeFilterImpl *i);
+private:
NodeFilterImpl *impl;
};
/**
- * CustomNodeFilter can be used to define your own NodeFilter for use
- * with NodeIterators and TreeWalkers. You can create a custom filter
- * by doing the follwing:
- *
- * class MyCustomNodeFilter {
- * .....
- * virtual short acceptNode (const Node &n);
- * .....
- * }
- *
- * Then in your program:
- *
- * short MyCustomNodeFilter::acceptNode (const Node &n)
- * {
- * if (condition)
- * return NodeFilter::FILTER_ACCEPT;
- * else
- * ....
- * }
- *
- *
- * MyCustomFilter *filter = new MyCustomFilter();
- * NodeFilter nf = NodeFilter::createCutsom(filter);
- * NodeIterator ni = document.createNodeIterator(document,NodeFilter.SHOW_ALL,nf,false);
+ * NodeIterators are used to step through a set of nodes, e.g. the set
+ * of nodes in a NodeList, the document subtree governed by a
+ * particular node, the results of a query, or any other set of nodes.
+ * The set of nodes to be iterated is determined by the implementation
+ * of the NodeIterator. DOM Level 2 specifies a single NodeIterator
+ * implementation for document-order traversal of a document subtree.
+ * Instances of these iterators are created by calling
+ * DocumentTraversal.createNodeIterator().
*
- * The default implementation of acceptNode() returns NodeFilter::FILTER_ACCEPT
- * for all nodes.
+ * Any Iterator that returns nodes may implement the
+ * NodeIterator interface. Users and vendor libraries may also
+ * choose to create Iterators that implement the NodeIterator
+ * interface.
*
*/
-
-class CustomNodeFilter : public DomShared {
+class NodeIterator
+{
public:
- CustomNodeFilter();
- virtual ~CustomNodeFilter();
- virtual short acceptNode (const Node &n);
- virtual bool isNull();
+ NodeIterator(const NodeIterator &other);
+ NodeIterator &operator=(const NodeIterator &other);
+
+ ~NodeIterator();
/**
- * @internal
- * not part of the DOM
+ * The root node of the NodeIterator, as specified when it was created.
+ */
+ Node root() const;
+
+ /**
+ * This attribute determines which node types are presented via the
+ * iterator. The available set of constants is defined in the NodeFilter
+ * interface. Nodes not accepted by whatToShow will be skipped, but their
+ * children may still be considered. Note that this skip takes precedence
+ * over the filter, if any.
+ */
+ unsigned long whatToShow() const;
+
+ /**
+ * The NodeFilter used to screen nodes.
+ */
+ NodeFilter filter() const;
+
+ /**
+ * The value of this flag determines whether the children of entity
+ * reference nodes are visible to the iterator. If false, they and
+ * their descendents will be rejected. Note that this rejection takes
+ * precedence over whatToShow and the filter. Also note that this is
+ * currently the only situation where NodeIterators may reject a complete
+ * subtree rather than skipping individual nodes.
+ *
+ * To produce a view of the document that has entity references expanded
+ * and does not expose the entity reference node itself, use the whatToShow
+ * flags to hide the entity reference node and set expandEntityReferences to
+ * true when creating the iterator. To produce a view of the document that
+ * has entity reference nodes but no entity expansion, use the whatToShow
+ * flags to show the entity reference node and set expandEntityReferences to
+ * false.
+ */
+ bool expandEntityReferences() const;
+
+ /**
+ * Returns the next node in the set and advances the position of
+ * the Iterator in the set. After a NodeIterator is created, the
+ * first call to nextNode() returns the first node in the set.
+ *
+ * @return The next Node in the set being iterated
+ * over, or null if there are no more members in
+ * that set.
+ *
+ * @exception Exceptions from user code
+ * Any exceptions raised by a user-written Filter will propagate
+ * through.
*
- * Returns a name specifying the type of custom node filter. Useful for checking
- * if an custom node filter is of a particular sublass.
+ */
+ Node nextNode();
+
+ /**
+ * Returns the previous node in the set and moves the position of
+ * the Iterator backwards in the set.
*
+ * @return The previous Node in the set being
+ * iterated over, or null if there are no more
+ * members in that set.
+ *
+ * @exception Exceptions from user code
+ * Any exceptions raised by a user-written Filter will propagate
+ * through.
+ *
+ */
+ Node previousNode();
+
+ /**
+ * Detaches the NodeIterator from the set which it iterated over,
+ * releasing any computational resources and placing the iterator in the
+ * INVALID state. After detach has been invoked, calls to nextNode or
+ * previousNode will raise the exception INVALID_STATE_ERR.
*/
- virtual DOMString customNodeFilterType();
+ void detach();
-protected:
/**
* @internal
- * Reserved. Do not use in your subclasses.
+ * not part of the DOM
*/
- CustomNodeFilterImpl *impl;
+ Node referenceNode() const;
+ bool pointerBeforeReferenceNode() const;
+ NodeIteratorImpl *handle() const { return impl; }
+ bool isNull() const { return impl == 0; }
+
+ friend class NodeIteratorImpl;
+ friend class Document;
+
+private:
+ NodeIterator();
+ NodeIterator(NodeIteratorImpl *);
+ NodeIteratorImpl *impl;
};
+
/**
- * <code> TreeWalker </code> objects are used to navigate a document
+ * TreeWalker objects are used to navigate a document
* tree or subtree using the view of the document defined by its
- * <code> whatToShow </code> flags and any filters that are defined
- * for the <code> TreeWalker </code> . Any function which performs
- * navigation using a <code> TreeWalker </code> will automatically
- * support any view defined by a <code> TreeWalker </code> .
+ * whatToShow flags and any filters that are defined
+ * for the TreeWalker . Any function which performs
+ * navigation using a TreeWalker will automatically
+ * support any view defined by a TreeWalker .
*
* Omitting nodes from the logical view of a subtree can result in a
* structure that is substantially different from the same subtree in
@@ -337,21 +274,15 @@ protected:
*/
class TreeWalker
{
- friend class Document;
- friend class TreeWalkerImpl;
public:
- TreeWalker();
TreeWalker(const TreeWalker &other);
-
- TreeWalker & operator = (const TreeWalker &other);
-
+ TreeWalker &operator=(const TreeWalker &other);
~TreeWalker();
-
/**
* The root node of the TreeWalker, as specified when it was created.
*/
- Node root();
+ Node root() const;
/**
* This attribute determines which node types are presented via the
@@ -360,12 +291,12 @@ public:
* children may still be considered. Note that this skip takes precedence
* over the filter, if any.
*/
- unsigned long whatToShow();
+ unsigned long whatToShow() const;
/**
* The filter used to screen nodes.
*/
- NodeFilter filter();
+ NodeFilter filter() const;
/**
* The value of this flag determines whether the children of entity
@@ -381,7 +312,7 @@ public:
* whatToShow flags to show the entity reference node and set
* expandEntityReferences to false.
*/
- bool expandEntityReferences();
+ bool expandEntityReferences() const;
/**
* The node at which the TreeWalker is currently positioned.
@@ -396,12 +327,12 @@ public:
* @exception DOMException
* NOT_SUPPORTED_ERR: Raised if an attempt is made to set currentNode to null.
*/
- Node currentNode();
+ Node currentNode() const;
/**
- * see @ref currentNode
+ * see currentNode
*/
- void setCurrentNode(const Node _currentNode);
+ void setCurrentNode(const Node &_currentNode);
/**
* Moves to and returns the parent node of the current node. If
@@ -420,12 +351,12 @@ public:
Node parentNode();
/**
- * Moves the <code> TreeWalker </code> to the first child of the
+ * Moves the TreeWalker to the first child of the
* current node, and returns the new node. If the current node has
- * no children, returns <code> null </code> , and retains the
+ * no children, returns null , and retains the
* current node.
*
- * @return The new node, or <code> null </code> if the current
+ * @return The new node, or null if the current
* node has no children.
*
* @exception Exceptions from user code
@@ -436,12 +367,12 @@ public:
Node firstChild();
/**
- * Moves the <code> TreeWalker </code> to the last child of the
+ * Moves the TreeWalker to the last child of the
* current node, and returns the new node. If the current node has
- * no children, returns <code> null </code> , and retains the
+ * no children, returns null , and retains the
* current node.
*
- * @return The new node, or <code> null </code> if the current
+ * @return The new node, or null if the current
* node has no children.
*
* @exception Exceptions from user code
@@ -452,12 +383,12 @@ public:
Node lastChild();
/**
- * Moves the <code> TreeWalker </code> to the previous sibling of
+ * Moves the TreeWalker to the previous sibling of
* the current node, and returns the new node. If the current node
- * has no previous sibling, returns <code> null </code> , and
+ * has no previous sibling, returns null , and
* retains the current node.
*
- * @return The new node, or <code> null </code> if the current
+ * @return The new node, or null if the current
* node has no previous sibling.
*
* @exception Exceptions from user code
@@ -468,12 +399,12 @@ public:
Node previousSibling();
/**
- * Moves the <code> TreeWalker </code> to the next sibling of the
+ * Moves the TreeWalker to the next sibling of the
* current node, and returns the new node. If the current node has
- * no next sibling, returns <code> null </code> , and retains the
+ * no next sibling, returns null , and retains the
* current node.
*
- * @return The new node, or <code> null </code> if the current
+ * @return The new node, or null if the current
* node has no next sibling.
*
* @exception Exceptions from user code
@@ -484,12 +415,12 @@ public:
Node nextSibling();
/**
- * Moves the <code> TreeWalker </code> to the previous node in
+ * Moves the TreeWalker to the previous node in
* document order relative to the current node, and returns the
* new node. If the current node has no previous node, returns
- * <code> null </code> , and retains the current node.
+ * null , and retains the current node.
*
- * @return The new node, or <code> null </code> if the current
+ * @return The new node, or null if the current
* node has no previous node.
*
* @exception Exceptions from user code
@@ -500,12 +431,12 @@ public:
Node previousNode();
/**
- * Moves the <code> TreeWalker </code> to the next node in
+ * Moves the TreeWalker to the next node in
* document order relative to the current node, and returns the
- * new node. If the current node has no next node, returns <code>
- * null </code> , and retains the current node.
+ * new node. If the current node has no next node, returns
+ * null , and retains the current node.
*
- * @return The new node, or <code> null </code> if the current
+ * @return The new node, or null if the current
* node has no next node.
*
* @exception Exceptions from user code
@@ -519,11 +450,15 @@ public:
* @internal
* not part of the DOM
*/
- TreeWalkerImpl *handle() const;
- bool isNull() const;
+ TreeWalkerImpl *handle() const { return impl; }
+ bool isNull() const { return impl == 0; }
+
+ friend class Document;
+ friend class TreeWalkerImpl;
-protected:
- TreeWalker(TreeWalkerImpl *i);
+private:
+ TreeWalker();
+ TreeWalker(TreeWalkerImpl *);
TreeWalkerImpl *impl;
};
@@ -532,7 +467,7 @@ protected:
// Document
/**
- * <code> DocumentTraversal </code> contains methods that creates
+ * DocumentTraversal contains methods that creates
* Iterators to traverse a node and its children in document order
* (depth first, pre-order traversal, which is equivalent to the order
* in which the start tags occur in the text representation of the
@@ -562,26 +497,26 @@ public:
* Iterator. See the description of Iterator for the set of
* possible values. These flags can be combined using OR.
*
- * These flags can be combined using <code> OR </code> .
+ * These flags can be combined using OR .
*
* @param filter The Filter to be used with this TreeWalker, or
* null to indicate no filter.
*
- * @param entityReferenceExpansion The value of this flag
+ * @param expandEntityReferences The value of this flag
* determines whether entity reference nodes are expanded.
*
- * @return The newly created <code> NodeIterator </code> .
+ * @return The newly created NodeIterator .
*
*
NodeIterator createNodeIterator ( const Node &root, long whatToShow,
- const NodeFilter &filter, bool entityReferenceExpansion );
+ const NodeFilter &filter, bool expandEntityReferences );
**
* Create a new TreeWalker over the subtree rooted by the
* specified node.
*
* @param root The node which will serve as the root for the
- * <code> TreeWalker </code> . The currentNode of the TreeWalker
+ * TreeWalker . The currentNode of the TreeWalker
* is set to this node. The whatToShow flags and the NodeFilter
* are not considered when setting this value; any node type will
* be accepted as the root. The root must not be null.
@@ -591,15 +526,15 @@ public:
* Iterator. See the description of TreeWalker for the set of
* possible values. These flags can be combined using OR.
*
- * These flags can be combined using <code> OR </code> .
+ * These flags can be combined using OR .
*
* @param filter The Filter to be used with this TreeWalker, or
* null to indicate no filter.
*
- * @param entityReferenceExpansion The value of this flag
+ * @param expandEntityReferences The value of this flag
* determines whether entity reference nodes are expanded.
*
- * @return The newly created <code> TreeWalker </code> .
+ * @return The newly created TreeWalker .
*
* @exception DOMException
* Raises the exception NOT_SUPPORTED_ERR if the specified root
@@ -607,10 +542,10 @@ public:
*
*
TreeWalker createTreeWalker ( const Node &root, long whatToShow,
- const NodeFilter &filter, bool entityReferenceExpansion );
+ const NodeFilter &filter, bool expandEntityReferences );
};
*/
-}; // namespace
+} // namespace
#endif
diff --git a/WebCore/khtml/dom/dom_doc.cpp b/WebCore/khtml/dom/dom_doc.cpp
index fa5abcc..743f161 100644
--- a/WebCore/khtml/dom/dom_doc.cpp
+++ b/WebCore/khtml/dom/dom_doc.cpp
@@ -367,25 +367,32 @@ Range Document::createRange()
return 0;
}
-NodeIterator Document::createNodeIterator(Node root, unsigned long whatToShow,
- NodeFilter filter, bool entityReferenceExpansion)
+NodeIterator Document::createNodeIterator(const Node &root, unsigned long whatToShow,
+ const NodeFilter &filter, bool expandEntityReferences)
{
if (!impl)
- throw DOMException(DOMException::INVALID_STATE_ERR);
+ throw DOMException(DOMException::INVALID_STATE_ERR);
int exceptioncode = 0;
- NodeIteratorImpl *r = static_cast<DocumentImpl*>(impl)->createNodeIterator(root.handle(),
- whatToShow,filter,entityReferenceExpansion,exceptioncode);
+ NodeIteratorImpl *result = static_cast<DocumentImpl*>(impl)->createNodeIterator(root.handle(), whatToShow,
+ filter.handle(), expandEntityReferences, exceptioncode);
if (exceptioncode)
- throw DOMException(exceptioncode);
- return r;
+ throw DOMException(exceptioncode);
+ return result;
}
-TreeWalker Document::createTreeWalker(Node root, unsigned long whatToShow, NodeFilter filter,
- bool entityReferenceExpansion)
+TreeWalker Document::createTreeWalker(const Node &root, unsigned long whatToShow,
+ const NodeFilter &filter, bool expandEntityReferences)
{
- if (impl) return ((DocumentImpl *)impl)->createTreeWalker(root,whatToShow,filter,entityReferenceExpansion);
- return 0;
+ if (!impl)
+ throw DOMException(DOMException::INVALID_STATE_ERR);
+
+ int exceptioncode = 0;
+ TreeWalkerImpl *result = static_cast<DocumentImpl*>(impl)->createTreeWalker(root.handle(), whatToShow,
+ filter.handle(), expandEntityReferences, exceptioncode);
+ if (exceptioncode)
+ throw DOMException(exceptioncode);
+ return result;
}
Event Document::createEvent(const DOMString &eventType)
diff --git a/WebCore/khtml/dom/dom_doc.h b/WebCore/khtml/dom/dom_doc.h
index 62063e9..932c806 100644
--- a/WebCore/khtml/dom/dom_doc.h
+++ b/WebCore/khtml/dom/dom_doc.h
@@ -655,7 +655,7 @@ public:
* @param filter The NodeFilter to be used with this TreeWalker, or null to
* indicate no filter.
*
- * @param entityReferenceExpansion The value of this flag determines
+ * @param expandEntityReferences The value of this flag determines
* whether entity reference nodes are expanded.
*
* @return NodeIterator The newly created NodeIterator.
@@ -663,9 +663,7 @@ public:
* @exception DOMException
* NOT_SUPPORTED_ERR: Raised if the specified root is null.
*/
- NodeIterator createNodeIterator(Node root, unsigned long whatToShow,
- NodeFilter filter,
- bool entityReferenceExpansion);
+ NodeIterator createNodeIterator(const Node &root, unsigned long whatToShow, const NodeFilter &filter, bool expandEntityReferences);
/**
* Introduced in DOM Level 2
@@ -689,7 +687,7 @@ public:
* @param filter The NodeFilter to be used with this TreeWalker, or null to
* indicate no filter.
*
- * @param entityReferenceExpansion If this flag is false, the contents of
+ * @param expandEntityReferences If this flag is false, the contents of
* EntityReference nodes are not presented in the logical view.
*
* @return The newly created TreeWalker.
@@ -697,9 +695,7 @@ public:
* @exception DOMException
* NOT_SUPPORTED_ERR: Raised if the specified root is null.
*/
- TreeWalker createTreeWalker(Node root, unsigned long whatToShow,
- NodeFilter filter,
- bool entityReferenceExpansion);
+ TreeWalker createTreeWalker(const Node &root, unsigned long whatToShow, const NodeFilter &filter, bool expandEntityReferences);
/**
* Introduced in DOM Level 2
diff --git a/WebCore/khtml/ecma/kjs_dom.cpp b/WebCore/khtml/ecma/kjs_dom.cpp
index 741d75e..f1adde1 100644
--- a/WebCore/khtml/ecma/kjs_dom.cpp
+++ b/WebCore/khtml/ecma/kjs_dom.cpp
@@ -48,6 +48,7 @@
using namespace KJS;
using DOM::DOMException;
+using DOM::NodeFilter;
// -------------------------------------------------------------------------
/* Source for DOMNodeProtoTable. Use "make hashtables" to regenerate.
@@ -862,29 +863,24 @@ Value DOMDocumentProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List
return getDOMNode(exec,doc.getElementById(args[0].toString(exec).string()));
case DOMDocument::CreateRange:
return getDOMRange(exec,doc.createRange());
- case DOMDocument::CreateNodeIterator:
- if (args[2].isA(NullType)) {
- DOM::NodeFilter filter;
- return getDOMNodeIterator(exec,
- doc.createNodeIterator(toNode(args[0]),
- (long unsigned int)(args[1].toNumber(exec)),
- filter,args[3].toBoolean(exec)));
+ case DOMDocument::CreateNodeIterator: {
+ NodeFilter filter;
+ if (!args[2].isA(NullType)) {
+ Object obj = Object::dynamicCast(args[2]);
+ if (!obj.isNull())
+ filter = NodeFilter(new JSNodeFilterCondition(obj));
}
- else {
- Object obj = Object::dynamicCast(args[2]);
- if (!obj.isNull())
- {
- DOM::CustomNodeFilter *customFilter = new JSNodeFilter(obj);
- DOM::NodeFilter filter = DOM::NodeFilter::createCustom(customFilter);
- return getDOMNodeIterator(exec,
- doc.createNodeIterator(
- toNode(args[0]),(long unsigned int)(args[1].toNumber(exec)),
- filter,args[3].toBoolean(exec)));
- }// else?
+ return getDOMNodeIterator(exec, doc.createNodeIterator(toNode(args[0]), (long unsigned int)(args[1].toNumber(exec)), filter, args[3].toBoolean(exec)));
+ }
+ case DOMDocument::CreateTreeWalker: {
+ NodeFilter filter;
+ if (!args[2].isA(NullType)) {
+ Object obj = Object::dynamicCast(args[2]);
+ if (!obj.isNull())
+ filter = NodeFilter(new JSNodeFilterCondition(obj));
}
- case DOMDocument::CreateTreeWalker:
- return getDOMTreeWalker(exec,doc.createTreeWalker(toNode(args[0]),(long unsigned int)(args[1].toNumber(exec)),
- toNodeFilter(args[2]),args[3].toBoolean(exec)));
+ return getDOMTreeWalker(exec, doc.createTreeWalker(toNode(args[0]), (long unsigned int)(args[1].toNumber(exec)), filter, args[3].toBoolean(exec)));
+ }
case DOMDocument::CreateEvent:
return getDOMEvent(exec,doc.createEvent(s));
case DOMDocument::GetOverrideStyle: {
diff --git a/WebCore/khtml/ecma/kjs_traversal.cpp b/WebCore/khtml/ecma/kjs_traversal.cpp
index e0b0d5c..09a28fa 100644
--- a/WebCore/khtml/ecma/kjs_traversal.cpp
+++ b/WebCore/khtml/ecma/kjs_traversal.cpp
@@ -38,6 +38,8 @@ const ClassInfo DOMNodeIterator::info = { "NodeIterator", 0, &DOMNodeIteratorTab
whatToShow DOMNodeIterator::WhatToShow DontDelete|ReadOnly
filter DOMNodeIterator::Filter DontDelete|ReadOnly
expandEntityReferences DOMNodeIterator::ExpandEntityReferences DontDelete|ReadOnly
+ referenceNode DOMNodeIterator::ReferenceNode DontDelete|ReadOnly
+ pointerBeforeReferenceNode DOMNodeIterator::PointerBeforeReferenceNode DontDelete|ReadOnly
@end
@begin DOMNodeIteratorProtoTable 3
nextNode DOMNodeIterator::NextNode DontDelete|Function 0
@@ -74,6 +76,10 @@ Value DOMNodeIterator::getValueProperty(ExecState *exec, int token) const
return getDOMNodeFilter(exec,ni.filter());
case ExpandEntityReferences:
return Boolean(ni.expandEntityReferences());
+ case ReferenceNode:
+ return getDOMNode(exec,ni.referenceNode());
+ case PointerBeforeReferenceNode:
+ return Boolean(ni.pointerBeforeReferenceNode());
default:
kdWarning() << "Unhandled token in DOMNodeIterator::getValueProperty : " << token << endl;
return Value();
@@ -182,7 +188,7 @@ Value DOMNodeFilterProtoFunc::tryCall(ExecState *exec, Object &thisObj, const Li
Value KJS::getDOMNodeFilter(ExecState *exec, DOM::NodeFilter nf)
{
- return cacheDOMObject<DOM::NodeFilter, DOMNodeFilter>(exec, nf);
+ return cacheDOMObject<DOM::NodeFilter, DOMNodeFilter>(exec, nf);
}
// -------------------------------------------------------------------------
@@ -273,7 +279,7 @@ Value DOMTreeWalkerProtoFunc::tryCall(ExecState *exec, Object &thisObj, const Li
case DOMTreeWalker::NextSibling:
return getDOMNode(exec,treeWalker.nextSibling());
case DOMTreeWalker::PreviousNode:
- return getDOMNode(exec,treeWalker.previousSibling());
+ return getDOMNode(exec,treeWalker.previousNode());
case DOMTreeWalker::NextNode:
return getDOMNode(exec,treeWalker.nextNode());
}
@@ -297,28 +303,22 @@ DOM::NodeFilter KJS::toNodeFilter(const Value& val)
// -------------------------------------------------------------------------
-JSNodeFilter::JSNodeFilter(Object & _filter) : DOM::CustomNodeFilter(), filter( _filter )
+JSNodeFilterCondition::JSNodeFilterCondition(Object & _filter) : filter( _filter )
{
}
-JSNodeFilter::~JSNodeFilter()
+short JSNodeFilterCondition::acceptNode(const DOM::Node &node) const
{
-}
-
-short JSNodeFilter::acceptNode(const DOM::Node &n)
-{
- KHTMLPart *part = static_cast<DOM::DocumentImpl *>( n.handle()->docPtr()->document() )->part();
- KJSProxy *proxy = KJSProxy::proxy( part );
- if (proxy) {
- ExecState *exec = proxy->interpreter()->globalExec();
- Object acceptNodeFunc = Object::dynamicCast( filter.get(exec, "acceptNode") );
- if (acceptNodeFunc.implementsCall()) {
- List args;
- args.append(getDOMNode(exec,n));
- Value result = acceptNodeFunc.call(exec,filter,args);
- return result.toInt32(exec);
+ KHTMLPart *part = static_cast<DOM::DocumentImpl *>(node.handle()->docPtr()->document())->part();
+ KJSProxy *proxy = KJSProxy::proxy(part);
+ if (proxy && filter.implementsCall()) {
+ ExecState *exec = proxy->interpreter()->globalExec();
+ List args;
+ args.append(getDOMNode(exec,node));
+ Object obj = const_cast<ProtectedObject &>(filter);
+ Value result = obj.call(exec, obj, args);
+ return result.toInt32(exec);
}
- }
- return DOM::NodeFilter::FILTER_REJECT;
+ return DOM::NodeFilter::FILTER_REJECT;
}
diff --git a/WebCore/khtml/ecma/kjs_traversal.h b/WebCore/khtml/ecma/kjs_traversal.h
index ec7264a..b786816 100644
--- a/WebCore/khtml/ecma/kjs_traversal.h
+++ b/WebCore/khtml/ecma/kjs_traversal.h
@@ -35,7 +35,7 @@ namespace KJS {
// no put - all read-only
virtual const ClassInfo* classInfo() const { return &info; }
static const ClassInfo info;
- enum { Filter, Root, WhatToShow, ExpandEntityReferences,
+ enum { Filter, Root, WhatToShow, ExpandEntityReferences, ReferenceNode, PointerBeforeReferenceNode,
NextNode, PreviousNode, Detach };
DOM::NodeIterator toNodeIterator() const { return nodeIterator; }
protected:
@@ -94,11 +94,11 @@ namespace KJS {
*/
DOM::NodeFilter toNodeFilter(const Value&);
- class JSNodeFilter : public DOM::CustomNodeFilter {
+ class JSNodeFilterCondition : public DOM::NodeFilterCondition {
public:
- JSNodeFilter(Object & _filter);
- virtual ~JSNodeFilter();
- virtual short acceptNode (const DOM::Node &n);
+ JSNodeFilterCondition(Object & _filter);
+ virtual ~JSNodeFilterCondition() {}
+ virtual short acceptNode(const DOM::Node &) const;
protected:
ProtectedObject filter;
};
diff --git a/WebCore/khtml/ecma/kjs_traversal.lut.h b/WebCore/khtml/ecma/kjs_traversal.lut.h
index bdcb918..9f0fc2d 100644
--- a/WebCore/khtml/ecma/kjs_traversal.lut.h
+++ b/WebCore/khtml/ecma/kjs_traversal.lut.h
@@ -3,15 +3,16 @@
namespace KJS {
const struct HashEntry DOMNodeIteratorTableEntries[] = {
- { 0, 0, 0, 0, 0 },
+ { "pointerBeforeReferenceNode", DOMNodeIterator::PointerBeforeReferenceNode, DontDelete|ReadOnly, 0, 0 },
{ "filter", DOMNodeIterator::Filter, DontDelete|ReadOnly, 0, 0 },
{ "root", DOMNodeIterator::Root, DontDelete|ReadOnly, 0, 0 },
{ "whatToShow", DOMNodeIterator::WhatToShow, DontDelete|ReadOnly, 0, &DOMNodeIteratorTableEntries[5] },
{ 0, 0, 0, 0, 0 },
- { "expandEntityReferences", DOMNodeIterator::ExpandEntityReferences, DontDelete|ReadOnly, 0, 0 }
+ { "expandEntityReferences", DOMNodeIterator::ExpandEntityReferences, DontDelete|ReadOnly, 0, &DOMNodeIteratorTableEntries[6] },
+ { "referenceNode", DOMNodeIterator::ReferenceNode, DontDelete|ReadOnly, 0, 0 }
};
-const struct HashTable DOMNodeIteratorTable = { 2, 6, DOMNodeIteratorTableEntries, 5 };
+const struct HashTable DOMNodeIteratorTable = { 2, 7, DOMNodeIteratorTableEntries, 5 };
} // namespace
diff --git a/WebCore/khtml/xml/dom2_traversalimpl.cpp b/WebCore/khtml/xml/dom2_traversalimpl.cpp
index 49c518c..bd094e6 100644
--- a/WebCore/khtml/xml/dom2_traversalimpl.cpp
+++ b/WebCore/khtml/xml/dom2_traversalimpl.cpp
@@ -4,6 +4,7 @@
* (C) 1999 Lars Knoll (knoll at kde.org)
* (C) 2000 Frederik Holljen (frederik.holljen at hig.no)
* (C) 2001 Peter Kelly (pmk at post.com)
+ * 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
@@ -21,688 +22,479 @@
* Boston, MA 02111-1307, USA.
*/
+#include "xml/dom2_traversalimpl.h"
#include "dom/dom_exception.h"
#include "xml/dom_docimpl.h"
-using namespace DOM;
+#include "htmltags.h"
-NodeIteratorImpl::NodeIteratorImpl(NodeImpl *_root, unsigned long _whatToShow,
- NodeFilter _filter, bool _entityReferenceExpansion)
-{
- m_root = _root;
- m_whatToShow = _whatToShow;
- m_filter = _filter;
- m_expandEntityReferences = _entityReferenceExpansion;
-
- m_referenceNode = _root;
- m_inFront = false;
+namespace DOM {
- m_doc = m_root->getDocument();
- m_doc->attachNodeIterator(this);
- m_doc->ref();
-
- m_detached = false;
+NodeFilterImpl::NodeFilterImpl(NodeFilterCondition *condition)
+ : m_condition(condition)
+{
+ if (m_condition)
+ m_condition->ref();
}
-NodeIteratorImpl::~NodeIteratorImpl()
+NodeFilterImpl::~NodeFilterImpl()
{
- m_doc->detachNodeIterator(this);
- m_doc->deref();
+ if (m_condition)
+ m_condition->deref();
}
-NodeImpl *NodeIteratorImpl::root()
+short NodeFilterImpl::acceptNode(const Node &node) const
{
- return m_root;
+ // cast to short silences "enumeral and non-enumeral types in return" warning
+ return m_condition ? m_condition->acceptNode(node) : static_cast<short>(NodeFilter::FILTER_ACCEPT);
}
-unsigned long NodeIteratorImpl::whatToShow()
+// --------------------------------------------------------------
+
+TraversalImpl::TraversalImpl(NodeImpl *rootNode, long whatToShow, NodeFilterImpl *nodeFilter, bool expandEntityReferences)
+ : m_root(rootNode), m_whatToShow(whatToShow), m_filter(nodeFilter), m_expandEntityReferences(expandEntityReferences)
{
- return m_whatToShow;
+ if (root())
+ root()->ref();
+ if (filter())
+ filter()->ref();
}
-NodeFilter NodeIteratorImpl::filter()
+TraversalImpl::~TraversalImpl()
{
- return m_filter;
+ if (root())
+ root()->deref();
+ if (filter())
+ filter()->deref();
}
-bool NodeIteratorImpl::expandEntityReferences()
+short TraversalImpl::acceptNode(NodeImpl *node) const
{
- return m_expandEntityReferences;
+ // FIXME: If XML is implemented we have to check expandEntityRerefences in this function.
+ // The bid twiddling here is done to map DOM node types, which are given as integers from
+ // 1 through 12, to whatToShow bit masks.
+ if (node && ((1 << (node->nodeType()-1)) & m_whatToShow) != 0)
+ // cast to short silences "enumeral and non-enumeral types in return" warning
+ return m_filter ? m_filter->acceptNode(node) : static_cast<short>(NodeFilter::FILTER_ACCEPT);
+ return NodeFilter::FILTER_SKIP;
}
-NodeImpl *NodeIteratorImpl::nextNode( int &exceptioncode )
+NodeImpl *TraversalImpl::findParentNode(NodeImpl *node, short accept) const
{
- if (m_detached) {
- exceptioncode = DOMException::INVALID_STATE_ERR;
- return 0;
- }
-
- if (!m_referenceNode) {
- m_inFront = true;
- return 0;
- }
-
- if (!m_inFront) {
- m_inFront = true;
- if (isAccepted(m_referenceNode) == NodeFilter::FILTER_ACCEPT)
- return m_referenceNode;
- }
-
- NodeImpl *_tempCurrent = getNextNode(m_referenceNode);
- while( _tempCurrent ) {
- m_referenceNode = _tempCurrent;
- if(isAccepted(_tempCurrent) == NodeFilter::FILTER_ACCEPT)
- return m_referenceNode;
- _tempCurrent = getNextNode(_tempCurrent);
+ if (!node || node == root())
+ return 0;
+ NodeImpl *n = node->parentNode();
+ while (n) {
+ if (acceptNode(n) & accept)
+ return n;
+ if (n == root())
+ return 0;
+ n = n->parentNode();
}
-
return 0;
}
-NodeImpl *NodeIteratorImpl::getNextNode(NodeImpl *n)
+NodeImpl *TraversalImpl::findFirstChild(NodeImpl *node) const
{
- /* 1. my first child
- * 2. my next sibling
- * 3. my parents sibling, or their parents sibling (loop)
- * 4. not found
- */
-
- if( !n )
- return 0;
-
- if( n->hasChildNodes() )
- return n->firstChild();
-
- if( n->nextSibling() )
- return n->nextSibling();
-
- if( m_root == n)
- return 0;
-
- NodeImpl *parent = n->parentNode();
- while( parent )
- {
- n = parent->nextSibling();
- if( n )
- return n;
-
- if( m_root == parent )
+ if (!node || acceptNode(node) == NodeFilter::FILTER_REJECT)
return 0;
-
- parent = parent->parentNode();
+ NodeImpl *n = node->firstChild();
+ while (n) {
+ if (acceptNode(n) == NodeFilter::FILTER_ACCEPT)
+ return n;
+ n = n->nextSibling();
}
- return 0;
+ return 0;
}
-NodeImpl *NodeIteratorImpl::previousNode( int &exceptioncode )
+NodeImpl *TraversalImpl::findLastChild(NodeImpl *node) const
{
- if (m_detached) {
- exceptioncode = DOMException::INVALID_STATE_ERR;
- return 0;
- }
-
- if (!m_referenceNode) {
- m_inFront = false;
- return 0;
- }
-
- if (m_inFront) {
- m_inFront = false;
- if (isAccepted(m_referenceNode) == NodeFilter::FILTER_ACCEPT)
- return m_referenceNode;
- }
-
- NodeImpl *_tempCurrent = getPreviousNode(m_referenceNode);
- while( _tempCurrent ) {
- m_referenceNode = _tempCurrent;
- if(isAccepted(_tempCurrent) == NodeFilter::FILTER_ACCEPT)
- return m_referenceNode;
- _tempCurrent = getPreviousNode(_tempCurrent);
+ if (!node || acceptNode(node) == NodeFilter::FILTER_REJECT)
+ return 0;
+ NodeImpl *n = node->lastChild();
+ while (n) {
+ if (acceptNode(n) == NodeFilter::FILTER_ACCEPT)
+ return n;
+ n = n->previousSibling();
}
-
return 0;
}
-NodeImpl *NodeIteratorImpl::getPreviousNode(NodeImpl *n)
+NodeImpl *TraversalImpl::findPreviousSibling(NodeImpl *node) const
{
-/* 1. my previous sibling.lastchild
- * 2. my previous sibling
- * 3. my parent
- */
- NodeImpl *_tempCurrent;
-
- if( !n )
- return 0;
-
- _tempCurrent = n->previousSibling();
- if( _tempCurrent )
- {
- if( _tempCurrent->lastChild() )
- {
- while( _tempCurrent->lastChild() )
- _tempCurrent = _tempCurrent->lastChild();
- return _tempCurrent;
- }
- else
- return _tempCurrent;
+ if (!node)
+ return 0;
+ NodeImpl *n = node->previousSibling();
+ while (n) {
+ if (acceptNode(n) == NodeFilter::FILTER_ACCEPT)
+ return n;
+ n = n->previousSibling();
}
-
-
- if(n == m_root)
return 0;
-
- return n->parentNode();
-
-
-}
-
-void NodeIteratorImpl::detach(int &/*exceptioncode*/)
-{
- m_doc->detachNodeIterator(this);
- m_detached = true;
}
-
-void NodeIteratorImpl::notifyBeforeNodeRemoval(NodeImpl *removed)
+NodeImpl *TraversalImpl::findNextSibling(NodeImpl *node) const
{
- // make sure the deleted node is with the root (but not the root itself)
- if (removed == m_root)
- return;
-
- NodeImpl *maybeRoot = removed->parentNode();
- while (maybeRoot && maybeRoot != m_root)
- maybeRoot = maybeRoot->parentNode();
- if (!maybeRoot)
- return;
-
- // did I get deleted, or one of my parents?
- NodeImpl *_tempDeleted = m_referenceNode;
- while( _tempDeleted && _tempDeleted != removed)
- _tempDeleted = _tempDeleted->parentNode();
-
- if( !_tempDeleted ) // someone that didn't consern me got deleted
- return;
-
- if( !m_inFront)
- {
- NodeImpl *_next = getNextNode(_tempDeleted);
- if( _next )
- m_referenceNode = _next;
- else
- {
- // deleted node was at end of list
- m_inFront = true;
- m_referenceNode = getPreviousNode(_tempDeleted);
- }
- }
- else {
- NodeImpl *_prev = getPreviousNode(_tempDeleted);
- if ( _prev )
- m_referenceNode = _prev;
- else
- {
- // deleted node was at start of list
- m_inFront = false;
- m_referenceNode = getNextNode(_tempDeleted);
- }
+ if (!node)
+ return 0;
+ NodeImpl *n = node->nextSibling();
+ while (n) {
+ if (acceptNode(n) == NodeFilter::FILTER_ACCEPT)
+ return n;
+ n = n->nextSibling();
}
-
+ return 0;
}
-short NodeIteratorImpl::isAccepted(NodeImpl *n)
+NodeImpl *TraversalImpl::findLastDescendant(NodeImpl *node) const
{
- // if XML is implemented we have to check expandEntityRerefences in this function
- if( ( ( 1 << n->nodeType()-1) & m_whatToShow) != 0 )
- {
- if(!m_filter.isNull())
- return m_filter.acceptNode(n);
+ NodeImpl *n = node;
+ NodeImpl *r = node;
+ while (n) {
+ short accepted = acceptNode(n);
+ if (accepted != NodeFilter::FILTER_REJECT) {
+ if (accepted == NodeFilter::FILTER_ACCEPT)
+ r = n;
+ if (n->lastChild())
+ n = n->lastChild();
+ else if (n != node && n->previousSibling())
+ n = n->previousSibling();
+ else
+ break;
+ }
else
- return NodeFilter::FILTER_ACCEPT;
+ break;
}
- return NodeFilter::FILTER_SKIP;
+ return r;
}
-// --------------------------------------------------------------
-
-
-NodeFilterImpl::NodeFilterImpl()
+NodeImpl *TraversalImpl::findPreviousNode(NodeImpl *node) const
{
- m_customNodeFilter = 0;
+ NodeImpl *n = node->previousSibling();
+ while (n) {
+ short accepted = acceptNode(n);
+ if (accepted != NodeFilter::FILTER_REJECT) {
+ NodeImpl *d = findLastDescendant(n);
+ if (acceptNode(d) == NodeFilter::FILTER_ACCEPT)
+ return d;
+ // else FILTER_SKIP
+ }
+ n = n->previousSibling();
+ }
+ return findParentNode(node);
}
-NodeFilterImpl::~NodeFilterImpl()
+NodeImpl *TraversalImpl::findNextNode(NodeImpl *node) const
{
- if (m_customNodeFilter)
- m_customNodeFilter->deref();
-}
+ NodeImpl *n = node->firstChild();
+ while (n) {
+ switch (acceptNode(n)) {
+ case NodeFilter::FILTER_ACCEPT:
+ return n;
+ case NodeFilter::FILTER_SKIP:
+ if (n->firstChild())
+ n = n->firstChild();
+ else
+ n = n->nextSibling();
+ break;
+ case NodeFilter::FILTER_REJECT:
+ n = n->nextSibling();
+ break;
+ }
+ }
-short NodeFilterImpl::acceptNode(const Node &n)
-{
- if (m_customNodeFilter)
- return m_customNodeFilter->acceptNode(n);
- else
- return NodeFilter::FILTER_ACCEPT;
-}
+ n = node->nextSibling();
+ while (n) {
+ switch (acceptNode(n)) {
+ case NodeFilter::FILTER_ACCEPT:
+ return n;
+ case NodeFilter::FILTER_SKIP:
+ return findNextNode(n);
+ case NodeFilter::FILTER_REJECT:
+ n = n->nextSibling();
+ break;
+ }
+ }
-void NodeFilterImpl::setCustomNodeFilter(CustomNodeFilter *custom)
-{
- m_customNodeFilter = custom;
- if (m_customNodeFilter)
- m_customNodeFilter->ref();
-}
+ NodeImpl *parent = findParentNode(node, NodeFilter::FILTER_ACCEPT | NodeFilter::FILTER_SKIP);
+ while (parent) {
+ n = parent->nextSibling();
+ while (n) {
+ switch (acceptNode(n)) {
+ case NodeFilter::FILTER_ACCEPT:
+ return n;
+ case NodeFilter::FILTER_SKIP:
+ return findNextNode(n);
+ case NodeFilter::FILTER_REJECT:
+ n = n->nextSibling();
+ break;
+ }
+ }
+ parent = findParentNode(parent, NodeFilter::FILTER_ACCEPT | NodeFilter::FILTER_SKIP);
+ }
-CustomNodeFilter *NodeFilterImpl::customNodeFilter()
-{
- return m_customNodeFilter;
+ return 0;
}
// --------------------------------------------------------------
-TreeWalkerImpl::TreeWalkerImpl()
+NodeIteratorImpl::NodeIteratorImpl(NodeImpl *rootNode, long whatToShow, NodeFilterImpl *filter, bool expandEntityReferences)
+ :TraversalImpl(rootNode, whatToShow, filter, expandEntityReferences), m_referenceNode(0), m_beforeReferenceNode(true), m_detached(false), m_doc(0)
{
- m_filter = 0;
- m_whatToShow = 0x0000FFFF;
- m_expandEntityReferences = true;
-}
-
-TreeWalkerImpl::TreeWalkerImpl(const TreeWalkerImpl &other)
- : khtml::Shared<TreeWalkerImpl>()
-{
- m_expandEntityReferences = other.m_expandEntityReferences;
- m_filter = other.m_filter;
- m_whatToShow = other.m_whatToShow;
- m_currentNode = other.m_currentNode;
- m_rootNode = other.m_rootNode;
-}
-
-TreeWalkerImpl::TreeWalkerImpl(Node n, NodeFilter *f)
-{
- m_currentNode = n;
- m_rootNode = n;
- m_whatToShow = 0x0000FFFF;
- m_filter = f;
-}
-
-TreeWalkerImpl::TreeWalkerImpl(Node n, long _whatToShow, NodeFilter *f)
-{
- m_currentNode = n;
- m_rootNode = n;
- m_whatToShow = _whatToShow;
- m_filter = f;
+ if (root()) {
+ setDocument(root()->getDocument());
+ if (document()) {
+ document()->attachNodeIterator(this);
+ document()->ref();
+ }
+ }
}
-TreeWalkerImpl &TreeWalkerImpl::operator = (const TreeWalkerImpl &other)
+NodeIteratorImpl::~NodeIteratorImpl()
{
- m_expandEntityReferences = other.m_expandEntityReferences;
- m_filter = other.m_filter;
- m_whatToShow = other.m_whatToShow;
- m_currentNode = other.m_currentNode;
- return *this;
+ if (referenceNode())
+ referenceNode()->deref();
+ if (document()) {
+ document()->detachNodeIterator(this);
+ document()->deref();
+ }
}
-TreeWalkerImpl::~TreeWalkerImpl()
+NodeImpl *NodeIteratorImpl::nextNode(int &exceptioncode)
{
- if(m_filter)
- {
- delete m_filter;
- m_filter = 0;
- }
-}
-
-
-
+ if (detached()) {
+ exceptioncode = DOMException::INVALID_STATE_ERR;
+ return 0;
+ }
+ NodeImpl *result = 0;
+ if (pointerBeforeReferenceNode() && acceptNode(referenceNode()) == NodeFilter::FILTER_ACCEPT)
+ result = referenceNode();
+ else {
+ result = findNextNode(referenceNode());
+ if (result)
+ setReferenceNode(result);
+ }
-Node TreeWalkerImpl::getRoot()
-{
- // ###
- return 0;
+ setPointerBeforeReferenceNode(false);
+ return result;
}
-unsigned long TreeWalkerImpl::getWhatToShow()
+NodeImpl *NodeIteratorImpl::previousNode(int &exceptioncode)
{
- // ###
- return 0;
-}
+ if (detached()) {
+ exceptioncode = DOMException::INVALID_STATE_ERR;
+ return 0;
+ }
-NodeFilter TreeWalkerImpl::getFilter()
-{
- // ###
- return 0;
-}
+ NodeImpl *result = 0;
+ if (!pointerBeforeReferenceNode() && acceptNode(referenceNode()) == NodeFilter::FILTER_ACCEPT)
+ result = referenceNode();
+ else {
+ result = findPreviousNode(referenceNode());
+ if (result)
+ setReferenceNode(result);
+ }
-bool TreeWalkerImpl::getExpandEntityReferences()
-{
- // ###
- return 0;
+ setPointerBeforeReferenceNode();
+ return result;
}
-Node TreeWalkerImpl::getCurrentNode()
+void NodeIteratorImpl::detach(int &/*exceptioncode*/)
{
- return m_currentNode;
+ if (document())
+ document()->detachNodeIterator(this);
+ m_detached = true;
}
-void TreeWalkerImpl::setWhatToShow(long _whatToShow)
+void NodeIteratorImpl::setReferenceNode(NodeImpl *node)
{
- // do some testing wether this is an accepted value
- m_whatToShow = _whatToShow;
+ if (node == m_referenceNode)
+ return;
+
+ NodeImpl *old = m_referenceNode;
+ m_referenceNode = node;
+ if (m_referenceNode)
+ m_referenceNode->ref();
+ if (old)
+ old->deref();
}
-void TreeWalkerImpl::setFilter(NodeFilter *_filter)
+void NodeIteratorImpl::setDocument(DocumentImpl *doc)
{
- // ### allow setting of filter to 0?
- if(_filter)
- m_filter = _filter;
+ if (doc == m_doc)
+ return;
+
+ DocumentImpl *old = m_doc;
+ m_doc = doc;
+ if (m_doc)
+ m_doc->ref();
+ if (old)
+ old->deref();
}
-void TreeWalkerImpl::setExpandEntityReferences(bool value)
+void NodeIteratorImpl::notifyBeforeNodeRemoval(NodeImpl *willRemove)
{
- m_expandEntityReferences = value;
-}
+ // Iterator is not affected if the removed node is the reference node and is the root.
+ // or if removed node is not the reference node, or the ancestor of the reference node.
+ if (!willRemove || willRemove == root())
+ return;
+ bool willRemoveReferenceNode = willRemove == referenceNode();
+ bool willRemoveReferenceNodeAncestor = willRemove->isAncestor(referenceNode());
+ if (!willRemoveReferenceNode && !willRemoveReferenceNodeAncestor)
+ return;
-void TreeWalkerImpl::setCurrentNode( const Node n )
-{
- if( !n.isNull() )
- {
- m_rootNode = n;
- m_currentNode = n;
+ if (pointerBeforeReferenceNode()) {
+ NodeImpl *node = findNextNode(willRemove);
+ if (node) {
+ // Move out from under the node being removed if the reference node is
+ // a descendant of the node being removed.
+ if (willRemoveReferenceNodeAncestor) {
+ while (node && willRemove->isAncestor(node))
+ node = findNextNode(node);
+ }
+ if (node)
+ setReferenceNode(node);
+ }
+ else {
+ node = findPreviousNode(willRemove);
+ if (node) {
+ // Move out from under the node being removed if the reference node is
+ // a descendant of the node being removed.
+ if (willRemoveReferenceNodeAncestor) {
+ while (node && willRemove->isAncestor(node))
+ node = findPreviousNode(node);
+ }
+ if (node) {
+ // Removing last node.
+ // Need to move the pointer after the node preceding the
+ // new reference node.
+ setReferenceNode(node);
+ setPointerBeforeReferenceNode(false);
+ }
+ }
+ }
+ }
+ else {
+ NodeImpl *node = findPreviousNode(willRemove);
+ if (node) {
+ // Move out from under the node being removed if the reference node is
+ // a descendant of the node being removed.
+ if (willRemoveReferenceNodeAncestor) {
+ while (node && willRemove->isAncestor(node))
+ node = findPreviousNode(node);
+ }
+ if (node)
+ setReferenceNode(node);
+ }
+ else {
+ node = findNextNode(willRemove);
+ // Move out from under the node being removed if the reference node is
+ // a descendant of the node being removed.
+ if (willRemoveReferenceNodeAncestor) {
+ while (node && willRemove->isAncestor(node))
+ node = findPreviousNode(node);
+ }
+ if (node)
+ setReferenceNode(node);
+ }
}
-// else
-// throw( DOMException::NOT_SUPPORTED_ERR );
-}
-
-Node TreeWalkerImpl::parentNode( )
-{
- Node n = getParentNode(m_currentNode);
- if( !n.isNull() )
- m_currentNode = n;
- return n;
}
+// --------------------------------------------------------------
-Node TreeWalkerImpl::firstChild( )
+TreeWalkerImpl::TreeWalkerImpl(NodeImpl *rootNode, long whatToShow, NodeFilterImpl *filter, bool expandEntityReferences)
+ : TraversalImpl(rootNode, whatToShow, filter, expandEntityReferences), m_current(rootNode)
{
- Node n = getFirstChild(m_currentNode);
- if( !n.isNull() )
- m_currentNode = n;
- return n;
+ if (currentNode())
+ currentNode()->ref();
}
-
-Node TreeWalkerImpl::lastChild( )
+TreeWalkerImpl::~TreeWalkerImpl()
{
- Node n = getLastChild(m_currentNode);
- if( !n.isNull() )
- m_currentNode = n;
- return n;
+ if (currentNode())
+ currentNode()->deref();
}
-Node TreeWalkerImpl::previousSibling( )
+void TreeWalkerImpl::setCurrentNode(NodeImpl *node, int &exceptioncode)
{
- Node n = getPreviousSibling(m_currentNode);
- if( !n.isNull() )
- m_currentNode = n;
- return n;
-}
+ if (!node) {
+ exceptioncode = DOMException::NOT_SUPPORTED_ERR;
+ return;
+ }
-Node TreeWalkerImpl::nextSibling( )
-{
- Node n = getNextSibling(m_currentNode);
- if( !n.isNull() )
- m_currentNode = n;
- return n;
+ if (node == m_current)
+ return;
+
+ NodeImpl *old = m_current;
+ m_current = node;
+ if (m_current)
+ m_current->ref();
+ if (old)
+ old->deref();
}
-Node TreeWalkerImpl::previousNode( )
+void TreeWalkerImpl::setCurrentNode(NodeImpl *node)
{
-/* 1. my previous sibling.lastchild
- * 2. my previous sibling
- * 3. my parent
- */
-
- Node n = getPreviousSibling(m_currentNode);
- if( n.isNull() )
- {
- n = getParentNode(m_currentNode);
- if( !n.isNull() ) //parent
- {
- m_currentNode = n;
- return m_currentNode;
- }
- else // parent failed.. no previous node
- return Node();
- }
-
- Node child = getLastChild(n);
- if( !child.isNull() ) // previous siblings last child
- {
- m_currentNode = child;
- return m_currentNode;
- }
- else // previous sibling
- {
- m_currentNode = n;
- return m_currentNode;
- }
- return Node(); // should never get here!
+ assert(node);
+ int dummy;
+ setCurrentNode(node, dummy);
}
-Node TreeWalkerImpl::nextNode( )
+NodeImpl *TreeWalkerImpl::parentNode()
{
-/* 1. my first child
- * 2. my next sibling
- * 3. my parents sibling, or their parents sibling (loop)
- * 4. not found
- */
-
- Node n = getFirstChild(m_currentNode);
- if( !n.isNull() ) // my first child
- {
- m_currentNode = n;
- return n;
- }
-
- n = getNextSibling(m_currentNode); // my next sibling
- if( !n.isNull() )
- {
- m_currentNode = n;
- return m_currentNode;
- }
- Node parent = getParentNode(m_currentNode);
- while( !parent.isNull() ) // parents sibling
- {
- n = getNextSibling(parent);
- if( !n.isNull() )
- {
- m_currentNode = n;
- return m_currentNode;
- }
- else
- parent = getParentNode(parent);
- }
- return Node();
+ NodeImpl *node = findParentNode(currentNode());
+ if (node)
+ setCurrentNode(node);
+ return currentNode();
}
-short TreeWalkerImpl::isAccepted(Node n)
+NodeImpl *TreeWalkerImpl::firstChild()
{
- // if XML is implemented we have to check expandEntityRerefences in this function
- if( ( ( 1 << n.nodeType()-1 ) & m_whatToShow) != 0 )
- {
- if(m_filter)
- return m_filter->acceptNode(n);
- else
- return NodeFilter::FILTER_ACCEPT;
- }
- return NodeFilter::FILTER_SKIP;
+ NodeImpl *node = findFirstChild(currentNode());
+ if (node)
+ setCurrentNode(node);
+ return currentNode();
}
-Node TreeWalkerImpl::getParentNode(Node n)
+NodeImpl *TreeWalkerImpl::lastChild()
{
- short _result = NodeFilter::FILTER_ACCEPT;
-
- if( n == m_rootNode /*|| n.isNull()*/ )
- return Node();
-
- Node _tempCurrent = n.parentNode();
-
- if( _tempCurrent.isNull() )
- return Node();
-
- _result = isAccepted(_tempCurrent );
- if(_result == NodeFilter::FILTER_ACCEPT)
- return _tempCurrent; // match found
-
- return getParentNode(_tempCurrent);
+ NodeImpl *node = findLastChild(currentNode());
+ if (node)
+ setCurrentNode(node);
+ return currentNode();
}
-Node TreeWalkerImpl::getFirstChild(Node n)
+NodeImpl *TreeWalkerImpl::previousSibling()
{
- short _result;
-
- if( n.isNull() || n.firstChild().isNull() )
- return Node();
- n = n.firstChild();
-
- _result = isAccepted(n);
-
- switch(_result)
- {
- case NodeFilter::FILTER_ACCEPT:
- return n;
- break;
- case NodeFilter::FILTER_SKIP:
- if( n.hasChildNodes() )
- return getFirstChild(n);
- else
- return getNextSibling(n);
- break;
-
- case NodeFilter::FILTER_REJECT:
- return getNextSibling(n);
- break;
- }
- return Node(); // should never get here!
+ NodeImpl *node = findPreviousSibling(currentNode());
+ if (node)
+ setCurrentNode(node);
+ return currentNode();
}
-Node TreeWalkerImpl::getLastChild(Node n)
+NodeImpl *TreeWalkerImpl::nextSibling()
{
- short _result;
-
- if( n.isNull() || n.lastChild().isNull() )
- return Node();
- n = n.lastChild();
- _result = isAccepted(n);
- switch(_result)
- {
- case NodeFilter::FILTER_ACCEPT:
- return n;
- break;
-
- case NodeFilter::FILTER_SKIP:
- if( n.hasChildNodes() )
- return getLastChild(n);
- else
- return getPreviousSibling(n);
- break;
-
- case NodeFilter::FILTER_REJECT:
- return getPreviousSibling(n);
- break;
- }
- return Node();
+ NodeImpl *node = findNextSibling(currentNode());
+ if (node)
+ setCurrentNode(node);
+ return currentNode();
}
-Node TreeWalkerImpl::getPreviousSibling(Node n)
+NodeImpl *TreeWalkerImpl::previousNode()
{
- short _result;
- Node _tempCurrent;
-
- if( n.isNull() )
- return Node();
- //first the cases if we have a previousSibling
- _tempCurrent = n.previousSibling();
- if( !_tempCurrent.isNull() )
- {
- _result = isAccepted(_tempCurrent);
- switch(_result)
- {
- case NodeFilter::FILTER_ACCEPT:
- return _tempCurrent;
- break;
-
- case NodeFilter::FILTER_SKIP:
- {
- Node nskip = getLastChild(_tempCurrent);
- if( !nskip.isNull() )
- return nskip;
- return getPreviousSibling(_tempCurrent);
- break;
- }
-
- case NodeFilter::FILTER_REJECT:
- return getPreviousSibling(_tempCurrent);
- break;
- }
- }
- // now the case if we don't have previous sibling
- else
- {
- _tempCurrent = _tempCurrent.parentNode();
- if(_tempCurrent.isNull() || _tempCurrent == m_rootNode)
- return Node();
- _result = isAccepted(_tempCurrent);
- if(_result == NodeFilter::FILTER_SKIP)
- return getPreviousSibling(_tempCurrent);
-
- return Node();
-
- }
- return Node(); // should never get here!
+ NodeImpl *node = findPreviousNode(currentNode());
+ if (node)
+ setCurrentNode(node);
+ return currentNode();
}
-Node TreeWalkerImpl::getNextSibling(Node n)
+NodeImpl *TreeWalkerImpl::nextNode()
{
- Node _tempCurrent;
- short _result;
-
- if( n.isNull() || _tempCurrent == m_rootNode)
- return Node();
-
- _tempCurrent = n.nextSibling();
- if( !_tempCurrent.isNull() )
- {
- _result = isAccepted(_tempCurrent);
- switch(_result)
- {
- case NodeFilter::FILTER_ACCEPT:
- return _tempCurrent;
- break;
-
- case NodeFilter::FILTER_SKIP:
- {
- Node nskip = getFirstChild(_tempCurrent);
- if( !nskip.isNull() )
- return nskip;
- return getNextSibling(_tempCurrent);
- break;
- }
-
- case NodeFilter::FILTER_REJECT:
- return getNextSibling(_tempCurrent);
- break;
- }
- }
- else
- {
- _tempCurrent = _tempCurrent.parentNode();
- if(_tempCurrent.isNull() || _tempCurrent == m_rootNode)
- return Node();
- _result = isAccepted(_tempCurrent);
- if(_result == NodeFilter::FILTER_SKIP)
- return getNextSibling(_tempCurrent);
-
- return Node();
- }
- return Node();
+ NodeImpl *node = findNextNode(currentNode());
+ if (node)
+ setCurrentNode(node);
+ return currentNode();
}
+} // namespace DOM
diff --git a/WebCore/khtml/xml/dom2_traversalimpl.h b/WebCore/khtml/xml/dom2_traversalimpl.h
index 1a218d0..d8426ea 100644
--- a/WebCore/khtml/xml/dom2_traversalimpl.h
+++ b/WebCore/khtml/xml/dom2_traversalimpl.h
@@ -4,6 +4,7 @@
* (C) 1999 Lars Knoll (knoll at kde.org)
* (C) 2000 Frederik Holljen (frederik.holljen at hig.no)
* (C) 2001 Peter Kelly (pmk at post.com)
+ * 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
@@ -22,37 +23,75 @@
*
*/
-#ifndef _DOM2_TraversalImpl_h_
-#define _DOM2_TraversalImpl_h_
+#ifndef _dom2_traversal_h
+#define _dom2_traversal_h
+#include "dom/dom2_traversal.h"
#include "dom/dom_node.h"
#include "dom/dom_misc.h"
#include "misc/shared.h"
-#include "dom/dom2_traversal.h"
namespace DOM {
class NodeImpl;
class DocumentImpl;
-class NodeIteratorImpl : public khtml::Shared<NodeIteratorImpl>
+class NodeFilterImpl : public khtml::Shared<NodeFilterImpl>
{
public:
- NodeIteratorImpl(NodeImpl *_root, unsigned long _whatToShow, NodeFilter _filter, bool _entityReferenceExpansion);
- ~NodeIteratorImpl();
+ NodeFilterImpl() {}
+ NodeFilterImpl(NodeFilterCondition *);
+ ~NodeFilterImpl();
+
+ short acceptNode(const Node &) const;
+
+private:
+ NodeFilterImpl(const NodeFilterImpl &) : khtml::Shared<NodeFilterImpl>() {}
+ NodeFilterImpl &operator=(const NodeFilterImpl &) { return *this; }
+ NodeFilterCondition *m_condition;
+};
+class TraversalImpl : public khtml::Shared<TraversalImpl>
+{
+public:
+ TraversalImpl();
+ TraversalImpl(NodeImpl *, long whatToShow, NodeFilterImpl *, bool expandEntityReferences);
+ ~TraversalImpl();
+
+ NodeImpl *root() const { return m_root; }
+ unsigned long whatToShow() const { return m_whatToShow; }
+ NodeFilterImpl *filter() const { return m_filter; }
+ bool expandEntityReferences() const { return m_expandEntityReferences; }
+
+ NodeImpl *findParentNode(NodeImpl *, short accept=NodeFilter::FILTER_ACCEPT) const;
+ NodeImpl *findFirstChild(NodeImpl *) const;
+ NodeImpl *findLastChild(NodeImpl *) const;
+ NodeImpl *findNextSibling(NodeImpl *) const;
+ NodeImpl *findPreviousSibling(NodeImpl *) const;
+ NodeImpl *findNextNode(NodeImpl *) const;
+ NodeImpl *findLastDescendant(NodeImpl *node) const;
+ NodeImpl *findPreviousNode(NodeImpl *) const;
+ short acceptNode(NodeImpl *) const;
+
+private:
+ NodeImpl *m_root;
+ long m_whatToShow;
+ NodeFilterImpl *m_filter;
+ bool m_expandEntityReferences;
+};
- NodeImpl *root();
- unsigned long whatToShow();
- NodeFilter filter();
- bool expandEntityReferences();
+class NodeIteratorImpl : public TraversalImpl
+{
+public:
+ NodeIteratorImpl(NodeImpl *, long whatToShow, NodeFilterImpl *, bool expandEntityReferences);
+ ~NodeIteratorImpl();
NodeImpl *nextNode(int &exceptioncode);
NodeImpl *previousNode(int &exceptioncode);
void detach(int &exceptioncode);
-
-
+ NodeImpl *referenceNode() const { return m_referenceNode; }
+ bool pointerBeforeReferenceNode() const { return m_beforeReferenceNode; }
/**
* This function has to be called if you delete a node from the
@@ -61,136 +100,52 @@ public:
*/
void notifyBeforeNodeRemoval(NodeImpl *removed);
- short isAccepted(NodeImpl *n);
- NodeImpl *getNextNode(NodeImpl *n);
- NodeImpl *getPreviousNode(NodeImpl *n);
-protected:
- NodeImpl *m_root;
- long m_whatToShow;
- NodeFilter m_filter;
- bool m_expandEntityReferences;
+private:
+ NodeIteratorImpl() {};
+ NodeIteratorImpl(const NodeIteratorImpl &) : TraversalImpl() {}
+ NodeIteratorImpl &operator=(const NodeIteratorImpl &) { return *this; }
+
+ void setReferenceNode(NodeImpl *);
+ void setPointerBeforeReferenceNode(bool flag=true) { m_beforeReferenceNode = flag; }
+ bool detached() const { return m_detached; }
+ DocumentImpl * document() const { return m_doc; }
+ void setDocument(DocumentImpl *);
- bool m_inFront;
NodeImpl *m_referenceNode;
+ bool m_beforeReferenceNode;
bool m_detached;
DocumentImpl *m_doc;
};
-class NodeFilterImpl : public khtml::Shared<NodeFilterImpl>
-{
-public:
- NodeFilterImpl();
- ~NodeFilterImpl();
-
- short acceptNode(const Node &n);
-
- void setCustomNodeFilter(CustomNodeFilter *custom);
- CustomNodeFilter *customNodeFilter();
-protected:
- CustomNodeFilter *m_customNodeFilter;
-
-};
-
-class TreeWalkerImpl : public khtml::Shared<TreeWalkerImpl>
+class TreeWalkerImpl : public TraversalImpl
{
public:
- TreeWalkerImpl();
- TreeWalkerImpl(const TreeWalkerImpl &other);
- TreeWalkerImpl(Node n, NodeFilter *f=0);
- TreeWalkerImpl(Node n, long _whatToShow, NodeFilter *f=0);
- TreeWalkerImpl & operator = (const TreeWalkerImpl &other);
-
-
+ TreeWalkerImpl(NodeImpl *, long whatToShow, NodeFilterImpl *, bool expandEntityReferences);
~TreeWalkerImpl();
- Node getRoot();
-
- unsigned long getWhatToShow();
-
- NodeFilter getFilter();
-
- bool getExpandEntityReferences();
-
- Node getCurrentNode();
-
- void setCurrentNode(const Node _currentNode);
-
- Node parentNode();
-
- Node firstChild();
-
- Node lastChild ();
-
- Node previousSibling ();
-
- Node nextSibling();
-
- Node previousNode();
-
- Node nextNode();
-
-
- /**
- * Sets which node types are to be presented via the TreeWalker
- */
- void setWhatToShow(long _whatToShow);
- void setFilter(NodeFilter *_filter);
- void setExpandEntityReferences(bool value);
-
- Node getParentNode(Node n);
- Node getFirstChild(Node n);
- Node getLastChild(Node n);
- Node getPreviousSibling(Node n);
- Node getNextSibling(Node n);
-
- short isAccepted(Node n);
-
-protected:
- /**
- * This attribute determines which node types are presented via
- * the TreeWalker.
- *
- */
- long m_whatToShow;
-
- /**
- * The filter used to screen nodes.
- *
- */
- NodeFilter *m_filter;
-
- /**
- * The value of this flag determines whether entity reference
- * nodes are expanded. To produce a view of the document that has
- * entity references expanded and does not expose the entity
- * reference node itself, use the whatToShow flags to hide the
- * entity reference node and set expandEntityReferences to true
- * when creating the iterator. To produce a view of the document
- * that has entity reference nodes but no entity expansion, use
- * the whatToShow flags to show the entity reference node and set
- * expandEntityReferences to true.
- *
- * This is not implemented (allways true)
- */
- bool m_expandEntityReferences;
-
- /**
- * The current node.
- *
- * The value must not be null. Attempting to set it to null will
- * raise a NOT_SUPPORTED_ERR exception. When setting a node, the
- * whatToShow flags and any Filter associated with the TreeWalker
- * are not checked. The currentNode may be set to any Node of any
- * type.
- *
- */
- Node m_currentNode;
-
- Node m_rootNode;
+ NodeImpl *currentNode() const { return m_current; }
+ void setCurrentNode(NodeImpl *, int &exceptioncode);
+
+ NodeImpl *parentNode();
+ NodeImpl *firstChild();
+ NodeImpl *lastChild();
+ NodeImpl *previousSibling();
+ NodeImpl *nextSibling();
+ NodeImpl *previousNode();
+ NodeImpl *nextNode();
+
+private:
+ TreeWalkerImpl() {};
+ TreeWalkerImpl(const TreeWalkerImpl &) : TraversalImpl() {}
+ TreeWalkerImpl &operator=(const TreeWalkerImpl &) { return *this; }
+
+ // convenience for when it is known there will be no exception
+ void setCurrentNode(NodeImpl *);
+
+ NodeImpl *m_current;
};
-
-}; // namespace
+} // namespace
#endif
diff --git a/WebCore/khtml/xml/dom_docimpl.cpp b/WebCore/khtml/xml/dom_docimpl.cpp
index 464cbf4..555cce5 100644
--- a/WebCore/khtml/xml/dom_docimpl.cpp
+++ b/WebCore/khtml/xml/dom_docimpl.cpp
@@ -970,22 +970,24 @@ RangeImpl *DocumentImpl::createRange()
return new RangeImpl( docPtr() );
}
-NodeIteratorImpl *DocumentImpl::createNodeIterator(NodeImpl *root, unsigned long whatToShow,
- NodeFilter &filter, bool entityReferenceExpansion,
- int &exceptioncode)
+NodeIteratorImpl *DocumentImpl::createNodeIterator(NodeImpl *root, unsigned long whatToShow,
+ NodeFilterImpl *filter, bool expandEntityReferences, int &exceptioncode)
{
if (!root) {
exceptioncode = DOMException::NOT_SUPPORTED_ERR;
return 0;
}
-
- return new NodeIteratorImpl(root,whatToShow,filter,entityReferenceExpansion);
+ return new NodeIteratorImpl(root, whatToShow, filter, expandEntityReferences);
}
-TreeWalkerImpl *DocumentImpl::createTreeWalker(const Node &root, unsigned long whatToShow, const NodeFilter &filter,
- bool entityReferenceExpansion)
+TreeWalkerImpl *DocumentImpl::createTreeWalker(NodeImpl *root, unsigned long whatToShow,
+ NodeFilterImpl *filter, bool expandEntityReferences, int &exceptioncode)
{
- return new TreeWalkerImpl;
+ if (!root) {
+ exceptioncode = DOMException::NOT_SUPPORTED_ERR;
+ return 0;
+ }
+ return new TreeWalkerImpl(root, whatToShow, filter, expandEntityReferences);
}
void DocumentImpl::setDocumentChanged(bool b)
diff --git a/WebCore/khtml/xml/dom_docimpl.h b/WebCore/khtml/xml/dom_docimpl.h
index 26f4266..db2ce55 100644
--- a/WebCore/khtml/xml/dom_docimpl.h
+++ b/WebCore/khtml/xml/dom_docimpl.h
@@ -243,10 +243,10 @@ public:
RangeImpl *createRange();
NodeIteratorImpl *createNodeIterator(NodeImpl *root, unsigned long whatToShow,
- NodeFilter &filter, bool entityReferenceExpansion, int &exceptioncode);
+ NodeFilterImpl *filter, bool expandEntityReferences, int &exceptioncode);
- TreeWalkerImpl *createTreeWalker(const Node &root, unsigned long whatToShow, const NodeFilter &filter,
- bool entityReferenceExpansion);
+ TreeWalkerImpl *createTreeWalker(NodeImpl *root, unsigned long whatToShow,
+ NodeFilterImpl *filter, bool expandEntityReferences, int &exceptioncode);
// Special support for editing
CSSStyleDeclarationImpl *createCSSStyleDeclaration();
diff --git a/WebCore/khtml/xml/dom_nodeimpl.cpp b/WebCore/khtml/xml/dom_nodeimpl.cpp
index 3d3508c..c07d6df 100644
--- a/WebCore/khtml/xml/dom_nodeimpl.cpp
+++ b/WebCore/khtml/xml/dom_nodeimpl.cpp
@@ -987,7 +987,7 @@ void NodeImpl::checkAddChild(NodeImpl *newChild, int &exceptioncode)
// newChild node, or if the node to append is one of this node's ancestors.
// check for ancestor/same node
- if (isAncestor(newChild)) {
+ if (newChild == this || isAncestor(newChild)) {
exceptioncode = DOMException::HIERARCHY_REQUEST_ERR;
return;
}
@@ -1018,12 +1018,12 @@ void NodeImpl::checkAddChild(NodeImpl *newChild, int &exceptioncode)
}
}
-bool NodeImpl::isAncestor( NodeImpl *other )
+bool NodeImpl::isAncestor(NodeImpl *node) const
{
- // Return true if other is the same as this node or an ancestor of it, otherwise false
- NodeImpl *n;
- for (n = this; n; n = n->parentNode()) {
- if (n == other)
+ if (!node || node == this)
+ return false;
+ for (NodeImpl *p = node->parentNode(); p; p = p->parentNode()) {
+ if (p == this)
return true;
}
return false;
diff --git a/WebCore/khtml/xml/dom_nodeimpl.h b/WebCore/khtml/xml/dom_nodeimpl.h
index 110b50e..f961638 100644
--- a/WebCore/khtml/xml/dom_nodeimpl.h
+++ b/WebCore/khtml/xml/dom_nodeimpl.h
@@ -339,7 +339,7 @@ public:
void checkSetPrefix(const DOMString &_prefix, int &exceptioncode);
void checkAddChild(NodeImpl *newChild, int &exceptioncode);
- bool isAncestor( NodeImpl *other );
+ bool isAncestor(NodeImpl *) const;
virtual bool childAllowed( NodeImpl *newChild );
virtual long maxOffset() const;
diff --git a/WebCore/kwq/DOM.mm b/WebCore/kwq/DOM.mm
index 857519c..72c3147 100644
--- a/WebCore/kwq/DOM.mm
+++ b/WebCore/kwq/DOM.mm
@@ -35,6 +35,7 @@
#import <dom/dom_text.h>
#import <dom/dom_xml.h>
#import <dom/dom2_range.h>
+#import <dom/dom2_traversal.h>
#import <html/html_elementimpl.h>
#import <misc/htmltags.h>
#import <xml/dom_docimpl.h>
@@ -68,7 +69,11 @@ using DOM::HTMLElementImpl;
using DOM::NamedNodeMap;
using DOM::NamedNodeMapImpl;
using DOM::Node;
+using DOM::NodeFilter;
+using DOM::NodeFilterCondition;
+using DOM::NodeFilterImpl;
using DOM::NodeImpl;
+using DOM::NodeIteratorImpl;
using DOM::NodeListImpl;
using DOM::NotationImpl;
using DOM::ProcessingInstructionImpl;
@@ -76,6 +81,7 @@ using DOM::Range;
using DOM::RangeException;
using DOM::RangeImpl;
using DOM::TextImpl;
+using DOM::TreeWalkerImpl;
@interface DOMAttr (WebCoreInternal)
+ (DOMAttr *)_attrWithImpl:(AttrImpl *)impl;
@@ -1858,154 +1864,320 @@ inline Document DocumentImpl::createInstance(DocumentImpl *impl)
@end
- at implementation DOMDocument (DOMDocumentTraversal)
+//------------------------------------------------------------------------------------------
+
+ at implementation DOMNodeFilter
-- (DOMNodeIterator *)createNodeIterator:(DOMNode *)root :(unsigned long)whatToShow :(DOMNodeFilter *)filter :(BOOL)entityReferenceExpansion
+- (id)_initWithNodeFilterImpl:(NodeFilterImpl *)impl
{
- ERROR("unimplemented");
- return nil;
+ ASSERT(impl);
+
+ [super _init];
+ _internal = DOM_cast<DOMObjectInternal *>(impl);
+ impl->ref();
+ addDOMWrapper(self, impl);
+ return self;
}
-- (DOMTreeWalker *)createTreeWalker:(DOMNode *)root :(unsigned long)whatToShow :(DOMNodeFilter *)filter :(BOOL)entityReferenceExpansion
++ (DOMNodeFilter *)_nodeFilterWithImpl:(NodeFilterImpl *)impl
{
- ERROR("unimplemented");
- return nil;
+ if (!impl)
+ return nil;
+
+ id cachedInstance;
+ cachedInstance = getDOMWrapper(impl);
+ if (cachedInstance)
+ return [[cachedInstance retain] autorelease];
+
+ return [[[self alloc] _initWithNodeFilterImpl:impl] autorelease];
}
- at end
+- (NodeFilterImpl *)_nodeFilterImpl
+{
+ return DOM_cast<NodeFilterImpl *>(_internal);
+}
- at implementation DOMNodeFilter
+- (void)dealloc
+{
+ if (_internal)
+ DOM_cast<NodeFilterImpl *>(_internal)->deref();
+ [super dealloc];
+}
-- (short)acceptNode:(DOMNode *)n
+- (short)acceptNode:(DOMNode *)node
{
- ERROR("unimplemented");
- return 0;
+ return [self _nodeFilterImpl]->acceptNode([node _nodeImpl]);
}
@end
+
@implementation DOMNodeIterator
+- (id)_initWithNodeIteratorImpl:(NodeIteratorImpl *)impl filter:(id <DOMNodeFilter>)filter
+{
+ ASSERT(impl);
+
+ [super _init];
+ _internal = DOM_cast<DOMObjectInternal *>(impl);
+ impl->ref();
+ addDOMWrapper(self, impl);
+ m_filter = [filter retain];
+ return self;
+}
+
+- (NodeIteratorImpl *)_nodeIteratorImpl
+{
+ return DOM_cast<NodeIteratorImpl *>(_internal);
+}
+
+- (void)dealloc
+{
+ if (m_filter)
+ [m_filter release];
+ if (_internal)
+ DOM_cast<NodeIteratorImpl *>(_internal)->deref();
+ [super dealloc];
+}
+
- (DOMNode *)root
{
- ERROR("unimplemented");
- return nil;
+ return [DOMNode _nodeWithImpl:[self _nodeIteratorImpl]->root()];
}
- (unsigned long)whatToShow
{
- ERROR("unimplemented");
- return 0;
+ return [self _nodeIteratorImpl]->whatToShow();
}
-- (DOMNodeFilter *)filter
+- (id <DOMNodeFilter>)filter
{
- ERROR("unimplemented");
- return nil;
+ if (m_filter)
+ // This node iterator was created from the objc side
+ return [[m_filter retain] autorelease];
+
+ // This node iterator was created from the c++ side
+ return [DOMNodeFilter _nodeFilterWithImpl:[self _nodeIteratorImpl]->filter()];
}
- (BOOL)expandEntityReferences
{
- ERROR("unimplemented");
- return NO;
+ return [self _nodeIteratorImpl]->expandEntityReferences();
}
- (DOMNode *)nextNode
{
- ERROR("unimplemented");
- return nil;
+ int exceptionCode = 0;
+ DOMNode *result = [DOMNode _nodeWithImpl:[self _nodeIteratorImpl]->nextNode(exceptionCode)];
+ raiseOnDOMError(exceptionCode);
+ return result;
}
- (DOMNode *)previousNode
{
- ERROR("unimplemented");
- return nil;
+ int exceptionCode = 0;
+ DOMNode *result = [DOMNode _nodeWithImpl:[self _nodeIteratorImpl]->previousNode(exceptionCode)];
+ raiseOnDOMError(exceptionCode);
+ return result;
}
- (void)detach
{
- ERROR("unimplemented");
+ int exceptionCode = 0;
+ [self _nodeIteratorImpl]->detach(exceptionCode);
+ raiseOnDOMError(exceptionCode);
+}
+
+ at end
+
+ at implementation DOMNodeIterator(WebCoreInternal)
+
++ (DOMNodeIterator *)_nodeIteratorWithImpl:(NodeIteratorImpl *)impl filter:(id <DOMNodeFilter>)filter
+{
+ if (!impl)
+ return nil;
+
+ id cachedInstance;
+ cachedInstance = getDOMWrapper(impl);
+ if (cachedInstance)
+ return [[cachedInstance retain] autorelease];
+
+ return [[[self alloc] _initWithNodeIteratorImpl:impl filter:filter] autorelease];
}
@end
@implementation DOMTreeWalker
+- (id)_initWithTreeWalkerImpl:(TreeWalkerImpl *)impl filter:(id <DOMNodeFilter>)filter
+{
+ ASSERT(impl);
+
+ [super _init];
+ _internal = DOM_cast<DOMObjectInternal *>(impl);
+ impl->ref();
+ addDOMWrapper(self, impl);
+ m_filter = [filter retain];
+ return self;
+}
+
+- (TreeWalkerImpl *)_treeWalkerImpl
+{
+ return DOM_cast<TreeWalkerImpl *>(_internal);
+}
+
+- (void)dealloc
+{
+ if (m_filter)
+ [m_filter release];
+ if (_internal)
+ DOM_cast<TreeWalkerImpl *>(_internal)->deref();
+ [super dealloc];
+}
+
- (DOMNode *)root
{
- ERROR("unimplemented");
- return nil;
+ return [DOMNode _nodeWithImpl:[self _treeWalkerImpl]->root()];
}
- (unsigned long)whatToShow
{
- ERROR("unimplemented");
- return 0;
+ return [self _treeWalkerImpl]->whatToShow();
}
-- (DOMNodeFilter *)filter
+- (id <DOMNodeFilter>)filter
{
- ERROR("unimplemented");
- return nil;
+ if (m_filter)
+ // This tree walker was created from the objc side
+ return [[m_filter retain] autorelease];
+
+ // This tree walker was created from the c++ side
+ return [DOMNodeFilter _nodeFilterWithImpl:[self _treeWalkerImpl]->filter()];
}
- (BOOL)expandEntityReferences
{
- ERROR("unimplemented");
- return NO;
+ return [self _treeWalkerImpl]->expandEntityReferences();
}
- (DOMNode *)currentNode
{
- ERROR("unimplemented");
- return nil;
+ return [DOMNode _nodeWithImpl:[self _treeWalkerImpl]->currentNode()];
}
- (void)setCurrentNode:(DOMNode *)currentNode
{
- ERROR("unimplemented");
+ int exceptionCode = 0;
+ [self _treeWalkerImpl]->setCurrentNode([currentNode _nodeImpl], exceptionCode);
+ raiseOnDOMError(exceptionCode);
}
- (DOMNode *)parentNode
{
- ERROR("unimplemented");
- return nil;
+ return [DOMNode _nodeWithImpl:[self _treeWalkerImpl]->parentNode()];
}
- (DOMNode *)firstChild
{
- ERROR("unimplemented");
- return nil;
+ return [DOMNode _nodeWithImpl:[self _treeWalkerImpl]->firstChild()];
}
- (DOMNode *)lastChild
{
- ERROR("unimplemented");
- return nil;
+ return [DOMNode _nodeWithImpl:[self _treeWalkerImpl]->lastChild()];
}
- (DOMNode *)previousSibling
{
- ERROR("unimplemented");
- return nil;
+ return [DOMNode _nodeWithImpl:[self _treeWalkerImpl]->previousSibling()];
}
- (DOMNode *)nextSibling
{
- ERROR("unimplemented");
- return nil;
+ return [DOMNode _nodeWithImpl:[self _treeWalkerImpl]->nextSibling()];
}
- (DOMNode *)previousNode
{
- ERROR("unimplemented");
- return nil;
+ return [DOMNode _nodeWithImpl:[self _treeWalkerImpl]->previousNode()];
}
- (DOMNode *)nextNode
{
- ERROR("unimplemented");
- return nil;
+ return [DOMNode _nodeWithImpl:[self _treeWalkerImpl]->nextNode()];
+}
+
+ at end
+
+ at implementation DOMTreeWalker (WebCoreInternal)
+
++ (DOMTreeWalker *)_treeWalkerWithImpl:(TreeWalkerImpl *)impl filter:(id <DOMNodeFilter>)filter
+{
+ if (!impl)
+ return nil;
+
+ id cachedInstance;
+ cachedInstance = getDOMWrapper(impl);
+ if (cachedInstance)
+ return [[cachedInstance retain] autorelease];
+
+ return [[[self alloc] _initWithTreeWalkerImpl:impl filter:filter] autorelease];
+}
+
+ at end
+
+class ObjCNodeFilterCondition : public NodeFilterCondition
+{
+public:
+ ObjCNodeFilterCondition(id <DOMNodeFilter>);
+ virtual ~ObjCNodeFilterCondition();
+ virtual short acceptNode(const Node &) const;
+private:
+ id <DOMNodeFilter> m_filter;
+};
+
+ObjCNodeFilterCondition::ObjCNodeFilterCondition(id <DOMNodeFilter> filter)
+ : m_filter(filter)
+{
+ ASSERT(m_filter);
+ [m_filter retain];
+}
+
+ObjCNodeFilterCondition::~ObjCNodeFilterCondition()
+{
+ [m_filter release];
+}
+
+short ObjCNodeFilterCondition::acceptNode(const Node &n) const
+{
+ if (n.isNull())
+ return NodeFilter::FILTER_REJECT;
+
+ return [m_filter acceptNode:[DOMNode _nodeWithImpl:n.handle()]];
+}
+
+ at implementation DOMDocument (DOMDocumentTraversal)
+
+- (DOMNodeIterator *)createNodeIterator:(DOMNode *)root :(unsigned long)whatToShow :(id <DOMNodeFilter>)filter :(BOOL)expandEntityReferences
+{
+ NodeFilter cppFilter;
+ if (filter)
+ cppFilter = NodeFilter(new ObjCNodeFilterCondition(filter));
+ int exceptionCode = 0;
+ NodeIteratorImpl *impl = [self _documentImpl]->createNodeIterator([root _nodeImpl], whatToShow, cppFilter.handle(), expandEntityReferences, exceptionCode);
+ raiseOnDOMError(exceptionCode);
+ return [DOMNodeIterator _nodeIteratorWithImpl:impl filter:filter];
+}
+
+- (DOMTreeWalker *)createTreeWalker:(DOMNode *)root :(unsigned long)whatToShow :(id <DOMNodeFilter>)filter :(BOOL)expandEntityReferences
+{
+ NodeFilter cppFilter;
+ if (filter)
+ cppFilter = NodeFilter(new ObjCNodeFilterCondition(filter));
+ int exceptionCode = 0;
+ TreeWalkerImpl *impl = [self _documentImpl]->createTreeWalker([root _nodeImpl], whatToShow, cppFilter.handle(), expandEntityReferences, exceptionCode);
+ raiseOnDOMError(exceptionCode);
+ return [DOMTreeWalker _treeWalkerWithImpl:impl filter:filter];
}
@end
diff --git a/WebCore/kwq/DOMInternal.h b/WebCore/kwq/DOMInternal.h
index c1e4bdf..d965658 100644
--- a/WebCore/kwq/DOMInternal.h
+++ b/WebCore/kwq/DOMInternal.h
@@ -30,10 +30,13 @@ namespace DOM {
class CSSStyleSheetImpl;
class DocumentImpl;
class ElementImpl;
+ class NodeFilterImpl;
class NodeImpl;
+ class NodeIteratorImpl;
class NodeListImpl;
class RangeImpl;
class StyleSheetListImpl;
+ class TreeWalkerImpl;
}
@interface DOMNode (WebCoreInternal)
@@ -60,6 +63,14 @@ namespace DOM {
- (DOM::RangeImpl *)_rangeImpl;
@end
+ at interface DOMNodeIterator (WebCoreInternal)
++ (DOMNodeIterator *)_nodeIteratorWithImpl:(DOM::NodeIteratorImpl *)impl filter:(id <DOMNodeFilter>)filter;
+ at end
+
+ at interface DOMTreeWalker (WebCoreInternal)
++ (DOMTreeWalker *)_treeWalkerWithImpl:(DOM::TreeWalkerImpl *)impl filter:(id <DOMNodeFilter>)filter;
+ at end
+
@interface DOMObject (WebCoreInternal)
- (id)_init;
@end
@@ -77,6 +88,10 @@ namespace DOM {
+ (DOMCSSStyleSheet *)_CSSStyleSheetWithImpl:(DOM::CSSStyleSheetImpl *)impl;
@end
+ at interface DOMNodeFilter : DOMObject <DOMNodeFilter>
++ (DOMNodeFilter *)_nodeFilterWithImpl:(DOM::NodeFilterImpl *)impl;
+ at end
+
// Helper functions for DOM wrappers and gluing to Objective-C
// Like reinterpret_cast, but a compiler error if you use it on the wrong type.
@@ -120,9 +135,12 @@ ALLOW_DOM_CAST(HTMLCollectionImpl)
ALLOW_DOM_CAST(HTMLOptionsCollectionImpl)
ALLOW_DOM_CAST(MediaListImpl)
ALLOW_DOM_CAST(NamedNodeMapImpl)
+ALLOW_DOM_CAST(NodeFilterImpl)
ALLOW_DOM_CAST(NodeImpl)
+ALLOW_DOM_CAST(NodeIteratorImpl)
ALLOW_DOM_CAST(NodeListImpl)
ALLOW_DOM_CAST(RangeImpl)
ALLOW_DOM_CAST(RectImpl)
ALLOW_DOM_CAST(StyleSheetImpl)
ALLOW_DOM_CAST(StyleSheetListImpl)
+ALLOW_DOM_CAST(TreeWalkerImpl)
diff --git a/WebCore/kwq/DOMTraversal.h b/WebCore/kwq/DOMTraversal.h
index 5f3eba8..61922fd 100644
--- a/WebCore/kwq/DOMTraversal.h
+++ b/WebCore/kwq/DOMTraversal.h
@@ -40,16 +40,6 @@
@class DOMNodeFilter;
- at interface DOMNodeIterator : DOMObject
-- (DOMNode *)root;
-- (unsigned long)whatToShow;
-- (DOMNodeFilter *)filter;
-- (BOOL)expandEntityReferences;
-- (DOMNode *)nextNode;
-- (DOMNode *)previousNode;
-- (void)detach;
- at end
-
enum {
// Constants returned by acceptNode
DOM_FILTER_ACCEPT = 1,
@@ -74,14 +64,30 @@ enum {
DOM_SHOW_NOTATION = 0x00000800,
};
- at interface DOMNodeFilter : DOMObject
+ at protocol DOMNodeFilter <NSObject>
- (short)acceptNode:(DOMNode *)n;
@end
+ at interface DOMNodeIterator : DOMObject
+{
+ id <DOMNodeFilter> m_filter;
+}
+- (DOMNode *)root;
+- (unsigned long)whatToShow;
+- (id <DOMNodeFilter>)filter;
+- (BOOL)expandEntityReferences;
+- (DOMNode *)nextNode;
+- (DOMNode *)previousNode;
+- (void)detach;
+ at end
+
@interface DOMTreeWalker : DOMObject
+{
+ id <DOMNodeFilter> m_filter;
+}
- (DOMNode *)root;
- (unsigned long)whatToShow;
-- (DOMNodeFilter *)filter;
+- (id <DOMNodeFilter>)filter;
- (BOOL)expandEntityReferences;
- (DOMNode *)currentNode;
- (void)setCurrentNode:(DOMNode *)currentNode;
@@ -95,6 +101,6 @@ enum {
@end
@interface DOMDocument (DOMDocumentTraversal)
-- (DOMNodeIterator *)createNodeIterator:(DOMNode *)root :(unsigned long)whatToShow :(DOMNodeFilter *)filter :(BOOL)entityReferenceExpansion;
-- (DOMTreeWalker *)createTreeWalker:(DOMNode *)root :(unsigned long)whatToShow :(DOMNodeFilter *)filter :(BOOL)entityReferenceExpansion;
+- (DOMNodeIterator *)createNodeIterator:(DOMNode *)root :(unsigned long)whatToShow :(id <DOMNodeFilter>)filter :(BOOL)expandEntityReferences;
+- (DOMTreeWalker *)createTreeWalker:(DOMNode *)root :(unsigned long)whatToShow :(id <DOMNodeFilter>)filter :(BOOL)expandEntityReferences;
@end
diff --git a/WebKit/ChangeLog b/WebKit/ChangeLog
index 3ed5ac4..08fd63a 100644
--- a/WebKit/ChangeLog
+++ b/WebKit/ChangeLog
@@ -1,3 +1,9 @@
+2004-05-04 Ken Kocienda <kocienda at apple.com>
+
+ Reviewed by Hyatt
+
+ * DOM.subproj/DOMTraversal.h: File coppied from WebCore
+
2004-05-02 Darin Adler <darin at apple.com>
Reviewed by Ken.
diff --git a/WebKit/DOM.subproj/DOMTraversal.h b/WebKit/DOM.subproj/DOMTraversal.h
index 5f3eba8..61922fd 100644
--- a/WebKit/DOM.subproj/DOMTraversal.h
+++ b/WebKit/DOM.subproj/DOMTraversal.h
@@ -40,16 +40,6 @@
@class DOMNodeFilter;
- at interface DOMNodeIterator : DOMObject
-- (DOMNode *)root;
-- (unsigned long)whatToShow;
-- (DOMNodeFilter *)filter;
-- (BOOL)expandEntityReferences;
-- (DOMNode *)nextNode;
-- (DOMNode *)previousNode;
-- (void)detach;
- at end
-
enum {
// Constants returned by acceptNode
DOM_FILTER_ACCEPT = 1,
@@ -74,14 +64,30 @@ enum {
DOM_SHOW_NOTATION = 0x00000800,
};
- at interface DOMNodeFilter : DOMObject
+ at protocol DOMNodeFilter <NSObject>
- (short)acceptNode:(DOMNode *)n;
@end
+ at interface DOMNodeIterator : DOMObject
+{
+ id <DOMNodeFilter> m_filter;
+}
+- (DOMNode *)root;
+- (unsigned long)whatToShow;
+- (id <DOMNodeFilter>)filter;
+- (BOOL)expandEntityReferences;
+- (DOMNode *)nextNode;
+- (DOMNode *)previousNode;
+- (void)detach;
+ at end
+
@interface DOMTreeWalker : DOMObject
+{
+ id <DOMNodeFilter> m_filter;
+}
- (DOMNode *)root;
- (unsigned long)whatToShow;
-- (DOMNodeFilter *)filter;
+- (id <DOMNodeFilter>)filter;
- (BOOL)expandEntityReferences;
- (DOMNode *)currentNode;
- (void)setCurrentNode:(DOMNode *)currentNode;
@@ -95,6 +101,6 @@ enum {
@end
@interface DOMDocument (DOMDocumentTraversal)
-- (DOMNodeIterator *)createNodeIterator:(DOMNode *)root :(unsigned long)whatToShow :(DOMNodeFilter *)filter :(BOOL)entityReferenceExpansion;
-- (DOMTreeWalker *)createTreeWalker:(DOMNode *)root :(unsigned long)whatToShow :(DOMNodeFilter *)filter :(BOOL)entityReferenceExpansion;
+- (DOMNodeIterator *)createNodeIterator:(DOMNode *)root :(unsigned long)whatToShow :(id <DOMNodeFilter>)filter :(BOOL)expandEntityReferences;
+- (DOMTreeWalker *)createTreeWalker:(DOMNode *)root :(unsigned long)whatToShow :(id <DOMNodeFilter>)filter :(BOOL)expandEntityReferences;
@end
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list