18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/** 28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com) 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version. 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful, 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details. 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB. If not, write to 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA. 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderCounter.h" 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CounterNode.h" 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Document.h" 272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include "Element.h" 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLNames.h" 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLOListElement.h" 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderListItem.h" 318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderListMarker.h" 328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderStyle.h" 33635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <wtf/StdLibExtras.h> 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore { 368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace HTMLNames; 388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 39a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochtypedef HashMap<RefPtr<AtomicStringImpl>, RefPtr<CounterNode> > CounterMap; 408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttypedef HashMap<const RenderObject*, CounterMap*> CounterMaps; 418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 42d0825bca7fe65beaee391d30da42e937db621564Steve Blockstatic CounterNode* makeCounterNode(RenderObject*, const AtomicString& identifier, bool alwaysCreateCounter); 438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic CounterMaps& counterMaps() 458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 46635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_STATIC_LOCAL(CounterMaps, staticCounterMaps, ()); 478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return staticCounterMaps; 488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// This function processes the renderer tree in the order of the DOM tree 512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// including pseudo elements as defined in CSS 2.1. 522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// Anonymous renderers are skipped except for those representing pseudo elements. 532fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic RenderObject* previousInPreOrder(const RenderObject* object) 548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Element* parent; 562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Element* sibling; 572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block switch (object->style()->styleType()) { 582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block case NOPSEUDO: 592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ASSERT(!object->isAnonymous()); 602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block parent = toElement(object->node()); 612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block sibling = parent->previousElementSibling(); 622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block parent = parent->parentElement(); 632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block break; 642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block case BEFORE: 652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return object->generatingNode()->renderer(); // It is always the generating node's renderer 662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block case AFTER: 672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block parent = toElement(object->generatingNode()); 682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block sibling = parent->lastElementChild(); 692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block break; 702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block default: 712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ASSERT_NOT_REACHED(); 722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return 0; 732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block while (sibling) { 752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (RenderObject* renderer = sibling->renderer()) { 762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (RenderObject* after = renderer->afterPseudoElementRenderer()) 772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return after; 782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block parent = sibling; 792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block sibling = sibling->lastElementChild(); 802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!sibling) { 812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (RenderObject* before = renderer->beforePseudoElementRenderer()) 822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return before; 832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return renderer; 842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } else 862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block sibling = sibling->previousElementSibling(); 872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!parent) 892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return 0; 902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block RenderObject* renderer = parent->renderer(); // Should never be null 912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (RenderObject* before = renderer->beforePseudoElementRenderer()) 922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return before; 932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return renderer; 942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// This function processes the renderer tree in the order of the DOM tree 972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// including pseudo elements as defined in CSS 2.1. 982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// Anonymous renderers are skipped except for those representing pseudo elements. 992fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic RenderObject* previousSiblingOrParent(const RenderObject* object) 1002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 1012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Element* parent; 1022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Element* sibling; 1032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block switch (object->style()->styleType()) { 1042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block case NOPSEUDO: 1052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ASSERT(!object->isAnonymous()); 1062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block parent = toElement(object->node()); 1072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block sibling = parent->previousElementSibling(); 1082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block parent = parent->parentElement(); 1092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block break; 1102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block case BEFORE: 1112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return object->generatingNode()->renderer(); // It is always the generating node's renderer 1122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block case AFTER: 1132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block parent = toElement(object->generatingNode()); 1142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block sibling = parent->lastElementChild(); 1152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block break; 1162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block default: 1172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ASSERT_NOT_REACHED(); 1182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return 0; 1192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 1202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block while (sibling) { 1212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (RenderObject* renderer = sibling->renderer()) // This skips invisible nodes 1222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return renderer; 1232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block sibling = sibling->previousElementSibling(); 1242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 1252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (parent) { 1262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block RenderObject* renderer = parent->renderer(); 1272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (RenderObject* before = renderer->virtualChildren()->beforePseudoElementRenderer(renderer)) 1282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return before; 1292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return renderer; 1302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 1312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return 0; 1322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 1332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1342fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic Element* parentElement(RenderObject* object) 1352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 1362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block switch (object->style()->styleType()) { 1372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block case NOPSEUDO: 1382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ASSERT(!object->isAnonymous()); 1392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return toElement(object->node())->parentElement(); 1402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block case BEFORE: 1412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block case AFTER: 1422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return toElement(object->generatingNode()); 1432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block default: 1442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ASSERT_NOT_REACHED(); 1452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return 0; 1462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 1472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 1482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1492fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic inline bool areRenderersElementsSiblings(RenderObject* first, RenderObject* second) 1502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 1512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return parentElement(first) == parentElement(second); 1522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 1532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// This function processes the renderer tree in the order of the DOM tree 1552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// including pseudo elements as defined in CSS 2.1. 1562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// Anonymous renderers are skipped except for those representing pseudo elements. 1572fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic RenderObject* nextInPreOrder(const RenderObject* object, const Element* stayWithin, bool skipDescendants = false) 1582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 1592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Element* self; 1602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Element* child; 1612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block RenderObject* result; 1622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block self = toElement(object->generatingNode()); 1632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (skipDescendants) 1642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block goto nextsibling; 1652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block switch (object->style()->styleType()) { 1662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block case NOPSEUDO: 1672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ASSERT(!object->isAnonymous()); 1682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block result = object->beforePseudoElementRenderer(); 1692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (result) 1702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return result; 1712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block break; 1722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block case BEFORE: 1732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block break; 1742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block case AFTER: 1752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block goto nextsibling; 1762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block default: 1772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ASSERT_NOT_REACHED(); 1782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return 0; 1792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 1802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block child = self->firstElementChild(); 1812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block while (true) { 1822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block while (child) { 1832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block result = child->renderer(); 1842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (result) 1852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return result; 1862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block child = child->nextElementSibling(); 1872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 1882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block result = self->renderer()->afterPseudoElementRenderer(); 1892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (result) 1902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return result; 1912fc2651226baac27029e38c9d6ef883fa32084dbSteve Blocknextsibling: 1922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (self == stayWithin) 1932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return 0; 1942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block child = self->nextElementSibling(); 1952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block self = self->parentElement(); 1962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!self) { 1972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ASSERT(!child); // We can only reach this if we are searching beyond the root element 1982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return 0; // which cannot have siblings 1992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 2002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 203d0825bca7fe65beaee391d30da42e937db621564Steve Blockstatic bool planCounter(RenderObject* object, const AtomicString& identifier, bool& isReset, int& value) 2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(object); 2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Real text nodes don't have their own style so they can't have counters. 2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We can't even look at their styles or we'll see extra resets and increments! 2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (object->isText() && !object->isBR()) 2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 2112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Node* generatingNode = object->generatingNode(); 2122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // We must have a generating node or else we cannot have a counter. 2132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!generatingNode) 2142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return false; 2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderStyle* style = object->style(); 2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(style); 2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block switch (style->styleType()) { 2192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block case NOPSEUDO: 2202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Sometimes nodes have more then one renderer. Only the first one gets the counter 2212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // LayoutTests/http/tests/css/counter-crash.html 2222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (generatingNode->renderer() != object) 2232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return false; 2242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block break; 2252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block case BEFORE: 2262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block case AFTER: 2272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block break; 2282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block default: 2292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return false; // Counters are forbidden from all other pseudo elements. 2302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 2312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (const CounterDirectiveMap* directivesMap = style->counterDirectives()) { 233d0825bca7fe65beaee391d30da42e937db621564Steve Block CounterDirectives directives = directivesMap->get(identifier.impl()); 2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (directives.m_reset) { 2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project value = directives.m_resetValue; 2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (directives.m_increment) 2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project value += directives.m_incrementValue; 2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project isReset = true; 2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (directives.m_increment) { 2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project value = directives.m_incrementValue; 2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project isReset = false; 2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 248d0825bca7fe65beaee391d30da42e937db621564Steve Block if (identifier == "list-item") { 2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (object->isListItem()) { 2500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (toRenderListItem(object)->hasExplicitValue()) { 2510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch value = toRenderListItem(object)->explicitValue(); 2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project isReset = true; 2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project value = 1; 2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project isReset = false; 2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (Node* e = object->node()) { 2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (e->hasTagName(olTag)) { 2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project value = static_cast<HTMLOListElement*>(e)->start(); 2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project isReset = true; 2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (e->hasTagName(ulTag) || e->hasTagName(menuTag) || e->hasTagName(dirTag)) { 2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project value = 0; 2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project isReset = true; 2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 276643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// - Finds the insertion point for the counter described by counterOwner, isReset and 277643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// identifier in the CounterNode tree for identifier and sets parent and 278643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// previousSibling accordingly. 279643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// - The function returns true if the counter whose insertion point is searched is NOT 280643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// the root of the tree. 281643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// - The root of the tree is a counter reference that is not in the scope of any other 282643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// counter with the same identifier. 283643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// - All the counter references with the same identifier as this one that are in 284643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// children or subsequent siblings of the renderer that owns the root of the tree 285643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// form the rest of of the nodes of the tree. 286643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// - The root of the tree is always a reset type reference. 287643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// - A subtree rooted at any reset node in the tree is equivalent to all counter 288643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// references that are in the scope of the counter or nested counter defined by that 289643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// reset node. 290643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// - Non-reset CounterNodes cannot have descendants. 291643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 292643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic bool findPlaceForCounter(RenderObject* counterOwner, const AtomicString& identifier, bool isReset, CounterNode*& parent, CounterNode*& previousSibling) 2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 294643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // We cannot stop searching for counters with the same identifier before we also 295643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // check this renderer, because it may affect the positioning in the tree of our counter. 296643ca7872b450ea4efacab6188849e5aac2ba161Steve Block RenderObject* searchEndRenderer = previousSiblingOrParent(counterOwner); 297643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // We check renderers in preOrder from the renderer that our counter is attached to 298643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // towards the begining of the document for counters with the same identifier as the one 299643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // we are trying to find a place for. This is the next renderer to be checked. 3002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block RenderObject* currentRenderer = previousInPreOrder(counterOwner); 3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project previousSibling = 0; 302643ca7872b450ea4efacab6188849e5aac2ba161Steve Block while (currentRenderer) { 303643ca7872b450ea4efacab6188849e5aac2ba161Steve Block CounterNode* currentCounter = makeCounterNode(currentRenderer, identifier, false); 304643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (searchEndRenderer == currentRenderer) { 305643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // We may be at the end of our search. 306643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (currentCounter) { 307643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // We have a suitable counter on the EndSearchRenderer. 308643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (previousSibling) { // But we already found another counter that we come after. 309d0825bca7fe65beaee391d30da42e937db621564Steve Block if (currentCounter->actsAsReset()) { 310643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // We found a reset counter that is on a renderer that is a sibling of ours or a parent. 3112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (isReset && areRenderersElementsSiblings(currentRenderer, counterOwner)) { 312643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // We are also a reset counter and the previous reset was on a sibling renderer 313643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // hence we are the next sibling of that counter if that reset is not a root or 314643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // we are a root node if that reset is a root. 315643ca7872b450ea4efacab6188849e5aac2ba161Steve Block parent = currentCounter->parent(); 316643ca7872b450ea4efacab6188849e5aac2ba161Steve Block previousSibling = parent ? currentCounter : 0; 317643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return parent; 318643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 3192bde8e466a4451c7319e3a072d118917957d6554Steve Block // We are not a reset node or the previous reset must be on an ancestor of our owner renderer 320643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // hence we must be a child of that reset counter. 321643ca7872b450ea4efacab6188849e5aac2ba161Steve Block parent = currentCounter; 322643ca7872b450ea4efacab6188849e5aac2ba161Steve Block ASSERT(previousSibling->parent() == currentCounter); 323643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return true; 324643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 325643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // CurrentCounter, the counter at the EndSearchRenderer, is not reset. 3262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!isReset || !areRenderersElementsSiblings(currentRenderer, counterOwner)) { 327643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // If the node we are placing is not reset or we have found a counter that is attached 3282bde8e466a4451c7319e3a072d118917957d6554Steve Block // to an ancestor of the placed counter's owner renderer we know we are a sibling of that node. 329643ca7872b450ea4efacab6188849e5aac2ba161Steve Block ASSERT(currentCounter->parent() == previousSibling->parent()); 330643ca7872b450ea4efacab6188849e5aac2ba161Steve Block parent = currentCounter->parent(); 331643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return true; 332643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 333643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } else { 334643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // We are at the potential end of the search, but we had no previous sibling candidate 335643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // In this case we follow pretty much the same logic as above but no ASSERTs about 336643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // previousSibling, and when we are a sibling of the end counter we must set previousSibling 337643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // to currentCounter. 338d0825bca7fe65beaee391d30da42e937db621564Steve Block if (currentCounter->actsAsReset()) { 3392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (isReset && areRenderersElementsSiblings(currentRenderer, counterOwner)) { 340643ca7872b450ea4efacab6188849e5aac2ba161Steve Block parent = currentCounter->parent(); 341643ca7872b450ea4efacab6188849e5aac2ba161Steve Block previousSibling = currentCounter; 342643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return parent; 343643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 344643ca7872b450ea4efacab6188849e5aac2ba161Steve Block parent = currentCounter; 345643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return true; 346643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 3472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!isReset || !areRenderersElementsSiblings(currentRenderer, counterOwner)) { 348643ca7872b450ea4efacab6188849e5aac2ba161Steve Block parent = currentCounter->parent(); 349643ca7872b450ea4efacab6188849e5aac2ba161Steve Block previousSibling = currentCounter; 350643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return true; 351643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 352643ca7872b450ea4efacab6188849e5aac2ba161Steve Block previousSibling = currentCounter; 3538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3552bde8e466a4451c7319e3a072d118917957d6554Steve Block // We come here if the previous sibling or parent of our owner renderer had no 356643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // good counter, or we are a reset node and the counter on the previous sibling 3572bde8e466a4451c7319e3a072d118917957d6554Steve Block // of our owner renderer was not a reset counter. 358643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // Set a new goal for the end of the search. 359643ca7872b450ea4efacab6188849e5aac2ba161Steve Block searchEndRenderer = previousSiblingOrParent(currentRenderer); 360643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } else { 361643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // We are searching descendants of a previous sibling of the renderer that the 362643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // counter being placed is attached to. 363643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (currentCounter) { 364643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // We found a suitable counter. 365643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (previousSibling) { 366643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // Since we had a suitable previous counter before, we should only consider this one as our 367643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // previousSibling if it is a reset counter and hence the current previousSibling is its child. 368d0825bca7fe65beaee391d30da42e937db621564Steve Block if (currentCounter->actsAsReset()) { 369643ca7872b450ea4efacab6188849e5aac2ba161Steve Block previousSibling = currentCounter; 370643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // We are no longer interested in previous siblings of the currentRenderer or their children 371643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // as counters they may have attached cannot be the previous sibling of the counter we are placing. 3722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block currentRenderer = parentElement(currentRenderer)->renderer(); 373643ca7872b450ea4efacab6188849e5aac2ba161Steve Block continue; 374643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 375643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } else 376643ca7872b450ea4efacab6188849e5aac2ba161Steve Block previousSibling = currentCounter; 377643ca7872b450ea4efacab6188849e5aac2ba161Steve Block currentRenderer = previousSiblingOrParent(currentRenderer); 378643ca7872b450ea4efacab6188849e5aac2ba161Steve Block continue; 379231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 3808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 381643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // This function is designed so that the same test is not done twice in an iteration, except for this one 382643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // which may be done twice in some cases. Rearranging the decision points though, to accommodate this 383643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // performance improvement would create more code duplication than is worthwhile in my oppinion and may further 384643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // impede the readability of this already complex algorithm. 385643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (previousSibling) 386643ca7872b450ea4efacab6188849e5aac2ba161Steve Block currentRenderer = previousSiblingOrParent(currentRenderer); 387643ca7872b450ea4efacab6188849e5aac2ba161Steve Block else 38881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch currentRenderer = previousInPreOrder(currentRenderer); 3898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 3918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 393d0825bca7fe65beaee391d30da42e937db621564Steve Blockstatic CounterNode* makeCounterNode(RenderObject* object, const AtomicString& identifier, bool alwaysCreateCounter) 3948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(object); 3968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 397a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (object->m_hasCounterNodeMap) { 398a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (CounterMap* nodeMap = counterMaps().get(object)) { 399a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (CounterNode* node = nodeMap->get(identifier.impl()).get()) 4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return node; 401a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 402a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 4038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool isReset = false; 4058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int value = 0; 406d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!planCounter(object, identifier, isReset, value) && !alwaysCreateCounter) 4078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 4088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CounterNode* newParent = 0; 4108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CounterNode* newPreviousSibling = 0; 411a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<CounterNode> newNode = CounterNode::create(object, isReset, value); 412d0825bca7fe65beaee391d30da42e937db621564Steve Block if (findPlaceForCounter(object, identifier, isReset, newParent, newPreviousSibling)) 413a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch newParent->insertAfter(newNode.get(), newPreviousSibling, identifier); 4148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CounterMap* nodeMap; 4158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (object->m_hasCounterNodeMap) 4168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project nodeMap = counterMaps().get(object); 4178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 4188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project nodeMap = new CounterMap; 4198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project counterMaps().set(object, nodeMap); 4208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project object->m_hasCounterNodeMap = true; 4218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 422d0825bca7fe65beaee391d30da42e937db621564Steve Block nodeMap->set(identifier.impl(), newNode); 4232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (newNode->parent()) 424a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return newNode.get(); 425d0825bca7fe65beaee391d30da42e937db621564Steve Block // Checking if some nodes that were previously counter tree root nodes 426d0825bca7fe65beaee391d30da42e937db621564Steve Block // should become children of this node now. 427d0825bca7fe65beaee391d30da42e937db621564Steve Block CounterMaps& maps = counterMaps(); 4282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Element* stayWithin = parentElement(object); 4292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block bool skipDescendants; 4302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block for (RenderObject* currentRenderer = nextInPreOrder(object, stayWithin); currentRenderer; currentRenderer = nextInPreOrder(currentRenderer, stayWithin, skipDescendants)) { 4312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block skipDescendants = false; 432d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!currentRenderer->m_hasCounterNodeMap) 433d0825bca7fe65beaee391d30da42e937db621564Steve Block continue; 434a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch CounterNode* currentCounter = maps.get(currentRenderer)->get(identifier.impl()).get(); 435d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!currentCounter) 436d0825bca7fe65beaee391d30da42e937db621564Steve Block continue; 4372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block skipDescendants = true; 438d0825bca7fe65beaee391d30da42e937db621564Steve Block if (currentCounter->parent()) { 439d0825bca7fe65beaee391d30da42e937db621564Steve Block ASSERT(newNode->firstChild()); 440d0825bca7fe65beaee391d30da42e937db621564Steve Block continue; 441d0825bca7fe65beaee391d30da42e937db621564Steve Block } 4422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (stayWithin == parentElement(currentRenderer) && currentCounter->hasResetType()) 4432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block break; 4442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block newNode->insertAfter(currentCounter, newNode->lastChild(), identifier); 445d0825bca7fe65beaee391d30da42e937db621564Steve Block } 446a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return newNode.get(); 4478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRenderCounter::RenderCounter(Document* node, const CounterContent& counter) 4508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project : RenderText(node, StringImpl::empty()) 4518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_counter(counter) 4528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_counterNode(0) 4532bde8e466a4451c7319e3a072d118917957d6554Steve Block , m_nextForSameCounter(0) 4548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 457a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochRenderCounter::~RenderCounter() 458a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 4592bde8e466a4451c7319e3a072d118917957d6554Steve Block if (m_counterNode) { 4602bde8e466a4451c7319e3a072d118917957d6554Steve Block m_counterNode->removeRenderer(this); 4612bde8e466a4451c7319e3a072d118917957d6554Steve Block ASSERT(!m_counterNode); 4622bde8e466a4451c7319e3a072d118917957d6554Steve Block } 463a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 464a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 4658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst char* RenderCounter::renderName() const 4668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return "RenderCounter"; 4688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderCounter::isCounter() const 4718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 4738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<StringImpl> RenderCounter::originalText() const 4768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4772bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!m_counterNode) { 4782bde8e466a4451c7319e3a072d118917957d6554Steve Block RenderObject* beforeAfterContainer = parent(); 4792bde8e466a4451c7319e3a072d118917957d6554Steve Block while (true) { 4802bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!beforeAfterContainer) 4812bde8e466a4451c7319e3a072d118917957d6554Steve Block return 0; 4822bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!beforeAfterContainer->isAnonymous()) 4832bde8e466a4451c7319e3a072d118917957d6554Steve Block return 0; // RenderCounters are restricted to before and after pseudo elements 4842bde8e466a4451c7319e3a072d118917957d6554Steve Block PseudoId containerStyle = beforeAfterContainer->style()->styleType(); 4852bde8e466a4451c7319e3a072d118917957d6554Steve Block if ((containerStyle == BEFORE) || (containerStyle == AFTER)) 4862bde8e466a4451c7319e3a072d118917957d6554Steve Block break; 4872bde8e466a4451c7319e3a072d118917957d6554Steve Block beforeAfterContainer = beforeAfterContainer->parent(); 4882bde8e466a4451c7319e3a072d118917957d6554Steve Block } 4892bde8e466a4451c7319e3a072d118917957d6554Steve Block makeCounterNode(beforeAfterContainer, m_counter.identifier(), true)->addRenderer(const_cast<RenderCounter*>(this)); 4902bde8e466a4451c7319e3a072d118917957d6554Steve Block ASSERT(m_counterNode); 4912bde8e466a4451c7319e3a072d118917957d6554Steve Block } 4928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CounterNode* child = m_counterNode; 493d0825bca7fe65beaee391d30da42e937db621564Steve Block int value = child->actsAsReset() ? child->value() : child->countInParent(); 4948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project String text = listMarkerText(m_counter.listStyle(), value); 4968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!m_counter.separator().isNull()) { 498d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!child->actsAsReset()) 4998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project child = child->parent(); 5008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (CounterNode* parent = child->parent()) { 5018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project text = listMarkerText(m_counter.listStyle(), child->countInParent()) 5028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project + m_counter.separator() + text; 5038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project child = parent; 5048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return text.impl(); 5088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 51081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid RenderCounter::computePreferredLogicalWidths(float lead) 5118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project setTextInternal(originalText()); 513bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen RenderText::computePreferredLogicalWidths(lead); 5148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5162bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid RenderCounter::invalidate() 5178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5182bde8e466a4451c7319e3a072d118917957d6554Steve Block m_counterNode->removeRenderer(this); 5192bde8e466a4451c7319e3a072d118917957d6554Steve Block ASSERT(!m_counterNode); 5202bde8e466a4451c7319e3a072d118917957d6554Steve Block if (documentBeingDestroyed()) 521643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return; 5228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project setNeedsLayoutAndPrefWidthsRecalc(); 5238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 525d0825bca7fe65beaee391d30da42e937db621564Steve Blockstatic void destroyCounterNodeWithoutMapRemoval(const AtomicString& identifier, CounterNode* node) 5268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CounterNode* previous; 528a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch for (RefPtr<CounterNode> child = node->lastDescendant(); child && child != node; child = previous) { 529643ca7872b450ea4efacab6188849e5aac2ba161Steve Block previous = child->previousInPreOrder(); 5302bde8e466a4451c7319e3a072d118917957d6554Steve Block child->parent()->removeChild(child.get()); 5312bde8e466a4451c7319e3a072d118917957d6554Steve Block ASSERT(counterMaps().get(child->owner())->get(identifier.impl()) == child); 5322bde8e466a4451c7319e3a072d118917957d6554Steve Block counterMaps().get(child->owner())->remove(identifier.impl()); 533d0825bca7fe65beaee391d30da42e937db621564Steve Block } 534d0825bca7fe65beaee391d30da42e937db621564Steve Block if (CounterNode* parent = node->parent()) 5352bde8e466a4451c7319e3a072d118917957d6554Steve Block parent->removeChild(node); 5368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5382bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid RenderCounter::destroyCounterNodes(RenderObject* owner) 5398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CounterMaps& maps = counterMaps(); 5412bde8e466a4451c7319e3a072d118917957d6554Steve Block CounterMaps::iterator mapsIterator = maps.find(owner); 542d0825bca7fe65beaee391d30da42e937db621564Steve Block if (mapsIterator == maps.end()) 5438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 544d0825bca7fe65beaee391d30da42e937db621564Steve Block CounterMap* map = mapsIterator->second; 5458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CounterMap::const_iterator end = map->end(); 5468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (CounterMap::const_iterator it = map->begin(); it != end; ++it) { 547643ca7872b450ea4efacab6188849e5aac2ba161Steve Block AtomicString identifier(it->first.get()); 548a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch destroyCounterNodeWithoutMapRemoval(identifier, it->second.get()); 5498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 550d0825bca7fe65beaee391d30da42e937db621564Steve Block maps.remove(mapsIterator); 5518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delete map; 5522bde8e466a4451c7319e3a072d118917957d6554Steve Block owner->m_hasCounterNodeMap = false; 553d0825bca7fe65beaee391d30da42e937db621564Steve Block} 554d0825bca7fe65beaee391d30da42e937db621564Steve Block 5552bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid RenderCounter::destroyCounterNode(RenderObject* owner, const AtomicString& identifier) 556d0825bca7fe65beaee391d30da42e937db621564Steve Block{ 5572bde8e466a4451c7319e3a072d118917957d6554Steve Block CounterMap* map = counterMaps().get(owner); 558d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!map) 559d0825bca7fe65beaee391d30da42e937db621564Steve Block return; 560d0825bca7fe65beaee391d30da42e937db621564Steve Block CounterMap::iterator mapIterator = map->find(identifier.impl()); 561d0825bca7fe65beaee391d30da42e937db621564Steve Block if (mapIterator == map->end()) 562d0825bca7fe65beaee391d30da42e937db621564Steve Block return; 563a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch destroyCounterNodeWithoutMapRemoval(identifier, mapIterator->second.get()); 564d0825bca7fe65beaee391d30da42e937db621564Steve Block map->remove(mapIterator); 565d0825bca7fe65beaee391d30da42e937db621564Steve Block // We do not delete "map" here even if empty because we expect to reuse 566d0825bca7fe65beaee391d30da42e937db621564Steve Block // it soon. In order for a renderer to lose all its counters permanently, 567d0825bca7fe65beaee391d30da42e937db621564Steve Block // a style change for the renderer involving removal of all counter 568d0825bca7fe65beaee391d30da42e937db621564Steve Block // directives must occur, in which case, RenderCounter::destroyCounterNodes() 569d0825bca7fe65beaee391d30da42e937db621564Steve Block // must be called. 570d0825bca7fe65beaee391d30da42e937db621564Steve Block // The destruction of the Renderer (possibly caused by the removal of its 571d0825bca7fe65beaee391d30da42e937db621564Steve Block // associated DOM node) is the other case that leads to the permanent 572d0825bca7fe65beaee391d30da42e937db621564Steve Block // destruction of all counters attached to a Renderer. In this case 573d0825bca7fe65beaee391d30da42e937db621564Steve Block // RenderCounter::destroyCounterNodes() must be and is now called, too. 574d0825bca7fe65beaee391d30da42e937db621564Steve Block // RenderCounter::destroyCounterNodes() handles destruction of the counter 575d0825bca7fe65beaee391d30da42e937db621564Steve Block // map associated with a renderer, so there is no risk in leaking the map. 576d0825bca7fe65beaee391d30da42e937db621564Steve Block} 577d0825bca7fe65beaee391d30da42e937db621564Steve Block 57854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Blockvoid RenderCounter::rendererRemovedFromTree(RenderObject* removedRenderer) 57954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block{ 58054cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block RenderObject* currentRenderer = removedRenderer->lastLeafChild(); 58154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block if (!currentRenderer) 58254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block currentRenderer = removedRenderer; 58354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block while (true) { 58454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block destroyCounterNodes(currentRenderer); 58554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block if (currentRenderer == removedRenderer) 58654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block break; 58754cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block currentRenderer = currentRenderer->previousInPreOrder(); 58854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block } 58954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block} 59054cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block 591d0825bca7fe65beaee391d30da42e937db621564Steve Blockstatic void updateCounters(RenderObject* renderer) 592d0825bca7fe65beaee391d30da42e937db621564Steve Block{ 593d0825bca7fe65beaee391d30da42e937db621564Steve Block ASSERT(renderer->style()); 594d0825bca7fe65beaee391d30da42e937db621564Steve Block const CounterDirectiveMap* directiveMap = renderer->style()->counterDirectives(); 595d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!directiveMap) 596d0825bca7fe65beaee391d30da42e937db621564Steve Block return; 597d0825bca7fe65beaee391d30da42e937db621564Steve Block CounterDirectiveMap::const_iterator end = directiveMap->end(); 598d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!renderer->m_hasCounterNodeMap) { 599d0825bca7fe65beaee391d30da42e937db621564Steve Block for (CounterDirectiveMap::const_iterator it = directiveMap->begin(); it != end; ++it) 600d0825bca7fe65beaee391d30da42e937db621564Steve Block makeCounterNode(renderer, AtomicString(it->first.get()), false); 601d0825bca7fe65beaee391d30da42e937db621564Steve Block return; 602d0825bca7fe65beaee391d30da42e937db621564Steve Block } 603d0825bca7fe65beaee391d30da42e937db621564Steve Block CounterMap* counterMap = counterMaps().get(renderer); 604d0825bca7fe65beaee391d30da42e937db621564Steve Block ASSERT(counterMap); 605d0825bca7fe65beaee391d30da42e937db621564Steve Block for (CounterDirectiveMap::const_iterator it = directiveMap->begin(); it != end; ++it) { 606a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<CounterNode> node = counterMap->get(it->first.get()); 607d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!node) { 608d0825bca7fe65beaee391d30da42e937db621564Steve Block makeCounterNode(renderer, AtomicString(it->first.get()), false); 609d0825bca7fe65beaee391d30da42e937db621564Steve Block continue; 610d0825bca7fe65beaee391d30da42e937db621564Steve Block } 611d0825bca7fe65beaee391d30da42e937db621564Steve Block CounterNode* newParent = 0; 612d0825bca7fe65beaee391d30da42e937db621564Steve Block CounterNode* newPreviousSibling; 613a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 614d0825bca7fe65beaee391d30da42e937db621564Steve Block findPlaceForCounter(renderer, AtomicString(it->first.get()), node->hasResetType(), newParent, newPreviousSibling); 615a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (node != counterMap->get(it->first.get())) 616a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch continue; 617d0825bca7fe65beaee391d30da42e937db621564Steve Block CounterNode* parent = node->parent(); 618d0825bca7fe65beaee391d30da42e937db621564Steve Block if (newParent == parent && newPreviousSibling == node->previousSibling()) 619d0825bca7fe65beaee391d30da42e937db621564Steve Block continue; 620d0825bca7fe65beaee391d30da42e937db621564Steve Block if (parent) 6212bde8e466a4451c7319e3a072d118917957d6554Steve Block parent->removeChild(node.get()); 6225e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block if (newParent) 623a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch newParent->insertAfter(node.get(), newPreviousSibling, it->first.get()); 624d0825bca7fe65beaee391d30da42e937db621564Steve Block } 625d0825bca7fe65beaee391d30da42e937db621564Steve Block} 626d0825bca7fe65beaee391d30da42e937db621564Steve Block 627d0825bca7fe65beaee391d30da42e937db621564Steve Blockvoid RenderCounter::rendererSubtreeAttached(RenderObject* renderer) 628d0825bca7fe65beaee391d30da42e937db621564Steve Block{ 6292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Node* node = renderer->node(); 6302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (node) 6312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block node = node->parentNode(); 6322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block else 6332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block node = renderer->generatingNode(); 6342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (node && !node->attached()) 6352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return; // No need to update if the parent is not attached yet 636d0825bca7fe65beaee391d30da42e937db621564Steve Block for (RenderObject* descendant = renderer; descendant; descendant = descendant->nextInPreOrder(renderer)) 637d0825bca7fe65beaee391d30da42e937db621564Steve Block updateCounters(descendant); 638d0825bca7fe65beaee391d30da42e937db621564Steve Block} 639d0825bca7fe65beaee391d30da42e937db621564Steve Block 640d0825bca7fe65beaee391d30da42e937db621564Steve Blockvoid RenderCounter::rendererStyleChanged(RenderObject* renderer, const RenderStyle* oldStyle, const RenderStyle* newStyle) 641d0825bca7fe65beaee391d30da42e937db621564Steve Block{ 6422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Node* node = renderer->generatingNode(); 6432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!node || !node->attached()) 6442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return; // cannot have generated content or if it can have, it will be handled during attaching 645d0825bca7fe65beaee391d30da42e937db621564Steve Block const CounterDirectiveMap* newCounterDirectives; 646d0825bca7fe65beaee391d30da42e937db621564Steve Block const CounterDirectiveMap* oldCounterDirectives; 647d0825bca7fe65beaee391d30da42e937db621564Steve Block if (oldStyle && (oldCounterDirectives = oldStyle->counterDirectives())) { 648d0825bca7fe65beaee391d30da42e937db621564Steve Block if (newStyle && (newCounterDirectives = newStyle->counterDirectives())) { 649d0825bca7fe65beaee391d30da42e937db621564Steve Block CounterDirectiveMap::const_iterator newMapEnd = newCounterDirectives->end(); 650d0825bca7fe65beaee391d30da42e937db621564Steve Block CounterDirectiveMap::const_iterator oldMapEnd = oldCounterDirectives->end(); 651d0825bca7fe65beaee391d30da42e937db621564Steve Block for (CounterDirectiveMap::const_iterator it = newCounterDirectives->begin(); it != newMapEnd; ++it) { 652d0825bca7fe65beaee391d30da42e937db621564Steve Block CounterDirectiveMap::const_iterator oldMapIt = oldCounterDirectives->find(it->first); 653d0825bca7fe65beaee391d30da42e937db621564Steve Block if (oldMapIt != oldMapEnd) { 654d0825bca7fe65beaee391d30da42e937db621564Steve Block if (oldMapIt->second == it->second) 655d0825bca7fe65beaee391d30da42e937db621564Steve Block continue; 656d0825bca7fe65beaee391d30da42e937db621564Steve Block RenderCounter::destroyCounterNode(renderer, it->first.get()); 657d0825bca7fe65beaee391d30da42e937db621564Steve Block } 658d0825bca7fe65beaee391d30da42e937db621564Steve Block // We must create this node here, because the changed node may be a node with no display such as 659d0825bca7fe65beaee391d30da42e937db621564Steve Block // as those created by the increment or reset directives and the re-layout that will happen will 660d0825bca7fe65beaee391d30da42e937db621564Steve Block // not catch the change if the node had no children. 661d0825bca7fe65beaee391d30da42e937db621564Steve Block makeCounterNode(renderer, it->first.get(), false); 662d0825bca7fe65beaee391d30da42e937db621564Steve Block } 663d0825bca7fe65beaee391d30da42e937db621564Steve Block // Destroying old counters that do not exist in the new counterDirective map. 664d0825bca7fe65beaee391d30da42e937db621564Steve Block for (CounterDirectiveMap::const_iterator it = oldCounterDirectives->begin(); it !=oldMapEnd; ++it) { 665d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!newCounterDirectives->contains(it->first)) 666d0825bca7fe65beaee391d30da42e937db621564Steve Block RenderCounter::destroyCounterNode(renderer, it->first.get()); 667d0825bca7fe65beaee391d30da42e937db621564Steve Block } 668d0825bca7fe65beaee391d30da42e937db621564Steve Block } else { 669d0825bca7fe65beaee391d30da42e937db621564Steve Block if (renderer->m_hasCounterNodeMap) 670d0825bca7fe65beaee391d30da42e937db621564Steve Block RenderCounter::destroyCounterNodes(renderer); 671d0825bca7fe65beaee391d30da42e937db621564Steve Block } 672d0825bca7fe65beaee391d30da42e937db621564Steve Block } else if (newStyle && (newCounterDirectives = newStyle->counterDirectives())) { 673d0825bca7fe65beaee391d30da42e937db621564Steve Block CounterDirectiveMap::const_iterator newMapEnd = newCounterDirectives->end(); 674d0825bca7fe65beaee391d30da42e937db621564Steve Block for (CounterDirectiveMap::const_iterator it = newCounterDirectives->begin(); it != newMapEnd; ++it) { 675d0825bca7fe65beaee391d30da42e937db621564Steve Block // We must create this node here, because the added node may be a node with no display such as 676d0825bca7fe65beaee391d30da42e937db621564Steve Block // as those created by the increment or reset directives and the re-layout that will happen will 677d0825bca7fe65beaee391d30da42e937db621564Steve Block // not catch the change if the node had no children. 678d0825bca7fe65beaee391d30da42e937db621564Steve Block makeCounterNode(renderer, it->first.get(), false); 679d0825bca7fe65beaee391d30da42e937db621564Steve Block } 680d0825bca7fe65beaee391d30da42e937db621564Steve Block } 6818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore 6842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 6852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#ifndef NDEBUG 6862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 6872fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid showCounterRendererTree(const WebCore::RenderObject* renderer, const char* counterName) 6882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 6892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!renderer) 6902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return; 6912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block const WebCore::RenderObject* root = renderer; 6922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block while (root->parent()) 6932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block root = root->parent(); 6942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 6952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block AtomicString identifier(counterName); 6962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block for (const WebCore::RenderObject* current = root; current; current = current->nextInPreOrder()) { 6972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block fprintf(stderr, "%c", (current == renderer) ? '*' : ' '); 6982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block for (const WebCore::RenderObject* parent = current; parent && parent != root; parent = parent->parent()) 6992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block fprintf(stderr, " "); 7002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block fprintf(stderr, "%p N:%p P:%p PS:%p NS:%p C:%p\n", 7012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block current, current->node(), current->parent(), current->previousSibling(), 7022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block current->nextSibling(), current->m_hasCounterNodeMap? 7032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block counterName ? WebCore::counterMaps().get(current)->get(identifier.impl()).get() : (WebCore::CounterNode*)1 : (WebCore::CounterNode*)0); 7042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 7052bde8e466a4451c7319e3a072d118917957d6554Steve Block fflush(stderr); 7062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 7072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 7082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#endif // NDEBUG 709