Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(467)

Side by Side Diff: third_party/WebKit/Source/core/dom/Element.cpp

Issue 2450093005: Support display: contents for elements, first-line and first-letter pseudos. (Closed)
Patch Set: Support display: contents for elements, first-line and first-letter pseudos. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698