diff options
author | Matt A. Tobin <email@mattatobin.com> | 2020-04-17 05:10:25 -0400 |
---|---|---|
committer | Matt A. Tobin <email@mattatobin.com> | 2020-04-17 05:10:25 -0400 |
commit | 7614fdb51b177e6975fce5bf9a7facef170e61aa (patch) | |
tree | 598e187ce71ae82b300a3a6b6b2f199aa2f3c43d /layout/style | |
parent | 5f297c5f57583b0f9d27d714beb285919f42d655 (diff) | |
download | UXP-7614fdb51b177e6975fce5bf9a7facef170e61aa.tar UXP-7614fdb51b177e6975fce5bf9a7facef170e61aa.tar.gz UXP-7614fdb51b177e6975fce5bf9a7facef170e61aa.tar.lz UXP-7614fdb51b177e6975fce5bf9a7facef170e61aa.tar.xz UXP-7614fdb51b177e6975fce5bf9a7facef170e61aa.zip |
Bug 1355351 - Make pseudo-elements return the correct style via getComputedStyle
* Add a node property to access the ::before and ::after pseudo-elements
* Look for the frame for ::before and ::after pseudos
* Clean up pseudo-element props
* Simplify nsLayoutUtils callers, and make child iterators notice display: contents pseudos
Tag #1375
Diffstat (limited to 'layout/style')
-rw-r--r-- | layout/style/nsComputedDOMStyle.cpp | 47 |
1 files changed, 43 insertions, 4 deletions
diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index 102e0df18..20e5651bd 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -638,6 +638,34 @@ nsComputedDOMStyle::SetFrameStyleContext(nsStyleContext* aContext) mStyleContext = aContext; } +/** + * The following function checks whether we need to explicitly resolve the style + * again, even though we have a style context coming from the frame. + * + * This basically checks whether the style is or may be under a ::first-line or + * ::first-letter frame, in which case we can't return the frame style, and we + * need to resolve it. See bug 505515. + */ +static bool +MustReresolveStyle(const nsStyleContext* aContext) +{ + MOZ_ASSERT(aContext); + + if (aContext->HasPseudoElementData()) { + if (!aContext->GetPseudo() || + aContext->StyleSource().IsServoComputedValues()) { + // TODO(emilio): When ::first-line is supported in Servo, we may want to + // fix this to avoid re-resolving pseudo-element styles. + return true; + } + + return aContext->GetParent() && + aContext->GetParent()->HasPseudoElementData(); + } + + return false; +} + void nsComputedDOMStyle::UpdateCurrentStyleSources(bool aNeedsLayoutFlush) { @@ -690,9 +718,20 @@ nsComputedDOMStyle::UpdateCurrentStyleSources(bool aNeedsLayoutFlush) // XXX the !mElement->IsHTMLElement(nsGkAtoms::area) // check is needed due to bug 135040 (to avoid using // mPrimaryFrame). Remove it once that's fixed. - if (!mPseudo && mStyleType == eAll && - !mElement->IsHTMLElement(nsGkAtoms::area)) { - mOuterFrame = mElement->GetPrimaryFrame(); + if (mStyleType == eAll && !mElement->IsHTMLElement(nsGkAtoms::area)) { + mOuterFrame = nullptr; + + if (!mPseudo) { + mOuterFrame = mElement->GetPrimaryFrame(); + } else if (mPseudo == nsCSSPseudoElements::before || + mPseudo == nsCSSPseudoElements::after) { + nsIAtom* property = mPseudo == nsCSSPseudoElements::before + ? nsGkAtoms::beforePseudoProperty + : nsGkAtoms::afterPseudoProperty; + + auto* pseudo = static_cast<Element*>(mElement->GetProperty(property)); + mOuterFrame = pseudo ? pseudo->GetPrimaryFrame() : nullptr; + } mInnerFrame = mOuterFrame; if (mOuterFrame) { nsIAtom* type = mOuterFrame->GetType(); @@ -711,7 +750,7 @@ nsComputedDOMStyle::UpdateCurrentStyleSources(bool aNeedsLayoutFlush) } } - if (!mStyleContext || mStyleContext->HasPseudoElementData()) { + if (!mStyleContext || MustReresolveStyle(mStyleContext)) { #ifdef DEBUG if (mStyleContext) { // We want to check that going through this path because of |