bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 1 | /* |
bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 2 | * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) |
darin | b5a0e3d | 2007-01-10 00:08:18 +0000 | [diff] [blame] | 3 | * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. |
bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 4 | * |
| 5 | * This library is free software; you can redistribute it and/or |
| 6 | * modify it under the terms of the GNU Library General Public |
| 7 | * License as published by the Free Software Foundation; either |
| 8 | * version 2 of the License, or (at your option) any later version. |
| 9 | * |
| 10 | * This library is distributed in the hope that it will be useful, |
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 13 | * Library General Public License for more details. |
| 14 | * |
| 15 | * You should have received a copy of the GNU Library General Public License |
| 16 | * along with this library; see the file COPYING.LIB. If not, write to |
ddkilzer | c8eccec | 2007-09-26 02:29:57 +0000 | [diff] [blame] | 17 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| 18 | * Boston, MA 02110-1301, USA. |
bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 19 | * |
| 20 | */ |
| 21 | |
| 22 | #include "config.h" |
| 23 | #include "CounterNode.h" |
| 24 | |
eric@webkit.org | ae29b2f | 2010-01-16 02:14:25 +0000 | [diff] [blame] | 25 | #include "RenderCounter.h" |
bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 26 | #include "RenderObject.h" |
hausmann@webkit.org | 3de6b94 | 2008-02-25 13:16:40 +0000 | [diff] [blame] | 27 | #include <stdio.h> |
bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 28 | |
| 29 | namespace WebCore { |
| 30 | |
eric@webkit.org | d8ca5e1 | 2009-12-21 20:11:47 +0000 | [diff] [blame] | 31 | CounterNode::CounterNode(RenderObject* o, bool hasResetType, int value) |
| 32 | : m_hasResetType(hasResetType) |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 33 | , m_value(value) |
| 34 | , m_countInParent(0) |
carol.szabo@nokia.com | 7cf0a55 | 2011-03-23 00:04:58 +0000 | [diff] [blame] | 35 | , m_owner(o) |
| 36 | , m_rootRenderer(0) |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 37 | , m_parent(0) |
| 38 | , m_previousSibling(0) |
| 39 | , m_nextSibling(0) |
| 40 | , m_firstChild(0) |
| 41 | , m_lastChild(0) |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 42 | { |
| 43 | } |
| 44 | |
carol.szabo@nokia.com | d7917f7 | 2011-03-24 02:25:06 +0000 | [diff] [blame] | 45 | CounterNode::~CounterNode() |
| 46 | { |
cdn@chromium.org | c9e0506 | 2011-08-08 20:39:23 +0000 | [diff] [blame] | 47 | // Ideally this would be an assert and this would never be reached. In reality this happens a lot |
| 48 | // so we need to handle these cases. The node is still connected to the tree so we need to detach it. |
| 49 | if (m_parent || m_previousSibling || m_nextSibling || m_firstChild || m_lastChild) { |
| 50 | CounterNode* oldParent = 0; |
| 51 | CounterNode* oldPreviousSibling = 0; |
| 52 | // Instead of calling removeChild() we do this safely as the tree is likely broken if we get here. |
| 53 | if (m_parent) { |
| 54 | if (m_parent->m_firstChild == this) |
| 55 | m_parent->m_firstChild = m_nextSibling; |
| 56 | if (m_parent->m_lastChild == this) |
| 57 | m_parent->m_lastChild = m_previousSibling; |
| 58 | oldParent = m_parent; |
| 59 | m_parent = 0; |
| 60 | } |
| 61 | if (m_previousSibling) { |
| 62 | if (m_previousSibling->m_nextSibling == this) |
| 63 | m_previousSibling->m_nextSibling = m_nextSibling; |
| 64 | oldPreviousSibling = m_previousSibling; |
| 65 | m_previousSibling = 0; |
| 66 | } |
| 67 | if (m_nextSibling) { |
| 68 | if (m_nextSibling->m_previousSibling == this) |
| 69 | m_nextSibling->m_previousSibling = oldPreviousSibling; |
| 70 | m_nextSibling = 0; |
| 71 | } |
| 72 | if (m_firstChild) { |
| 73 | // The node's children are reparented to the old parent. |
| 74 | for (CounterNode* child = m_firstChild; child; ) { |
| 75 | CounterNode* nextChild = child->m_nextSibling; |
| 76 | CounterNode* nextSibling = 0; |
| 77 | child->m_parent = oldParent; |
| 78 | if (oldPreviousSibling) { |
| 79 | nextSibling = oldPreviousSibling->m_nextSibling; |
| 80 | child->m_previousSibling = oldPreviousSibling; |
| 81 | oldPreviousSibling->m_nextSibling = child; |
| 82 | child->m_nextSibling = nextSibling; |
| 83 | nextSibling->m_previousSibling = child; |
| 84 | oldPreviousSibling = child; |
| 85 | } |
| 86 | child = nextChild; |
| 87 | } |
| 88 | } |
| 89 | } |
carol.szabo@nokia.com | d7917f7 | 2011-03-24 02:25:06 +0000 | [diff] [blame] | 90 | resetRenderers(); |
| 91 | } |
| 92 | |
carol.szabo@nokia.com | 7cf0a55 | 2011-03-23 00:04:58 +0000 | [diff] [blame] | 93 | PassRefPtr<CounterNode> CounterNode::create(RenderObject* owner, bool hasResetType, int value) |
jschuh@chromium.org | e94df97 | 2010-09-30 20:31:45 +0000 | [diff] [blame] | 94 | { |
carol.szabo@nokia.com | 7cf0a55 | 2011-03-23 00:04:58 +0000 | [diff] [blame] | 95 | return adoptRef(new CounterNode(owner, hasResetType, value)); |
jschuh@chromium.org | e94df97 | 2010-09-30 20:31:45 +0000 | [diff] [blame] | 96 | } |
| 97 | |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 98 | CounterNode* CounterNode::nextInPreOrderAfterChildren(const CounterNode* stayWithin) const |
| 99 | { |
| 100 | if (this == stayWithin) |
| 101 | return 0; |
| 102 | |
eric@webkit.org | d9edbba | 2010-01-14 03:30:36 +0000 | [diff] [blame] | 103 | const CounterNode* current = this; |
| 104 | CounterNode* next; |
| 105 | while (!(next = current->m_nextSibling)) { |
| 106 | current = current->m_parent; |
| 107 | if (!current || current == stayWithin) |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 108 | return 0; |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 109 | } |
eric@webkit.org | d9edbba | 2010-01-14 03:30:36 +0000 | [diff] [blame] | 110 | return next; |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 111 | } |
| 112 | |
| 113 | CounterNode* CounterNode::nextInPreOrder(const CounterNode* stayWithin) const |
| 114 | { |
| 115 | if (CounterNode* next = m_firstChild) |
| 116 | return next; |
| 117 | |
| 118 | return nextInPreOrderAfterChildren(stayWithin); |
| 119 | } |
| 120 | |
| 121 | CounterNode* CounterNode::lastDescendant() const |
| 122 | { |
| 123 | CounterNode* last = m_lastChild; |
| 124 | if (!last) |
| 125 | return 0; |
| 126 | |
| 127 | while (CounterNode* lastChild = last->m_lastChild) |
| 128 | last = lastChild; |
| 129 | |
| 130 | return last; |
| 131 | } |
| 132 | |
| 133 | CounterNode* CounterNode::previousInPreOrder() const |
| 134 | { |
| 135 | CounterNode* previous = m_previousSibling; |
| 136 | if (!previous) |
| 137 | return m_parent; |
| 138 | |
| 139 | while (CounterNode* lastChild = previous->m_lastChild) |
| 140 | previous = lastChild; |
| 141 | |
| 142 | return previous; |
bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 143 | } |
| 144 | |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 145 | int CounterNode::computeCountInParent() const |
bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 146 | { |
eric@webkit.org | d8ca5e1 | 2009-12-21 20:11:47 +0000 | [diff] [blame] | 147 | int increment = actsAsReset() ? 0 : m_value; |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 148 | if (m_previousSibling) |
| 149 | return m_previousSibling->m_countInParent + increment; |
| 150 | ASSERT(m_parent->m_firstChild == this); |
| 151 | return m_parent->m_value + increment; |
bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 152 | } |
| 153 | |
carol.szabo@nokia.com | 7cf0a55 | 2011-03-23 00:04:58 +0000 | [diff] [blame] | 154 | void CounterNode::addRenderer(RenderCounter* value) |
bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 155 | { |
carol.szabo@nokia.com | 7cf0a55 | 2011-03-23 00:04:58 +0000 | [diff] [blame] | 156 | if (!value) { |
| 157 | ASSERT_NOT_REACHED(); |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 158 | return; |
carol.szabo@nokia.com | 7cf0a55 | 2011-03-23 00:04:58 +0000 | [diff] [blame] | 159 | } |
| 160 | if (value->m_counterNode) { |
| 161 | ASSERT_NOT_REACHED(); |
| 162 | value->m_counterNode->removeRenderer(value); |
| 163 | } |
| 164 | ASSERT(!value->m_nextForSameCounter); |
| 165 | for (RenderCounter* iterator = m_rootRenderer;iterator; iterator = iterator->m_nextForSameCounter) { |
| 166 | if (iterator == value) { |
| 167 | ASSERT_NOT_REACHED(); |
| 168 | return; |
| 169 | } |
| 170 | } |
| 171 | value->m_nextForSameCounter = m_rootRenderer; |
| 172 | m_rootRenderer = value; |
| 173 | if (value->m_counterNode != this) { |
| 174 | if (value->m_counterNode) { |
| 175 | ASSERT_NOT_REACHED(); |
| 176 | value->m_counterNode->removeRenderer(value); |
| 177 | } |
| 178 | value->m_counterNode = this; |
| 179 | } |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 180 | } |
| 181 | |
carol.szabo@nokia.com | 7cf0a55 | 2011-03-23 00:04:58 +0000 | [diff] [blame] | 182 | void CounterNode::removeRenderer(RenderCounter* value) |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 183 | { |
carol.szabo@nokia.com | 7cf0a55 | 2011-03-23 00:04:58 +0000 | [diff] [blame] | 184 | if (!value) { |
| 185 | ASSERT_NOT_REACHED(); |
| 186 | return; |
| 187 | } |
| 188 | if (value->m_counterNode && value->m_counterNode != this) { |
| 189 | ASSERT_NOT_REACHED(); |
| 190 | value->m_counterNode->removeRenderer(value); |
| 191 | } |
| 192 | RenderCounter* previous = 0; |
| 193 | for (RenderCounter* iterator = m_rootRenderer;iterator; iterator = iterator->m_nextForSameCounter) { |
| 194 | if (iterator == value) { |
| 195 | if (previous) |
| 196 | previous->m_nextForSameCounter = value->m_nextForSameCounter; |
| 197 | else |
| 198 | m_rootRenderer = value->m_nextForSameCounter; |
| 199 | value->m_nextForSameCounter = 0; |
| 200 | value->m_counterNode = 0; |
| 201 | return; |
| 202 | } |
| 203 | previous = iterator; |
| 204 | } |
| 205 | ASSERT_NOT_REACHED(); |
| 206 | } |
| 207 | |
| 208 | void CounterNode::resetRenderers() |
| 209 | { |
carol.szabo@nokia.com | d7917f7 | 2011-03-24 02:25:06 +0000 | [diff] [blame] | 210 | while (m_rootRenderer) |
| 211 | m_rootRenderer->invalidate(); // This makes m_rootRenderer point to the next renderer if any since it disconnects the m_rootRenderer from this. |
carol.szabo@nokia.com | 7cf0a55 | 2011-03-23 00:04:58 +0000 | [diff] [blame] | 212 | } |
| 213 | |
| 214 | void CounterNode::resetThisAndDescendantsRenderers() |
| 215 | { |
| 216 | CounterNode* node = this; |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 217 | do { |
carol.szabo@nokia.com | 7cf0a55 | 2011-03-23 00:04:58 +0000 | [diff] [blame] | 218 | node->resetRenderers(); |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 219 | node = node->nextInPreOrder(this); |
| 220 | } while (node); |
| 221 | } |
| 222 | |
carol.szabo@nokia.com | 7cf0a55 | 2011-03-23 00:04:58 +0000 | [diff] [blame] | 223 | void CounterNode::recount() |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 224 | { |
| 225 | for (CounterNode* node = this; node; node = node->m_nextSibling) { |
| 226 | int oldCount = node->m_countInParent; |
| 227 | int newCount = node->computeCountInParent(); |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 228 | if (oldCount == newCount) |
| 229 | break; |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 230 | node->m_countInParent = newCount; |
carol.szabo@nokia.com | 7cf0a55 | 2011-03-23 00:04:58 +0000 | [diff] [blame] | 231 | node->resetThisAndDescendantsRenderers(); |
bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 232 | } |
| 233 | } |
| 234 | |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 235 | void CounterNode::insertAfter(CounterNode* newChild, CounterNode* refChild, const AtomicString& identifier) |
bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 236 | { |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 237 | ASSERT(newChild); |
| 238 | ASSERT(!newChild->m_parent); |
| 239 | ASSERT(!newChild->m_previousSibling); |
| 240 | ASSERT(!newChild->m_nextSibling); |
cdn@chromium.org | 009d1ab | 2011-09-13 22:49:15 +0000 | [diff] [blame] | 241 | // If the refChild is not our child we can not complete the request. This hardens against bugs in RenderCounter. |
| 242 | // When renderers are reparented it may request that we insert counter nodes improperly. |
| 243 | if (refChild && refChild->m_parent != this) |
| 244 | return; |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 245 | |
eric@webkit.org | ae29b2f | 2010-01-16 02:14:25 +0000 | [diff] [blame] | 246 | if (newChild->m_hasResetType) { |
| 247 | while (m_lastChild != refChild) |
carol.szabo@nokia.com | 7cf0a55 | 2011-03-23 00:04:58 +0000 | [diff] [blame] | 248 | RenderCounter::destroyCounterNode(m_lastChild->owner(), identifier); |
eric@webkit.org | ae29b2f | 2010-01-16 02:14:25 +0000 | [diff] [blame] | 249 | } |
| 250 | |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 251 | CounterNode* next; |
| 252 | |
| 253 | if (refChild) { |
| 254 | next = refChild->m_nextSibling; |
| 255 | refChild->m_nextSibling = newChild; |
| 256 | } else { |
| 257 | next = m_firstChild; |
| 258 | m_firstChild = newChild; |
| 259 | } |
| 260 | |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 261 | newChild->m_parent = this; |
| 262 | newChild->m_previousSibling = refChild; |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 263 | |
cdn@chromium.org | 32296c3 | 2012-06-20 05:36:27 +0000 | [diff] [blame] | 264 | if (next) { |
| 265 | ASSERT(next->m_previousSibling == refChild); |
| 266 | next->m_previousSibling = newChild; |
eric@webkit.org | ae29b2f | 2010-01-16 02:14:25 +0000 | [diff] [blame] | 267 | newChild->m_nextSibling = next; |
cdn@chromium.org | 32296c3 | 2012-06-20 05:36:27 +0000 | [diff] [blame] | 268 | } else { |
| 269 | ASSERT(m_lastChild == refChild); |
| 270 | m_lastChild = newChild; |
| 271 | } |
eric@webkit.org | ae29b2f | 2010-01-16 02:14:25 +0000 | [diff] [blame] | 272 | |
cdn@chromium.org | 32296c3 | 2012-06-20 05:36:27 +0000 | [diff] [blame] | 273 | if (!newChild->m_firstChild || newChild->m_hasResetType) { |
eric@webkit.org | ae29b2f | 2010-01-16 02:14:25 +0000 | [diff] [blame] | 274 | newChild->m_countInParent = newChild->computeCountInParent(); |
carol.szabo@nokia.com | 7cf0a55 | 2011-03-23 00:04:58 +0000 | [diff] [blame] | 275 | newChild->resetThisAndDescendantsRenderers(); |
eric@webkit.org | ae29b2f | 2010-01-16 02:14:25 +0000 | [diff] [blame] | 276 | if (next) |
carol.szabo@nokia.com | 7cf0a55 | 2011-03-23 00:04:58 +0000 | [diff] [blame] | 277 | next->recount(); |
eric@webkit.org | ae29b2f | 2010-01-16 02:14:25 +0000 | [diff] [blame] | 278 | return; |
| 279 | } |
| 280 | |
| 281 | // The code below handles the case when a formerly root increment counter is loosing its root position |
| 282 | // and therefore its children become next siblings. |
| 283 | CounterNode* last = newChild->m_lastChild; |
| 284 | CounterNode* first = newChild->m_firstChild; |
| 285 | |
cdn@chromium.org | 009d1ab | 2011-09-13 22:49:15 +0000 | [diff] [blame] | 286 | if (first) { |
| 287 | ASSERT(last); |
| 288 | newChild->m_nextSibling = first; |
| 289 | if (m_lastChild == newChild) |
| 290 | m_lastChild = last; |
| 291 | |
| 292 | first->m_previousSibling = newChild; |
| 293 | |
| 294 | // The case when the original next sibling of the inserted node becomes a child of |
| 295 | // one of the former children of the inserted node is not handled as it is believed |
| 296 | // to be impossible since: |
| 297 | // 1. if the increment counter node lost it's root position as a result of another |
| 298 | // counter node being created, it will be inserted as the last child so next is null. |
| 299 | // 2. if the increment counter node lost it's root position as a result of a renderer being |
| 300 | // inserted into the document's render tree, all its former children counters are attached |
| 301 | // to children of the inserted renderer and hence cannot be in scope for counter nodes |
| 302 | // attached to renderers that were already in the document's render tree. |
| 303 | last->m_nextSibling = next; |
| 304 | if (next) { |
| 305 | ASSERT(next->m_previousSibling == newChild); |
| 306 | next->m_previousSibling = last; |
| 307 | } else |
| 308 | m_lastChild = last; |
| 309 | for (next = first; ; next = next->m_nextSibling) { |
| 310 | next->m_parent = this; |
| 311 | if (last == next) |
| 312 | break; |
| 313 | } |
eric@webkit.org | ae29b2f | 2010-01-16 02:14:25 +0000 | [diff] [blame] | 314 | } |
| 315 | newChild->m_firstChild = 0; |
| 316 | newChild->m_lastChild = 0; |
| 317 | newChild->m_countInParent = newChild->computeCountInParent(); |
carol.szabo@nokia.com | 7cf0a55 | 2011-03-23 00:04:58 +0000 | [diff] [blame] | 318 | newChild->resetRenderers(); |
| 319 | first->recount(); |
bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 320 | } |
| 321 | |
carol.szabo@nokia.com | 7cf0a55 | 2011-03-23 00:04:58 +0000 | [diff] [blame] | 322 | void CounterNode::removeChild(CounterNode* oldChild) |
bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 323 | { |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 324 | ASSERT(oldChild); |
| 325 | ASSERT(!oldChild->m_firstChild); |
| 326 | ASSERT(!oldChild->m_lastChild); |
| 327 | |
| 328 | CounterNode* next = oldChild->m_nextSibling; |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 329 | CounterNode* previous = oldChild->m_previousSibling; |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 330 | |
| 331 | oldChild->m_nextSibling = 0; |
| 332 | oldChild->m_previousSibling = 0; |
| 333 | oldChild->m_parent = 0; |
| 334 | |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 335 | if (previous) |
| 336 | previous->m_nextSibling = next; |
bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 337 | else { |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 338 | ASSERT(m_firstChild == oldChild); |
| 339 | m_firstChild = next; |
bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 340 | } |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 341 | |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 342 | if (next) |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 343 | next->m_previousSibling = previous; |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 344 | else { |
| 345 | ASSERT(m_lastChild == oldChild); |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 346 | m_lastChild = previous; |
bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 347 | } |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 348 | |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 349 | if (next) |
carol.szabo@nokia.com | 7cf0a55 | 2011-03-23 00:04:58 +0000 | [diff] [blame] | 350 | next->recount(); |
bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 351 | } |
| 352 | |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 353 | #ifndef NDEBUG |
| 354 | |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 355 | static void showTreeAndMark(const CounterNode* node) |
bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 356 | { |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 357 | const CounterNode* root = node; |
| 358 | while (root->parent()) |
| 359 | root = root->parent(); |
| 360 | |
eric@webkit.org | cb91842 | 2009-11-13 20:55:51 +0000 | [diff] [blame] | 361 | for (const CounterNode* current = root; current; current = current->nextInPreOrder()) { |
jschuh@chromium.org | b375c98 | 2011-01-12 16:07:53 +0000 | [diff] [blame] | 362 | fprintf(stderr, "%c", (current == node) ? '*' : ' '); |
eric@webkit.org | a006295 | 2009-11-09 19:43:17 +0000 | [diff] [blame] | 363 | for (const CounterNode* parent = current; parent && parent != root; parent = parent->parent()) |
jschuh@chromium.org | b375c98 | 2011-01-12 16:07:53 +0000 | [diff] [blame] | 364 | fprintf(stderr, " "); |
eric@webkit.org | a006295 | 2009-11-09 19:43:17 +0000 | [diff] [blame] | 365 | fprintf(stderr, "%p %s: %d %d P:%p PS:%p NS:%p R:%p\n", |
eric@webkit.org | d8ca5e1 | 2009-12-21 20:11:47 +0000 | [diff] [blame] | 366 | current, current->actsAsReset() ? "reset____" : "increment", current->value(), |
eric@webkit.org | a006295 | 2009-11-09 19:43:17 +0000 | [diff] [blame] | 367 | current->countInParent(), current->parent(), current->previousSibling(), |
carol.szabo@nokia.com | 7cf0a55 | 2011-03-23 00:04:58 +0000 | [diff] [blame] | 368 | current->nextSibling(), current->owner()); |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 369 | } |
carol.szabo@nokia.com | 7cf0a55 | 2011-03-23 00:04:58 +0000 | [diff] [blame] | 370 | fflush(stderr); |
bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 371 | } |
| 372 | |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 373 | #endif |
| 374 | |
weinig | 1497a7e | 2006-10-26 20:23:55 +0000 | [diff] [blame] | 375 | } // namespace WebCore |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 376 | |
| 377 | #ifndef NDEBUG |
| 378 | |
carol.szabo@nokia.com | 02635bf | 2011-02-05 00:28:57 +0000 | [diff] [blame] | 379 | void showCounterTree(const WebCore::CounterNode* counter) |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 380 | { |
| 381 | if (counter) |
| 382 | showTreeAndMark(counter); |
| 383 | } |
| 384 | |
| 385 | #endif |