PassRefPtr<TypeBuilder::LayerTree::Layer> InspectorLayerTreeAgent::buildObjectForLayer(ErrorString* errorString, RenderLayer* renderLayer) { RenderObject* renderer = &renderLayer->renderer(); RenderLayerBacking* backing = renderLayer->backing(); Node* node = renderer->node(); bool isReflection = renderLayer->isReflection(); bool isGenerated = (isReflection ? renderer->parent() : renderer)->isBeforeOrAfterContent(); bool isAnonymous = renderer->isAnonymous(); if (renderer->isRenderView()) node = &renderer->document(); else if (isReflection && isGenerated) node = renderer->parent()->generatingElement(); else if (isGenerated) node = renderer->generatingNode(); else if (isReflection || isAnonymous) node = renderer->parent()->element(); // Basic set of properties. RefPtr<TypeBuilder::LayerTree::Layer> layerObject = TypeBuilder::LayerTree::Layer::create() .setLayerId(bind(renderLayer)) .setNodeId(idForNode(errorString, node)) .setBounds(buildObjectForIntRect(renderer->absoluteBoundingBoxRect())) .setMemory(backing->backingStoreMemoryEstimate()) .setCompositedBounds(buildObjectForIntRect(enclosingIntRect(backing->compositedBounds()))) .setPaintCount(backing->graphicsLayer()->repaintCount()); if (node && node->shadowHost()) layerObject->setIsInShadowTree(true); if (isReflection) layerObject->setIsReflection(true); if (isGenerated) { if (isReflection) renderer = renderer->parent(); layerObject->setIsGeneratedContent(true); layerObject->setPseudoElementId(bindPseudoElement(toPseudoElement(renderer->node()))); if (renderer->isBeforeContent()) layerObject->setPseudoElement("before"); else if (renderer->isAfterContent()) layerObject->setPseudoElement("after"); } // FIXME: RenderView is now really anonymous but don't tell about it to the frontend before making sure it can handle it. if (isAnonymous && !renderer->isRenderView()) { layerObject->setIsAnonymous(true); if (RenderStyle* style = renderer->style()) { if (style->styleType() == FIRST_LETTER) layerObject->setPseudoElement("first-letter"); else if (style->styleType() == FIRST_LINE) layerObject->setPseudoElement("first-line"); } } return layerObject; }
void RenderCounter::rendererStyleChanged(RenderObject& renderer, const RenderStyle* oldStyle, const RenderStyle* newStyle) { Node* node = renderer.generatingNode(); if (!node || node->needsAttach()) return; // cannot have generated content or if it can have, it will be handled during attaching const CounterDirectiveMap* newCounterDirectives; const CounterDirectiveMap* oldCounterDirectives; if (oldStyle && (oldCounterDirectives = oldStyle->counterDirectives())) { if (newStyle && (newCounterDirectives = newStyle->counterDirectives())) { CounterDirectiveMap::const_iterator newMapEnd = newCounterDirectives->end(); CounterDirectiveMap::const_iterator oldMapEnd = oldCounterDirectives->end(); for (CounterDirectiveMap::const_iterator it = newCounterDirectives->begin(); it != newMapEnd; ++it) { CounterDirectiveMap::const_iterator oldMapIt = oldCounterDirectives->find(it->key); if (oldMapIt != oldMapEnd) { if (oldMapIt->value == it->value) continue; RenderCounter::destroyCounterNode(renderer, it->key); } // We must create this node here, because the changed node may be a node with no display such as // as those created by the increment or reset directives and the re-layout that will happen will // not catch the change if the node had no children. makeCounterNode(renderer, it->key, false); } // Destroying old counters that do not exist in the new counterDirective map. for (CounterDirectiveMap::const_iterator it = oldCounterDirectives->begin(); it !=oldMapEnd; ++it) { if (!newCounterDirectives->contains(it->key)) RenderCounter::destroyCounterNode(renderer, it->key); } } else { if (renderer.hasCounterNodeMap()) RenderCounter::destroyCounterNodes(renderer); } } else if (newStyle && (newCounterDirectives = newStyle->counterDirectives())) { CounterDirectiveMap::const_iterator newMapEnd = newCounterDirectives->end(); for (CounterDirectiveMap::const_iterator it = newCounterDirectives->begin(); it != newMapEnd; ++it) { // We must create this node here, because the added node may be a node with no display such as // as those created by the increment or reset directives and the re-layout that will happen will // not catch the change if the node had no children. makeCounterNode(renderer, it->key, false); } } }
static bool planCounter(RenderObject& object, const AtomicString& identifier, bool& isReset, int& value) { // 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() && !object.isBR()) return false; Node* generatingNode = object.generatingNode(); // We must have a generating node or else we cannot have a counter. if (!generatingNode) return false; RenderStyle* style = object.style(); ASSERT(style); switch (style->styleType()) { case NOPSEUDO: // Sometimes nodes have more then one renderer. Only the first one gets the counter // LayoutTests/http/tests/css/counter-crash.html if (generatingNode->renderer() != &object) return false; break; case BEFORE: case AFTER: break; default: return false; // Counters are forbidden from all other pseudo elements. } const CounterDirectives directives = style->getCounterDirectives(identifier); if (directives.isDefined()) { value = directives.combinedValue(); isReset = directives.isReset(); return true; } if (identifier == "list-item") { if (object.isListItem()) { if (toRenderListItem(object).hasExplicitValue()) { value = toRenderListItem(object).explicitValue(); isReset = true; return true; } value = 1; isReset = false; return true; } if (Node* e = object.node()) { if (isHTMLOListElement(*e)) { value = toHTMLOListElement(e)->start(); isReset = true; return true; } if (isHTMLUListElement(*e) || isHTMLMenuElement(*e) || isHTMLDirectoryElement(*e)) { value = 0; isReset = true; return true; } } } return false; }