15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version. 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful, 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details. 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB. If not, write to 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA. 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 2353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/CounterNode.h" 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderCounter.h" 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 278abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)#ifndef NDEBUG 288abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)#include <stdio.h> 298abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)#endif 308abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore { 325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)CounterNode::CounterNode(RenderObject& o, bool hasResetType, int value) 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : m_hasResetType(hasResetType) 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_value(value) 365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_countInParent(0) 375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_owner(o) 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_rootRenderer(0) 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_parent(0) 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_previousSibling(0) 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_nextSibling(0) 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_firstChild(0) 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_lastChild(0) 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)CounterNode::~CounterNode() 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Ideally this would be an assert and this would never be reached. In reality this happens a lot 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // so we need to handle these cases. The node is still connected to the tree so we need to detach it. 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_parent || m_previousSibling || m_nextSibling || m_firstChild || m_lastChild) { 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CounterNode* oldParent = 0; 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CounterNode* oldPreviousSibling = 0; 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Instead of calling removeChild() we do this safely as the tree is likely broken if we get here. 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_parent) { 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_parent->m_firstChild == this) 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_parent->m_firstChild = m_nextSibling; 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_parent->m_lastChild == this) 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_parent->m_lastChild = m_previousSibling; 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) oldParent = m_parent; 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_parent = 0; 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_previousSibling) { 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_previousSibling->m_nextSibling == this) 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_previousSibling->m_nextSibling = m_nextSibling; 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) oldPreviousSibling = m_previousSibling; 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_previousSibling = 0; 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_nextSibling) { 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_nextSibling->m_previousSibling == this) 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_nextSibling->m_previousSibling = oldPreviousSibling; 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_nextSibling = 0; 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_firstChild) { 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The node's children are reparented to the old parent. 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (CounterNode* child = m_firstChild; child; ) { 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CounterNode* nextChild = child->m_nextSibling; 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CounterNode* nextSibling = 0; 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) child->m_parent = oldParent; 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (oldPreviousSibling) { 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) nextSibling = oldPreviousSibling->m_nextSibling; 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) child->m_previousSibling = oldPreviousSibling; 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) oldPreviousSibling->m_nextSibling = child; 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) child->m_nextSibling = nextSibling; 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) nextSibling->m_previousSibling = child; 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) oldPreviousSibling = child; 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) child = nextChild; 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) resetRenderers(); 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)PassRefPtr<CounterNode> CounterNode::create(RenderObject& owner, bool hasResetType, int value) 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return adoptRef(new CounterNode(owner, hasResetType, value)); 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)CounterNode* CounterNode::nextInPreOrderAfterChildren(const CounterNode* stayWithin) const 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (this == stayWithin) 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const CounterNode* current = this; 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CounterNode* next; 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (!(next = current->m_nextSibling)) { 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) current = current->m_parent; 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!current || current == stayWithin) 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return next; 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)CounterNode* CounterNode::nextInPreOrder(const CounterNode* stayWithin) const 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (CounterNode* next = m_firstChild) 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return next; 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return nextInPreOrderAfterChildren(stayWithin); 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)CounterNode* CounterNode::lastDescendant() const 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CounterNode* last = m_lastChild; 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!last) 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (CounterNode* lastChild = last->m_lastChild) 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) last = lastChild; 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return last; 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)CounterNode* CounterNode::previousInPreOrder() const 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CounterNode* previous = m_previousSibling; 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!previous) 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_parent; 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (CounterNode* lastChild = previous->m_lastChild) 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) previous = lastChild; 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return previous; 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int CounterNode::computeCountInParent() const 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int increment = actsAsReset() ? 0 : m_value; 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_previousSibling) 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_previousSibling->m_countInParent + increment; 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_parent->m_firstChild == this); 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_parent->m_value + increment; 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void CounterNode::addRenderer(RenderCounter* value) 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!value) { 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_NOT_REACHED(); 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (value->m_counterNode) { 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_NOT_REACHED(); 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) value->m_counterNode->removeRenderer(value); 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!value->m_nextForSameCounter); 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (RenderCounter* iterator = m_rootRenderer;iterator; iterator = iterator->m_nextForSameCounter) { 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (iterator == value) { 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_NOT_REACHED(); 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) value->m_nextForSameCounter = m_rootRenderer; 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_rootRenderer = value; 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (value->m_counterNode != this) { 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (value->m_counterNode) { 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_NOT_REACHED(); 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) value->m_counterNode->removeRenderer(value); 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) value->m_counterNode = this; 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void CounterNode::removeRenderer(RenderCounter* value) 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!value) { 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_NOT_REACHED(); 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (value->m_counterNode && value->m_counterNode != this) { 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_NOT_REACHED(); 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) value->m_counterNode->removeRenderer(value); 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderCounter* previous = 0; 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (RenderCounter* iterator = m_rootRenderer;iterator; iterator = iterator->m_nextForSameCounter) { 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (iterator == value) { 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (previous) 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) previous->m_nextForSameCounter = value->m_nextForSameCounter; 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_rootRenderer = value->m_nextForSameCounter; 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) value->m_nextForSameCounter = 0; 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) value->m_counterNode = 0; 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) previous = iterator; 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_NOT_REACHED(); 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void CounterNode::resetRenderers() 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (m_rootRenderer) 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_rootRenderer->invalidate(); // This makes m_rootRenderer point to the next renderer if any since it disconnects the m_rootRenderer from this. 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void CounterNode::resetThisAndDescendantsRenderers() 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CounterNode* node = this; 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) do { 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) node->resetRenderers(); 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) node = node->nextInPreOrder(this); 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } while (node); 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void CounterNode::recount() 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (CounterNode* node = this; node; node = node->m_nextSibling) { 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int oldCount = node->m_countInParent; 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int newCount = node->computeCountInParent(); 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (oldCount == newCount) 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) node->m_countInParent = newCount; 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) node->resetThisAndDescendantsRenderers(); 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void CounterNode::insertAfter(CounterNode* newChild, CounterNode* refChild, const AtomicString& identifier) 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(newChild); 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!newChild->m_parent); 2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!newChild->m_previousSibling); 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!newChild->m_nextSibling); 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If the refChild is not our child we can not complete the request. This hardens against bugs in RenderCounter. 2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // When renderers are reparented it may request that we insert counter nodes improperly. 2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (refChild && refChild->m_parent != this) 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (newChild->m_hasResetType) { 2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (m_lastChild != refChild) 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderCounter::destroyCounterNode(m_lastChild->owner(), identifier); 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CounterNode* next; 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (refChild) { 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next = refChild->m_nextSibling; 2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) refChild->m_nextSibling = newChild; 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next = m_firstChild; 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_firstChild = newChild; 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newChild->m_parent = this; 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newChild->m_previousSibling = refChild; 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (next) { 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(next->m_previousSibling == refChild); 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next->m_previousSibling = newChild; 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newChild->m_nextSibling = next; 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_lastChild == refChild); 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_lastChild = newChild; 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!newChild->m_firstChild || newChild->m_hasResetType) { 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newChild->m_countInParent = newChild->computeCountInParent(); 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newChild->resetThisAndDescendantsRenderers(); 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (next) 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next->recount(); 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The code below handles the case when a formerly root increment counter is loosing its root position 2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // and therefore its children become next siblings. 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CounterNode* last = newChild->m_lastChild; 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CounterNode* first = newChild->m_firstChild; 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (first) { 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(last); 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newChild->m_nextSibling = first; 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_lastChild == newChild) 2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_lastChild = last; 2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) first->m_previousSibling = newChild; 29502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The case when the original next sibling of the inserted node becomes a child of 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // one of the former children of the inserted node is not handled as it is believed 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // to be impossible since: 2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // 1. if the increment counter node lost it's root position as a result of another 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // counter node being created, it will be inserted as the last child so next is null. 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // 2. if the increment counter node lost it's root position as a result of a renderer being 3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // inserted into the document's render tree, all its former children counters are attached 3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // to children of the inserted renderer and hence cannot be in scope for counter nodes 3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // attached to renderers that were already in the document's render tree. 3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) last->m_nextSibling = next; 3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (next) { 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(next->m_previousSibling == newChild); 3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next->m_previousSibling = last; 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else 3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_lastChild = last; 3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (next = first; ; next = next->m_nextSibling) { 3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next->m_parent = this; 3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (last == next) 3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newChild->m_firstChild = 0; 3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newChild->m_lastChild = 0; 3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newChild->m_countInParent = newChild->computeCountInParent(); 3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newChild->resetRenderers(); 3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) first->recount(); 3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void CounterNode::removeChild(CounterNode* oldChild) 3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(oldChild); 3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!oldChild->m_firstChild); 3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!oldChild->m_lastChild); 3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CounterNode* next = oldChild->m_nextSibling; 3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CounterNode* previous = oldChild->m_previousSibling; 3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) oldChild->m_nextSibling = 0; 3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) oldChild->m_previousSibling = 0; 3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) oldChild->m_parent = 0; 3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 33702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch if (previous) 3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) previous->m_nextSibling = next; 3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else { 3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_firstChild == oldChild); 3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_firstChild = next; 3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (next) 3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next->m_previousSibling = previous; 3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else { 3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_lastChild == oldChild); 3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_lastChild = previous; 3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (next) 3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next->recount(); 3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef NDEBUG 3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void showTreeAndMark(const CounterNode* node) 3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const CounterNode* root = node; 3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (root->parent()) 3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) root = root->parent(); 3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (const CounterNode* current = root; current; current = current->nextInPreOrder()) { 3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) fprintf(stderr, "%c", (current == node) ? '*' : ' '); 3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (const CounterNode* parent = current; parent && parent != root; parent = parent->parent()) 3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) fprintf(stderr, " "); 3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) fprintf(stderr, "%p %s: %d %d P:%p PS:%p NS:%p R:%p\n", 3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) current, current->actsAsReset() ? "reset____" : "increment", current->value(), 3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) current->countInParent(), current->parent(), current->previousSibling(), 37051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) current->nextSibling(), ¤t->owner()); 3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) fflush(stderr); 3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebCore 3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef NDEBUG 3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void showCounterTree(const WebCore::CounterNode* counter) 3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (counter) 3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) showTreeAndMark(counter); 3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 388