Bug 1359779: Also look at pseudo frames in nsComputedDOMStyle::DoGetStyleContextNoFlush. r?heycam
MozReview-Commit-ID: IvAehgyv18T
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -514,16 +514,44 @@ public:
private:
GeckoRestyleManager* mRestyleManager = nullptr;
bool mOldSkipAnimationRules = false;
nsComputedDOMStyle::AnimationFlag mAnimationFlag;
};
}
+/**
+ * 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;
+}
+
already_AddRefed<nsStyleContext>
nsComputedDOMStyle::DoGetStyleContextNoFlush(Element* aElement,
nsIAtom* aPseudo,
nsIPresShell* aPresShell,
AnimationFlag aAnimationFlag)
{
MOZ_ASSERT(aElement, "NULL element");
// If the content has a pres shell, we must use it. Otherwise we'd
@@ -538,26 +566,32 @@ nsComputedDOMStyle::DoGetStyleContextNoF
presShell = aPresShell;
if (!presShell)
return nullptr;
}
// XXX the !aElement->IsHTMLElement(nsGkAtoms::area)
// check is needed due to bug 135040 (to avoid using
// mPrimaryFrame). Remove it once that's fixed.
- if (!aPseudo &&
- inDocWithShell &&
+ if (inDocWithShell &&
!aElement->IsHTMLElement(nsGkAtoms::area)) {
- nsIFrame* frame = nsLayoutUtils::GetStyleFrame(aElement);
+ nsIFrame* frame = nullptr;
+ if (aPseudo == nsCSSPseudoElements::before) {
+ frame = nsLayoutUtils::GetBeforeFrame(aElement);
+ } else if (aPseudo == nsCSSPseudoElements::after) {
+ frame = nsLayoutUtils::GetAfterFrame(aElement);
+ } else if (!aPseudo) {
+ frame = nsLayoutUtils::GetStyleFrame(aElement);
+ }
if (frame) {
nsStyleContext* result = frame->StyleContext();
// Don't use the style context if it was influenced by
// pseudo-elements, since then it's not the primary style
- // for this element.
- if (!result->HasPseudoElementData()) {
+ // for this element / pseudo.
+ if (!MustReresolveStyle(result)) {
// The existing style context may have animation styles so check if we
// need to remove them.
if (aAnimationFlag == eWithoutAnimation) {
nsPresContext* presContext = presShell->GetPresContext();
MOZ_ASSERT(presContext, "Should have a prescontext if we have a frame");
MOZ_ASSERT(presContext->StyleSet()->IsGecko(),
"stylo: Need ResolveStyleByRemovingAnimation for stylo");
if (presContext && presContext->StyleSet()->IsGecko()) {
@@ -574,17 +608,17 @@ nsComputedDOMStyle::DoGetStyleContextNoF
return ret.forget();
}
}
}
// No frame has been created, or we have a pseudo, or we're looking
// for the default style, so resolve the style ourselves.
- nsPresContext *presContext = presShell->GetPresContext();
+ nsPresContext* presContext = presShell->GetPresContext();
if (!presContext)
return nullptr;
StyleSetHandle styleSet = presShell->StyleSet();
auto type = CSSPseudoElementType::NotPseudo;
if (aPseudo) {
type = nsCSSPseudoElements::
@@ -710,44 +744,16 @@ nsComputedDOMStyle::SetResolvedStyleCont
void
nsComputedDOMStyle::SetFrameStyleContext(nsStyleContext* aContext)
{
ClearStyleContext();
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)
{
nsCOMPtr<nsIDocument> document = do_QueryReferent(mDocumentWeak);
if (!document) {
ClearStyleContext();
return;
}