bool HTMLOptGroupElement::isFocusable() const { // Optgroup elements do not have a renderer so we check the renderStyle instead. return supportsFocus() && renderStyle() && renderStyle()->display() != NONE; }
void Element::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) { ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); if (!changedByParser) checkForSiblingStyleChanges(this, renderStyle(), false, beforeChange, afterChange, childCountDelta); }
void Element::finishParsingChildren() { ContainerNode::finishParsingChildren(); m_parsingChildrenFinished = true; checkForSiblingStyleChanges(this, renderStyle(), true, lastChild(), 0, 0); }
void Element::recalcStyle(StyleChange change) { RenderStyle* currentStyle = renderStyle(); bool hasParentStyle = parentNode() ? parentNode()->renderStyle() : false; bool hasPositionalRules = changed() && currentStyle && currentStyle->childrenAffectedByPositionalRules(); bool hasDirectAdjacentRules = currentStyle && currentStyle->childrenAffectedByDirectAdjacentRules(); #if ENABLE(SVG) if (!hasParentStyle && isShadowNode() && isSVGElement()) hasParentStyle = true; #endif if ((change > NoChange || changed())) { if (hasRareData()) rareData()->resetComputedStyle(); } if (hasParentStyle && (change >= Inherit || changed())) { RefPtr<RenderStyle> newStyle = document()->styleSelector()->styleForElement(this); StyleChange ch = diff(currentStyle, newStyle.get()); if (ch == Detach || !currentStyle) { if (attached()) detach(); attach(); // FIXME: The style gets computed twice by calling attach. We could do better if we passed the style along. // attach recalulates the style for all children. No need to do it twice. setChanged(NoStyleChange); setHasChangedChild(false); return; } if (currentStyle) { // Preserve "affected by" bits that were propagated to us from descendants in the case where we didn't do a full // style change (e.g., only inline style changed). if (currentStyle->affectedByHoverRules()) newStyle->setAffectedByHoverRules(true); if (currentStyle->affectedByActiveRules()) newStyle->setAffectedByActiveRules(true); if (currentStyle->affectedByDragRules()) newStyle->setAffectedByDragRules(true); if (currentStyle->childrenAffectedByForwardPositionalRules()) newStyle->setChildrenAffectedByForwardPositionalRules(); if (currentStyle->childrenAffectedByBackwardPositionalRules()) newStyle->setChildrenAffectedByBackwardPositionalRules(); if (currentStyle->childrenAffectedByFirstChildRules()) newStyle->setChildrenAffectedByFirstChildRules(); if (currentStyle->childrenAffectedByLastChildRules()) newStyle->setChildrenAffectedByLastChildRules(); if (currentStyle->childrenAffectedByDirectAdjacentRules()) newStyle->setChildrenAffectedByDirectAdjacentRules(); } if (ch != NoChange) { setRenderStyle(newStyle); } else if (changed() && (styleChangeType() != AnimationStyleChange) && (document()->usesSiblingRules() || document()->usesDescendantRules())) { // Although no change occurred, we use the new style so that the cousin style sharing code won't get // fooled into believing this style is the same. This is only necessary if the document actually uses // sibling/descendant rules, since otherwise it isn't possible for ancestor styles to affect sharing of // descendants. if (renderer()) renderer()->setStyleInternal(newStyle.get()); else setRenderStyle(newStyle); } else if (styleChangeType() == AnimationStyleChange) setRenderStyle(newStyle); if (change != Force) { if ((document()->usesDescendantRules() || hasPositionalRules) && styleChangeType() >= FullStyleChange) change = Force; else change = ch; } } // FIXME: This check is good enough for :hover + foo, but it is not good enough for :hover + foo + bar. // For now we will just worry about the common case, since it's a lot trickier to get the second case right // without doing way too much re-resolution. bool forceCheckOfNextElementSibling = false; for (Node *n = firstChild(); n; n = n->nextSibling()) { bool childRulesChanged = n->changed() && n->styleChangeType() == FullStyleChange; if (forceCheckOfNextElementSibling && n->isElementNode()) n->setChanged(); if (change >= Inherit || n->isTextNode() || n->hasChangedChild() || n->changed()) n->recalcStyle(change); if (n->isElementNode()) forceCheckOfNextElementSibling = childRulesChanged && hasDirectAdjacentRules; } setChanged(NoStyleChange); setHasChangedChild(false); }