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 |