Commit 3071affa authored by hyatt's avatar hyatt
Browse files

Fix for bug 13785, O(n^2) counter creation.

        Reviewed by darin

        * rendering/RenderCounter.cpp:
        (WebCore::findPlaceForCounter):
        (WebCore::RenderCounter::originalText):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@21606 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 97b9586a
2007-05-19 David Hyatt <hyatt@apple.com>
Fix for bug 13785, O(n^2) counter creation.
Reviewed by darin
* rendering/RenderCounter.cpp:
(WebCore::findPlaceForCounter):
(WebCore::RenderCounter::originalText):
2007-05-19 Mitz Pettel <mitz@webkit.org>
 
Reviewed by Dave Hyatt.
......@@ -135,32 +135,38 @@ static bool planCounter(RenderObject* object, const AtomicString& counterName, b
static bool findPlaceForCounter(RenderObject* object, const AtomicString& counterName,
bool isReset, CounterNode*& parent, CounterNode*& previousSibling)
{
// Look for the parent node.
// Start with the render tree parent for a reset node, or the render tree sibling for an increment node.
parent = 0;
RenderObject* candidate = isReset ? object->parent() : previousSiblingOrParent(object);
for (; candidate; candidate = previousSiblingOrParent(candidate))
if (CounterNode* c = counter(candidate, counterName, false))
if (c->isReset()) {
parent = c;
break;
}
if (!parent)
return false;
// Find the appropriate previous sibling for insertion into the parent node
// by searching in render tree order for a child of the counter.
parent = 0;
previousSibling = 0;
candidate = object;
while ((candidate = candidate->previousInPreOrder())) {
CounterNode* c = counter(candidate, counterName, false);
if (c && c->parent() == parent) {
previousSibling = c;
break;
RenderObject* resetCandidate = isReset ? object->parent() : previousSiblingOrParent(object);
RenderObject* prevCounterCandidate = object;
CounterNode* candidateCounter = 0;
while ((prevCounterCandidate = prevCounterCandidate->previousInPreOrder())) {
CounterNode* c = counter(prevCounterCandidate, counterName, false);
if (prevCounterCandidate == resetCandidate) {
if (!candidateCounter)
candidateCounter = c;
if (candidateCounter) {
if (candidateCounter->isReset()) {
parent = candidateCounter;
previousSibling = 0;
} else {
parent = candidateCounter->parent();
previousSibling = candidateCounter;
}
return true;
}
resetCandidate = previousSiblingOrParent(resetCandidate);
} else if (c) {
if (c->isReset())
candidateCounter = 0;
else if (!candidateCounter)
candidateCounter = c;
}
}
return true;
return false;
}
static CounterNode* counter(RenderObject* object, const AtomicString& counterName, bool alwaysCreateCounter)
......@@ -224,7 +230,7 @@ PassRefPtr<StringImpl> RenderCounter::originalText() const
return 0;
if (!m_counterNode)
m_counterNode = counter(const_cast<RenderCounter*>(this), m_counter.identifier(), true);
m_counterNode = counter(parent(), m_counter.identifier(), true);
CounterNode* child = m_counterNode;
int value = child->isReset() ? child->value() : child->countInParent();
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment