Bug 1097499 part 3 - Add a separate anonbox for text nodes. r=heycam
MozReview-Commit-ID: 1GfoFEGhyka
This commit is contained in:
@@ -3118,7 +3118,7 @@ ElementRestyler::MoveStyleContextsForContentChildren(
|
||||
return false;
|
||||
}
|
||||
nsIAtom* pseudoTag = sc->GetPseudo();
|
||||
if (pseudoTag && pseudoTag != nsCSSAnonBoxes::mozNonElement) {
|
||||
if (pseudoTag && !nsCSSAnonBoxes::IsNonElement(pseudoTag)) {
|
||||
return false;
|
||||
}
|
||||
aContextsToMove.AppendElement(sc);
|
||||
@@ -3551,7 +3551,7 @@ ElementRestyler::ComputeRestyleResultFromFrame(nsIFrame* aSelf,
|
||||
// where we have this kind of inheritance, we keep restyling past
|
||||
// pseudos.
|
||||
nsIAtom* pseudoTag = oldContext->GetPseudo();
|
||||
if (pseudoTag && pseudoTag != nsCSSAnonBoxes::mozNonElement) {
|
||||
if (pseudoTag && !nsCSSAnonBoxes::IsNonElement(pseudoTag)) {
|
||||
LOG_RESTYLE_CONTINUE("the old style context is for a pseudo");
|
||||
aRestyleResult = eRestyleResult_Continue;
|
||||
aCanStopWithStyleChange = false;
|
||||
@@ -3565,7 +3565,10 @@ ElementRestyler::ComputeRestyleResultFromFrame(nsIFrame* aSelf,
|
||||
// be inheriting from a grandparent frame's style context (or a further
|
||||
// ancestor).
|
||||
nsIAtom* parentPseudoTag = parent->StyleContext()->GetPseudo();
|
||||
if (parentPseudoTag && parentPseudoTag != nsCSSAnonBoxes::mozNonElement) {
|
||||
if (parentPseudoTag &&
|
||||
parentPseudoTag != nsCSSAnonBoxes::mozOtherNonElement) {
|
||||
MOZ_ASSERT(parentPseudoTag != nsCSSAnonBoxes::mozText,
|
||||
"Style of text node should not be parent of anything");
|
||||
LOG_RESTYLE_CONTINUE("the old style context's parent is for a pseudo");
|
||||
aRestyleResult = eRestyleResult_Continue;
|
||||
// Parent style context pseudo-ness doesn't affect whether we can
|
||||
@@ -3922,11 +3925,10 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf,
|
||||
// continuation.
|
||||
LOG_RESTYLE("using previous continuation's context");
|
||||
newContext = prevContinuationContext;
|
||||
}
|
||||
else if (pseudoTag == nsCSSAnonBoxes::mozNonElement) {
|
||||
} else if (nsCSSAnonBoxes::IsNonElement(pseudoTag)) {
|
||||
NS_ASSERTION(aSelf->GetContent(),
|
||||
"non pseudo-element frame without content node");
|
||||
newContext = styleSet->ResolveStyleForNonElement(parentContext);
|
||||
newContext = styleSet->ResolveStyleForNonElement(parentContext, pseudoTag);
|
||||
}
|
||||
else {
|
||||
Element* element = ElementForStyleContext(mParentContent, aSelf, pseudoType);
|
||||
@@ -4271,7 +4273,7 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf,
|
||||
const CSSPseudoElementType extraPseudoType =
|
||||
oldExtraContext->GetPseudoType();
|
||||
NS_ASSERTION(extraPseudoTag &&
|
||||
extraPseudoTag != nsCSSAnonBoxes::mozNonElement,
|
||||
!nsCSSAnonBoxes::IsNonElement(extraPseudoTag),
|
||||
"extra style context is not pseudo element");
|
||||
Element* element = extraPseudoType != CSSPseudoElementType::AnonBox
|
||||
? mContent->AsElement() : nullptr;
|
||||
|
||||
@@ -3001,7 +3001,7 @@ nsCSSFrameConstructor::CreatePlaceholderFrameFor(nsIPresShell* aPresShell,
|
||||
nsFrameState aTypeBit)
|
||||
{
|
||||
RefPtr<nsStyleContext> placeholderStyle = aPresShell->StyleSet()->
|
||||
ResolveStyleForNonElement(aParentStyle);
|
||||
ResolveStyleForNonElement(aParentStyle, nsCSSAnonBoxes::mozOtherNonElement);
|
||||
|
||||
// The placeholder frame gets a pseudo style context
|
||||
nsPlaceholderFrame* placeholderFrame =
|
||||
@@ -4960,7 +4960,8 @@ nsCSSFrameConstructor::ResolveStyleContext(nsStyleContext* aParentStyleContext,
|
||||
NS_ASSERTION(aContent->IsNodeOfType(nsINode::eTEXT),
|
||||
"shouldn't waste time creating style contexts for "
|
||||
"comments and processing instructions");
|
||||
result = styleSet->ResolveStyleForNonElement(aParentStyleContext);
|
||||
result = styleSet->ResolveStyleForNonElement(aParentStyleContext,
|
||||
nsCSSAnonBoxes::mozText);
|
||||
}
|
||||
|
||||
// ServoRestyleManager does not handle transitions yet, and when it does
|
||||
@@ -11103,9 +11104,9 @@ nsCSSFrameConstructor::CreateFloatingLetterFrame(
|
||||
// get a proper style context for it (the one passed in is for the
|
||||
// letter frame and will have the float property set on it; the text
|
||||
// frame shouldn't have that set).
|
||||
RefPtr<nsStyleContext> textSC;
|
||||
StyleSetHandle styleSet = mPresShell->StyleSet();
|
||||
textSC = styleSet->ResolveStyleForNonElement(aStyleContext);
|
||||
RefPtr<nsStyleContext> textSC = styleSet->
|
||||
ResolveStyleForNonElement(aStyleContext, nsCSSAnonBoxes::mozText);
|
||||
aTextFrame->SetStyleContextWithoutNotification(textSC);
|
||||
InitAndRestoreFrame(aState, aTextContent, letterFrame, aTextFrame);
|
||||
|
||||
@@ -11123,8 +11124,8 @@ nsCSSFrameConstructor::CreateFloatingLetterFrame(
|
||||
// Repair the continuations style context
|
||||
nsStyleContext* parentStyleContext = aStyleContext->GetParent();
|
||||
if (parentStyleContext) {
|
||||
RefPtr<nsStyleContext> newSC;
|
||||
newSC = styleSet->ResolveStyleForNonElement(parentStyleContext);
|
||||
RefPtr<nsStyleContext> newSC = styleSet->
|
||||
ResolveStyleForNonElement(parentStyleContext, nsCSSAnonBoxes::mozText);
|
||||
nextTextFrame->SetStyleContext(newSC);
|
||||
}
|
||||
}
|
||||
@@ -11177,8 +11178,8 @@ nsCSSFrameConstructor::CreateLetterFrame(nsContainerFrame* aBlockFrame,
|
||||
RefPtr<nsStyleContext> sc = GetFirstLetterStyle(blockContent,
|
||||
parentStyleContext);
|
||||
if (sc) {
|
||||
RefPtr<nsStyleContext> textSC;
|
||||
textSC = mPresShell->StyleSet()->ResolveStyleForNonElement(sc);
|
||||
RefPtr<nsStyleContext> textSC = mPresShell->StyleSet()->
|
||||
ResolveStyleForNonElement(sc, nsCSSAnonBoxes::mozText);
|
||||
|
||||
// Create a new text frame (the original one will be discarded)
|
||||
// pass a temporary stylecontext, the correct one will be set
|
||||
@@ -11376,8 +11377,8 @@ nsCSSFrameConstructor::RemoveFloatingFirstLetterFrames(
|
||||
if (!textContent) {
|
||||
return NS_OK;
|
||||
}
|
||||
RefPtr<nsStyleContext> newSC;
|
||||
newSC = aPresShell->StyleSet()->ResolveStyleForNonElement(parentSC);
|
||||
RefPtr<nsStyleContext> newSC = aPresShell->StyleSet()->
|
||||
ResolveStyleForNonElement(parentSC, nsCSSAnonBoxes::mozText);
|
||||
nsIFrame* newTextFrame = NS_NewTextFrame(aPresShell, newSC);
|
||||
newTextFrame->Init(textContent, parentFrame, nullptr);
|
||||
|
||||
@@ -11449,8 +11450,8 @@ nsCSSFrameConstructor::RemoveFirstLetterFrames(nsIPresShell* aPresShell,
|
||||
if (!textContent) {
|
||||
break;
|
||||
}
|
||||
RefPtr<nsStyleContext> newSC;
|
||||
newSC = aPresShell->StyleSet()->ResolveStyleForNonElement(parentSC);
|
||||
RefPtr<nsStyleContext> newSC = aPresShell->StyleSet()->
|
||||
ResolveStyleForNonElement(parentSC, nsCSSAnonBoxes::mozText);
|
||||
textFrame = NS_NewTextFrame(aPresShell, newSC);
|
||||
textFrame->Init(textContent, aFrame, nullptr);
|
||||
|
||||
|
||||
@@ -1372,7 +1372,8 @@ nsComboboxControlFrame::CreateFrameFor(nsIContent* aContent)
|
||||
nsStyleSet::eSkipParentDisplayBasedStyleFixup);
|
||||
|
||||
RefPtr<nsStyleContext> textStyleContext;
|
||||
textStyleContext = styleSet->ResolveStyleForNonElement(mStyleContext);
|
||||
textStyleContext = styleSet->
|
||||
ResolveStyleForNonElement(mStyleContext, nsCSSAnonBoxes::mozText);
|
||||
|
||||
// Start by creating our anonymous block frame
|
||||
mDisplayFrame = new (shell) nsComboboxDisplayFrame(styleContext, this);
|
||||
|
||||
@@ -91,7 +91,7 @@ nsGfxButtonControlFrame::CreateFrameFor(nsIContent* aContent)
|
||||
nsPresContext* presContext = PresContext();
|
||||
RefPtr<nsStyleContext> textStyleContext;
|
||||
textStyleContext = presContext->StyleSet()->
|
||||
ResolveStyleForNonElement(mStyleContext);
|
||||
ResolveStyleForNonElement(mStyleContext, nsCSSAnonBoxes::mozText);
|
||||
|
||||
newFrame = NS_NewTextFrame(presContext->PresShell(), textStyleContext);
|
||||
// initialize the text frame
|
||||
|
||||
@@ -70,7 +70,8 @@ nsFirstLetterFrame::Init(nsIContent* aContent,
|
||||
nsStyleContext* parentStyleContext = mStyleContext->GetParent();
|
||||
if (parentStyleContext) {
|
||||
newSC = PresContext()->StyleSet()->
|
||||
ResolveStyleForNonElement(parentStyleContext);
|
||||
ResolveStyleForNonElement(parentStyleContext,
|
||||
nsCSSAnonBoxes::mozOtherNonElement);
|
||||
SetStyleContextWithoutNotification(newSC);
|
||||
}
|
||||
}
|
||||
@@ -331,7 +332,8 @@ nsFirstLetterFrame::CreateContinuationForFloatingParent(nsPresContext* aPresCont
|
||||
nsStyleContext* parentSC = this->StyleContext()->GetParent();
|
||||
if (parentSC) {
|
||||
RefPtr<nsStyleContext> newSC;
|
||||
newSC = presShell->StyleSet()->ResolveStyleForNonElement(parentSC);
|
||||
newSC = presShell->StyleSet()->
|
||||
ResolveStyleForNonElement(parentSC, nsCSSAnonBoxes::mozOtherNonElement);
|
||||
continuation->SetStyleContext(newSC);
|
||||
nsLayoutUtils::MarkDescendantsDirty(continuation);
|
||||
}
|
||||
@@ -385,7 +387,8 @@ nsFirstLetterFrame::DrainOverflowFrames(nsPresContext* aPresContext)
|
||||
"should contain only text nodes");
|
||||
nsStyleContext* parentSC = prevInFlow ? mStyleContext->GetParent() :
|
||||
mStyleContext;
|
||||
sc = aPresContext->StyleSet()->ResolveStyleForNonElement(parentSC);
|
||||
sc = aPresContext->StyleSet()->
|
||||
ResolveStyleForNonElement(parentSC, nsCSSAnonBoxes::mozText);
|
||||
kid->SetStyleContext(sc);
|
||||
nsLayoutUtils::MarkDescendantsDirty(kid);
|
||||
}
|
||||
|
||||
@@ -1004,7 +1004,7 @@ GetFirstNonAnonBoxDescendant(nsIFrame* aFrame)
|
||||
// If aFrame isn't an anonymous container, then it'll do.
|
||||
if (!pseudoTag || // No pseudotag.
|
||||
!nsCSSAnonBoxes::IsAnonBox(pseudoTag) || // Pseudotag isn't anon.
|
||||
pseudoTag == nsCSSAnonBoxes::mozNonElement) { // Text, not a container.
|
||||
nsCSSAnonBoxes::IsNonElement(pseudoTag)) { // Text, not a container.
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -8330,7 +8330,7 @@ nsFrame::CorrectStyleParentFrame(nsIFrame* aProspectiveParent,
|
||||
|
||||
// Anon boxes are parented to their actual parent already, except
|
||||
// for non-elements. Those should not be treated as an anon box.
|
||||
if (aChildPseudo && aChildPseudo != nsCSSAnonBoxes::mozNonElement &&
|
||||
if (aChildPseudo && !nsCSSAnonBoxes::IsNonElement(aChildPseudo) &&
|
||||
nsCSSAnonBoxes::IsAnonBox(aChildPseudo)) {
|
||||
NS_ASSERTION(aChildPseudo != nsCSSAnonBoxes::mozAnonymousBlock &&
|
||||
aChildPseudo != nsCSSAnonBoxes::mozAnonymousPositionedBlock,
|
||||
|
||||
@@ -96,7 +96,8 @@ ServoStyleSet::ResolveStyleFor(Element* aElement,
|
||||
}
|
||||
|
||||
already_AddRefed<nsStyleContext>
|
||||
ServoStyleSet::ResolveStyleForNonElement(nsStyleContext* aParentContext)
|
||||
ServoStyleSet::ResolveStyleForNonElement(nsStyleContext* aParentContext,
|
||||
nsIAtom* aPseudoTag)
|
||||
{
|
||||
MOZ_CRASH("stylo: not implemented");
|
||||
}
|
||||
|
||||
@@ -63,7 +63,8 @@ public:
|
||||
TreeMatchContext& aTreeMatchContext);
|
||||
|
||||
already_AddRefed<nsStyleContext>
|
||||
ResolveStyleForNonElement(nsStyleContext* aParentContext);
|
||||
ResolveStyleForNonElement(nsStyleContext* aParentContext,
|
||||
nsIAtom* aPseudoTag);
|
||||
|
||||
already_AddRefed<nsStyleContext>
|
||||
ResolvePseudoElementStyle(dom::Element* aParentElement,
|
||||
|
||||
@@ -119,7 +119,8 @@ public:
|
||||
nsStyleContext* aParentContext,
|
||||
TreeMatchContext& aTreeMatchContext);
|
||||
inline already_AddRefed<nsStyleContext>
|
||||
ResolveStyleForNonElement(nsStyleContext* aParentContext);
|
||||
ResolveStyleForNonElement(nsStyleContext* aParentContext,
|
||||
nsIAtom* aPseudoTag);
|
||||
inline already_AddRefed<nsStyleContext>
|
||||
ResolvePseudoElementStyle(dom::Element* aParentElement,
|
||||
mozilla::CSSPseudoElementType aType,
|
||||
|
||||
@@ -94,9 +94,10 @@ StyleSetHandle::Ptr::ResolveStyleFor(dom::Element* aElement,
|
||||
}
|
||||
|
||||
already_AddRefed<nsStyleContext>
|
||||
StyleSetHandle::Ptr::ResolveStyleForNonElement(nsStyleContext* aParentContext)
|
||||
StyleSetHandle::Ptr::ResolveStyleForNonElement(nsStyleContext* aParentContext,
|
||||
nsIAtom* aPseudoTag)
|
||||
{
|
||||
FORWARD(ResolveStyleForNonElement, (aParentContext));
|
||||
FORWARD(ResolveStyleForNonElement, (aParentContext, aPseudoTag));
|
||||
}
|
||||
|
||||
already_AddRefed<nsStyleContext>
|
||||
|
||||
@@ -19,7 +19,13 @@
|
||||
// OUTPUT_CLASS=nsCSSAnonBoxes
|
||||
// MACRO_NAME=CSS_ANON_BOX
|
||||
|
||||
CSS_ANON_BOX(mozNonElement, ":-moz-non-element")
|
||||
// ::-moz-text and ::-moz-other-non-element 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")
|
||||
|
||||
CSS_ANON_BOX(mozAnonymousBlock, ":-moz-anonymous-block")
|
||||
CSS_ANON_BOX(mozAnonymousPositionedBlock, ":-moz-anonymous-positioned-block")
|
||||
|
||||
@@ -23,6 +23,8 @@ public:
|
||||
#ifdef MOZ_XUL
|
||||
static bool IsTreePseudoElement(nsIAtom* aPseudo);
|
||||
#endif
|
||||
static bool IsNonElement(nsIAtom* aPseudo)
|
||||
{ return aPseudo == mozText || aPseudo == mozOtherNonElement; }
|
||||
|
||||
#define CSS_ANON_BOX(_name, _value) static nsICSSAnonBoxPseudo* _name;
|
||||
#include "nsCSSAnonBoxList.h"
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "nsColor.h"
|
||||
#include "nsCSSPseudoClasses.h"
|
||||
#include "nsCSSPseudoElements.h"
|
||||
#include "nsCSSAnonBoxes.h"
|
||||
#include "nsNameSpaceManager.h"
|
||||
#include "nsXMLNameSpaceMap.h"
|
||||
#include "nsError.h"
|
||||
@@ -5927,6 +5928,13 @@ CSSParserImpl::ParsePseudoSelector(int32_t& aDataMask,
|
||||
return eSelectorParsingStatus_Error;
|
||||
}
|
||||
|
||||
if (nsCSSAnonBoxes::IsNonElement(pseudo)) {
|
||||
// Non-element anonymous boxes should not match any rule.
|
||||
REPORT_UNEXPECTED_TOKEN(PEPseudoSelUnknown);
|
||||
UngetToken();
|
||||
return eSelectorParsingStatus_Error;
|
||||
}
|
||||
|
||||
// We currently allow :-moz-placeholder and ::-moz-placeholder. We have to
|
||||
// be a bit stricter regarding the pseudo-element parsing rules.
|
||||
if (pseudoElementType == CSSPseudoElementType::mozPlaceholder &&
|
||||
|
||||
@@ -575,7 +575,7 @@ ShouldSuppressLineBreak(const nsStyleContext* aContext,
|
||||
// which represents text frames, as well as ruby pseudos are excluded
|
||||
// because we still want to set the flag for them.
|
||||
if (aContext->GetPseudoType() == CSSPseudoElementType::AnonBox &&
|
||||
aContext->GetPseudo() != nsCSSAnonBoxes::mozNonElement &&
|
||||
!nsCSSAnonBoxes::IsNonElement(aContext->GetPseudo()) &&
|
||||
!RubyUtils::IsRubyPseudo(aContext->GetPseudo())) {
|
||||
return false;
|
||||
}
|
||||
@@ -744,7 +744,7 @@ nsStyleContext::ApplyStyleFixups(bool aSkipParentDisplayBasedStyleFixup)
|
||||
containerDisp = containerContext->StyleDisplay();
|
||||
}
|
||||
if (ShouldBlockifyChildren(containerDisp) &&
|
||||
GetPseudo() != nsCSSAnonBoxes::mozNonElement) {
|
||||
!nsCSSAnonBoxes::IsNonElement(GetPseudo())) {
|
||||
// NOTE: Technically, we shouldn't modify the 'display' value of
|
||||
// positioned elements, since they aren't flex/grid items. However,
|
||||
// we don't need to worry about checking for that, because if we're
|
||||
@@ -815,7 +815,7 @@ nsStyleContext::ApplyStyleFixups(bool aSkipParentDisplayBasedStyleFixup)
|
||||
* ...etc.
|
||||
*/
|
||||
if (disp->mDisplay == NS_STYLE_DISPLAY_INLINE &&
|
||||
mPseudoTag != nsCSSAnonBoxes::mozNonElement &&
|
||||
!nsCSSAnonBoxes::IsNonElement(mPseudoTag) &&
|
||||
mParent) {
|
||||
auto cbContext = mParent;
|
||||
while (cbContext->StyleDisplay()->mDisplay == NS_STYLE_DISPLAY_CONTENTS) {
|
||||
|
||||
@@ -1781,12 +1781,12 @@ nsStyleSet::ResolveStyleWithoutAnimation(dom::Element* aTarget,
|
||||
}
|
||||
|
||||
already_AddRefed<nsStyleContext>
|
||||
nsStyleSet::ResolveStyleForNonElement(nsStyleContext* aParentContext)
|
||||
nsStyleSet::ResolveStyleForNonElement(nsStyleContext* aParentContext,
|
||||
nsIAtom* aPseudoTag)
|
||||
{
|
||||
return GetContext(aParentContext, mRuleTree, nullptr,
|
||||
nsCSSAnonBoxes::mozNonElement,
|
||||
CSSPseudoElementType::AnonBox, nullptr,
|
||||
eNoFlags);
|
||||
MOZ_ASSERT(nsCSSAnonBoxes::IsNonElement(aPseudoTag));
|
||||
return GetContext(aParentContext, mRuleTree, nullptr, aPseudoTag,
|
||||
CSSPseudoElementType::AnonBox, nullptr, eNoFlags);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -166,11 +166,16 @@ class nsStyleSet final
|
||||
// such as text nodes, placeholder frames, and the nsFirstLetterFrame
|
||||
// for everything after the first letter.
|
||||
//
|
||||
// Perhaps this 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.
|
||||
// aPseudoTag can be either mozText or mozOtherNonElement.
|
||||
//
|
||||
// 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.
|
||||
// When text-combine-upright is not present, we may also want to avoid
|
||||
// resolving style contexts for text frames as well.
|
||||
already_AddRefed<nsStyleContext>
|
||||
ResolveStyleForNonElement(nsStyleContext* aParentContext);
|
||||
ResolveStyleForNonElement(nsStyleContext* aParentContext,
|
||||
nsIAtom* aPseudoTag);
|
||||
|
||||
// Get a style context for a pseudo-element. aParentElement must be
|
||||
// non-null. aPseudoID is the CSSPseudoElementType for the
|
||||
|
||||
Reference in New Issue
Block a user