Chromium Code Reviews| 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 1556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 if (style.display() == EDisplay::None) |
| 1578 style.display() != EDisplay::Contents; | 1578 return false; |
| 1579 | |
| 1580 if (style.display() == EDisplay::Contents) | |
| 1581 return isPseudoElement(); | |
|
rune
2017/03/13 10:29:50
What layout object is needed and created for the :
emilio
2017/03/13 13:28:31
Whoops, this is leftover from the previous approac
| |
| 1582 | |
| 1583 return true; | |
| 1579 } | 1584 } |
| 1580 | 1585 |
| 1581 LayoutObject* Element::createLayoutObject(const ComputedStyle& style) { | 1586 LayoutObject* Element::createLayoutObject(const ComputedStyle& style) { |
| 1582 return LayoutObject::createObject(this, style); | 1587 return LayoutObject::createObject(this, style); |
| 1583 } | 1588 } |
| 1584 | 1589 |
| 1585 Node::InsertionNotificationRequest Element::insertedInto( | 1590 Node::InsertionNotificationRequest Element::insertedInto( |
| 1586 ContainerNode* insertionPoint) { | 1591 ContainerNode* insertionPoint) { |
| 1587 // need to do superclass processing first so isConnected() is true | 1592 // need to do superclass processing first so isConnected() is true |
| 1588 // by the time we reach updateId | 1593 // by the time we reach updateId |
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1997 if (localChange != NoChange) { | 2002 if (localChange != NoChange) { |
| 1998 layoutObject->setStyle(newStyle.get()); | 2003 layoutObject->setStyle(newStyle.get()); |
| 1999 } else { | 2004 } else { |
| 2000 // Although no change occurred, we use the new style so that the cousin | 2005 // Although no change occurred, we use the new style so that the cousin |
| 2001 // style sharing code won't get fooled into believing this style is the | 2006 // style sharing code won't get fooled into believing this style is the |
| 2002 // same. | 2007 // same. |
| 2003 // FIXME: We may be able to remove this hack, see discussion in | 2008 // FIXME: We may be able to remove this hack, see discussion in |
| 2004 // https://codereview.chromium.org/30453002/ | 2009 // https://codereview.chromium.org/30453002/ |
| 2005 layoutObject->setStyleInternal(newStyle.get()); | 2010 layoutObject->setStyleInternal(newStyle.get()); |
| 2006 } | 2011 } |
| 2007 } else if (localChange != NoChange && | 2012 } else { |
| 2008 shouldStoreNonLayoutObjectComputedStyle(*newStyle)) { | 2013 if (localChange != NoChange) { |
| 2009 storeNonLayoutObjectComputedStyle(newStyle); | 2014 if (shouldStoreNonLayoutObjectComputedStyle(*newStyle)) |
| 2015 storeNonLayoutObjectComputedStyle(newStyle); | |
| 2016 else if (hasRareData()) | |
| 2017 elementRareData()->clearComputedStyle(); | |
| 2018 } | |
| 2010 } | 2019 } |
| 2011 | 2020 |
| 2012 if (getStyleChangeType() >= SubtreeStyleChange) | 2021 if (getStyleChangeType() >= SubtreeStyleChange) |
| 2013 return Force; | 2022 return Force; |
| 2014 | 2023 |
| 2015 if (change > Inherit || localChange > Inherit) | 2024 if (change > Inherit || localChange > Inherit) |
| 2016 return max(localChange, change); | 2025 return max(localChange, change); |
| 2017 | 2026 |
| 2018 if (localChange < IndependentInherit) { | 2027 if (localChange < IndependentInherit) { |
| 2019 if (oldStyle->hasChildDependentFlags()) { | 2028 if (oldStyle->hasChildDependentFlags()) { |
| (...skipping 1154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3174 ElementRareData& rareData = ensureElementRareData(); | 3183 ElementRareData& rareData = ensureElementRareData(); |
| 3175 if (!rareData.computedStyle()) | 3184 if (!rareData.computedStyle()) |
| 3176 rareData.setComputedStyle( | 3185 rareData.setComputedStyle( |
| 3177 document().styleForElementIgnoringPendingStylesheets(this)); | 3186 document().styleForElementIgnoringPendingStylesheets(this)); |
| 3178 elementStyle = rareData.computedStyle(); | 3187 elementStyle = rareData.computedStyle(); |
| 3179 } | 3188 } |
| 3180 | 3189 |
| 3181 if (!pseudoElementSpecifier) | 3190 if (!pseudoElementSpecifier) |
| 3182 return elementStyle; | 3191 return elementStyle; |
| 3183 | 3192 |
| 3184 if (ComputedStyle* pseudoElementStyle = | 3193 if (ComputedStyle* cached = |
| 3185 elementStyle->getCachedPseudoStyle(pseudoElementSpecifier)) | 3194 elementStyle->getCachedPseudoStyle(pseudoElementSpecifier)) |
| 3186 return pseudoElementStyle; | 3195 return cached; |
|
rune
2017/03/13 10:29:50
This and the code below duplicates the code in Ele
emilio
2017/03/13 13:28:31
No, I can't. We use pseudoStyleForElement instead
| |
| 3187 | 3196 |
| 3188 // TODO(ecobos): Passing two times elementStyle may be wrong, though we don't | 3197 const ComputedStyle* layoutParentStyle = elementStyle; |
| 3189 // support display: contents elements' pseudo-elements yet, so this is not a | 3198 if (hasDisplayContentsStyle()) { |
| 3190 // problem for now. | 3199 LayoutObject* parentLayoutObject = |
| 3200 LayoutTreeBuilderTraversal::parentLayoutObject(*this); | |
| 3201 if (parentLayoutObject) | |
| 3202 layoutParentStyle = parentLayoutObject->style(); | |
| 3203 } | |
| 3204 | |
| 3191 RefPtr<ComputedStyle> result = | 3205 RefPtr<ComputedStyle> result = |
| 3192 document().ensureStyleResolver().pseudoStyleForElement( | 3206 document().ensureStyleResolver().pseudoStyleForElement( |
| 3193 this, PseudoStyleRequest(pseudoElementSpecifier, | 3207 this, |
| 3194 PseudoStyleRequest::ForComputedStyle), | 3208 PseudoStyleRequest(pseudoElementSpecifier, |
| 3195 elementStyle, elementStyle); | 3209 PseudoStyleRequest::ForComputedStyle), |
| 3210 elementStyle, layoutParentStyle); | |
| 3196 DCHECK(result); | 3211 DCHECK(result); |
| 3197 return elementStyle->addCachedPseudoStyle(result.release()); | 3212 return elementStyle->addCachedPseudoStyle(result.release()); |
| 3198 } | 3213 } |
| 3199 | 3214 |
| 3200 const ComputedStyle* Element::nonLayoutObjectComputedStyle() const { | 3215 const ComputedStyle* Element::nonLayoutObjectComputedStyle() const { |
| 3201 if (layoutObject() || !hasRareData()) | 3216 if (layoutObject() || !hasRareData()) |
| 3202 return nullptr; | 3217 return nullptr; |
| 3203 | 3218 |
| 3204 return elementRareData()->computedStyle(); | 3219 return elementRareData()->computedStyle(); |
| 3205 } | 3220 } |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3269 PseudoElement* element = pseudoElement(pseudoId); | 3284 PseudoElement* element = pseudoElement(pseudoId); |
| 3270 | 3285 |
| 3271 if (element && (change == UpdatePseudoElements || | 3286 if (element && (change == UpdatePseudoElements || |
| 3272 element->shouldCallRecalcStyle(change))) { | 3287 element->shouldCallRecalcStyle(change))) { |
| 3273 if (pseudoId == PseudoIdFirstLetter && updateFirstLetter(element)) | 3288 if (pseudoId == PseudoIdFirstLetter && updateFirstLetter(element)) |
| 3274 return; | 3289 return; |
| 3275 | 3290 |
| 3276 // Need to clear the cached style if the PseudoElement wants a recalc so it | 3291 // Need to clear the cached style if the PseudoElement wants a recalc so it |
| 3277 // computes a new style. | 3292 // computes a new style. |
| 3278 if (element->needsStyleRecalc()) | 3293 if (element->needsStyleRecalc()) |
| 3279 layoutObject()->mutableStyle()->removeCachedPseudoStyle(pseudoId); | 3294 mutableComputedStyle()->removeCachedPseudoStyle(pseudoId); |
| 3280 | 3295 |
| 3281 // PseudoElement styles hang off their parent element's style so if we | 3296 // PseudoElement styles hang off their parent element's style so if we |
| 3282 // needed a style recalc we should Force one on the pseudo. FIXME: We | 3297 // needed a style recalc we should Force one on the pseudo. FIXME: We |
| 3283 // should figure out the right text sibling to pass. | 3298 // should figure out the right text sibling to pass. |
| 3284 element->recalcStyle(change == UpdatePseudoElements ? Force : change); | 3299 element->recalcStyle(change == UpdatePseudoElements ? Force : change); |
| 3285 | 3300 |
| 3286 // Wait until our parent is not displayed or | 3301 // Wait until our parent is not displayed or |
| 3287 // pseudoElementLayoutObjectIsNeeded is false, otherwise we could | 3302 // pseudoElementLayoutObjectIsNeeded is false, otherwise we could |
| 3288 // continuously create and destroy PseudoElements when | 3303 // continuously create and destroy PseudoElements when |
| 3289 // LayoutObject::isChildAllowed on our parent returns false for the | 3304 // LayoutObject::isChildAllowed on our parent returns false for the |
| 3290 // PseudoElement's layoutObject for each style recalc. | 3305 // PseudoElement's layoutObject for each style recalc. |
| 3291 if (!layoutObject() || | 3306 if (!canHaveGeneratedPseudo(pseudoId) || |
| 3292 !pseudoElementLayoutObjectIsNeeded( | 3307 !pseudoElementLayoutObjectIsNeeded(pseudoStyle(pseudoId))) |
| 3293 layoutObject()->getCachedPseudoStyle(pseudoId))) | |
| 3294 elementRareData()->setPseudoElement(pseudoId, nullptr); | 3308 elementRareData()->setPseudoElement(pseudoId, nullptr); |
| 3295 } else if (pseudoId == PseudoIdFirstLetter && element && | 3309 } else if (pseudoId == PseudoIdFirstLetter && element && |
| 3296 change >= UpdatePseudoElements && | 3310 change >= UpdatePseudoElements && |
| 3297 !FirstLetterPseudoElement::firstLetterTextLayoutObject(*element)) { | 3311 !FirstLetterPseudoElement::firstLetterTextLayoutObject(*element)) { |
| 3298 // This can happen if we change to a float, for example. We need to cleanup | 3312 // This can happen if we change to a float, for example. We need to cleanup |
| 3299 // the first-letter pseudoElement and then fix the text of the original | 3313 // the first-letter pseudoElement and then fix the text of the original |
| 3300 // remaining text layoutObject. This can be seen in Test 7 of | 3314 // remaining text layoutObject. This can be seen in Test 7 of |
| 3301 // fast/css/first-letter-removed-added.html | 3315 // fast/css/first-letter-removed-added.html |
| 3302 elementRareData()->setPseudoElement(pseudoId, nullptr); | 3316 elementRareData()->setPseudoElement(pseudoId, nullptr); |
| 3303 } else if (change >= UpdatePseudoElements) { | 3317 } else if (change >= UpdatePseudoElements) { |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 3320 // incorrect results due to setting the first letter back. | 3334 // incorrect results due to setting the first letter back. |
| 3321 if (remainingTextLayoutObject) | 3335 if (remainingTextLayoutObject) |
| 3322 element->reattachLayoutTree(); | 3336 element->reattachLayoutTree(); |
| 3323 else | 3337 else |
| 3324 elementRareData()->setPseudoElement(PseudoIdFirstLetter, nullptr); | 3338 elementRareData()->setPseudoElement(PseudoIdFirstLetter, nullptr); |
| 3325 return true; | 3339 return true; |
| 3326 } | 3340 } |
| 3327 return false; | 3341 return false; |
| 3328 } | 3342 } |
| 3329 | 3343 |
| 3344 ComputedStyle* Element::pseudoStyle(PseudoId pseudoId) const { | |
| 3345 ComputedStyle* style = mutableComputedStyle(); | |
| 3346 DCHECK(pseudoId < FirstInternalPseudoId); | |
| 3347 if (!style->hasPseudoStyle(pseudoId)) | |
| 3348 return nullptr; | |
| 3349 | |
| 3350 if (ComputedStyle* cached = style->getCachedPseudoStyle(pseudoId)) | |
| 3351 return cached; | |
| 3352 RefPtr<ComputedStyle> uncached = getUncachedPseudoStyle(pseudoId); | |
| 3353 if (uncached) | |
| 3354 return style->addCachedPseudoStyle(uncached.release()); | |
| 3355 return nullptr; | |
| 3356 } | |
| 3357 | |
| 3358 PassRefPtr<ComputedStyle> Element::getUncachedPseudoStyle( | |
| 3359 PseudoId pseudoId) const { | |
| 3360 if (pseudoId == PseudoIdBefore || pseudoId == PseudoIdAfter) { | |
| 3361 LayoutObject* parentLayoutObject = layoutObject(); | |
| 3362 if (!parentLayoutObject && hasDisplayContentsStyle()) { | |
| 3363 parentLayoutObject = | |
| 3364 LayoutTreeBuilderTraversal::parentLayoutObject(*this); | |
| 3365 } | |
| 3366 if (!parentLayoutObject) | |
| 3367 return nullptr; | |
| 3368 return document().ensureStyleResolver().pseudoStyleForElement( | |
| 3369 const_cast<Element*>(this), PseudoStyleRequest(pseudoId), | |
| 3370 computedStyle(), parentLayoutObject->style()); | |
| 3371 } | |
| 3372 if (!layoutObject()) | |
| 3373 return nullptr; | |
| 3374 return layoutObject()->getUncachedPseudoStyle(PseudoStyleRequest(pseudoId)); | |
| 3375 } | |
| 3376 | |
| 3377 // For display: contents elements, we still need to generate ::before and | |
| 3378 // ::after, but the rest of the pseudo-elements should only be used for elements | |
| 3379 // with an actual layout object. | |
| 3380 bool Element::canHaveGeneratedPseudo(PseudoId pseudoId) const { | |
| 3381 if (hasDisplayContentsStyle()) | |
| 3382 return pseudoId == PseudoIdBefore || pseudoId == PseudoIdAfter; | |
| 3383 return !!layoutObject(); | |
| 3384 } | |
| 3385 | |
| 3330 void Element::createPseudoElementIfNeeded(PseudoId pseudoId) { | 3386 void Element::createPseudoElementIfNeeded(PseudoId pseudoId) { |
| 3331 if (isPseudoElement()) | 3387 if (isPseudoElement()) |
| 3332 return; | 3388 return; |
| 3333 | 3389 |
| 3334 // Document::ensureStyleResolver is not inlined and shows up on profiles, | 3390 // Document::ensureStyleResolver is not inlined and shows up on profiles, |
| 3335 // avoid it here. | 3391 // avoid it here. |
| 3336 PseudoElement* element = | 3392 PseudoElement* element = |
| 3337 document().styleEngine().ensureResolver().createPseudoElementIfNeeded( | 3393 document().styleEngine().ensureResolver().createPseudoElementIfNeeded( |
| 3338 *this, pseudoId); | 3394 *this, pseudoId); |
| 3339 if (!element) | 3395 if (!element) |
| (...skipping 845 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4185 } | 4241 } |
| 4186 | 4242 |
| 4187 DEFINE_TRACE_WRAPPERS(Element) { | 4243 DEFINE_TRACE_WRAPPERS(Element) { |
| 4188 if (hasRareData()) { | 4244 if (hasRareData()) { |
| 4189 visitor->traceWrappers(elementRareData()); | 4245 visitor->traceWrappers(elementRareData()); |
| 4190 } | 4246 } |
| 4191 ContainerNode::traceWrappers(visitor); | 4247 ContainerNode::traceWrappers(visitor); |
| 4192 } | 4248 } |
| 4193 | 4249 |
| 4194 } // namespace blink | 4250 } // namespace blink |
| OLD | NEW |