Changeset 50960 in webkit
- Timestamp:
- Nov 13, 2009 12:21:44 PM (14 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r50958 r50960 1 2009-11-13 Carol Szabo <carol.szabo@nokia.com> 2 3 Reviewed by Darin Adler. 4 5 The CounterNode class is missing some basic tree navigation methods common in other WebKit trees such as the rendering tree 6 https://bugs.webkit.org/show_bug.cgi?id=31213 7 Added tree navigation methods that permit full implementation of CSS2.1 8 counter feature without using recursion proportional to the counter 9 tree depth. 10 No new tests because I did not find any bug that is fixed by this 11 commit yet, this just reduces the size of the patch for 11031 and 12 helps respond to some concerns regarding that patch. 13 14 * rendering/CounterNode.cpp: 15 (WebCore::CounterNode::CounterNode): 16 17 (WebCore::CounterNode::nextInPreOrderAfterChildren): 18 (WebCore::CounterNode::nextInPreOrder): 19 Added to support non-recursive tree traversal necessary for 20 efficient full implementation of CSS2.1 counters. 21 22 (WebCore::CounterNode::lastDescendant): 23 (WebCore::CounterNode::previousInPreOrder): 24 Moved this methods such that they occupy a place similar to that of 25 identically named methods on the render tree. This allows for their 26 broader use needed in full implementation of CSS2.1 counters. 27 28 (WebCore::CounterNode::resetRenderer): 29 (WebCore::CounterNode::resetRenderers): 30 (WebCore::CounterNode::recount): 31 (WebCore::CounterNode::insertAfter): 32 (WebCore::CounterNode::removeChild): 33 Changed such that insertion/removal of a counter, triggers not only 34 recalculation of PrefixWidths, but also reassesment of values in 35 counter nodes. This is the basis full implementation of CSS2.1 36 counters. It does not change current behavior by much because of 37 changes needed to the recalculation algorithm, but those are comming 38 in the patch for 11031. 39 (WebCore::showTreeAndMark): 40 * rendering/CounterNode.h: 41 * rendering/RenderCounter.cpp: 42 (WebCore::counter): 43 Only changed argument type to prepare for implementation of Darin 44 Adler's recommendation for the patch to 11031. 45 46 (WebCore::RenderCounter::invalidate): 47 (WebCore::destroyCounterNodeChildren): 48 (WebCore::RenderCounter::destroyCounterNodes): 49 * rendering/RenderCounter.h: 50 * rendering/RenderObjectChildList.cpp: 51 (WebCore::invalidateCountersInContainer): 52 (WebCore::RenderObjectChildList::invalidateCounters): 53 * rendering/RenderObjectChildList.h: 54 Added the ability to restrict invalidation to counters with a given 55 identifier. 56 Also invalidated counters that are on the child container itself 57 which were missed by the previous algorithm, but were a valid case. 58 1 59 2009-11-13 Vitaly Repeshko <vitalyr@chromium.org> 2 60 -
trunk/WebCore/rendering/CounterNode.cpp
r50673 r50960 45 45 , m_firstChild(0) 46 46 , m_lastChild(0) 47 { 47 { 48 } 49 50 CounterNode* CounterNode::nextInPreOrderAfterChildren(const CounterNode* stayWithin) const 51 { 52 if (this == stayWithin) 53 return 0; 54 55 CounterNode* next = m_nextSibling; 56 if (next) 57 return next; 58 next = m_parent; 59 while (next && !next->m_nextSibling) { 60 if (next == stayWithin) 61 return 0; 62 next = next->m_parent; 63 } 64 if (next) 65 return next->m_nextSibling; 66 return 0; 67 } 68 69 CounterNode* CounterNode::nextInPreOrder(const CounterNode* stayWithin) const 70 { 71 if (CounterNode* next = m_firstChild) 72 return next; 73 74 return nextInPreOrderAfterChildren(stayWithin); 75 } 76 77 CounterNode* CounterNode::lastDescendant() const 78 { 79 CounterNode* last = m_lastChild; 80 if (!last) 81 return 0; 82 83 while (CounterNode* lastChild = last->m_lastChild) 84 last = lastChild; 85 86 return last; 87 } 88 89 CounterNode* CounterNode::previousInPreOrder() const 90 { 91 CounterNode* previous = m_previousSibling; 92 if (!previous) 93 return m_parent; 94 95 while (CounterNode* lastChild = previous->m_lastChild) 96 previous = lastChild; 97 98 return previous; 48 99 } 49 100 … … 57 108 } 58 109 59 void CounterNode::recount() 60 { 61 for (CounterNode* c = this; c; c = c->m_nextSibling) { 62 int oldCount = c->m_countInParent; 63 int newCount = c->computeCountInParent(); 110 111 void CounterNode::resetRenderer(const AtomicString& identifier) const 112 { 113 if (!m_renderer || m_renderer->documentBeingDestroyed()) 114 return; 115 if (RenderObjectChildList* children = m_renderer->virtualChildren()) 116 children->invalidateCounters(m_renderer, identifier); 117 } 118 119 void CounterNode::resetRenderers(const AtomicString& identifier) const 120 { 121 const CounterNode* node = this; 122 do { 123 node->resetRenderer(identifier); 124 node = node->nextInPreOrder(this); 125 } while (node); 126 } 127 128 void CounterNode::recount(const AtomicString& identifier) 129 { 130 for (CounterNode* node = this; node; node = node->m_nextSibling) { 131 int oldCount = node->m_countInParent; 132 int newCount = node->computeCountInParent(); 64 133 if (oldCount == newCount) 65 134 break; 66 c->m_countInParent = newCount; 67 // m_renderer contains the parent of the render node 68 // corresponding to a CounterNode. Let's find the counter 69 // child and make this re-layout. 70 for (RenderObject* o = c->m_renderer->firstChild(); o; o = o->nextSibling()) 71 if (!o->documentBeingDestroyed() && o->isCounter()) { 72 o->setNeedsLayoutAndPrefWidthsRecalc(); 73 break; 74 } 75 } 76 } 77 78 void CounterNode::insertAfter(CounterNode* newChild, CounterNode* refChild) 135 node->m_countInParent = newCount; 136 node->resetRenderers(identifier); 137 } 138 } 139 140 void CounterNode::insertAfter(CounterNode* newChild, CounterNode* refChild, const AtomicString& identifier) 79 141 { 80 142 ASSERT(newChild); … … 108 170 newChild->m_countInParent = newChild->computeCountInParent(); 109 171 if (next) 110 next->recount( );111 } 112 113 void CounterNode::removeChild(CounterNode* oldChild )172 next->recount(identifier); 173 } 174 175 void CounterNode::removeChild(CounterNode* oldChild, const AtomicString& identifier) 114 176 { 115 177 ASSERT(oldChild); … … 118 180 119 181 CounterNode* next = oldChild->m_nextSibling; 120 CounterNode* prev = oldChild->m_previousSibling;182 CounterNode* previous = oldChild->m_previousSibling; 121 183 122 184 oldChild->m_nextSibling = 0; … … 124 186 oldChild->m_parent = 0; 125 187 126 if (prev )127 prev ->m_nextSibling = next;188 if (previous) 189 previous->m_nextSibling = next; 128 190 else { 129 191 ASSERT(m_firstChild == oldChild); 130 192 m_firstChild = next; 131 193 } 132 133 if (next) 134 next->m_previousSibling = prev ;194 195 if (next) 196 next->m_previousSibling = previous; 135 197 else { 136 198 ASSERT(m_lastChild == oldChild); 137 m_lastChild = prev ;138 } 139 140 if (next) 141 next->recount( );199 m_lastChild = previous; 200 } 201 202 if (next) 203 next->recount(identifier); 142 204 } 143 205 144 206 #ifndef NDEBUG 145 146 static const CounterNode* nextInPreOrderAfterChildren(const CounterNode* node)147 {148 CounterNode* next = node->nextSibling();149 if (!next) {150 next = node->parent();151 while (next && !next->nextSibling())152 next = next->parent();153 if (next)154 next = next->nextSibling();155 }156 return next;157 }158 159 static const CounterNode* nextInPreOrder(const CounterNode* node)160 {161 if (CounterNode* child = node->firstChild())162 return child;163 return nextInPreOrderAfterChildren(node);164 }165 207 166 208 static void showTreeAndMark(const CounterNode* node) -
trunk/WebCore/rendering/CounterNode.h
r45891 r50960 36 36 namespace WebCore { 37 37 38 class AtomicString; 38 39 class RenderObject; 39 40 … … 52 53 CounterNode* firstChild() const { return m_firstChild; } 53 54 CounterNode* lastChild() const { return m_lastChild; } 55 CounterNode* lastDescendant() const; 56 CounterNode* previousInPreOrder() const; 57 CounterNode* nextInPreOrder(const CounterNode* stayWithin = 0) const; 58 CounterNode* nextInPreOrderAfterChildren(const CounterNode* stayWithin = 0) const; 54 59 55 void insertAfter(CounterNode* newChild, CounterNode* beforeChild );56 void removeChild(CounterNode* );60 void insertAfter(CounterNode* newChild, CounterNode* beforeChild, const AtomicString& identifier); 61 void removeChild(CounterNode*, const AtomicString& identifier); 57 62 58 63 private: 59 64 int computeCountInParent() const; 60 void recount(); 65 void recount(const AtomicString& identifier); 66 void resetRenderer(const AtomicString& identifier) const; 67 void resetRenderers(const AtomicString& identifier) const; 61 68 62 69 bool m_isReset; -
trunk/WebCore/rendering/RenderCounter.cpp
r50787 r50960 52 52 return sibling; 53 53 return object->parent(); 54 }55 56 static CounterNode* lastDescendant(CounterNode* node)57 {58 CounterNode* last = node->lastChild();59 if (!last)60 return 0;61 62 while (CounterNode* lastChild = last->lastChild())63 last = lastChild;64 65 return last;66 }67 68 static CounterNode* previousInPreOrder(CounterNode* node)69 {70 CounterNode* previous = node->previousSibling();71 if (!previous)72 return node->parent();73 74 while (CounterNode* lastChild = previous->lastChild())75 previous = lastChild;76 77 return previous;78 54 } 79 55 … … 205 181 if (findPlaceForCounter(object, counterName, isReset, newParent, newPreviousSibling)) { 206 182 newNode = new CounterNode(object, isReset, value); 207 newParent->insertAfter(newNode, newPreviousSibling );183 newParent->insertAfter(newNode, newPreviousSibling, counterName); 208 184 } else { 209 185 // Make a reset node for counters that aren't inside an existing reset node. … … 273 249 } 274 250 275 void RenderCounter::invalidate() 276 { 251 void RenderCounter::invalidate(const AtomicString& identifier) 252 { 253 if (m_counter.identifier() != identifier) 254 return; 277 255 m_counterNode = 0; 278 256 setNeedsLayoutAndPrefWidthsRecalc(); 279 257 } 280 258 281 static void destroyCounterNodeChildren( AtomicStringImpl*identifier, CounterNode* node)259 static void destroyCounterNodeChildren(const AtomicString& identifier, CounterNode* node) 282 260 { 283 261 CounterNode* previous; 284 for (CounterNode* child = lastDescendant(node); child && child != node; child = previous) {285 previous = previousInPreOrder(child);286 child->parent()->removeChild(child );287 ASSERT(counterMaps().get(child->renderer())->get(identifier ) == child);288 counterMaps().get(child->renderer())->remove(identifier );262 for (CounterNode* child = node->lastDescendant(); child && child != node; child = previous) { 263 previous = child->previousInPreOrder(); 264 child->parent()->removeChild(child, identifier); 265 ASSERT(counterMaps().get(child->renderer())->get(identifier->impl()) == child); 266 counterMaps().get(child->renderer())->remove(identifier.impl()); 289 267 if (!child->renderer()->documentBeingDestroyed()) { 290 268 RenderObjectChildList* children = child->renderer()->virtualChildren(); 291 269 if (children) 292 children->invalidateCounters(child->renderer() );270 children->invalidateCounters(child->renderer(), identifier); 293 271 } 294 272 delete child; … … 307 285 for (CounterMap::const_iterator it = map->begin(); it != end; ++it) { 308 286 CounterNode* node = it->second; 309 destroyCounterNodeChildren(it->first.get(), node); 287 AtomicString identifier(it->first.get()); 288 destroyCounterNodeChildren(identifier, node); 310 289 if (CounterNode* parent = node->parent()) 311 parent->removeChild(node );290 parent->removeChild(node, identifier); 312 291 delete node; 313 292 } -
trunk/WebCore/rendering/RenderCounter.h
r46815 r50960 34 34 RenderCounter(Document*, const CounterContent&); 35 35 36 void invalidate(); 36 // Removes the reference to the CounterNode associated with this renderer 37 // if its identifier matches the argument. 38 // This is used to cause a counter display update when the CounterNode 39 // tree for identifier changes. 40 void invalidate(const AtomicString& identifier); 37 41 38 42 static void destroyCounterNodes(RenderObject*); -
trunk/WebCore/rendering/RenderObjectChildList.cpp
r50386 r50960 272 272 } 273 273 274 static void invalidateCountersInContainer(RenderObject* container )274 static void invalidateCountersInContainer(RenderObject* container, const AtomicString& identifier) 275 275 { 276 276 if (!container) … … 279 279 if (!container) 280 280 return; 281 // Sometimes the counter is attached directly on the container. 282 if (container->isCounter()) { 283 toRenderCounter(container)->invalidate(identifier); 284 return; 285 } 281 286 for (RenderObject* content = container->firstChild(); content; content = content->nextSibling()) { 282 287 if (content->isCounter()) 283 toRenderCounter(content)->invalidate( );284 } 285 } 286 287 void RenderObjectChildList::invalidateCounters(RenderObject* owner )288 toRenderCounter(content)->invalidate(identifier); 289 } 290 } 291 292 void RenderObjectChildList::invalidateCounters(RenderObject* owner, const AtomicString& identifier) 288 293 { 289 294 ASSERT(!owner->documentBeingDestroyed()); 290 invalidateCountersInContainer(beforeAfterContainer(owner, BEFORE) );291 invalidateCountersInContainer(beforeAfterContainer(owner, AFTER) );295 invalidateCountersInContainer(beforeAfterContainer(owner, BEFORE), identifier); 296 invalidateCountersInContainer(beforeAfterContainer(owner, AFTER), identifier); 292 297 } 293 298 -
trunk/WebCore/rendering/RenderObjectChildList.h
r40651 r50960 31 31 namespace WebCore { 32 32 33 class AtomicString; 33 34 class RenderObject; 34 35 … … 56 57 57 58 void updateBeforeAfterContent(RenderObject* owner, PseudoId type, RenderObject* styledObject = 0); 58 void invalidateCounters(RenderObject* owner );59 void invalidateCounters(RenderObject* owner, const AtomicString& identifier); 59 60 60 61 private:
Note: See TracChangeset
for help on using the changeset viewer.