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

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 3 years, 10 months 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 1556 matching lines...) Expand 10 before | Expand all | Expand 10 after
1567 return parent->locateNamespacePrefix(namespaceToLocate); 1567 return parent->locateNamespacePrefix(namespaceToLocate);
1568 1568
1569 return nullAtom; 1569 return nullAtom;
1570 } 1570 }
1571 1571
1572 const AtomicString Element::imageSourceURL() const { 1572 const AtomicString Element::imageSourceURL() const {
1573 return getAttribute(srcAttr); 1573 return getAttribute(srcAttr);
1574 } 1574 }
1575 1575
1576 bool Element::layoutObjectIsNeeded(const ComputedStyle& style) { 1576 bool Element::layoutObjectIsNeeded(const ComputedStyle& style) {
1577 return style.display() != EDisplay::None; 1577 return style.display() != EDisplay::None &&
1578 style.display() != EDisplay::Contents;
1578 } 1579 }
1579 1580
1580 LayoutObject* Element::createLayoutObject(const ComputedStyle& style) { 1581 LayoutObject* Element::createLayoutObject(const ComputedStyle& style) {
1581 return LayoutObject::createObject(this, style); 1582 return LayoutObject::createObject(this, style);
1582 } 1583 }
1583 1584
1584 Node::InsertionNotificationRequest Element::insertedInto( 1585 Node::InsertionNotificationRequest Element::insertedInto(
1585 ContainerNode* insertionPoint) { 1586 ContainerNode* insertionPoint) {
1586 // need to do superclass processing first so isConnected() is true 1587 // need to do superclass processing first so isConnected() is true
1587 // by the time we reach updateId 1588 // by the time we reach updateId
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
1708 void Element::attachLayoutTree(const AttachContext& context) { 1709 void Element::attachLayoutTree(const AttachContext& context) {
1709 DCHECK(document().inStyleRecalc()); 1710 DCHECK(document().inStyleRecalc());
1710 1711
1711 // We've already been through detach when doing an attach, but we might 1712 // We've already been through detach when doing an attach, but we might
1712 // need to clear any state that's been added since then. 1713 // need to clear any state that's been added since then.
1713 if (hasRareData() && needsAttach()) { 1714 if (hasRareData() && needsAttach()) {
1714 ElementRareData* data = elementRareData(); 1715 ElementRareData* data = elementRareData();
1715 data->clearComputedStyle(); 1716 data->clearComputedStyle();
1716 } 1717 }
1717 1718
1718 if (!isActiveSlotOrActiveInsertionPoint()) 1719 if (!isActiveSlotOrActiveInsertionPoint()) {
1719 LayoutTreeBuilderForElement(*this, context.resolvedStyle) 1720 LayoutTreeBuilderForElement builder(*this, context.resolvedStyle);
1720 .createLayoutObjectIfNeeded(); 1721 builder.createLayoutObjectIfNeeded();
1722
1723 if (ComputedStyle* style = builder.resolvedStyle()) {
1724 if (!layoutObject() && shouldStoreNonLayoutObjectComputedStyle(*style))
1725 storeNonLayoutObjectComputedStyle(style);
1726 }
1727 }
1721 1728
1722 addCallbackSelectors(); 1729 addCallbackSelectors();
1723 1730
1724 if (hasRareData() && !layoutObject()) { 1731 if (hasRareData() && !layoutObject()) {
1725 if (ElementAnimations* elementAnimations = 1732 if (ElementAnimations* elementAnimations =
1726 elementRareData()->elementAnimations()) { 1733 elementRareData()->elementAnimations()) {
1727 elementAnimations->cssAnimations().cancel(); 1734 elementAnimations->cssAnimations().cancel();
1728 elementAnimations->setAnimationStyleChange(false); 1735 elementAnimations->setAnimationStyleChange(false);
1729 } 1736 }
1730 } 1737 }
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
1886 DCHECK(!document().lifecycle().inDetach()); 1893 DCHECK(!document().lifecycle().inDetach());
1887 DCHECK(!parentOrShadowHostNode()->needsStyleRecalc()); 1894 DCHECK(!parentOrShadowHostNode()->needsStyleRecalc());
1888 DCHECK(inActiveDocument()); 1895 DCHECK(inActiveDocument());
1889 1896
1890 if (hasCustomStyleCallbacks()) 1897 if (hasCustomStyleCallbacks())
1891 willRecalcStyle(change); 1898 willRecalcStyle(change);
1892 1899
1893 if (change >= IndependentInherit || needsStyleRecalc()) { 1900 if (change >= IndependentInherit || needsStyleRecalc()) {
1894 if (hasRareData()) { 1901 if (hasRareData()) {
1895 ElementRareData* data = elementRareData(); 1902 ElementRareData* data = elementRareData();
1896 if (change != IndependentInherit) 1903 if (change != IndependentInherit) {
1897 data->clearComputedStyle(); 1904 // We keep the old computed style around for display: contents, option
1905 // and optgroup. This way we can call stylePropagationDiff accurately.
1906 //
1907 // We could clear it always, but we'd have more expensive restyles for
1908 // children.
1909 //
1910 // Note that we can't just keep stored other kind of non-layout object
1911 // computed style (like the one that gets set when getComputedStyle is
1912 // called on a display: none element), because that is a sizable memory
1913 // hit.
1914 //
1915 // Also, we don't want to leave a stale computed style, which may happen
1916 // if we don't end up calling recalcOwnStyle because there's no parent
1917 // style.
1918 const ComputedStyle* nonLayoutStyle = nonLayoutObjectComputedStyle();
1919 if (!nonLayoutStyle ||
1920 !shouldStoreNonLayoutObjectComputedStyle(*nonLayoutStyle) ||
1921 !parentComputedStyle()) {
1922 data->clearComputedStyle();
1923 }
1924 }
1898 1925
1899 if (change >= IndependentInherit) { 1926 if (change >= IndependentInherit) {
1900 if (ElementAnimations* elementAnimations = data->elementAnimations()) 1927 if (ElementAnimations* elementAnimations = data->elementAnimations())
1901 elementAnimations->setAnimationStyleChange(false); 1928 elementAnimations->setAnimationStyleChange(false);
1902 } 1929 }
1903 } 1930 }
1904 if (parentComputedStyle()) 1931 if (parentComputedStyle())
1905 change = recalcOwnStyle(change, nextTextSibling); 1932 change = recalcOwnStyle(change, nextTextSibling);
1906 clearNeedsStyleRecalc(); 1933 clearNeedsStyleRecalc();
1907 clearNeedsReattachLayoutTree(); 1934 clearNeedsReattachLayoutTree();
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
2009 pseudoStyleCacheIsInvalid(oldStyle.get(), newStyle.get())) { 2036 pseudoStyleCacheIsInvalid(oldStyle.get(), newStyle.get())) {
2010 layoutObject->setStyle(newStyle.get()); 2037 layoutObject->setStyle(newStyle.get());
2011 } else { 2038 } else {
2012 // Although no change occurred, we use the new style so that the cousin 2039 // Although no change occurred, we use the new style so that the cousin
2013 // style sharing code won't get fooled into believing this style is the 2040 // style sharing code won't get fooled into believing this style is the
2014 // same. 2041 // same.
2015 // FIXME: We may be able to remove this hack, see discussion in 2042 // FIXME: We may be able to remove this hack, see discussion in
2016 // https://codereview.chromium.org/30453002/ 2043 // https://codereview.chromium.org/30453002/
2017 layoutObject->setStyleInternal(newStyle.get()); 2044 layoutObject->setStyleInternal(newStyle.get());
2018 } 2045 }
2046 } else if (localChange != NoChange &&
2047 shouldStoreNonLayoutObjectComputedStyle(*newStyle)) {
2048 storeNonLayoutObjectComputedStyle(newStyle);
2019 } 2049 }
2020 2050
2021 if (getStyleChangeType() >= SubtreeStyleChange) 2051 if (getStyleChangeType() >= SubtreeStyleChange)
2022 return Force; 2052 return Force;
2023 2053
2024 if (change > Inherit || localChange > Inherit) 2054 if (change > Inherit || localChange > Inherit)
2025 return max(localChange, change); 2055 return max(localChange, change);
2026 2056
2027 if (localChange < IndependentInherit) { 2057 if (localChange < IndependentInherit) {
2028 if (oldStyle->hasChildDependentFlags()) { 2058 if (oldStyle->hasChildDependentFlags()) {
(...skipping 1137 matching lines...) Expand 10 before | Expand all | Expand 10 after
3166 elementStyle = rareData.computedStyle(); 3196 elementStyle = rareData.computedStyle();
3167 } 3197 }
3168 3198
3169 if (!pseudoElementSpecifier) 3199 if (!pseudoElementSpecifier)
3170 return elementStyle; 3200 return elementStyle;
3171 3201
3172 if (ComputedStyle* pseudoElementStyle = 3202 if (ComputedStyle* pseudoElementStyle =
3173 elementStyle->getCachedPseudoStyle(pseudoElementSpecifier)) 3203 elementStyle->getCachedPseudoStyle(pseudoElementSpecifier))
3174 return pseudoElementStyle; 3204 return pseudoElementStyle;
3175 3205
3206 // TODO(ecobos): Passing two times elementStyle may be wrong, though we don't
3207 // support display: contents elements' pseudo-elements yet, so this is not a
3208 // problem for now.
3176 RefPtr<ComputedStyle> result = 3209 RefPtr<ComputedStyle> result =
3177 document().ensureStyleResolver().pseudoStyleForElement( 3210 document().ensureStyleResolver().pseudoStyleForElement(
3178 this, PseudoStyleRequest(pseudoElementSpecifier, 3211 this, PseudoStyleRequest(pseudoElementSpecifier,
3179 PseudoStyleRequest::ForComputedStyle), 3212 PseudoStyleRequest::ForComputedStyle),
3180 elementStyle); 3213 elementStyle, elementStyle);
3181 DCHECK(result); 3214 DCHECK(result);
3182 return elementStyle->addCachedPseudoStyle(result.release()); 3215 return elementStyle->addCachedPseudoStyle(result.release());
3183 } 3216 }
3184 3217
3218 const ComputedStyle* Element::nonLayoutObjectComputedStyle() const {
3219 if (layoutObject() || !hasRareData())
3220 return nullptr;
3221
3222 return elementRareData()->computedStyle();
3223 }
3224
3225 bool Element::hasDisplayContentsStyle() const {
3226 if (const ComputedStyle* style = nonLayoutObjectComputedStyle())
3227 return style->display() == EDisplay::Contents;
3228 return false;
3229 }
3230
3231 bool Element::shouldStoreNonLayoutObjectComputedStyle(
3232 const ComputedStyle& style) const {
3233 #if DCHECK_IS_ON()
3234 if (style.display() == EDisplay::Contents)
3235 DCHECK(!layoutObject());
3236 #endif
3237
3238 return style.display() == EDisplay::Contents ||
3239 isHTMLOptGroupElement(*this) || isHTMLOptionElement(*this);
3240 }
3241
3242 void Element::storeNonLayoutObjectComputedStyle(
3243 PassRefPtr<ComputedStyle> style) {
3244 DCHECK(style);
3245 DCHECK(shouldStoreNonLayoutObjectComputedStyle(*style));
3246 ensureElementRareData().setComputedStyle(std::move(style));
3247 }
3248
3185 AtomicString Element::computeInheritedLanguage() const { 3249 AtomicString Element::computeInheritedLanguage() const {
3186 const Node* n = this; 3250 const Node* n = this;
3187 AtomicString value; 3251 AtomicString value;
3188 // The language property is inherited, so we iterate over the parents to find 3252 // The language property is inherited, so we iterate over the parents to find
3189 // the first language. 3253 // the first language.
3190 do { 3254 do {
3191 if (n->isElementNode()) { 3255 if (n->isElementNode()) {
3192 if (const ElementData* elementData = toElement(n)->elementData()) { 3256 if (const ElementData* elementData = toElement(n)->elementData()) {
3193 AttributeCollection attributes = elementData->attributes(); 3257 AttributeCollection attributes = elementData->attributes();
3194 // Spec: xml:lang takes precedence -- http://www.w3.org/TR/xhtml1/#C_7 3258 // Spec: xml:lang takes precedence -- http://www.w3.org/TR/xhtml1/#C_7
(...skipping 944 matching lines...) Expand 10 before | Expand all | Expand 10 after
4139 } 4203 }
4140 4204
4141 DEFINE_TRACE_WRAPPERS(Element) { 4205 DEFINE_TRACE_WRAPPERS(Element) {
4142 if (hasRareData()) { 4206 if (hasRareData()) {
4143 visitor->traceWrappers(elementRareData()); 4207 visitor->traceWrappers(elementRareData());
4144 } 4208 }
4145 ContainerNode::traceWrappers(visitor); 4209 ContainerNode::traceWrappers(visitor);
4146 } 4210 }
4147 4211
4148 } // namespace blink 4212 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698