summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering/CounterNode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/rendering/CounterNode.cpp')
-rw-r--r--WebCore/rendering/CounterNode.cpp151
1 files changed, 95 insertions, 56 deletions
diff --git a/WebCore/rendering/CounterNode.cpp b/WebCore/rendering/CounterNode.cpp
index f546abb..95a3748 100644
--- a/WebCore/rendering/CounterNode.cpp
+++ b/WebCore/rendering/CounterNode.cpp
@@ -1,6 +1,4 @@
/*
- * This file is part of the HTML rendering engine for KDE.
- *
* Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
* Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
*
@@ -46,7 +44,58 @@ CounterNode::CounterNode(RenderObject* o, bool isReset, int value)
, m_nextSibling(0)
, m_firstChild(0)
, m_lastChild(0)
-{
+{
+}
+
+CounterNode* CounterNode::nextInPreOrderAfterChildren(const CounterNode* stayWithin) const
+{
+ if (this == stayWithin)
+ return 0;
+
+ CounterNode* next = m_nextSibling;
+ if (next)
+ return next;
+ next = m_parent;
+ while (next && !next->m_nextSibling) {
+ if (next == stayWithin)
+ return 0;
+ next = next->m_parent;
+ }
+ if (next)
+ return next->m_nextSibling;
+ return 0;
+}
+
+CounterNode* CounterNode::nextInPreOrder(const CounterNode* stayWithin) const
+{
+ if (CounterNode* next = m_firstChild)
+ return next;
+
+ return nextInPreOrderAfterChildren(stayWithin);
+}
+
+CounterNode* CounterNode::lastDescendant() const
+{
+ CounterNode* last = m_lastChild;
+ if (!last)
+ return 0;
+
+ while (CounterNode* lastChild = last->m_lastChild)
+ last = lastChild;
+
+ return last;
+}
+
+CounterNode* CounterNode::previousInPreOrder() const
+{
+ CounterNode* previous = m_previousSibling;
+ if (!previous)
+ return m_parent;
+
+ while (CounterNode* lastChild = previous->m_lastChild)
+ previous = lastChild;
+
+ return previous;
}
int CounterNode::computeCountInParent() const
@@ -58,26 +107,37 @@ int CounterNode::computeCountInParent() const
return m_parent->m_value + increment;
}
-void CounterNode::recount()
+
+void CounterNode::resetRenderer(const AtomicString& identifier) const
+{
+ if (!m_renderer || m_renderer->documentBeingDestroyed())
+ return;
+ if (RenderObjectChildList* children = m_renderer->virtualChildren())
+ children->invalidateCounters(m_renderer, identifier);
+}
+
+void CounterNode::resetRenderers(const AtomicString& identifier) const
+{
+ const CounterNode* node = this;
+ do {
+ node->resetRenderer(identifier);
+ node = node->nextInPreOrder(this);
+ } while (node);
+}
+
+void CounterNode::recount(const AtomicString& identifier)
{
- for (CounterNode* c = this; c; c = c->m_nextSibling) {
- int oldCount = c->m_countInParent;
- int newCount = c->computeCountInParent();
+ for (CounterNode* node = this; node; node = node->m_nextSibling) {
+ int oldCount = node->m_countInParent;
+ int newCount = node->computeCountInParent();
if (oldCount == newCount)
break;
- c->m_countInParent = newCount;
- // m_renderer contains the parent of the render node
- // corresponding to a CounterNode. Let's find the counter
- // child and make this re-layout.
- for (RenderObject* o = c->m_renderer->firstChild(); o; o = o->nextSibling())
- if (!o->documentBeingDestroyed() && o->isCounter()) {
- o->setNeedsLayoutAndPrefWidthsRecalc();
- break;
- }
+ node->m_countInParent = newCount;
+ node->resetRenderers(identifier);
}
}
-void CounterNode::insertAfter(CounterNode* newChild, CounterNode* refChild)
+void CounterNode::insertAfter(CounterNode* newChild, CounterNode* refChild, const AtomicString& identifier)
{
ASSERT(newChild);
ASSERT(!newChild->m_parent);
@@ -109,77 +169,56 @@ void CounterNode::insertAfter(CounterNode* newChild, CounterNode* refChild)
newChild->m_countInParent = newChild->computeCountInParent();
if (next)
- next->recount();
+ next->recount(identifier);
}
-void CounterNode::removeChild(CounterNode* oldChild)
+void CounterNode::removeChild(CounterNode* oldChild, const AtomicString& identifier)
{
ASSERT(oldChild);
ASSERT(!oldChild->m_firstChild);
ASSERT(!oldChild->m_lastChild);
CounterNode* next = oldChild->m_nextSibling;
- CounterNode* prev = oldChild->m_previousSibling;
+ CounterNode* previous = oldChild->m_previousSibling;
oldChild->m_nextSibling = 0;
oldChild->m_previousSibling = 0;
oldChild->m_parent = 0;
- if (prev)
- prev->m_nextSibling = next;
+ if (previous)
+ previous->m_nextSibling = next;
else {
ASSERT(m_firstChild == oldChild);
m_firstChild = next;
}
-
+
if (next)
- next->m_previousSibling = prev;
+ next->m_previousSibling = previous;
else {
ASSERT(m_lastChild == oldChild);
- m_lastChild = prev;
+ m_lastChild = previous;
}
-
+
if (next)
- next->recount();
+ next->recount(identifier);
}
#ifndef NDEBUG
-static const CounterNode* nextInPreOrderAfterChildren(const CounterNode* node)
-{
- CounterNode* next = node->nextSibling();
- if (!next) {
- next = node->parent();
- while (next && !next->nextSibling())
- next = next->parent();
- if (next)
- next = next->nextSibling();
- }
- return next;
-}
-
-static const CounterNode* nextInPreOrder(const CounterNode* node)
-{
- if (CounterNode* child = node->firstChild())
- return child;
- return nextInPreOrderAfterChildren(node);
-}
-
static void showTreeAndMark(const CounterNode* node)
{
const CounterNode* root = node;
while (root->parent())
root = root->parent();
- for (const CounterNode* c = root; c; c = nextInPreOrder(c)) {
- if (c == node)
- fprintf(stderr, "*");
- for (const CounterNode* d = c; d && d != root; d = d->parent())
- fprintf(stderr, "\t");
- if (c->isReset())
- fprintf(stderr, "reset: %d %d\n", c->value(), c->countInParent());
- else
- fprintf(stderr, "increment: %d %d\n", c->value(), c->countInParent());
+ for (const CounterNode* current = root; current; current = current->nextInPreOrder()) {
+ fwrite((current == node) ? "*" : " ", 1, 1, stderr);
+ for (const CounterNode* parent = current; parent && parent != root; parent = parent->parent())
+ fwrite(" ", 1, 2, stderr);
+ fprintf(stderr, "%p %s: %d %d P:%p PS:%p NS:%p R:%p\n",
+ current, current->isReset() ? "reset____" : "increment", current->value(),
+ current->countInParent(), current->parent(), current->previousSibling(),
+ current->nextSibling(), current->renderer());
}
}