static CounterNode* makeCounterNode(RenderObject* object, const AtomicString& identifier, bool alwaysCreateCounter) { ASSERT(object); // Real text nodes don't have their own style so they can't have counters. // We can't even look at their styles or we'll see extra resets and increments! if (object->isText()) return nullptr; RenderElement* element = toRenderElement(object); if (element->hasCounterNodeMap()) { if (CounterMap* nodeMap = counterMaps().get(element)) { if (CounterNode* node = nodeMap->get(identifier)) return node; } } bool isReset = false; int value = 0; if (!planCounter(element, identifier, isReset, value) && !alwaysCreateCounter) return nullptr; RefPtr<CounterNode> newParent = 0; RefPtr<CounterNode> newPreviousSibling = 0; RefPtr<CounterNode> newNode = CounterNode::create(element, isReset, value); if (findPlaceForCounter(element, identifier, isReset, newParent, newPreviousSibling)) newParent->insertAfter(newNode.get(), newPreviousSibling.get(), identifier); CounterMap* nodeMap; if (element->hasCounterNodeMap()) nodeMap = counterMaps().get(element); else { nodeMap = new CounterMap; counterMaps().set(element, adoptPtr(nodeMap)); element->setHasCounterNodeMap(true); } nodeMap->set(identifier, newNode); if (newNode->parent()) return newNode.get(); // Checking if some nodes that were previously counter tree root nodes // should become children of this node now. CounterMaps& maps = counterMaps(); Element* stayWithin = parentOrPseudoHostElement(element); bool skipDescendants; for (RenderElement* currentRenderer = nextInPreOrder(element, stayWithin); currentRenderer; currentRenderer = nextInPreOrder(currentRenderer, stayWithin, skipDescendants)) { skipDescendants = false; if (!currentRenderer->hasCounterNodeMap()) continue; CounterNode* currentCounter = maps.get(currentRenderer)->get(identifier); if (!currentCounter) continue; skipDescendants = true; if (currentCounter->parent()) continue; if (stayWithin == parentOrPseudoHostElement(currentRenderer) && currentCounter->hasResetType()) break; newNode->insertAfter(currentCounter, newNode->lastChild(), identifier); } return newNode.get(); }
static CounterNode* makeCounterNode(RenderObject* object, const AtomicString& identifier, bool alwaysCreateCounter) { ASSERT(object); if (object->m_hasCounterNodeMap) { if (CounterMap* nodeMap = counterMaps().get(object)) { if (CounterNode* node = nodeMap->get(identifier.impl()).get()) return node; } } bool isReset = false; int value = 0; if (!planCounter(object, identifier, isReset, value) && !alwaysCreateCounter) return 0; CounterNode* newParent = 0; CounterNode* newPreviousSibling = 0; RefPtr<CounterNode> newNode = CounterNode::create(object, isReset, value); if (findPlaceForCounter(object, identifier, isReset, newParent, newPreviousSibling)) newParent->insertAfter(newNode.get(), newPreviousSibling, identifier); CounterMap* nodeMap; if (object->m_hasCounterNodeMap) nodeMap = counterMaps().get(object); else { nodeMap = new CounterMap; counterMaps().set(object, nodeMap); object->m_hasCounterNodeMap = true; } nodeMap->set(identifier.impl(), newNode); if (newNode->parent()) return newNode.get(); // Checking if some nodes that were previously counter tree root nodes // should become children of this node now. CounterMaps& maps = counterMaps(); Element* stayWithin = parentElement(object); bool skipDescendants; for (RenderObject* currentRenderer = nextInPreOrder(object, stayWithin); currentRenderer; currentRenderer = nextInPreOrder(currentRenderer, stayWithin, skipDescendants)) { skipDescendants = false; if (!currentRenderer->m_hasCounterNodeMap) continue; CounterNode* currentCounter = maps.get(currentRenderer)->get(identifier.impl()).get(); if (!currentCounter) continue; skipDescendants = true; if (currentCounter->parent()) { ASSERT(newNode->firstChild()); continue; } if (stayWithin == parentElement(currentRenderer) && currentCounter->hasResetType()) break; newNode->insertAfter(currentCounter, newNode->lastChild(), identifier); } return newNode.get(); }
static CounterNode* makeCounterNode(RenderElement& renderer, const AtomicString& identifier, bool alwaysCreateCounter) { if (renderer.hasCounterNodeMap()) { if (CounterMap* nodeMap = counterMaps().get(&renderer)) { if (CounterNode* node = nodeMap->get(identifier)) return node; } } bool isReset = false; int value = 0; if (!planCounter(renderer, identifier, isReset, value) && !alwaysCreateCounter) return nullptr; RefPtr<CounterNode> newParent = 0; RefPtr<CounterNode> newPreviousSibling = 0; RefPtr<CounterNode> newNode = CounterNode::create(renderer, isReset, value); if (findPlaceForCounter(renderer, identifier, isReset, newParent, newPreviousSibling)) newParent->insertAfter(newNode.get(), newPreviousSibling.get(), identifier); CounterMap* nodeMap; if (renderer.hasCounterNodeMap()) nodeMap = counterMaps().get(&renderer); else { nodeMap = new CounterMap; counterMaps().set(&renderer, std::unique_ptr<CounterMap>(nodeMap)); renderer.setHasCounterNodeMap(true); } nodeMap->set(identifier, newNode); if (newNode->parent()) return newNode.get(); // Checking if some nodes that were previously counter tree root nodes // should become children of this node now. CounterMaps& maps = counterMaps(); Element* stayWithin = parentOrPseudoHostElement(renderer); bool skipDescendants; for (RenderElement* currentRenderer = nextInPreOrder(renderer, stayWithin); currentRenderer; currentRenderer = nextInPreOrder(*currentRenderer, stayWithin, skipDescendants)) { skipDescendants = false; if (!currentRenderer->hasCounterNodeMap()) continue; CounterNode* currentCounter = maps.get(currentRenderer)->get(identifier); if (!currentCounter) continue; skipDescendants = true; if (currentCounter->parent()) continue; if (stayWithin == parentOrPseudoHostElement(*currentRenderer) && currentCounter->hasResetType()) break; newNode->insertAfter(currentCounter, newNode->lastChild(), identifier); } return newNode.get(); }
static void showTreeAndMark(const CounterNode* node) { const CounterNode* root = node; while (root->parent()) root = root->parent(); for (const CounterNode* c = root; c; c = nextInPreOrder(c)) { if (c == node) fprintf(stderr, "*"); for (const CounterNode* d = c; d && d != root; d = d->parent()) fprintf(stderr, "\t"); if (c->isReset()) fprintf(stderr, "reset: %d\n", c->value()); else fprintf(stderr, "increment: %d\n", c->value()); } }