Bug 1343078 part 1. Give placeholders and first-letter continuations different kinds of anonymous boxes. r?dbaron
MozReview-Commit-ID: B5IHgVUo1Rp
--- a/layout/base/GeckoRestyleManager.cpp
+++ b/layout/base/GeckoRestyleManager.cpp
@@ -2090,19 +2090,21 @@ ElementRestyler::ComputeRestyleResultFro
nsIFrame* parent = mFrame->GetParent();
if (parent) {
// Also if the parent has a pseudo, as this frame's style context will
// be inheriting from a grandparent frame's style context (or a further
// ancestor).
nsIAtom* parentPseudoTag = parent->StyleContext()->GetPseudo();
if (parentPseudoTag &&
- parentPseudoTag != nsCSSAnonBoxes::mozOtherNonElement) {
+ parentPseudoTag != nsCSSAnonBoxes::firstLetterContinuation) {
MOZ_ASSERT(parentPseudoTag != nsCSSAnonBoxes::mozText,
"Style of text node should not be parent of anything");
+ MOZ_ASSERT(parentPseudoTag != nsCSSAnonBoxes::oofPlaceholder,
+ "Style of placeholder should not be parent of anything");
LOG_RESTYLE_CONTINUE("the old style context's parent is for a pseudo");
aRestyleResult = RestyleResult::eContinue;
// Parent style context pseudo-ness doesn't affect whether we can
// return RestyleResult::eStopWithStyleChange.
//
// If we had later conditions to check in this function, we would
// continue to check them, in case we set aCanStopWithStyleChange to
// false.
@@ -2461,18 +2463,20 @@ ElementRestyler::RestyleSelf(nsIFrame* a
// Just use the style context from the frame's previous
// continuation.
LOG_RESTYLE("using previous continuation's context");
newContext = prevContinuationContext;
} else if (pseudoTag == nsCSSAnonBoxes::mozText) {
MOZ_ASSERT(aSelf->GetType() == nsGkAtoms::textFrame);
newContext =
styleSet->ResolveStyleForText(aSelf->GetContent(), parentContext);
- } else if (nsCSSAnonBoxes::IsNonElement(pseudoTag)) {
- newContext = styleSet->ResolveStyleForOtherNonElement(parentContext);
+ } else if (pseudoTag == nsCSSAnonBoxes::firstLetterContinuation) {
+ newContext = styleSet->ResolveStyleForFirstLetterContinuation(parentContext);
+ } else if (pseudoTag == nsCSSAnonBoxes::oofPlaceholder) {
+ newContext = styleSet->ResolveStyleForPlaceholder(parentContext);
}
else {
Element* element = ElementForStyleContext(mParentContent, aSelf, pseudoType);
if (!MustRestyleSelf(aRestyleHint, element)) {
if (CanReparentStyleContext(aRestyleHint)) {
LOG_RESTYLE("reparenting style context");
newContext =
styleSet->ReparentStyleContext(oldContext, parentContext, element);
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -3035,17 +3035,17 @@ nsCSSFrameConstructor::CreatePlaceholder
nsIContent* aContent,
nsIFrame* aFrame,
nsStyleContext* aParentStyle,
nsContainerFrame* aParentFrame,
nsIFrame* aPrevInFlow,
nsFrameState aTypeBit)
{
RefPtr<nsStyleContext> placeholderStyle = aPresShell->StyleSet()->
- ResolveStyleForOtherNonElement(aParentStyle);
+ ResolveStyleForPlaceholder(aParentStyle);
// The placeholder frame gets a pseudo style context
nsPlaceholderFrame* placeholderFrame =
(nsPlaceholderFrame*)NS_NewPlaceholderFrame(aPresShell, placeholderStyle,
aTypeBit);
placeholderFrame->Init(aContent, aParentFrame, aPrevInFlow);
--- a/layout/generic/nsFirstLetterFrame.cpp
+++ b/layout/generic/nsFirstLetterFrame.cpp
@@ -64,17 +64,17 @@ nsFirstLetterFrame::Init(nsIContent*
RefPtr<nsStyleContext> newSC;
if (aPrevInFlow) {
// Get proper style context for ourselves. We're creating the frame
// that represents everything *except* the first letter, so just create
// a style context like we would for a text node.
nsStyleContext* parentStyleContext = mStyleContext->GetParent();
if (parentStyleContext) {
newSC = PresContext()->StyleSet()->
- ResolveStyleForOtherNonElement(parentStyleContext);
+ ResolveStyleForFirstLetterContinuation(parentStyleContext);
SetStyleContextWithoutNotification(newSC);
}
}
nsContainerFrame::Init(aContent, aParent, aPrevInFlow);
}
void
@@ -329,17 +329,17 @@ nsFirstLetterFrame::CreateContinuationFo
CreateContinuingFrame(aPresContext, aChild, parent, aIsFluid);
// The continuation will have gotten the first letter style from its
// prev continuation, so we need to repair the style context so it
// doesn't have the first letter styling.
nsStyleContext* parentSC = this->StyleContext()->GetParent();
if (parentSC) {
RefPtr<nsStyleContext> newSC;
- newSC = presShell->StyleSet()->ResolveStyleForOtherNonElement(parentSC);
+ newSC = presShell->StyleSet()->ResolveStyleForFirstLetterContinuation(parentSC);
continuation->SetStyleContext(newSC);
nsLayoutUtils::MarkDescendantsDirty(continuation);
}
//XXX Bidi may not be involved but we have to use the list name
// kNoReflowPrincipalList because this is just like creating a continuation
// except we have to insert it in a different place and we don't want a
// reflow command to try to be issued.
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -242,28 +242,42 @@ ServoStyleSet::ResolveStyleForText(nsICo
Servo_ComputedValues_Inherit(mRawSet.get(), parentComputedValues).Consume();
return GetContext(computedValues.forget(), aParentContext,
nsCSSAnonBoxes::mozText, CSSPseudoElementType::AnonBox,
nullptr);
}
already_AddRefed<nsStyleContext>
-ServoStyleSet::ResolveStyleForOtherNonElement(nsStyleContext* aParentContext)
+ServoStyleSet::ResolveStyleForFirstLetterContinuation(nsStyleContext* aParentContext)
{
- // The parent context can be null if the non-element share a style context
- // with the root of an anonymous subtree.
+ const ServoComputedValues* parent = aParentContext->StyleSource().AsServoComputedValues();
+ RefPtr<ServoComputedValues> computedValues =
+ Servo_ComputedValues_Inherit(mRawSet.get(), parent).Consume();
+ MOZ_ASSERT(computedValues);
+
+ return GetContext(computedValues.forget(), aParentContext,
+ nsCSSAnonBoxes::firstLetterContinuation,
+ CSSPseudoElementType::AnonBox,
+ nullptr);
+}
+
+already_AddRefed<nsStyleContext>
+ServoStyleSet::ResolveStyleForPlaceholder(nsStyleContext* aParentContext)
+{
+ // The parent context can be null if the placeholder's element is a root
+ // element.
const ServoComputedValues* parent =
aParentContext ? aParentContext->StyleSource().AsServoComputedValues() : nullptr;
RefPtr<ServoComputedValues> computedValues =
Servo_ComputedValues_Inherit(mRawSet.get(), parent).Consume();
MOZ_ASSERT(computedValues);
return GetContext(computedValues.forget(), aParentContext,
- nsCSSAnonBoxes::mozOtherNonElement,
+ nsCSSAnonBoxes::oofPlaceholder,
CSSPseudoElementType::AnonBox,
nullptr);
}
already_AddRefed<nsStyleContext>
ServoStyleSet::ResolvePseudoElementStyle(Element* aOriginatingElement,
CSSPseudoElementType aType,
nsStyleContext* aParentContext,
--- a/layout/style/ServoStyleSet.h
+++ b/layout/style/ServoStyleSet.h
@@ -77,23 +77,56 @@ public:
LazyComputeBehavior aMayCompute);
already_AddRefed<nsStyleContext>
ResolveStyleFor(dom::Element* aElement,
nsStyleContext* aParentContext,
LazyComputeBehavior aMayCompute,
TreeMatchContext& aTreeMatchContext);
+ // Get a style context for a text node (which no rules will match).
+ //
+ // The returned style context will have nsCSSAnonBoxes::mozText as its pseudo.
+ //
+ // (Perhaps mozText should go away and we shouldn't even create style
+ // contexts for such content nodes, when text-combine-upright is not
+ // present. However, not doing any rule matching for them is a first step.)
already_AddRefed<nsStyleContext>
ResolveStyleForText(nsIContent* aTextNode,
nsStyleContext* aParentContext);
+ // Get a style context for a first-letter continuation (which no rules will
+ // match).
+ //
+ // The returned style context will have
+ // nsCSSAnonBoxes::firstLetterContinuation as its pseudo.
+ //
+ // (Perhaps nsCSSAnonBoxes::firstLetterContinuation should go away and we
+ // shouldn't even create style contexts for such frames. However, not doing
+ // any rule matching for them is a first step. And right now we do use this
+ // style context for some things)
already_AddRefed<nsStyleContext>
- ResolveStyleForOtherNonElement(nsStyleContext* aParentContext);
+ ResolveStyleForFirstLetterContinuation(nsStyleContext* aParentContext);
+ // Get a style context for a placeholder frame (which no rules will match).
+ //
+ // The returned style context will have nsCSSAnonBoxes::oofPlaceholder as
+ // its pseudo.
+ //
+ // (Perhaps nsCSSAnonBoxes::oofPaceholder should go away and we shouldn't even
+ // create style contexts for placeholders. However, not doing
+ // any rule matching for them is a first step.)
+ already_AddRefed<nsStyleContext>
+ ResolveStyleForPlaceholder(nsStyleContext* aParentContext);
+
+ // Get a style context for a pseudo-element. aParentElement must be
+ // non-null. aPseudoID is the CSSPseudoElementType for the
+ // pseudo-element. aPseudoElement must be non-null if the pseudo-element
+ // type is one that allows user action pseudo-classes after it or allows
+ // style attributes; otherwise, it is ignored.
already_AddRefed<nsStyleContext>
ResolvePseudoElementStyle(dom::Element* aOriginatingElement,
mozilla::CSSPseudoElementType aType,
nsStyleContext* aParentContext,
dom::Element* aPseudoElement);
// Resolves style for a (possibly-pseudo) Element without assuming that the
// style has been resolved, and without worrying about setting the style
--- a/layout/style/StyleSetHandle.h
+++ b/layout/style/StyleSetHandle.h
@@ -121,17 +121,19 @@ public:
ResolveStyleFor(dom::Element* aElement,
nsStyleContext* aParentContext,
LazyComputeBehavior aMayCompute,
TreeMatchContext& aTreeMatchContext);
inline already_AddRefed<nsStyleContext>
ResolveStyleForText(nsIContent* aTextNode,
nsStyleContext* aParentContext);
inline already_AddRefed<nsStyleContext>
- ResolveStyleForOtherNonElement(nsStyleContext* aParentContext);
+ ResolveStyleForFirstLetterContinuation(nsStyleContext* aParentContext);
+ inline already_AddRefed<nsStyleContext>
+ ResolveStyleForPlaceholder(nsStyleContext* aParentContext);
inline already_AddRefed<nsStyleContext>
ResolvePseudoElementStyle(dom::Element* aParentElement,
mozilla::CSSPseudoElementType aType,
nsStyleContext* aParentContext,
dom::Element* aPseudoElement);
inline already_AddRefed<nsStyleContext>
ResolveAnonymousBoxStyle(nsIAtom* aPseudoTag, nsStyleContext* aParentContext,
uint32_t aFlags = 0);
--- a/layout/style/StyleSetHandleInlines.h
+++ b/layout/style/StyleSetHandleInlines.h
@@ -97,19 +97,25 @@ StyleSetHandle::Ptr::ResolveStyleFor(dom
already_AddRefed<nsStyleContext>
StyleSetHandle::Ptr::ResolveStyleForText(nsIContent* aTextNode,
nsStyleContext* aParentContext)
{
FORWARD(ResolveStyleForText, (aTextNode, aParentContext));
}
already_AddRefed<nsStyleContext>
-StyleSetHandle::Ptr::ResolveStyleForOtherNonElement(nsStyleContext* aParentContext)
+StyleSetHandle::Ptr::ResolveStyleForPlaceholder(nsStyleContext* aParentContext)
{
- FORWARD(ResolveStyleForOtherNonElement, (aParentContext));
+ FORWARD(ResolveStyleForPlaceholder, (aParentContext));
+}
+
+already_AddRefed<nsStyleContext>
+StyleSetHandle::Ptr::ResolveStyleForFirstLetterContinuation(nsStyleContext* aParentContext)
+{
+ FORWARD(ResolveStyleForFirstLetterContinuation, (aParentContext));
}
already_AddRefed<nsStyleContext>
StyleSetHandle::Ptr::ResolvePseudoElementStyle(dom::Element* aParentElement,
CSSPseudoElementType aType,
nsStyleContext* aParentContext,
dom::Element* aPseudoElement)
{
--- a/layout/style/nsCSSAnonBoxList.h
+++ b/layout/style/nsCSSAnonBoxList.h
@@ -14,23 +14,25 @@
* done to it. The entries should be kept in some sort of logical
* order. The first argument to CSS_ANON_BOX is the C++ identifier of
* the atom. The second argument is the string value of the atom.
*/
// OUTPUT_CLASS=nsCSSAnonBoxes
// MACRO_NAME=CSS_ANON_BOX
-// ::-moz-text and ::-moz-other-non-element are non-elements which no
-// rule will match.
+// ::-moz-text, ::-moz-oof-placeholder, and ::-moz-first-letter-continuation are
+// non-elements which no rule will match.
CSS_ANON_BOX(mozText, ":-moz-text")
-// This anonymous box has two uses:
-// 1. placeholder frames,
-// 2. nsFirstLetterFrames for content outside the ::first-letter.
-CSS_ANON_BOX(mozOtherNonElement, ":-moz-other-non-element")
+// placeholder frames for out of flows. Note that :-moz-placeholder is used for
+// the pseudo-element that represents the placeholder text in <input
+// placeholder="foo">, so we need a different string here.
+CSS_ANON_BOX(oofPlaceholder, ":-moz-oof-placeholder")
+// nsFirstLetterFrames for content outside the ::first-letter.
+CSS_ANON_BOX(firstLetterContinuation, ":-moz-first-letter-continuation")
CSS_ANON_BOX(mozAnonymousBlock, ":-moz-anonymous-block")
CSS_ANON_BOX(mozAnonymousPositionedBlock, ":-moz-anonymous-positioned-block")
CSS_ANON_BOX(mozMathMLAnonymousBlock, ":-moz-mathml-anonymous-block")
CSS_ANON_BOX(mozXULAnonymousBlock, ":-moz-xul-anonymous-block")
// Framesets
CSS_ANON_BOX(horizontalFramesetBorder, ":-moz-hframeset-border")
--- a/layout/style/nsCSSAnonBoxes.h
+++ b/layout/style/nsCSSAnonBoxes.h
@@ -19,16 +19,19 @@ public:
static void AddRefAtoms();
static bool IsAnonBox(nsIAtom *aAtom);
#ifdef MOZ_XUL
static bool IsTreePseudoElement(nsIAtom* aPseudo);
#endif
static bool IsNonElement(nsIAtom* aPseudo)
- { return aPseudo == mozText || aPseudo == mozOtherNonElement; }
+ {
+ return aPseudo == mozText || aPseudo == oofPlaceholder ||
+ aPseudo == firstLetterContinuation;
+ }
#define CSS_ANON_BOX(_name, _value) static nsICSSAnonBoxPseudo* _name;
#include "nsCSSAnonBoxList.h"
#undef CSS_ANON_BOX
};
#endif /* nsCSSAnonBoxes_h___ */
--- a/layout/style/nsStyleSet.cpp
+++ b/layout/style/nsStyleSet.cpp
@@ -1825,20 +1825,28 @@ nsStyleSet::ResolveStyleForText(nsIConte
{
MOZ_ASSERT(aTextNode && aTextNode->IsNodeOfType(nsINode::eTEXT));
return GetContext(aParentContext, mRuleTree, nullptr,
nsCSSAnonBoxes::mozText,
CSSPseudoElementType::AnonBox, nullptr, eNoFlags);
}
already_AddRefed<nsStyleContext>
-nsStyleSet::ResolveStyleForOtherNonElement(nsStyleContext* aParentContext)
+nsStyleSet::ResolveStyleForFirstLetterContinuation(nsStyleContext* aParentContext)
{
return GetContext(aParentContext, mRuleTree, nullptr,
- nsCSSAnonBoxes::mozOtherNonElement,
+ nsCSSAnonBoxes::firstLetterContinuation,
+ CSSPseudoElementType::AnonBox, nullptr, eNoFlags);
+}
+
+already_AddRefed<nsStyleContext>
+nsStyleSet::ResolveStyleForPlaceholder(nsStyleContext* aParentContext)
+{
+ return GetContext(aParentContext, mRuleTree, nullptr,
+ nsCSSAnonBoxes::oofPlaceholder,
CSSPseudoElementType::AnonBox, nullptr, eNoFlags);
}
void
nsStyleSet::WalkRestrictionRule(CSSPseudoElementType aPseudoType,
nsRuleWalker* aRuleWalker)
{
// This needs to match GetPseudoRestriction in nsRuleNode.cpp.
--- a/layout/style/nsStyleSet.h
+++ b/layout/style/nsStyleSet.h
@@ -204,28 +204,39 @@ class nsStyleSet final
// The returned style context will have nsCSSAnonBoxes::mozText as its pseudo.
//
// (Perhaps mozText should go away and we shouldn't even create style
// contexts for such content nodes, when text-combine-upright is not
// present. However, not doing any rule matching for them is a first step.)
already_AddRefed<nsStyleContext>
ResolveStyleForText(nsIContent* aTextNode, nsStyleContext* aParentContext);
- // Get a style context for a non-element (which no rules will match)
- // other than a text node, such as placeholder frames, and the
- // nsFirstLetterFrame for everything after the first letter.
+ // Get a style context for a first-letter continuation (which no rules will
+ // match).
+ //
+ // The returned style context will have
+ // nsCSSAnonBoxes::firstLetterContinuation as its pseudo.
//
- // The returned style context will have nsCSSAnonBoxes::mozOtherNonElement as
+ // (Perhaps nsCSSAnonBoxes::firstLetterContinuation should go away and we
+ // shouldn't even create style contexts for such frames. However, not doing
+ // any rule matching for them is a first step. And right now we do use this
+ // style context for some things)
+ already_AddRefed<nsStyleContext>
+ ResolveStyleForFirstLetterContinuation(nsStyleContext* aParentContext);
+
+ // Get a style context for a placeholder frame (which no rules will match).
+ //
+ // The returned style context will have nsCSSAnonBoxes::oofPlaceholder as
// its pseudo.
//
- // (Perhaps mozOtherNonElement should go away and we shouldn't even
- // create style contexts for such content nodes. However, not doing
- // any rule matching for them is a first step.)
+ // (Perhaps nsCSSAnonBoxes::oofPlaceholder should go away and we shouldn't
+ // even create style contexts for placeholders. However, not doing any rule
+ // matching for them is a first step.)
already_AddRefed<nsStyleContext>
- ResolveStyleForOtherNonElement(nsStyleContext* aParentContext);
+ ResolveStyleForPlaceholder(nsStyleContext* aParentContext);
// Get a style context for a pseudo-element. aParentElement must be
// non-null. aPseudoID is the CSSPseudoElementType for the
// pseudo-element. aPseudoElement must be non-null if the pseudo-element
// type is one that allows user action pseudo-classes after it or allows
// style attributes; otherwise, it is ignored.
already_AddRefed<nsStyleContext>
ResolvePseudoElementStyle(mozilla::dom::Element* aParentElement,
--- a/layout/xul/tree/nsTreeStyleCache.cpp
+++ b/layout/xul/tree/nsTreeStyleCache.cpp
@@ -78,17 +78,17 @@ nsTreeStyleCache::GetStyleContext(nsICSS
}
if (!result) {
// We missed the cache. Resolve this pseudo-style.
// XXXheycam ServoStyleSets do not support XUL tree styles.
RefPtr<nsStyleContext> newResult;
if (aPresContext->StyleSet()->IsServo()) {
NS_ERROR("stylo: ServoStyleSets should not support XUL tree styles yet");
newResult = aPresContext->StyleSet()->
- ResolveStyleForOtherNonElement(aContext);
+ ResolveStyleForPlaceholder(aContext);
} else {
newResult = aPresContext->StyleSet()->AsGecko()->
ResolveXULTreePseudoStyle(aContent->AsElement(), aPseudoElement,
aContext, aComparator);
}
// Put the style context in our table, transferring the owning reference to the table.
if (!mCache) {