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

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 if (hasDisplayContentsStyle() && !isPseudoElement() && parentNode() &&
1712 !parentNode()->needsAttach()) {
1713 parentNode()->reattachLayoutTree();
1714 DCHECK(!needsAttach());
1715 return;
1716 }
1717
1695 createPseudoElementIfNeeded(PseudoIdAfter); 1718 createPseudoElementIfNeeded(PseudoIdAfter);
1696 createPseudoElementIfNeeded(PseudoIdBackdrop); 1719 createPseudoElementIfNeeded(PseudoIdBackdrop);
1697 1720
1698 // We create the first-letter element after the :before, :after and 1721 // We create the first-letter element after the :before, :after and
1699 // children are attached because the first letter text could come 1722 // children are attached because the first letter text could come
1700 // from any of them. 1723 // from any of them.
1701 createPseudoElementIfNeeded(PseudoIdFirstLetter); 1724 createPseudoElementIfNeeded(PseudoIdFirstLetter);
1702 } 1725 }
1703 1726
1704 void Element::detachLayoutTree(const AttachContext& context) { 1727 void Element::detachLayoutTree(const AttachContext& context) {
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
1959 svgFilterNeedsLayerUpdate()) { 1982 svgFilterNeedsLayerUpdate()) {
1960 layoutObject->setStyle(newStyle.get()); 1983 layoutObject->setStyle(newStyle.get());
1961 } else { 1984 } else {
1962 // Although no change occurred, we use the new style so that the cousin 1985 // Although no change occurred, we use the new style so that the cousin
1963 // style sharing code won't get fooled into believing this style is the 1986 // style sharing code won't get fooled into believing this style is the
1964 // same. 1987 // same.
1965 // FIXME: We may be able to remove this hack, see discussion in 1988 // FIXME: We may be able to remove this hack, see discussion in
1966 // https://codereview.chromium.org/30453002/ 1989 // https://codereview.chromium.org/30453002/
1967 layoutObject->setStyleInternal(newStyle.get()); 1990 layoutObject->setStyleInternal(newStyle.get());
1968 } 1991 }
1992 } else if (localChange != NoChange &&
1993 shouldStoreNonLayoutObjectComputedStyle(*newStyle)) {
1994 storeNonLayoutObjectComputedStyle(newStyle);
1969 } 1995 }
1970 1996
1971 if (getStyleChangeType() >= SubtreeStyleChange) 1997 if (getStyleChangeType() >= SubtreeStyleChange)
1972 return Force; 1998 return Force;
1973 1999
1974 if (change > Inherit || localChange > Inherit) 2000 if (change > Inherit || localChange > Inherit)
1975 return max(localChange, change); 2001 return max(localChange, change);
1976 2002
1977 if (localChange < IndependentInherit) { 2003 if (localChange < IndependentInherit) {
1978 if (oldStyle->hasChildDependentFlags()) { 2004 if (oldStyle->hasChildDependentFlags()) {
(...skipping 1142 matching lines...) Expand 10 before | Expand all | Expand 10 after
3121 3147
3122 RefPtr<ComputedStyle> result = 3148 RefPtr<ComputedStyle> result =
3123 document().ensureStyleResolver().pseudoStyleForElement( 3149 document().ensureStyleResolver().pseudoStyleForElement(
3124 this, PseudoStyleRequest(pseudoElementSpecifier, 3150 this, PseudoStyleRequest(pseudoElementSpecifier,
3125 PseudoStyleRequest::ForComputedStyle), 3151 PseudoStyleRequest::ForComputedStyle),
3126 elementStyle); 3152 elementStyle);
3127 DCHECK(result); 3153 DCHECK(result);
3128 return elementStyle->addCachedPseudoStyle(result.release()); 3154 return elementStyle->addCachedPseudoStyle(result.release());
3129 } 3155 }
3130 3156
3157 const ComputedStyle* Element::nonLayoutObjectComputedStyle() const {
3158 if (layoutObject() || !hasRareData())
3159 return nullptr;
3160
3161 return elementRareData()->computedStyle();
3162 }
3163
3164 bool Element::hasDisplayContentsStyle() const {
3165 if (const ComputedStyle* style = nonLayoutObjectComputedStyle())
3166 return style->display() == EDisplay::Contents;
3167 return false;
3168 }
3169
3170 bool Element::shouldStoreNonLayoutObjectComputedStyle(
3171 const ComputedStyle& style) const {
3172 #if DCHECK_IS_ON()
3173 if (style.display() == EDisplay::Contents)
3174 DCHECK(!layoutObject());
3175 #endif
3176
3177 return style.display() == EDisplay::Contents ||
3178 isHTMLOptGroupElement(*this) || isHTMLOptionElement(*this);
3179 }
3180
3181 void Element::storeNonLayoutObjectComputedStyle(
3182 PassRefPtr<ComputedStyle> style) {
3183 DCHECK(style);
3184 DCHECK(shouldStoreNonLayoutObjectComputedStyle(*style));
3185 ensureElementRareData().setComputedStyle(std::move(style));
3186 }
3187
3188 void Element::clearNonLayoutObjectComputedStyle() {
3189 DCHECK(nonLayoutObjectComputedStyle());
3190 elementRareData()->clearComputedStyle();
3191 }
3192
3131 AtomicString Element::computeInheritedLanguage() const { 3193 AtomicString Element::computeInheritedLanguage() const {
3132 const Node* n = this; 3194 const Node* n = this;
3133 AtomicString value; 3195 AtomicString value;
3134 // The language property is inherited, so we iterate over the parents to find 3196 // The language property is inherited, so we iterate over the parents to find
3135 // the first language. 3197 // the first language.
3136 do { 3198 do {
3137 if (n->isElementNode()) { 3199 if (n->isElementNode()) {
3138 if (const ElementData* elementData = toElement(n)->elementData()) { 3200 if (const ElementData* elementData = toElement(n)->elementData()) {
3139 AttributeCollection attributes = elementData->attributes(); 3201 AttributeCollection attributes = elementData->attributes();
3140 // Spec: xml:lang takes precedence -- http://www.w3.org/TR/xhtml1/#C_7 3202 // Spec: xml:lang takes precedence -- http://www.w3.org/TR/xhtml1/#C_7
(...skipping 715 matching lines...) Expand 10 before | Expand all | Expand 10 after
3856 StyleChangeReasonForTracing::create(StyleChangeReason::StyleSheetChange)); 3918 StyleChangeReasonForTracing::create(StyleChangeReason::StyleSheetChange));
3857 InspectorInstrumentation::didInvalidateStyleAttr(this); 3919 InspectorInstrumentation::didInvalidateStyleAttr(this);
3858 } 3920 }
3859 3921
3860 void Element::inlineStyleChanged() { 3922 void Element::inlineStyleChanged() {
3861 DCHECK(isStyledElement()); 3923 DCHECK(isStyledElement());
3862 setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTracing::create( 3924 setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTracing::create(
3863 StyleChangeReason::Inline)); 3925 StyleChangeReason::Inline));
3864 DCHECK(elementData()); 3926 DCHECK(elementData());
3865 elementData()->m_styleAttributeIsDirty = true; 3927 elementData()->m_styleAttributeIsDirty = true;
3928
3866 InspectorInstrumentation::didInvalidateStyleAttr(this); 3929 InspectorInstrumentation::didInvalidateStyleAttr(this);
3867 3930
3868 if (MutationObserverInterestGroup* recipients = 3931 if (MutationObserverInterestGroup* recipients =
3869 MutationObserverInterestGroup::createForAttributesMutation( 3932 MutationObserverInterestGroup::createForAttributesMutation(
3870 *this, styleAttr)) { 3933 *this, styleAttr)) {
3871 // We don't use getAttribute() here to get a style attribute value 3934 // We don't use getAttribute() here to get a style attribute value
3872 // before the change. 3935 // before the change.
3873 AtomicString oldValue; 3936 AtomicString oldValue;
3874 if (const Attribute* attribute = 3937 if (const Attribute* attribute =
3875 elementData()->attributes().find(styleAttr)) 3938 elementData()->attributes().find(styleAttr))
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
4088 } 4151 }
4089 4152
4090 DEFINE_TRACE_WRAPPERS(Element) { 4153 DEFINE_TRACE_WRAPPERS(Element) {
4091 if (hasRareData()) { 4154 if (hasRareData()) {
4092 visitor->traceWrappers(elementRareData()); 4155 visitor->traceWrappers(elementRareData());
4093 } 4156 }
4094 ContainerNode::traceWrappers(visitor); 4157 ContainerNode::traceWrappers(visitor);
4095 } 4158 }
4096 4159
4097 } // namespace blink 4160 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698