--- a/layout/base/RestyleManager.cpp
+++ b/layout/base/RestyleManager.cpp
@@ -3113,17 +3113,17 @@ ElementRestyler::MoveStyleContextsForCon
type == nsGkAtoms::lineFrame) {
return false;
}
if (sc->HasChildThatUsesGrandancestorStyle()) {
// XXX Not sure if we need this?
return false;
}
nsIAtom* pseudoTag = sc->GetPseudo();
- if (pseudoTag && pseudoTag != nsCSSAnonBoxes::mozNonElement) {
+ if (pseudoTag && !nsCSSAnonBoxes::IsNonElement(pseudoTag)) {
return false;
}
aContextsToMove.AppendElement(sc);
}
}
return true;
}
@@ -3546,31 +3546,34 @@ ElementRestyler::ComputeRestyleResultFro
}
// We also ignore frames for pseudos, as their style contexts have
// inheritance structures that do not match the frame inheritance
// structure. To avoid enumerating and checking all of the cases
// 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;
return;
}
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::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
// return eRestyleResult_StopWithStyleChange.
//
// If we had later conditions to check in this function, we would
// continue to check them, in case we set aCanStopWithStyleChange to
// false.
@@ -3917,21 +3920,20 @@ ElementRestyler::RestyleSelf(nsIFrame* a
(prevContinuationContext = prevContinuation->StyleContext())
->GetPseudo() == oldContext->GetPseudo() &&
prevContinuationContext->GetParent() == parentContext;
if (copyFromContinuation) {
// Just use the style context from the frame's previous
// 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);
if (!MustRestyleSelf(aRestyleHint, element)) {
if (CanReparentStyleContext(aRestyleHint)) {
LOG_RESTYLE("reparenting style context");
newContext =
styleSet->ReparentStyleContext(oldContext, parentContext, element);
@@ -4266,17 +4268,17 @@ ElementRestyler::RestyleSelf(nsIFrame* a
++contextIndex) {
LOG_RESTYLE("extra context %d", contextIndex);
LOG_RESTYLE_INDENT();
RefPtr<nsStyleContext> newExtraContext;
nsIAtom* const extraPseudoTag = oldExtraContext->GetPseudo();
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;
if (!MustRestyleSelf(aRestyleHint, element)) {
if (CanReparentStyleContext(aRestyleHint)) {
newExtraContext =
styleSet->ReparentStyleContext(oldExtraContext, newContext, element);
} else {
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -2996,17 +2996,17 @@ nsCSSFrameConstructor::CreatePlaceholder
nsIContent* aContent,
nsIFrame* aFrame,
nsStyleContext* aParentStyle,
nsContainerFrame* aParentFrame,
nsIFrame* aPrevInFlow,
nsFrameState aTypeBit)
{
RefPtr<nsStyleContext> placeholderStyle = aPresShell->StyleSet()->
- ResolveStyleForNonElement(aParentStyle);
+ ResolveStyleForNonElement(aParentStyle, nsCSSAnonBoxes::mozOtherNonElement);
// The placeholder frame gets a pseudo style context
nsPlaceholderFrame* placeholderFrame =
(nsPlaceholderFrame*)NS_NewPlaceholderFrame(aPresShell, placeholderStyle,
aTypeBit);
placeholderFrame->Init(aContent, aParentFrame, aPrevInFlow);
@@ -4955,17 +4955,18 @@ nsCSSFrameConstructor::ResolveStyleConte
} else {
result = styleSet->ResolveStyleFor(aContent->AsElement(),
aParentStyleContext);
}
} else {
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
// it probably won't need to track reframed style contexts to start
// transitions correctly.
if (mozilla::RestyleManager* geckoRM = RestyleManager()->GetAsGecko()) {
RestyleManager::ReframingStyleContexts* rsc =
geckoRM->GetReframingStyleContexts();
@@ -11098,19 +11099,19 @@ nsCSSFrameConstructor::CreateFloatingLet
nsContainerFrame* containingBlock = aState.GetGeometricParent(
aStyleContext->StyleDisplay(), aParentFrame);
InitAndRestoreFrame(aState, letterContent, containingBlock, letterFrame);
// Init the text frame to refer to the letter frame. Make sure we
// 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);
// And then give the text frame to the letter frame
SetInitialSingleChild(letterFrame, aTextFrame);
// See if we will need to continue the text frame (does it contain
// more than just the first-letter text or not?) If it does, then we
@@ -11118,18 +11119,18 @@ nsCSSFrameConstructor::CreateFloatingLet
nsIFrame* nextTextFrame = nullptr;
if (NeedFirstLetterContinuation(aTextContent)) {
// Create continuation
nextTextFrame =
CreateContinuingFrame(aState.mPresContext, aTextFrame, aParentFrame);
// 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);
}
}
NS_ASSERTION(aResult.IsEmpty(), "aResult should be an empty nsFrameItems!");
// Put the new float before any of the floats in the block we're doing
// first-letter for, that is, before any floats whose parent is
// containingBlock.
@@ -11172,18 +11173,18 @@ nsCSSFrameConstructor::CreateLetterFrame
// Use content from containing block so that we can actually
// find a matching style rule.
nsIContent* blockContent = aBlockFrame->GetContent();
// Create first-letter style rule
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
// later. Start off by unsetting the primary frame for
// aTextContent, so it's no longer pointing to the to-be-destroyed
// frame.
// XXXbz it would be really nice to destroy the old frame _first_,
// then create the new one, so we could avoid this hack.
@@ -11371,18 +11372,18 @@ nsCSSFrameConstructor::RemoveFloatingFir
// Create a new text frame with the right style context that maps
// all of the content that was previously part of the letter frame
// (and probably continued elsewhere).
nsStyleContext* parentSC = parentFrame->StyleContext();
nsIContent* textContent = textFrame->GetContent();
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);
// Destroy the old text frame's continuations (the old text frame
// will be destroyed when its letter frame is destroyed).
nsIFrame* frameToDelete = textFrame->LastContinuation();
while (frameToDelete != textFrame) {
nsIFrame* nextFrameToDelete = frameToDelete->GetPrevContinuation();
@@ -11444,18 +11445,18 @@ nsCSSFrameConstructor::RemoveFirstLetter
nsStyleContext* parentSC = aFrame->StyleContext();
if (!parentSC) {
break;
}
nsIContent* textContent = textFrame->GetContent();
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);
// Next rip out the kid and replace it with the text frame
RemoveFrame(kPrincipalList, kid);
// Now that the old frames are gone, we can start pointing to our
// new primary frame.
--- a/layout/forms/nsComboboxControlFrame.cpp
+++ b/layout/forms/nsComboboxControlFrame.cpp
@@ -1367,17 +1367,18 @@ nsComboboxControlFrame::CreateFrameFor(n
// create the style contexts for the anonymous block frame and text frame
RefPtr<nsStyleContext> styleContext;
styleContext = styleSet->
ResolveAnonymousBoxStyle(nsCSSAnonBoxes::mozDisplayComboboxControlFrame,
mStyleContext,
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);
mDisplayFrame->Init(mContent, this, nullptr);
// Create a text frame and put it inside the block frame
nsIFrame* textFrame = NS_NewTextFrame(shell, textStyleContext);
--- a/layout/forms/nsGfxButtonControlFrame.cpp
+++ b/layout/forms/nsGfxButtonControlFrame.cpp
@@ -86,17 +86,17 @@ nsGfxButtonControlFrame::CreateFrameFor(
nsIFrame * newFrame = nullptr;
if (aContent == mTextContent) {
nsContainerFrame* parentFrame = do_QueryFrame(mFrames.FirstChild());
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
newFrame->Init(mTextContent, parentFrame, nullptr);
mTextContent->SetPrimaryFrame(newFrame);
}
return newFrame;
--- a/layout/generic/nsFirstLetterFrame.cpp
+++ b/layout/generic/nsFirstLetterFrame.cpp
@@ -65,17 +65,18 @@ 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()->
- ResolveStyleForNonElement(parentStyleContext);
+ ResolveStyleForNonElement(parentStyleContext,
+ nsCSSAnonBoxes::mozOtherNonElement);
SetStyleContextWithoutNotification(newSC);
}
}
nsContainerFrame::Init(aContent, aParent, aPrevInFlow);
}
void
@@ -326,17 +327,18 @@ 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()->ResolveStyleForNonElement(parentSC);
+ newSC = presShell->StyleSet()->
+ ResolveStyleForNonElement(parentSC, nsCSSAnonBoxes::mozOtherNonElement);
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.
@@ -380,17 +382,18 @@ nsFirstLetterFrame::DrainOverflowFrames(
if (kid) {
RefPtr<nsStyleContext> sc;
nsIContent* kidContent = kid->GetContent();
if (kidContent) {
NS_ASSERTION(kidContent->IsNodeOfType(nsINode::eTEXT),
"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);
}
}
}
nscoord
nsFirstLetterFrame::GetLogicalBaseline(WritingMode aWritingMode) const
--- a/layout/generic/nsFlexContainerFrame.cpp
+++ b/layout/generic/nsFlexContainerFrame.cpp
@@ -990,17 +990,17 @@ static nsIFrame*
GetFirstNonAnonBoxDescendant(nsIFrame* aFrame)
{
while (aFrame) {
nsIAtom* pseudoTag = aFrame->StyleContext()->GetPseudo();
// 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;
}
// Otherwise, descend to its first child and repeat.
// SPECIAL CASE: if we're dealing with an anonymous table, then it might
// be wrapping something non-anonymous in its caption or col-group lists
// (instead of its principal child list), so we have to look there.
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -8286,17 +8286,17 @@ GetCorrectedParent(const nsIFrame* aFram
nsIFrame*
nsFrame::CorrectStyleParentFrame(nsIFrame* aProspectiveParent,
nsIAtom* aChildPseudo)
{
NS_PRECONDITION(aProspectiveParent, "Must have a prospective parent");
// 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,
"Should have dealt with kids that have "
"NS_FRAME_PART_OF_IBSPLIT elsewhere");
return aProspectiveParent;
}
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -91,17 +91,18 @@ already_AddRefed<nsStyleContext>
ServoStyleSet::ResolveStyleFor(Element* aElement,
nsStyleContext* aParentContext,
TreeMatchContext& aTreeMatchContext)
{
MOZ_CRASH("stylo: not implemented");
}
already_AddRefed<nsStyleContext>
-ServoStyleSet::ResolveStyleForNonElement(nsStyleContext* aParentContext)
+ServoStyleSet::ResolveStyleForNonElement(nsStyleContext* aParentContext,
+ nsIAtom* aPseudoTag)
{
MOZ_CRASH("stylo: not implemented");
}
already_AddRefed<nsStyleContext>
ServoStyleSet::ResolvePseudoElementStyle(Element* aParentElement,
CSSPseudoElementType aType,
nsStyleContext* aParentContext,
--- a/layout/style/ServoStyleSet.h
+++ b/layout/style/ServoStyleSet.h
@@ -58,17 +58,18 @@ public:
nsStyleContext* aParentContext);
already_AddRefed<nsStyleContext>
ResolveStyleFor(dom::Element* aElement,
nsStyleContext* aParentContext,
TreeMatchContext& aTreeMatchContext);
already_AddRefed<nsStyleContext>
- ResolveStyleForNonElement(nsStyleContext* aParentContext);
+ ResolveStyleForNonElement(nsStyleContext* aParentContext,
+ nsIAtom* aPseudoTag);
already_AddRefed<nsStyleContext>
ResolvePseudoElementStyle(dom::Element* aParentElement,
mozilla::CSSPseudoElementType aType,
nsStyleContext* aParentContext,
dom::Element* aPseudoElement);
// aFlags is an nsStyleSet flags bitfield
--- a/layout/style/StyleSetHandle.h
+++ b/layout/style/StyleSetHandle.h
@@ -114,17 +114,18 @@ public:
inline already_AddRefed<nsStyleContext>
ResolveStyleFor(dom::Element* aElement,
nsStyleContext* aParentContext);
inline already_AddRefed<nsStyleContext>
ResolveStyleFor(dom::Element* aElement,
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,
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
@@ -89,19 +89,20 @@ already_AddRefed<nsStyleContext>
StyleSetHandle::Ptr::ResolveStyleFor(dom::Element* aElement,
nsStyleContext* aParentContext,
TreeMatchContext& aTreeMatchContext)
{
FORWARD(ResolveStyleFor, (aElement, aParentContext, aTreeMatchContext));
}
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>
StyleSetHandle::Ptr::ResolvePseudoElementStyle(dom::Element* aParentElement,
CSSPseudoElementType aType,
nsStyleContext* aParentContext,
dom::Element* aPseudoElement)
{
--- a/layout/style/nsCSSAnonBoxList.h
+++ b/layout/style/nsCSSAnonBoxList.h
@@ -14,17 +14,23 @@
* 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
-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")
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
@@ -18,15 +18,17 @@ class nsCSSAnonBoxes {
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; }
#define CSS_ANON_BOX(_name, _value) static nsICSSAnonBoxPseudo* _name;
#include "nsCSSAnonBoxList.h"
#undef CSS_ANON_BOX
};
#endif /* nsCSSAnonBoxes_h___ */
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -30,16 +30,17 @@
#include "nsStyleConsts.h"
#include "nsNetUtil.h"
#include "nsCOMPtr.h"
#include "nsString.h"
#include "nsIAtom.h"
#include "nsColor.h"
#include "nsCSSPseudoClasses.h"
#include "nsCSSPseudoElements.h"
+#include "nsCSSAnonBoxes.h"
#include "nsNameSpaceManager.h"
#include "nsXMLNameSpaceMap.h"
#include "nsError.h"
#include "nsIMediaList.h"
#include "nsStyleUtil.h"
#include "nsIPrincipal.h"
#include "nsICSSUnprefixingService.h"
#include "mozilla/Snprintf.h"
@@ -5922,16 +5923,23 @@ CSSParserImpl::ParsePseudoSelector(int32
(pseudoClassType != nsCSSPseudoClasses::ePseudoClass_NotPseudoClass &&
nsCSSPseudoClasses::PseudoClassIsUASheetAndChromeOnly(pseudoClassType))))) {
// This pseudo-element or pseudo-class is not exposed to content.
REPORT_UNEXPECTED_TOKEN(PEPseudoSelUnknown);
UngetToken();
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 &&
pseudoClassType == nsCSSPseudoClasses::ePseudoClass_mozPlaceholder) {
if (parsingPseudoElement) {
pseudoClassType = nsCSSPseudoClasses::ePseudoClass_NotPseudoClass;
} else {
pseudoElementType = CSSPseudoElementType::NotPseudo;
--- a/layout/style/nsStyleContext.cpp
+++ b/layout/style/nsStyleContext.cpp
@@ -570,17 +570,17 @@ ShouldSuppressLineBreak(const nsStyleCon
return false;
}
// Display value of any anonymous box should not be touched. In most
// cases, anonymous boxes are actually not in ruby frame, but instead,
// some other frame with a ruby display value. Non-element pseudos
// 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;
}
if (aParentContext->ShouldSuppressLineBreak()) {
// Line break suppressing bit is propagated to any children of
// line participants, which include inline, contents, and inline
// ruby boxes.
if (aParentDisplay->mDisplay == NS_STYLE_DISPLAY_INLINE ||
@@ -739,17 +739,17 @@ nsStyleContext::ApplyStyleFixups(bool aS
while (containerDisp->mDisplay == NS_STYLE_DISPLAY_CONTENTS) {
if (!containerContext->GetParent()) {
break;
}
containerContext = containerContext->GetParent();
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
// positioned, we'll have already been through a call to
// EnsureBlockDisplay() in nsRuleNode, so this call here won't change
// anything. So we're OK.
uint8_t displayVal = disp->mDisplay;
nsRuleNode::EnsureBlockDisplay(displayVal);
@@ -810,17 +810,17 @@ nsStyleContext::ApplyStyleFixups(bool aS
* According to https://drafts.csswg.org/css-writing-modes-3/#block-flow:
*
* If a box has a different block flow direction than its containing block:
* * If the box has a specified display of inline, its display computes
* to inline-block. [CSS21]
* ...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) {
cbContext = cbContext->mParent;
}
MOZ_ASSERT(cbContext, "the root context can't have display:contents");
// We don't need the full mozilla::WritingMode value (incorporating dir
// and text-orientation) here; just the writing-mode property is enough.
--- a/layout/style/nsStyleSet.cpp
+++ b/layout/style/nsStyleSet.cpp
@@ -1776,22 +1776,22 @@ nsStyleSet::ResolveStyleWithoutAnimation
eSkipStartingAnimations);
restyleManager->SetSkipAnimationRules(oldSkipAnimationRules);
return result.forget();
}
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
nsStyleSet::WalkRestrictionRule(CSSPseudoElementType aPseudoType,
nsRuleWalker* aRuleWalker)
{
// This needs to match GetPseudoRestriction in nsRuleNode.cpp.
aRuleWalker->SetLevel(SheetType::Agent, false, false);
--- a/layout/style/nsStyleSet.h
+++ b/layout/style/nsStyleSet.h
@@ -161,21 +161,26 @@ class nsStyleSet final
ResolveStyleWithoutAnimation(mozilla::dom::Element* aElement,
nsStyleContext* aStyleContext,
nsRestyleHint aWhichToRemove);
// Get a style context for a non-element (which no rules will match),
// 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
// 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,