18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version.
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful,
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details.
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB.  If not, write to
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA.
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CounterNode.h"
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "RenderCounter.h"
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderObject.h"
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <stdio.h>
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31d0825bca7fe65beaee391d30da42e937db621564Steve BlockCounterNode::CounterNode(RenderObject* o, bool hasResetType, int value)
32d0825bca7fe65beaee391d30da42e937db621564Steve Block    : m_hasResetType(hasResetType)
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_value(value)
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_countInParent(0)
352bde8e466a4451c7319e3a072d118917957d6554Steve Block    , m_owner(o)
362bde8e466a4451c7319e3a072d118917957d6554Steve Block    , m_rootRenderer(0)
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_parent(0)
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_previousSibling(0)
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_nextSibling(0)
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_firstChild(0)
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_lastChild(0)
42643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
43643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
44643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
452bde8e466a4451c7319e3a072d118917957d6554Steve BlockCounterNode::~CounterNode()
46a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
472bde8e466a4451c7319e3a072d118917957d6554Steve Block    resetRenderers();
482bde8e466a4451c7319e3a072d118917957d6554Steve Block}
492bde8e466a4451c7319e3a072d118917957d6554Steve Block
502bde8e466a4451c7319e3a072d118917957d6554Steve BlockPassRefPtr<CounterNode> CounterNode::create(RenderObject* owner, bool hasResetType, int value)
512bde8e466a4451c7319e3a072d118917957d6554Steve Block{
522bde8e466a4451c7319e3a072d118917957d6554Steve Block    return adoptRef(new CounterNode(owner, hasResetType, value));
53a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
54a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
55643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockCounterNode* CounterNode::nextInPreOrderAfterChildren(const CounterNode* stayWithin) const
56643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
57643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (this == stayWithin)
58643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return 0;
59643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
60d0825bca7fe65beaee391d30da42e937db621564Steve Block    const CounterNode* current = this;
61d0825bca7fe65beaee391d30da42e937db621564Steve Block    CounterNode* next;
62d0825bca7fe65beaee391d30da42e937db621564Steve Block    while (!(next = current->m_nextSibling)) {
63d0825bca7fe65beaee391d30da42e937db621564Steve Block        current = current->m_parent;
64d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (!current || current == stayWithin)
65643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            return 0;
66643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
67d0825bca7fe65beaee391d30da42e937db621564Steve Block    return next;
68643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
69643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
70643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockCounterNode* CounterNode::nextInPreOrder(const CounterNode* stayWithin) const
71643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
72643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (CounterNode* next = m_firstChild)
73643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return next;
74643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
75643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return nextInPreOrderAfterChildren(stayWithin);
76643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
77643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
78643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockCounterNode* CounterNode::lastDescendant() const
79643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
80643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    CounterNode* last = m_lastChild;
81643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (!last)
82643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return 0;
83643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
84643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    while (CounterNode* lastChild = last->m_lastChild)
85643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        last = lastChild;
86643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
87643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return last;
88643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
89643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
90643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockCounterNode* CounterNode::previousInPreOrder() const
91643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
92643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    CounterNode* previous = m_previousSibling;
93643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (!previous)
94643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return m_parent;
95643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
96643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    while (CounterNode* lastChild = previous->m_lastChild)
97643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        previous = lastChild;
98643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
99643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return previous;
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint CounterNode::computeCountInParent() const
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
104d0825bca7fe65beaee391d30da42e937db621564Steve Block    int increment = actsAsReset() ? 0 : m_value;
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_previousSibling)
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return m_previousSibling->m_countInParent + increment;
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_parent->m_firstChild == this);
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_parent->m_value + increment;
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1112bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid CounterNode::addRenderer(RenderCounter* value)
1122bde8e466a4451c7319e3a072d118917957d6554Steve Block{
1132bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!value) {
1142bde8e466a4451c7319e3a072d118917957d6554Steve Block        ASSERT_NOT_REACHED();
1152bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
1162bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
1172bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (value->m_counterNode) {
1182bde8e466a4451c7319e3a072d118917957d6554Steve Block        ASSERT_NOT_REACHED();
1192bde8e466a4451c7319e3a072d118917957d6554Steve Block        value->m_counterNode->removeRenderer(value);
1202bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
1212bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT(!value->m_nextForSameCounter);
1222bde8e466a4451c7319e3a072d118917957d6554Steve Block    for (RenderCounter* iterator = m_rootRenderer;iterator; iterator = iterator->m_nextForSameCounter) {
1232bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (iterator == value) {
1242bde8e466a4451c7319e3a072d118917957d6554Steve Block            ASSERT_NOT_REACHED();
1252bde8e466a4451c7319e3a072d118917957d6554Steve Block            return;
1262bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
1272bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
1282bde8e466a4451c7319e3a072d118917957d6554Steve Block    value->m_nextForSameCounter = m_rootRenderer;
1292bde8e466a4451c7319e3a072d118917957d6554Steve Block    m_rootRenderer = value;
1302bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (value->m_counterNode != this) {
1312bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (value->m_counterNode) {
1322bde8e466a4451c7319e3a072d118917957d6554Steve Block            ASSERT_NOT_REACHED();
1332bde8e466a4451c7319e3a072d118917957d6554Steve Block            value->m_counterNode->removeRenderer(value);
1342bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
1352bde8e466a4451c7319e3a072d118917957d6554Steve Block        value->m_counterNode = this;
1362bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
1372bde8e466a4451c7319e3a072d118917957d6554Steve Block}
1382bde8e466a4451c7319e3a072d118917957d6554Steve Block
1392bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid CounterNode::removeRenderer(RenderCounter* value)
140643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
1412bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!value) {
1422bde8e466a4451c7319e3a072d118917957d6554Steve Block        ASSERT_NOT_REACHED();
143643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return;
1442bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
1452bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (value->m_counterNode && value->m_counterNode != this) {
1462bde8e466a4451c7319e3a072d118917957d6554Steve Block        ASSERT_NOT_REACHED();
1472bde8e466a4451c7319e3a072d118917957d6554Steve Block        value->m_counterNode->removeRenderer(value);
1482bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
1492bde8e466a4451c7319e3a072d118917957d6554Steve Block    RenderCounter* previous = 0;
1502bde8e466a4451c7319e3a072d118917957d6554Steve Block    for (RenderCounter* iterator = m_rootRenderer;iterator; iterator = iterator->m_nextForSameCounter) {
1512bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (iterator == value) {
1522bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (previous)
1532bde8e466a4451c7319e3a072d118917957d6554Steve Block                previous->m_nextForSameCounter = value->m_nextForSameCounter;
1542bde8e466a4451c7319e3a072d118917957d6554Steve Block            else
1552bde8e466a4451c7319e3a072d118917957d6554Steve Block                m_rootRenderer = value->m_nextForSameCounter;
1562bde8e466a4451c7319e3a072d118917957d6554Steve Block            value->m_nextForSameCounter = 0;
1572bde8e466a4451c7319e3a072d118917957d6554Steve Block            value->m_counterNode = 0;
1582bde8e466a4451c7319e3a072d118917957d6554Steve Block            return;
1592bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
1602bde8e466a4451c7319e3a072d118917957d6554Steve Block        previous = iterator;
1612bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
1622bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT_NOT_REACHED();
1632bde8e466a4451c7319e3a072d118917957d6554Steve Block}
1642bde8e466a4451c7319e3a072d118917957d6554Steve Block
1652bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid CounterNode::resetRenderers()
1662bde8e466a4451c7319e3a072d118917957d6554Steve Block{
1672bde8e466a4451c7319e3a072d118917957d6554Steve Block    while (m_rootRenderer)
1682bde8e466a4451c7319e3a072d118917957d6554Steve Block        m_rootRenderer->invalidate(); // This makes m_rootRenderer point to the next renderer if any since it disconnects the m_rootRenderer from this.
169643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
170643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
1712bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid CounterNode::resetThisAndDescendantsRenderers()
172643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
1732bde8e466a4451c7319e3a072d118917957d6554Steve Block    CounterNode* node = this;
174643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    do {
1752bde8e466a4451c7319e3a072d118917957d6554Steve Block        node->resetRenderers();
176643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        node = node->nextInPreOrder(this);
177643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    } while (node);
178643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
179643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
1802bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid CounterNode::recount()
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
182643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    for (CounterNode* node = this; node; node = node->m_nextSibling) {
183643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        int oldCount = node->m_countInParent;
184643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        int newCount = node->computeCountInParent();
1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (oldCount == newCount)
1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
187643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        node->m_countInParent = newCount;
1882bde8e466a4451c7319e3a072d118917957d6554Steve Block        node->resetThisAndDescendantsRenderers();
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
192643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid CounterNode::insertAfter(CounterNode* newChild, CounterNode* refChild, const AtomicString& identifier)
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(newChild);
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!newChild->m_parent);
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!newChild->m_previousSibling);
1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!newChild->m_nextSibling);
1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!refChild || refChild->m_parent == this);
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
200d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (newChild->m_hasResetType) {
201d0825bca7fe65beaee391d30da42e937db621564Steve Block        while (m_lastChild != refChild)
2022bde8e466a4451c7319e3a072d118917957d6554Steve Block            RenderCounter::destroyCounterNode(m_lastChild->owner(), identifier);
203d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
204d0825bca7fe65beaee391d30da42e937db621564Steve Block
2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CounterNode* next;
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (refChild) {
2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        next = refChild->m_nextSibling;
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        refChild->m_nextSibling = newChild;
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        next = m_firstChild;
2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_firstChild = newChild;
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    newChild->m_parent = this;
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    newChild->m_previousSibling = refChild;
2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
218d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (!newChild->m_firstChild || newChild->m_hasResetType) {
219d0825bca7fe65beaee391d30da42e937db621564Steve Block        newChild->m_nextSibling = next;
220d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (next) {
221d0825bca7fe65beaee391d30da42e937db621564Steve Block            ASSERT(next->m_previousSibling == refChild);
222d0825bca7fe65beaee391d30da42e937db621564Steve Block            next->m_previousSibling = newChild;
223d0825bca7fe65beaee391d30da42e937db621564Steve Block        } else {
224d0825bca7fe65beaee391d30da42e937db621564Steve Block            ASSERT(m_lastChild == refChild);
225d0825bca7fe65beaee391d30da42e937db621564Steve Block            m_lastChild = newChild;
226d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
227d0825bca7fe65beaee391d30da42e937db621564Steve Block
228d0825bca7fe65beaee391d30da42e937db621564Steve Block        newChild->m_countInParent = newChild->computeCountInParent();
2292bde8e466a4451c7319e3a072d118917957d6554Steve Block        newChild->resetThisAndDescendantsRenderers();
230d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (next)
2312bde8e466a4451c7319e3a072d118917957d6554Steve Block            next->recount();
232d0825bca7fe65beaee391d30da42e937db621564Steve Block        return;
233d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
234d0825bca7fe65beaee391d30da42e937db621564Steve Block
235d0825bca7fe65beaee391d30da42e937db621564Steve Block    // The code below handles the case when a formerly root increment counter is loosing its root position
236d0825bca7fe65beaee391d30da42e937db621564Steve Block    // and therefore its children become next siblings.
237d0825bca7fe65beaee391d30da42e937db621564Steve Block    CounterNode* last = newChild->m_lastChild;
238d0825bca7fe65beaee391d30da42e937db621564Steve Block    CounterNode* first = newChild->m_firstChild;
239d0825bca7fe65beaee391d30da42e937db621564Steve Block
240d0825bca7fe65beaee391d30da42e937db621564Steve Block    newChild->m_nextSibling = first;
241d0825bca7fe65beaee391d30da42e937db621564Steve Block    first->m_previousSibling = newChild;
242d0825bca7fe65beaee391d30da42e937db621564Steve Block    // The case when the original next sibling of the inserted node becomes a child of
243d0825bca7fe65beaee391d30da42e937db621564Steve Block    // one of the former children of the inserted node is not handled as it is believed
244d0825bca7fe65beaee391d30da42e937db621564Steve Block    // to be impossible since:
245d0825bca7fe65beaee391d30da42e937db621564Steve Block    // 1. if the increment counter node lost it's root position as a result of another
246d0825bca7fe65beaee391d30da42e937db621564Steve Block    //    counter node being created, it will be inserted as the last child so next is null.
247d0825bca7fe65beaee391d30da42e937db621564Steve Block    // 2. if the increment counter node lost it's root position as a result of a renderer being
248d0825bca7fe65beaee391d30da42e937db621564Steve Block    //    inserted into the document's render tree, all its former children counters are attached
249d0825bca7fe65beaee391d30da42e937db621564Steve Block    //    to children of the inserted renderer and hence cannot be in scope for counter nodes
250d0825bca7fe65beaee391d30da42e937db621564Steve Block    //    attached to renderers that were already in the document's render tree.
251d0825bca7fe65beaee391d30da42e937db621564Steve Block    last->m_nextSibling = next;
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (next)
253d0825bca7fe65beaee391d30da42e937db621564Steve Block        next->m_previousSibling = last;
254d0825bca7fe65beaee391d30da42e937db621564Steve Block    else
255d0825bca7fe65beaee391d30da42e937db621564Steve Block        m_lastChild = last;
256d0825bca7fe65beaee391d30da42e937db621564Steve Block    for (next = first; ; next = next->m_nextSibling) {
257d0825bca7fe65beaee391d30da42e937db621564Steve Block        next->m_parent = this;
258d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (last == next)
259d0825bca7fe65beaee391d30da42e937db621564Steve Block            break;
260d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
261d0825bca7fe65beaee391d30da42e937db621564Steve Block    newChild->m_firstChild = 0;
262d0825bca7fe65beaee391d30da42e937db621564Steve Block    newChild->m_lastChild = 0;
263d0825bca7fe65beaee391d30da42e937db621564Steve Block    newChild->m_countInParent = newChild->computeCountInParent();
2642bde8e466a4451c7319e3a072d118917957d6554Steve Block    newChild->resetRenderers();
2652bde8e466a4451c7319e3a072d118917957d6554Steve Block    first->recount();
2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2682bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid CounterNode::removeChild(CounterNode* oldChild)
2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(oldChild);
2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!oldChild->m_firstChild);
2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!oldChild->m_lastChild);
2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CounterNode* next = oldChild->m_nextSibling;
275643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    CounterNode* previous = oldChild->m_previousSibling;
2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    oldChild->m_nextSibling = 0;
2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    oldChild->m_previousSibling = 0;
2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    oldChild->m_parent = 0;
2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
281643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (previous)
282643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        previous->m_nextSibling = next;
2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else {
2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(m_firstChild == oldChild);
2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_firstChild = next;
2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
287643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (next)
289643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        next->m_previousSibling = previous;
2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else {
2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(m_lastChild == oldChild);
292643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        m_lastChild = previous;
2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
294643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (next)
2962bde8e466a4451c7319e3a072d118917957d6554Steve Block        next->recount();
2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef NDEBUG
3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void showTreeAndMark(const CounterNode* node)
3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const CounterNode* root = node;
3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (root->parent())
3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        root = root->parent();
3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
307643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    for (const CounterNode* current = root; current; current = current->nextInPreOrder()) {
30865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        fprintf(stderr, "%c", (current == node) ? '*' : ' ');
309643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        for (const CounterNode* parent = current; parent && parent != root; parent = parent->parent())
31065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            fprintf(stderr, "    ");
311643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        fprintf(stderr, "%p %s: %d %d P:%p PS:%p NS:%p R:%p\n",
312d0825bca7fe65beaee391d30da42e937db621564Steve Block            current, current->actsAsReset() ? "reset____" : "increment", current->value(),
313643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            current->countInParent(), current->parent(), current->previousSibling(),
3142bde8e466a4451c7319e3a072d118917957d6554Steve Block            current->nextSibling(), current->owner());
3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3162bde8e466a4451c7319e3a072d118917957d6554Steve Block    fflush(stderr);
3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore
3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef NDEBUG
3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3252fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid showCounterTree(const WebCore::CounterNode* counter)
3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (counter)
3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        showTreeAndMark(counter);
3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
332