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" |
darin@apple.com | 8cdf712 | 2013-09-30 02:40:50 +0000 | [diff] [blame] | 26 | #include "RenderElement.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 | |
antti@apple.com | 9735e7d | 2014-08-18 22:16:47 +0000 | [diff] [blame] | 31 | CounterNode::CounterNode(RenderElement& owner, bool hasResetType, int value) |
eric@webkit.org | d8ca5e1 | 2009-12-21 20:11:47 +0000 | [diff] [blame] | 32 | : m_hasResetType(hasResetType) |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 33 | , m_value(value) |
| 34 | , m_countInParent(0) |
antti@apple.com | 9735e7d | 2014-08-18 22:16:47 +0000 | [diff] [blame] | 35 | , m_owner(owner) |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 36 | { |
| 37 | } |
| 38 | |
carol.szabo@nokia.com | d7917f7 | 2011-03-24 02:25:06 +0000 | [diff] [blame] | 39 | CounterNode::~CounterNode() |
| 40 | { |
cdn@chromium.org | c9e0506 | 2011-08-08 20:39:23 +0000 | [diff] [blame] | 41 | // Ideally this would be an assert and this would never be reached. In reality this happens a lot |
| 42 | // so we need to handle these cases. The node is still connected to the tree so we need to detach it. |
| 43 | if (m_parent || m_previousSibling || m_nextSibling || m_firstChild || m_lastChild) { |
zalan@apple.com | a057f4e | 2016-10-15 14:24:33 +0000 | [diff] [blame] | 44 | CounterNode* oldParent = nullptr; |
| 45 | CounterNode* oldPreviousSibling = nullptr; |
cdn@chromium.org | c9e0506 | 2011-08-08 20:39:23 +0000 | [diff] [blame] | 46 | // Instead of calling removeChild() we do this safely as the tree is likely broken if we get here. |
| 47 | if (m_parent) { |
| 48 | if (m_parent->m_firstChild == this) |
| 49 | m_parent->m_firstChild = m_nextSibling; |
| 50 | if (m_parent->m_lastChild == this) |
| 51 | m_parent->m_lastChild = m_previousSibling; |
| 52 | oldParent = m_parent; |
zalan@apple.com | a057f4e | 2016-10-15 14:24:33 +0000 | [diff] [blame] | 53 | m_parent = nullptr; |
cdn@chromium.org | c9e0506 | 2011-08-08 20:39:23 +0000 | [diff] [blame] | 54 | } |
| 55 | if (m_previousSibling) { |
| 56 | if (m_previousSibling->m_nextSibling == this) |
| 57 | m_previousSibling->m_nextSibling = m_nextSibling; |
| 58 | oldPreviousSibling = m_previousSibling; |
zalan@apple.com | a057f4e | 2016-10-15 14:24:33 +0000 | [diff] [blame] | 59 | m_previousSibling = nullptr; |
cdn@chromium.org | c9e0506 | 2011-08-08 20:39:23 +0000 | [diff] [blame] | 60 | } |
| 61 | if (m_nextSibling) { |
| 62 | if (m_nextSibling->m_previousSibling == this) |
| 63 | m_nextSibling->m_previousSibling = oldPreviousSibling; |
zalan@apple.com | a057f4e | 2016-10-15 14:24:33 +0000 | [diff] [blame] | 64 | m_nextSibling = nullptr; |
cdn@chromium.org | c9e0506 | 2011-08-08 20:39:23 +0000 | [diff] [blame] | 65 | } |
| 66 | if (m_firstChild) { |
| 67 | // The node's children are reparented to the old parent. |
| 68 | for (CounterNode* child = m_firstChild; child; ) { |
| 69 | CounterNode* nextChild = child->m_nextSibling; |
zalan@apple.com | a057f4e | 2016-10-15 14:24:33 +0000 | [diff] [blame] | 70 | CounterNode* nextSibling = nullptr; |
cdn@chromium.org | c9e0506 | 2011-08-08 20:39:23 +0000 | [diff] [blame] | 71 | child->m_parent = oldParent; |
| 72 | if (oldPreviousSibling) { |
| 73 | nextSibling = oldPreviousSibling->m_nextSibling; |
| 74 | child->m_previousSibling = oldPreviousSibling; |
| 75 | oldPreviousSibling->m_nextSibling = child; |
| 76 | child->m_nextSibling = nextSibling; |
| 77 | nextSibling->m_previousSibling = child; |
| 78 | oldPreviousSibling = child; |
| 79 | } |
| 80 | child = nextChild; |
| 81 | } |
| 82 | } |
| 83 | } |
carol.szabo@nokia.com | d7917f7 | 2011-03-24 02:25:06 +0000 | [diff] [blame] | 84 | resetRenderers(); |
| 85 | } |
| 86 | |
akling@apple.com | ad2beb5 | 2014-12-25 07:50:20 +0000 | [diff] [blame] | 87 | Ref<CounterNode> CounterNode::create(RenderElement& owner, bool hasResetType, int value) |
jschuh@chromium.org | e94df97 | 2010-09-30 20:31:45 +0000 | [diff] [blame] | 88 | { |
akling@apple.com | ad2beb5 | 2014-12-25 07:50:20 +0000 | [diff] [blame] | 89 | return adoptRef(*new CounterNode(owner, hasResetType, value)); |
jschuh@chromium.org | e94df97 | 2010-09-30 20:31:45 +0000 | [diff] [blame] | 90 | } |
| 91 | |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 92 | CounterNode* CounterNode::nextInPreOrderAfterChildren(const CounterNode* stayWithin) const |
| 93 | { |
| 94 | if (this == stayWithin) |
zalan@apple.com | a057f4e | 2016-10-15 14:24:33 +0000 | [diff] [blame] | 95 | return nullptr; |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 96 | |
eric@webkit.org | d9edbba | 2010-01-14 03:30:36 +0000 | [diff] [blame] | 97 | const CounterNode* current = this; |
| 98 | CounterNode* next; |
| 99 | while (!(next = current->m_nextSibling)) { |
| 100 | current = current->m_parent; |
| 101 | if (!current || current == stayWithin) |
zalan@apple.com | a057f4e | 2016-10-15 14:24:33 +0000 | [diff] [blame] | 102 | return nullptr; |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 103 | } |
eric@webkit.org | d9edbba | 2010-01-14 03:30:36 +0000 | [diff] [blame] | 104 | return next; |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 105 | } |
| 106 | |
| 107 | CounterNode* CounterNode::nextInPreOrder(const CounterNode* stayWithin) const |
| 108 | { |
| 109 | if (CounterNode* next = m_firstChild) |
| 110 | return next; |
| 111 | |
| 112 | return nextInPreOrderAfterChildren(stayWithin); |
| 113 | } |
| 114 | |
| 115 | CounterNode* CounterNode::lastDescendant() const |
| 116 | { |
| 117 | CounterNode* last = m_lastChild; |
| 118 | if (!last) |
zalan@apple.com | a057f4e | 2016-10-15 14:24:33 +0000 | [diff] [blame] | 119 | return nullptr; |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 120 | |
| 121 | while (CounterNode* lastChild = last->m_lastChild) |
| 122 | last = lastChild; |
| 123 | |
| 124 | return last; |
| 125 | } |
| 126 | |
| 127 | CounterNode* CounterNode::previousInPreOrder() const |
| 128 | { |
| 129 | CounterNode* previous = m_previousSibling; |
| 130 | if (!previous) |
| 131 | return m_parent; |
| 132 | |
| 133 | while (CounterNode* lastChild = previous->m_lastChild) |
| 134 | previous = lastChild; |
| 135 | |
| 136 | return previous; |
bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 137 | } |
| 138 | |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 139 | int CounterNode::computeCountInParent() const |
bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 140 | { |
eric@webkit.org | d8ca5e1 | 2009-12-21 20:11:47 +0000 | [diff] [blame] | 141 | int increment = actsAsReset() ? 0 : m_value; |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 142 | if (m_previousSibling) |
| 143 | return m_previousSibling->m_countInParent + increment; |
| 144 | ASSERT(m_parent->m_firstChild == this); |
| 145 | return m_parent->m_value + increment; |
bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 146 | } |
| 147 | |
zalan@apple.com | a057f4e | 2016-10-15 14:24:33 +0000 | [diff] [blame] | 148 | void CounterNode::addRenderer(RenderCounter& renderer) |
bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 149 | { |
zalan@apple.com | a057f4e | 2016-10-15 14:24:33 +0000 | [diff] [blame] | 150 | ASSERT(!renderer.m_counterNode); |
| 151 | ASSERT(!renderer.m_nextForSameCounter); |
| 152 | renderer.m_nextForSameCounter = m_rootRenderer; |
| 153 | m_rootRenderer = &renderer; |
| 154 | renderer.m_counterNode = this; |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 155 | } |
| 156 | |
zalan@apple.com | a057f4e | 2016-10-15 14:24:33 +0000 | [diff] [blame] | 157 | void CounterNode::removeRenderer(RenderCounter& renderer) |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 158 | { |
zalan@apple.com | a057f4e | 2016-10-15 14:24:33 +0000 | [diff] [blame] | 159 | ASSERT(renderer.m_counterNode && renderer.m_counterNode == this); |
| 160 | RenderCounter* previous = nullptr; |
| 161 | for (auto* current = m_rootRenderer; current; previous = current, current = current->m_nextForSameCounter) { |
| 162 | if (current != &renderer) |
| 163 | continue; |
| 164 | |
| 165 | if (previous) |
| 166 | previous->m_nextForSameCounter = renderer.m_nextForSameCounter; |
| 167 | else |
| 168 | m_rootRenderer = renderer.m_nextForSameCounter; |
| 169 | renderer.m_nextForSameCounter = nullptr; |
| 170 | renderer.m_counterNode = nullptr; |
carol.szabo@nokia.com | 7cf0a55 | 2011-03-23 00:04:58 +0000 | [diff] [blame] | 171 | return; |
| 172 | } |
carol.szabo@nokia.com | 7cf0a55 | 2011-03-23 00:04:58 +0000 | [diff] [blame] | 173 | ASSERT_NOT_REACHED(); |
| 174 | } |
| 175 | |
| 176 | void CounterNode::resetRenderers() |
| 177 | { |
zalan@apple.com | a057f4e | 2016-10-15 14:24:33 +0000 | [diff] [blame] | 178 | if (!m_rootRenderer) |
| 179 | return; |
simon.fraser@apple.com | b59c690 | 2017-03-17 00:20:45 +0000 | [diff] [blame] | 180 | bool skipLayoutAndPerfWidthsRecalc = m_rootRenderer->renderTreeBeingDestroyed(); |
zalan@apple.com | a057f4e | 2016-10-15 14:24:33 +0000 | [diff] [blame] | 181 | auto* current = m_rootRenderer; |
| 182 | while (current) { |
| 183 | if (!skipLayoutAndPerfWidthsRecalc) |
| 184 | current->setNeedsLayoutAndPrefWidthsRecalc(); |
| 185 | auto* next = current->m_nextForSameCounter; |
| 186 | current->m_nextForSameCounter = nullptr; |
| 187 | current->m_counterNode = nullptr; |
| 188 | current = next; |
| 189 | } |
| 190 | m_rootRenderer = nullptr; |
carol.szabo@nokia.com | 7cf0a55 | 2011-03-23 00:04:58 +0000 | [diff] [blame] | 191 | } |
| 192 | |
| 193 | void CounterNode::resetThisAndDescendantsRenderers() |
| 194 | { |
| 195 | CounterNode* node = this; |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 196 | do { |
carol.szabo@nokia.com | 7cf0a55 | 2011-03-23 00:04:58 +0000 | [diff] [blame] | 197 | node->resetRenderers(); |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 198 | node = node->nextInPreOrder(this); |
| 199 | } while (node); |
| 200 | } |
| 201 | |
carol.szabo@nokia.com | 7cf0a55 | 2011-03-23 00:04:58 +0000 | [diff] [blame] | 202 | void CounterNode::recount() |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 203 | { |
| 204 | for (CounterNode* node = this; node; node = node->m_nextSibling) { |
| 205 | int oldCount = node->m_countInParent; |
| 206 | int newCount = node->computeCountInParent(); |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 207 | if (oldCount == newCount) |
| 208 | break; |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 209 | node->m_countInParent = newCount; |
carol.szabo@nokia.com | 7cf0a55 | 2011-03-23 00:04:58 +0000 | [diff] [blame] | 210 | node->resetThisAndDescendantsRenderers(); |
bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 211 | } |
| 212 | } |
| 213 | |
darin@apple.com | 0ce67df | 2019-06-17 01:48:13 +0000 | [diff] [blame] | 214 | void CounterNode::insertAfter(CounterNode& newChild, CounterNode* beforeChild, const AtomString& identifier) |
bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 215 | { |
zalan@apple.com | 84066f8 | 2016-11-15 20:12:26 +0000 | [diff] [blame] | 216 | ASSERT(!newChild.m_parent); |
| 217 | ASSERT(!newChild.m_previousSibling); |
| 218 | ASSERT(!newChild.m_nextSibling); |
| 219 | // If the beforeChild is not our child we can not complete the request. This hardens against bugs in RenderCounter. |
cdn@chromium.org | 009d1ab | 2011-09-13 22:49:15 +0000 | [diff] [blame] | 220 | // When renderers are reparented it may request that we insert counter nodes improperly. |
zalan@apple.com | 84066f8 | 2016-11-15 20:12:26 +0000 | [diff] [blame] | 221 | if (beforeChild && beforeChild->m_parent != this) |
cdn@chromium.org | 009d1ab | 2011-09-13 22:49:15 +0000 | [diff] [blame] | 222 | return; |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 223 | |
zalan@apple.com | 84066f8 | 2016-11-15 20:12:26 +0000 | [diff] [blame] | 224 | if (newChild.m_hasResetType) { |
| 225 | while (m_lastChild != beforeChild) |
carol.szabo@nokia.com | 7cf0a55 | 2011-03-23 00:04:58 +0000 | [diff] [blame] | 226 | RenderCounter::destroyCounterNode(m_lastChild->owner(), identifier); |
eric@webkit.org | ae29b2f | 2010-01-16 02:14:25 +0000 | [diff] [blame] | 227 | } |
| 228 | |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 229 | CounterNode* next; |
| 230 | |
zalan@apple.com | 84066f8 | 2016-11-15 20:12:26 +0000 | [diff] [blame] | 231 | if (beforeChild) { |
| 232 | next = beforeChild->m_nextSibling; |
| 233 | beforeChild->m_nextSibling = &newChild; |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 234 | } else { |
| 235 | next = m_firstChild; |
zalan@apple.com | 84066f8 | 2016-11-15 20:12:26 +0000 | [diff] [blame] | 236 | m_firstChild = &newChild; |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 237 | } |
| 238 | |
zalan@apple.com | 84066f8 | 2016-11-15 20:12:26 +0000 | [diff] [blame] | 239 | newChild.m_parent = this; |
| 240 | newChild.m_previousSibling = beforeChild; |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 241 | |
cdn@chromium.org | 32296c3 | 2012-06-20 05:36:27 +0000 | [diff] [blame] | 242 | if (next) { |
zalan@apple.com | 84066f8 | 2016-11-15 20:12:26 +0000 | [diff] [blame] | 243 | ASSERT(next->m_previousSibling == beforeChild); |
| 244 | next->m_previousSibling = &newChild; |
| 245 | newChild.m_nextSibling = next; |
cdn@chromium.org | 32296c3 | 2012-06-20 05:36:27 +0000 | [diff] [blame] | 246 | } else { |
zalan@apple.com | 84066f8 | 2016-11-15 20:12:26 +0000 | [diff] [blame] | 247 | ASSERT(m_lastChild == beforeChild); |
| 248 | m_lastChild = &newChild; |
cdn@chromium.org | 32296c3 | 2012-06-20 05:36:27 +0000 | [diff] [blame] | 249 | } |
eric@webkit.org | ae29b2f | 2010-01-16 02:14:25 +0000 | [diff] [blame] | 250 | |
zalan@apple.com | 84066f8 | 2016-11-15 20:12:26 +0000 | [diff] [blame] | 251 | if (!newChild.m_firstChild || newChild.m_hasResetType) { |
| 252 | newChild.m_countInParent = newChild.computeCountInParent(); |
| 253 | newChild.resetThisAndDescendantsRenderers(); |
eric@webkit.org | ae29b2f | 2010-01-16 02:14:25 +0000 | [diff] [blame] | 254 | if (next) |
carol.szabo@nokia.com | 7cf0a55 | 2011-03-23 00:04:58 +0000 | [diff] [blame] | 255 | next->recount(); |
eric@webkit.org | ae29b2f | 2010-01-16 02:14:25 +0000 | [diff] [blame] | 256 | return; |
| 257 | } |
| 258 | |
| 259 | // The code below handles the case when a formerly root increment counter is loosing its root position |
| 260 | // and therefore its children become next siblings. |
zalan@apple.com | 84066f8 | 2016-11-15 20:12:26 +0000 | [diff] [blame] | 261 | CounterNode* last = newChild.m_lastChild; |
| 262 | CounterNode* first = newChild.m_firstChild; |
eric@webkit.org | ae29b2f | 2010-01-16 02:14:25 +0000 | [diff] [blame] | 263 | |
cdn@chromium.org | 009d1ab | 2011-09-13 22:49:15 +0000 | [diff] [blame] | 264 | if (first) { |
| 265 | ASSERT(last); |
zalan@apple.com | 84066f8 | 2016-11-15 20:12:26 +0000 | [diff] [blame] | 266 | newChild.m_nextSibling = first; |
| 267 | if (m_lastChild == &newChild) |
cdn@chromium.org | 009d1ab | 2011-09-13 22:49:15 +0000 | [diff] [blame] | 268 | m_lastChild = last; |
| 269 | |
zalan@apple.com | 84066f8 | 2016-11-15 20:12:26 +0000 | [diff] [blame] | 270 | first->m_previousSibling = &newChild; |
cdn@chromium.org | 009d1ab | 2011-09-13 22:49:15 +0000 | [diff] [blame] | 271 | |
| 272 | // The case when the original next sibling of the inserted node becomes a child of |
| 273 | // one of the former children of the inserted node is not handled as it is believed |
| 274 | // to be impossible since: |
| 275 | // 1. if the increment counter node lost it's root position as a result of another |
| 276 | // counter node being created, it will be inserted as the last child so next is null. |
| 277 | // 2. if the increment counter node lost it's root position as a result of a renderer being |
| 278 | // inserted into the document's render tree, all its former children counters are attached |
| 279 | // to children of the inserted renderer and hence cannot be in scope for counter nodes |
| 280 | // attached to renderers that were already in the document's render tree. |
| 281 | last->m_nextSibling = next; |
| 282 | if (next) { |
zalan@apple.com | 84066f8 | 2016-11-15 20:12:26 +0000 | [diff] [blame] | 283 | ASSERT(next->m_previousSibling == &newChild); |
cdn@chromium.org | 009d1ab | 2011-09-13 22:49:15 +0000 | [diff] [blame] | 284 | next->m_previousSibling = last; |
| 285 | } else |
| 286 | m_lastChild = last; |
| 287 | for (next = first; ; next = next->m_nextSibling) { |
| 288 | next->m_parent = this; |
| 289 | if (last == next) |
| 290 | break; |
| 291 | } |
eric@webkit.org | ae29b2f | 2010-01-16 02:14:25 +0000 | [diff] [blame] | 292 | } |
zalan@apple.com | 84066f8 | 2016-11-15 20:12:26 +0000 | [diff] [blame] | 293 | newChild.m_firstChild = nullptr; |
| 294 | newChild.m_lastChild = nullptr; |
| 295 | newChild.m_countInParent = newChild.computeCountInParent(); |
| 296 | newChild.resetRenderers(); |
carol.szabo@nokia.com | 7cf0a55 | 2011-03-23 00:04:58 +0000 | [diff] [blame] | 297 | first->recount(); |
bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 298 | } |
| 299 | |
zalan@apple.com | 84066f8 | 2016-11-15 20:12:26 +0000 | [diff] [blame] | 300 | void CounterNode::removeChild(CounterNode& oldChild) |
bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 301 | { |
zalan@apple.com | 84066f8 | 2016-11-15 20:12:26 +0000 | [diff] [blame] | 302 | ASSERT(!oldChild.m_firstChild); |
| 303 | ASSERT(!oldChild.m_lastChild); |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 304 | |
zalan@apple.com | 84066f8 | 2016-11-15 20:12:26 +0000 | [diff] [blame] | 305 | CounterNode* next = oldChild.m_nextSibling; |
| 306 | CounterNode* previous = oldChild.m_previousSibling; |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 307 | |
zalan@apple.com | 84066f8 | 2016-11-15 20:12:26 +0000 | [diff] [blame] | 308 | oldChild.m_nextSibling = nullptr; |
| 309 | oldChild.m_previousSibling = nullptr; |
| 310 | oldChild.m_parent = nullptr; |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 311 | |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 312 | if (previous) |
| 313 | previous->m_nextSibling = next; |
bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 314 | else { |
zalan@apple.com | 84066f8 | 2016-11-15 20:12:26 +0000 | [diff] [blame] | 315 | ASSERT(m_firstChild == &oldChild); |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 316 | m_firstChild = next; |
bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 317 | } |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 318 | |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 319 | if (next) |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 320 | next->m_previousSibling = previous; |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 321 | else { |
zalan@apple.com | 84066f8 | 2016-11-15 20:12:26 +0000 | [diff] [blame] | 322 | ASSERT(m_lastChild == &oldChild); |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 323 | m_lastChild = previous; |
bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 324 | } |
eric@webkit.org | 0248271 | 2009-11-13 20:21:44 +0000 | [diff] [blame] | 325 | |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 326 | if (next) |
carol.szabo@nokia.com | 7cf0a55 | 2011-03-23 00:04:58 +0000 | [diff] [blame] | 327 | next->recount(); |
bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 328 | } |
| 329 | |
simon.fraser@apple.com | c9f9613 | 2015-03-06 18:20:40 +0000 | [diff] [blame] | 330 | #if ENABLE(TREE_DEBUGGING) |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 331 | |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 332 | static void showTreeAndMark(const CounterNode* node) |
bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 333 | { |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 334 | const CounterNode* root = node; |
| 335 | while (root->parent()) |
| 336 | root = root->parent(); |
| 337 | |
eric@webkit.org | cb91842 | 2009-11-13 20:55:51 +0000 | [diff] [blame] | 338 | for (const CounterNode* current = root; current; current = current->nextInPreOrder()) { |
zalan@apple.com | 29eeb9d | 2017-06-28 16:45:14 +0000 | [diff] [blame] | 339 | fprintf(stderr, "%c", (current == node) ? '*' : ' '); |
eric@webkit.org | a006295 | 2009-11-09 19:43:17 +0000 | [diff] [blame] | 340 | for (const CounterNode* parent = current; parent && parent != root; parent = parent->parent()) |
zalan@apple.com | 29eeb9d | 2017-06-28 16:45:14 +0000 | [diff] [blame] | 341 | fprintf(stderr, " "); |
| 342 | 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] | 343 | current, current->actsAsReset() ? "reset____" : "increment", current->value(), |
eric@webkit.org | a006295 | 2009-11-09 19:43:17 +0000 | [diff] [blame] | 344 | current->countInParent(), current->parent(), current->previousSibling(), |
antti@apple.com | 9735e7d | 2014-08-18 22:16:47 +0000 | [diff] [blame] | 345 | current->nextSibling(), ¤t->owner()); |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 346 | } |
carol.szabo@nokia.com | 7cf0a55 | 2011-03-23 00:04:58 +0000 | [diff] [blame] | 347 | fflush(stderr); |
bdakin | 5d6edd4 | 2006-10-02 23:15:31 +0000 | [diff] [blame] | 348 | } |
| 349 | |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 350 | #endif |
| 351 | |
weinig | 1497a7e | 2006-10-26 20:23:55 +0000 | [diff] [blame] | 352 | } // namespace WebCore |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 353 | |
simon.fraser@apple.com | c9f9613 | 2015-03-06 18:20:40 +0000 | [diff] [blame] | 354 | #if ENABLE(TREE_DEBUGGING) |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 355 | |
carol.szabo@nokia.com | 02635bf | 2011-02-05 00:28:57 +0000 | [diff] [blame] | 356 | void showCounterTree(const WebCore::CounterNode* counter) |
darin | ec37548 | 2007-01-06 01:36:24 +0000 | [diff] [blame] | 357 | { |
| 358 | if (counter) |
| 359 | showTreeAndMark(counter); |
| 360 | } |
| 361 | |
| 362 | #endif |