示例#1
0
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();
}
示例#2
0
void RenderCounter::destroyCounterNodes(RenderElement& owner)
{
    CounterMaps& maps = counterMaps();
    CounterMaps::iterator mapsIterator = maps.find(&owner);
    if (mapsIterator == maps.end())
        return;
    CounterMap* map = mapsIterator->value.get();
    CounterMap::const_iterator end = map->end();
    for (CounterMap::const_iterator it = map->begin(); it != end; ++it) {
        destroyCounterNodeWithoutMapRemoval(it->key, it->value.get());
    }
    maps.remove(mapsIterator);
    owner.setHasCounterNodeMap(false);
}