OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * (C) 2001 Peter Kelly (pmk@post.com) | 4 * (C) 2001 Peter Kelly (pmk@post.com) |
5 * (C) 2001 Dirk Mueller (mueller@kde.org) | 5 * (C) 2001 Dirk Mueller (mueller@kde.org) |
6 * (C) 2007 David Smith (catfish.man@gmail.com) | 6 * (C) 2007 David Smith (catfish.man@gmail.com) |
7 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013 Apple Inc. | 7 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013 Apple Inc. |
8 * All rights reserved. | 8 * All rights reserved. |
9 * (C) 2007 Eric Seidel (eric@webkit.org) | 9 * (C) 2007 Eric Seidel (eric@webkit.org) |
10 * | 10 * |
(...skipping 1511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1522 return parent->locateNamespacePrefix(namespaceToLocate); | 1522 return parent->locateNamespacePrefix(namespaceToLocate); |
1523 | 1523 |
1524 return nullAtom; | 1524 return nullAtom; |
1525 } | 1525 } |
1526 | 1526 |
1527 const AtomicString Element::imageSourceURL() const { | 1527 const AtomicString Element::imageSourceURL() const { |
1528 return getAttribute(srcAttr); | 1528 return getAttribute(srcAttr); |
1529 } | 1529 } |
1530 | 1530 |
1531 bool Element::layoutObjectIsNeeded(const ComputedStyle& style) { | 1531 bool Element::layoutObjectIsNeeded(const ComputedStyle& style) { |
1532 return style.display() != EDisplay::None; | 1532 return style.display() != EDisplay::None && |
1533 style.display() != EDisplay::Contents; | |
1533 } | 1534 } |
1534 | 1535 |
1535 LayoutObject* Element::createLayoutObject(const ComputedStyle& style) { | 1536 LayoutObject* Element::createLayoutObject(const ComputedStyle& style) { |
1536 return LayoutObject::createObject(this, style); | 1537 return LayoutObject::createObject(this, style); |
1537 } | 1538 } |
1538 | 1539 |
1539 Node::InsertionNotificationRequest Element::insertedInto( | 1540 Node::InsertionNotificationRequest Element::insertedInto( |
1540 ContainerNode* insertionPoint) { | 1541 ContainerNode* insertionPoint) { |
1541 // need to do superclass processing first so isConnected() is true | 1542 // need to do superclass processing first so isConnected() is true |
1542 // by the time we reach updateId | 1543 // by the time we reach updateId |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1660 void Element::attachLayoutTree(const AttachContext& context) { | 1661 void Element::attachLayoutTree(const AttachContext& context) { |
1661 DCHECK(document().inStyleRecalc()); | 1662 DCHECK(document().inStyleRecalc()); |
1662 | 1663 |
1663 // We've already been through detach when doing an attach, but we might | 1664 // We've already been through detach when doing an attach, but we might |
1664 // need to clear any state that's been added since then. | 1665 // need to clear any state that's been added since then. |
1665 if (hasRareData() && getStyleChangeType() == NeedsReattachStyleChange) { | 1666 if (hasRareData() && getStyleChangeType() == NeedsReattachStyleChange) { |
1666 ElementRareData* data = elementRareData(); | 1667 ElementRareData* data = elementRareData(); |
1667 data->clearComputedStyle(); | 1668 data->clearComputedStyle(); |
1668 } | 1669 } |
1669 | 1670 |
1670 if (!isActiveSlotOrActiveInsertionPoint()) | 1671 if (!isActiveSlotOrActiveInsertionPoint()) { |
1671 LayoutTreeBuilderForElement(*this, context.resolvedStyle) | 1672 LayoutTreeBuilderForElement builder(*this, context.resolvedStyle); |
1672 .createLayoutObjectIfNeeded(); | 1673 builder.createLayoutObjectIfNeeded(); |
1674 | |
1675 if (ComputedStyle* style = builder.resolvedStyle()) { | |
1676 if (!layoutObject() && shouldStoreNonLayoutObjectComputedStyle(*style)) | |
1677 storeNonLayoutObjectComputedStyle(style); | |
1678 } | |
1679 } | |
1673 | 1680 |
1674 addCallbackSelectors(); | 1681 addCallbackSelectors(); |
1675 | 1682 |
1676 if (hasRareData() && !layoutObject()) { | 1683 if (hasRareData() && !layoutObject()) { |
1677 if (ElementAnimations* elementAnimations = | 1684 if (ElementAnimations* elementAnimations = |
1678 elementRareData()->elementAnimations()) { | 1685 elementRareData()->elementAnimations()) { |
1679 elementAnimations->cssAnimations().cancel(); | 1686 elementAnimations->cssAnimations().cancel(); |
1680 elementAnimations->setAnimationStyleChange(false); | 1687 elementAnimations->setAnimationStyleChange(false); |
1681 } | 1688 } |
1682 } | 1689 } |
1683 | 1690 |
1684 SelectorFilterParentScope filterScope(*this); | 1691 SelectorFilterParentScope filterScope(*this); |
1685 StyleSharingDepthScope sharingScope(*this); | 1692 StyleSharingDepthScope sharingScope(*this); |
1686 | 1693 |
1687 createPseudoElementIfNeeded(PseudoIdBefore); | 1694 createPseudoElementIfNeeded(PseudoIdBefore); |
1688 | 1695 |
1689 // When a shadow root exists, it does the work of attaching the children. | 1696 // When a shadow root exists, it does the work of attaching the children. |
1690 if (ElementShadow* shadow = this->shadow()) | 1697 if (ElementShadow* shadow = this->shadow()) |
1691 shadow->attach(context); | 1698 shadow->attach(context); |
1692 | 1699 |
1693 ContainerNode::attachLayoutTree(context); | 1700 ContainerNode::attachLayoutTree(context); |
1694 | 1701 |
1702 // Quite unfortunately, if we're a display: contents node reattaching our | |
1703 // subtree we need to reattach the parent's *after* attaching all our | |
1704 // children. We might be able to be more granular here, but otherwise we don't | |
1705 // always properly rebuild the layout tree due to anonymous boxes, for | |
1706 // example. See css-display-3/display-contents-reattachment.html, which fails | |
1707 // without this, for example, due to misplaced flex anonymous blocks. | |
1708 // | |
1709 // Also, don't do it if we're a pseudo-element, because it's pointless and | |
1710 // causes infinite recursion if the parent doesn't have display: contents. | |
1711 // | |
1712 // Finally, don't do it also if our parent is the document, since it's also | |
1713 // pointless, and it asserts when detached. | |
1714 if (hasDisplayContentsStyle() && !isPseudoElement() && parentNode() && | |
1715 parentNode() != &document() && !parentNode()->needsAttach()) { | |
1716 parentNode()->reattachLayoutTree(); | |
rune
2016/11/18 10:35:40
This is not good. So if you have N display:content
emilio
2016/11/18 10:54:35
Yes, this is the single most nasty thing I've had
emilio
2016/11/18 11:04:43
Also note that this is not as bad as you said (sor
| |
1717 DCHECK(!needsAttach()); | |
1718 return; | |
1719 } | |
1720 | |
1695 createPseudoElementIfNeeded(PseudoIdAfter); | 1721 createPseudoElementIfNeeded(PseudoIdAfter); |
1696 createPseudoElementIfNeeded(PseudoIdBackdrop); | 1722 createPseudoElementIfNeeded(PseudoIdBackdrop); |
1697 | 1723 |
1698 // We create the first-letter element after the :before, :after and | 1724 // We create the first-letter element after the :before, :after and |
1699 // children are attached because the first letter text could come | 1725 // children are attached because the first letter text could come |
1700 // from any of them. | 1726 // from any of them. |
1701 createPseudoElementIfNeeded(PseudoIdFirstLetter); | 1727 createPseudoElementIfNeeded(PseudoIdFirstLetter); |
1702 } | 1728 } |
1703 | 1729 |
1704 void Element::detachLayoutTree(const AttachContext& context) { | 1730 void Element::detachLayoutTree(const AttachContext& context) { |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1957 pseudoStyleCacheIsInvalid(oldStyle.get(), newStyle.get())) { | 1983 pseudoStyleCacheIsInvalid(oldStyle.get(), newStyle.get())) { |
1958 layoutObject->setStyle(newStyle.get()); | 1984 layoutObject->setStyle(newStyle.get()); |
1959 } else { | 1985 } else { |
1960 // Although no change occurred, we use the new style so that the cousin | 1986 // Although no change occurred, we use the new style so that the cousin |
1961 // style sharing code won't get fooled into believing this style is the | 1987 // style sharing code won't get fooled into believing this style is the |
1962 // same. | 1988 // same. |
1963 // FIXME: We may be able to remove this hack, see discussion in | 1989 // FIXME: We may be able to remove this hack, see discussion in |
1964 // https://codereview.chromium.org/30453002/ | 1990 // https://codereview.chromium.org/30453002/ |
1965 layoutObject->setStyleInternal(newStyle.get()); | 1991 layoutObject->setStyleInternal(newStyle.get()); |
1966 } | 1992 } |
1993 } else if (localChange != NoChange && | |
1994 shouldStoreNonLayoutObjectComputedStyle(*newStyle)) { | |
1995 storeNonLayoutObjectComputedStyle(newStyle); | |
1967 } | 1996 } |
1968 | 1997 |
1969 if (getStyleChangeType() >= SubtreeStyleChange) | 1998 if (getStyleChangeType() >= SubtreeStyleChange) |
1970 return Force; | 1999 return Force; |
1971 | 2000 |
1972 if (change > Inherit || localChange > Inherit) | 2001 if (change > Inherit || localChange > Inherit) |
1973 return max(localChange, change); | 2002 return max(localChange, change); |
1974 | 2003 |
1975 if (localChange < IndependentInherit) { | 2004 if (localChange < IndependentInherit) { |
1976 if (oldStyle->hasChildDependentFlags()) { | 2005 if (oldStyle->hasChildDependentFlags()) { |
(...skipping 1142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3119 | 3148 |
3120 RefPtr<ComputedStyle> result = | 3149 RefPtr<ComputedStyle> result = |
3121 document().ensureStyleResolver().pseudoStyleForElement( | 3150 document().ensureStyleResolver().pseudoStyleForElement( |
3122 this, PseudoStyleRequest(pseudoElementSpecifier, | 3151 this, PseudoStyleRequest(pseudoElementSpecifier, |
3123 PseudoStyleRequest::ForComputedStyle), | 3152 PseudoStyleRequest::ForComputedStyle), |
3124 elementStyle); | 3153 elementStyle); |
3125 DCHECK(result); | 3154 DCHECK(result); |
3126 return elementStyle->addCachedPseudoStyle(result.release()); | 3155 return elementStyle->addCachedPseudoStyle(result.release()); |
3127 } | 3156 } |
3128 | 3157 |
3158 const ComputedStyle* Element::nonLayoutObjectComputedStyle() const { | |
3159 if (layoutObject() || !hasRareData()) | |
3160 return nullptr; | |
3161 | |
3162 return elementRareData()->computedStyle(); | |
3163 } | |
3164 | |
3165 bool Element::hasDisplayContentsStyle() const { | |
3166 if (const ComputedStyle* style = nonLayoutObjectComputedStyle()) | |
3167 return style->display() == EDisplay::Contents; | |
3168 return false; | |
3169 } | |
3170 | |
3171 bool Element::shouldStoreNonLayoutObjectComputedStyle( | |
3172 const ComputedStyle& style) const { | |
3173 #if DCHECK_IS_ON() | |
3174 if (style.display() == EDisplay::Contents) | |
3175 DCHECK(!layoutObject()); | |
3176 #endif | |
3177 | |
3178 return style.display() == EDisplay::Contents || | |
3179 isHTMLOptGroupElement(*this) || isHTMLOptionElement(*this); | |
3180 } | |
3181 | |
3182 void Element::storeNonLayoutObjectComputedStyle( | |
3183 PassRefPtr<ComputedStyle> style) { | |
3184 DCHECK(style); | |
3185 DCHECK(shouldStoreNonLayoutObjectComputedStyle(*style)); | |
3186 ensureElementRareData().setComputedStyle(std::move(style)); | |
3187 } | |
3188 | |
3129 AtomicString Element::computeInheritedLanguage() const { | 3189 AtomicString Element::computeInheritedLanguage() const { |
3130 const Node* n = this; | 3190 const Node* n = this; |
3131 AtomicString value; | 3191 AtomicString value; |
3132 // The language property is inherited, so we iterate over the parents to find | 3192 // The language property is inherited, so we iterate over the parents to find |
3133 // the first language. | 3193 // the first language. |
3134 do { | 3194 do { |
3135 if (n->isElementNode()) { | 3195 if (n->isElementNode()) { |
3136 if (const ElementData* elementData = toElement(n)->elementData()) { | 3196 if (const ElementData* elementData = toElement(n)->elementData()) { |
3137 AttributeCollection attributes = elementData->attributes(); | 3197 AttributeCollection attributes = elementData->attributes(); |
3138 // Spec: xml:lang takes precedence -- http://www.w3.org/TR/xhtml1/#C_7 | 3198 // Spec: xml:lang takes precedence -- http://www.w3.org/TR/xhtml1/#C_7 |
(...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3852 StyleChangeReasonForTracing::create(StyleChangeReason::StyleSheetChange)); | 3912 StyleChangeReasonForTracing::create(StyleChangeReason::StyleSheetChange)); |
3853 InspectorInstrumentation::didInvalidateStyleAttr(this); | 3913 InspectorInstrumentation::didInvalidateStyleAttr(this); |
3854 } | 3914 } |
3855 | 3915 |
3856 void Element::inlineStyleChanged() { | 3916 void Element::inlineStyleChanged() { |
3857 DCHECK(isStyledElement()); | 3917 DCHECK(isStyledElement()); |
3858 setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTracing::create( | 3918 setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTracing::create( |
3859 StyleChangeReason::Inline)); | 3919 StyleChangeReason::Inline)); |
3860 DCHECK(elementData()); | 3920 DCHECK(elementData()); |
3861 elementData()->m_styleAttributeIsDirty = true; | 3921 elementData()->m_styleAttributeIsDirty = true; |
3922 | |
3862 InspectorInstrumentation::didInvalidateStyleAttr(this); | 3923 InspectorInstrumentation::didInvalidateStyleAttr(this); |
3863 | 3924 |
3864 if (MutationObserverInterestGroup* recipients = | 3925 if (MutationObserverInterestGroup* recipients = |
3865 MutationObserverInterestGroup::createForAttributesMutation( | 3926 MutationObserverInterestGroup::createForAttributesMutation( |
3866 *this, styleAttr)) { | 3927 *this, styleAttr)) { |
3867 // We don't use getAttribute() here to get a style attribute value | 3928 // We don't use getAttribute() here to get a style attribute value |
3868 // before the change. | 3929 // before the change. |
3869 AtomicString oldValue; | 3930 AtomicString oldValue; |
3870 if (const Attribute* attribute = | 3931 if (const Attribute* attribute = |
3871 elementData()->attributes().find(styleAttr)) | 3932 elementData()->attributes().find(styleAttr)) |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4084 } | 4145 } |
4085 | 4146 |
4086 DEFINE_TRACE_WRAPPERS(Element) { | 4147 DEFINE_TRACE_WRAPPERS(Element) { |
4087 if (hasRareData()) { | 4148 if (hasRareData()) { |
4088 visitor->traceWrappers(elementRareData()); | 4149 visitor->traceWrappers(elementRareData()); |
4089 } | 4150 } |
4090 ContainerNode::traceWrappers(visitor); | 4151 ContainerNode::traceWrappers(visitor); |
4091 } | 4152 } |
4092 | 4153 |
4093 } // namespace blink | 4154 } // namespace blink |
OLD | NEW |