Bug 1324618 part 9. Implement FrameForPseudoElement for ::first-letter. r?emilio
This also makes us stop reframing on lack of frame for pseudo-elements for which
such a lack is expected in various situations and means the pseudo-element's
styles do not matter.
MozReview-Commit-ID: K1qzeow2Z6H
--- a/layout/base/ServoRestyleManager.cpp
+++ b/layout/base/ServoRestyleManager.cpp
@@ -245,16 +245,40 @@ private:
nsStyleContext& mParentContext;
ServoRestyleState& mParentRestyleState;
RefPtr<nsStyleContext> mStyle;
bool mShouldPostHints;
bool mShouldComputeHints;
nsChangeHint mComputedHint;
};
+// Find the first-letter frame for the given element, if any. Returns null to
+// indicate there isn't one.
+static nsIFrame*
+FindFirstLetterFrameForElement(const Element* aElement)
+{
+ nsIFrame* frame = aElement->GetPrimaryFrame();
+ if (!frame) {
+ return nullptr;
+ }
+ // The first-letter frame will always be inside the content insertion frame,
+ // which will always be a block if we have a first-letter frame at all.
+ frame = frame->GetContentInsertionFrame();
+ if (!frame) {
+ // We're a leaf; certainly no first-letter frame.
+ return nullptr;
+ }
+
+ if (!frame->IsFrameOfType(nsIFrame::eBlockFrame)) {
+ return nullptr;
+ }
+
+ return static_cast<nsBlockFrame*>(frame)->GetFirstLetter();
+}
+
static void
UpdateBackdropIfNeeded(nsIFrame* aFrame, ServoRestyleState& aRestyleState)
{
const nsStyleDisplay* display = aFrame->StyleContext()->StyleDisplay();
if (display->mTopLayer != NS_STYLE_TOP_LAYER_TOP) {
return;
}
@@ -562,18 +586,21 @@ ServoRestyleManager::FrameForPseudoEleme
return pseudoElement ? nsLayoutUtils::GetStyleFrame(pseudoElement) : nullptr;
}
if (aPseudoTagOrNull == nsCSSPseudoElements::after) {
Element* pseudoElement = nsLayoutUtils::GetAfterPseudo(aElement);
return pseudoElement ? nsLayoutUtils::GetStyleFrame(pseudoElement) : nullptr;
}
- if (aPseudoTagOrNull == nsCSSPseudoElements::firstLine ||
- aPseudoTagOrNull == nsCSSPseudoElements::firstLetter) {
+ if (aPseudoTagOrNull == nsCSSPseudoElements::firstLetter) {
+ return FindFirstLetterFrameForElement(aElement);
+ }
+
+ if (aPseudoTagOrNull == nsCSSPseudoElements::firstLine) {
// TODO(emilio, bz): Figure out the best way to diff these styles.
return nullptr;
}
MOZ_CRASH("Unkown pseudo-element given to "
"ServoRestyleManager::FrameForPseudoElement");
return nullptr;
}