summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering/CounterNode.cpp
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2010-02-02 14:57:50 +0000
committerSteve Block <steveblock@google.com>2010-02-04 15:06:55 +0000
commitd0825bca7fe65beaee391d30da42e937db621564 (patch)
tree7461c49eb5844ffd1f35d1ba2c8b7584c1620823 /WebCore/rendering/CounterNode.cpp
parent3db770bd97c5a59b6c7574ca80a39e5a51c1defd (diff)
downloadexternal_webkit-d0825bca7fe65beaee391d30da42e937db621564.zip
external_webkit-d0825bca7fe65beaee391d30da42e937db621564.tar.gz
external_webkit-d0825bca7fe65beaee391d30da42e937db621564.tar.bz2
Merge webkit.org at r54127 : Initial merge by git
Change-Id: Ib661abb595522f50ea406f72d3a0ce17f7193c82
Diffstat (limited to 'WebCore/rendering/CounterNode.cpp')
-rw-r--r--WebCore/rendering/CounterNode.cpp96
1 files changed, 63 insertions, 33 deletions
diff --git a/WebCore/rendering/CounterNode.cpp b/WebCore/rendering/CounterNode.cpp
index 95a3748..c164c81 100644
--- a/WebCore/rendering/CounterNode.cpp
+++ b/WebCore/rendering/CounterNode.cpp
@@ -22,20 +22,14 @@
#include "config.h"
#include "CounterNode.h"
+#include "RenderCounter.h"
#include "RenderObject.h"
#include <stdio.h>
-// FIXME: There's currently no strategy for getting the counter tree updated when new
-// elements with counter-reset and counter-increment styles are added to the render tree.
-// Also, the code can't handle changes where an existing node needs to change into a
-// "reset" node, or from a "reset" node back to not a "reset" node. As of this writing,
-// at least some of these problems manifest as failures in the t1204-increment and
-// t1204-reset tests in the CSS 2.1 test suite.
-
namespace WebCore {
-CounterNode::CounterNode(RenderObject* o, bool isReset, int value)
- : m_isReset(isReset)
+CounterNode::CounterNode(RenderObject* o, bool hasResetType, int value)
+ : m_hasResetType(hasResetType)
, m_value(value)
, m_countInParent(0)
, m_renderer(o)
@@ -52,18 +46,14 @@ CounterNode* CounterNode::nextInPreOrderAfterChildren(const CounterNode* stayWit
if (this == stayWithin)
return 0;
- CounterNode* next = m_nextSibling;
- if (next)
- return next;
- next = m_parent;
- while (next && !next->m_nextSibling) {
- if (next == stayWithin)
+ const CounterNode* current = this;
+ CounterNode* next;
+ while (!(next = current->m_nextSibling)) {
+ current = current->m_parent;
+ if (!current || current == stayWithin)
return 0;
- next = next->m_parent;
}
- if (next)
- return next->m_nextSibling;
- return 0;
+ return next;
}
CounterNode* CounterNode::nextInPreOrder(const CounterNode* stayWithin) const
@@ -100,14 +90,13 @@ CounterNode* CounterNode::previousInPreOrder() const
int CounterNode::computeCountInParent() const
{
- int increment = m_isReset ? 0 : m_value;
+ int increment = actsAsReset() ? 0 : m_value;
if (m_previousSibling)
return m_previousSibling->m_countInParent + increment;
ASSERT(m_parent->m_firstChild == this);
return m_parent->m_value + increment;
}
-
void CounterNode::resetRenderer(const AtomicString& identifier) const
{
if (!m_renderer || m_renderer->documentBeingDestroyed())
@@ -145,6 +134,11 @@ void CounterNode::insertAfter(CounterNode* newChild, CounterNode* refChild, cons
ASSERT(!newChild->m_nextSibling);
ASSERT(!refChild || refChild->m_parent == this);
+ if (newChild->m_hasResetType) {
+ while (m_lastChild != refChild)
+ RenderCounter::destroyCounterNode(m_lastChild->renderer(), identifier);
+ }
+
CounterNode* next;
if (refChild) {
@@ -155,21 +149,57 @@ void CounterNode::insertAfter(CounterNode* newChild, CounterNode* refChild, cons
m_firstChild = newChild;
}
- if (next) {
- ASSERT(next->m_previousSibling == refChild);
- next->m_previousSibling = newChild;
- } else {
- ASSERT(m_lastChild == refChild);
- m_lastChild = newChild;
- }
-
newChild->m_parent = this;
newChild->m_previousSibling = refChild;
- newChild->m_nextSibling = next;
- newChild->m_countInParent = newChild->computeCountInParent();
+ if (!newChild->m_firstChild || newChild->m_hasResetType) {
+ newChild->m_nextSibling = next;
+ if (next) {
+ ASSERT(next->m_previousSibling == refChild);
+ next->m_previousSibling = newChild;
+ } else {
+ ASSERT(m_lastChild == refChild);
+ m_lastChild = newChild;
+ }
+
+ newChild->m_countInParent = newChild->computeCountInParent();
+ newChild->resetRenderers(identifier);
+ if (next)
+ next->recount(identifier);
+ return;
+ }
+
+ // The code below handles the case when a formerly root increment counter is loosing its root position
+ // and therefore its children become next siblings.
+ CounterNode* last = newChild->m_lastChild;
+ CounterNode* first = newChild->m_firstChild;
+
+ newChild->m_nextSibling = first;
+ first->m_previousSibling = newChild;
+ // The case when the original next sibling of the inserted node becomes a child of
+ // one of the former children of the inserted node is not handled as it is believed
+ // to be impossible since:
+ // 1. if the increment counter node lost it's root position as a result of another
+ // counter node being created, it will be inserted as the last child so next is null.
+ // 2. if the increment counter node lost it's root position as a result of a renderer being
+ // inserted into the document's render tree, all its former children counters are attached
+ // to children of the inserted renderer and hence cannot be in scope for counter nodes
+ // attached to renderers that were already in the document's render tree.
+ last->m_nextSibling = next;
if (next)
- next->recount(identifier);
+ next->m_previousSibling = last;
+ else
+ m_lastChild = last;
+ for (next = first; ; next = next->m_nextSibling) {
+ next->m_parent = this;
+ if (last == next)
+ break;
+ }
+ newChild->m_firstChild = 0;
+ newChild->m_lastChild = 0;
+ newChild->m_countInParent = newChild->computeCountInParent();
+ newChild->resetRenderer(identifier);
+ first->recount(identifier);
}
void CounterNode::removeChild(CounterNode* oldChild, const AtomicString& identifier)
@@ -216,7 +246,7 @@ static void showTreeAndMark(const CounterNode* node)
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, current->actsAsReset() ? "reset____" : "increment", current->value(),
current->countInParent(), current->parent(), current->previousSibling(),
current->nextSibling(), current->renderer());
}