| Index: Source/core/rendering/RenderObject.cpp
|
| diff --git a/Source/core/rendering/RenderObject.cpp b/Source/core/rendering/RenderObject.cpp
|
| index d0bd4e71771d876444c313adf8434ab6927d3ebc..973b4dbec2eda0db6c9064e947398da3780eb120 100644
|
| --- a/Source/core/rendering/RenderObject.cpp
|
| +++ b/Source/core/rendering/RenderObject.cpp
|
| @@ -359,6 +359,60 @@ void RenderObject::removeChild(RenderObject* oldChild)
|
| children->removeChildNode(this, oldChild);
|
| }
|
|
|
| +// This is a non-recursive algorithm for visiting the tree in both pre and post
|
| +// order as well as skipping children when necessary and staying within a given
|
| +// root. Further, the algorithm takes into account nodes that still use recursive
|
| +// traversal and provides a clean way to switch between the two modes of traversal.
|
| +// This will allow us to incrementally change each class to non-recursive traversal
|
| +// instead of having to change everything at once. I developed this algorithm
|
| +// using a toy model of a tree like structure with methods similar to the render
|
| +// tree and its layout methods.
|
| +//
|
| +// NOTE: Once we switch everything over to non-recursive this algorithm can be made
|
| +// much simpler :)
|
| +RenderObject* RenderObject::nextForLayout(Order& order, const RenderObject* stayWithin, bool skippingChildren) const
|
| +{
|
| + RenderObject* node = const_cast<RenderObject*>(this);
|
| + if (node == stayWithin && order == Post)
|
| + return 0;
|
| +
|
| + if (!node->isNonRecursiveLayout()) {
|
| + if (node->parent() && node->parent()->isNonRecursiveLayout()) {
|
| + if (node->nextSibling()) {
|
| + order = Pre;
|
| + return node->nextSibling();
|
| + }
|
| + order = Post;
|
| + return node->parent();
|
| + }
|
| + return 0;
|
| + }
|
| +
|
| + if (order == Pre) {
|
| + if (node->firstChild() && !skippingChildren)
|
| + return node->firstChild();
|
| + order = Post;
|
| + return node;
|
| + }
|
| +
|
| + if (node->nextSibling()) {
|
| + order = Pre;
|
| + return node->nextSibling();
|
| + }
|
| +
|
| + for (RenderObject* parent = node->parent(); parent; parent = parent->parent()) {
|
| + if (order == Post) {
|
| + if (parent->isNonRecursiveLayout())
|
| + return parent;
|
| + return 0;
|
| + }
|
| +
|
| + if (parent->nextSibling())
|
| + return parent->nextSibling();
|
| + }
|
| + return 0;
|
| +}
|
| +
|
| RenderObject* RenderObject::nextInPreOrder() const
|
| {
|
| if (RenderObject* o = firstChild())
|
|
|