mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-04-02 12:32:55 +00:00
Bug 525608 part 2. Change the CSS parser to not allow anon box selectors with more than the anon box name in them. Store the pseudo type in pseudo-element selectors. Enforce that all non-anon-box pseudo selectors have an mNext that selects the element they apply to. r=dbaron
This commit is contained in:
parent
c1d4ecaf51
commit
03a58e11a7
@ -137,3 +137,4 @@ PEMQNoMinMaxWithoutValue=Media features with min- or max- must have a value.
|
||||
PEMQExpectedFeatureValue=Found invalid value for media feature.
|
||||
PEBadFontBlockStart=Expected '{' to begin @font-face rule but found '%1$S'.
|
||||
PEBadFontBlockEnd=Expected '}' to end @font-face rule but found '%1$S'.
|
||||
PEAnonBoxNotAlone=Did not expect anonymous box.
|
@ -65,9 +65,6 @@ math[mode="display"], math[display="block"] {
|
||||
math[display="inline"] {
|
||||
display: inline;
|
||||
}
|
||||
::-moz-math-inline {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/* Style switching during frame construction depending on the context of <mi>:
|
||||
|
@ -165,8 +165,8 @@ nsMathMLFrame::ResolveMathMLCharStyle(nsPresContext* aPresContext,
|
||||
PRBool aIsMutableChar)
|
||||
{
|
||||
nsIAtom* pseudoStyle = (aIsMutableChar) ?
|
||||
nsCSSAnonBoxes::mozMathStretchy :
|
||||
nsCSSAnonBoxes::mozMathAnonymous; // savings
|
||||
nsCSSPseudoElements::mozMathStretchy :
|
||||
nsCSSPseudoElements::mozMathAnonymous; // savings
|
||||
nsRefPtr<nsStyleContext> newStyleContext;
|
||||
newStyleContext = aPresContext->StyleSet()->
|
||||
ResolvePseudoStyleFor(aContent, pseudoStyle, aParentStyleContext);
|
||||
|
@ -259,10 +259,6 @@ select:empty {
|
||||
-moz-box-sizing: border-box ! important;
|
||||
}
|
||||
|
||||
select::-moz-scrolled-content {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
option {
|
||||
display: block;
|
||||
float: none !important;
|
||||
|
@ -109,12 +109,6 @@ CSS_ANON_BOX(moztreeprogressmeter, ":-moz-tree-progressmeter")
|
||||
CSS_ANON_BOX(moztreedropfeedback, ":-moz-tree-drop-feedback")
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_MATHML
|
||||
CSS_ANON_BOX(mozMathStretchy, ":-moz-math-stretchy")
|
||||
CSS_ANON_BOX(mozMathAnonymous, ":-moz-math-anonymous")
|
||||
CSS_ANON_BOX(mozMathInline, ":-moz-math-inline")
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_SVG
|
||||
CSS_ANON_BOX(mozSVGForeignContent, ":-moz-svg-foreign-content")
|
||||
#endif
|
||||
|
@ -354,7 +354,8 @@ protected:
|
||||
nsCSSSelector& aSelector,
|
||||
PRBool aIsNegated,
|
||||
nsIAtom** aPseudoElement,
|
||||
nsPseudoClassList** aPseudoElementArgs);
|
||||
nsPseudoClassList** aPseudoElementArgs,
|
||||
nsCSSPseudoElements::Type* aPseudoElementType);
|
||||
|
||||
nsSelectorParsingStatus ParseAttributeSelector(PRInt32& aDataMask,
|
||||
nsCSSSelector& aSelector);
|
||||
@ -374,7 +375,8 @@ protected:
|
||||
|
||||
nsSelectorParsingStatus ParseSelector(nsCSSSelector& aSelectorResult,
|
||||
nsIAtom** aPseudoElement,
|
||||
nsPseudoClassList** aPseudoElementArgs);
|
||||
nsPseudoClassList** aPseudoElementArgs,
|
||||
nsCSSPseudoElements::Type* aPseudoElementType);
|
||||
|
||||
// If aTerminateAtBrace is true, the selector list is done when we
|
||||
// hit a '{'. Otherwise, it's done when we hit EOF.
|
||||
@ -2497,9 +2499,11 @@ CSSParserImpl::ParseSelectorGroup(nsCSSSelectorList*& aList)
|
||||
}
|
||||
nsCOMPtr<nsIAtom> pseudoElement;
|
||||
nsAutoPtr<nsPseudoClassList> pseudoElementArgs;
|
||||
nsCSSPseudoElements::Type pseudoElementType;
|
||||
nsSelectorParsingStatus parsingStatus =
|
||||
ParseSelector(*newSelector, getter_AddRefs(pseudoElement),
|
||||
getter_Transfers(pseudoElementArgs));
|
||||
getter_Transfers(pseudoElementArgs),
|
||||
&pseudoElementType);
|
||||
if (parsingStatus == eSelectorParsingStatus_Empty) {
|
||||
if (!list) {
|
||||
REPORT_UNEXPECTED(PESelectorGroupNoSelector);
|
||||
@ -2510,6 +2514,13 @@ CSSParserImpl::ParseSelectorGroup(nsCSSSelectorList*& aList)
|
||||
list = nsnull;
|
||||
break;
|
||||
}
|
||||
if (pseudoElement &&
|
||||
pseudoElementType == nsCSSPseudoElements::ePseudo_AnonBox &&
|
||||
(list || !IsUniversalSelector(*newSelector))) {
|
||||
REPORT_UNEXPECTED(PEAnonBoxNotAlone);
|
||||
list = nsnull;
|
||||
break;
|
||||
}
|
||||
if (nsnull == list) {
|
||||
list = new nsCSSSelectorList();
|
||||
if (nsnull == list) {
|
||||
@ -2517,16 +2528,16 @@ CSSParserImpl::ParseSelectorGroup(nsCSSSelectorList*& aList)
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
list->AddSelector(newSelector);
|
||||
nsCSSSelector* listSel = list->mSelectors;
|
||||
|
||||
// We got a pseudo-element (or anonymous box). We actually
|
||||
// represent pseudo-elements as a child of the rest of the selector.
|
||||
if (pseudoElement) {
|
||||
if (listSel->mNext || !IsUniversalSelector(*listSel)) {
|
||||
if (pseudoElementType != nsCSSPseudoElements::ePseudo_AnonBox) {
|
||||
// We need to put the pseudo-element on a new selector that's a
|
||||
// child of the current one. (If it's the only thing in the
|
||||
// entire selector group, we can just put it on this one.)
|
||||
// child of the current one.
|
||||
listSel->mOperator = PRUnichar('>');
|
||||
nsAutoPtr<nsCSSSelector> empty(new nsCSSSelector());
|
||||
if (!empty) {
|
||||
@ -2544,6 +2555,7 @@ CSSParserImpl::ParseSelectorGroup(nsCSSSelectorList*& aList)
|
||||
"already initialized");
|
||||
listSel->mLowercaseTag.swap(pseudoElement);
|
||||
listSel->mPseudoClassList = pseudoElementArgs.forget();
|
||||
listSel->SetPseudoType(pseudoElementType);
|
||||
havePseudoElement = PR_TRUE;
|
||||
}
|
||||
|
||||
@ -2991,7 +3003,8 @@ CSSParserImpl::ParsePseudoSelector(PRInt32& aDataMask,
|
||||
nsCSSSelector& aSelector,
|
||||
PRBool aIsNegated,
|
||||
nsIAtom** aPseudoElement,
|
||||
nsPseudoClassList** aPseudoElementArgs)
|
||||
nsPseudoClassList** aPseudoElementArgs,
|
||||
nsCSSPseudoElements::Type* aPseudoElementType)
|
||||
{
|
||||
NS_ASSERTION(aIsNegated || (aPseudoElement && aPseudoElementArgs),
|
||||
"expected location to store pseudo element");
|
||||
@ -3035,8 +3048,10 @@ CSSParserImpl::ParsePseudoSelector(PRInt32& aDataMask,
|
||||
|
||||
// stash away some info about this pseudo so we only have to get it once.
|
||||
PRBool isTreePseudo = PR_FALSE;
|
||||
nsCSSPseudoElements::Type pseudoElementType =
|
||||
nsCSSPseudoElements::GetPseudoType(pseudo);
|
||||
#ifdef MOZ_XUL
|
||||
isTreePseudo = nsCSSAnonBoxes::IsTreePseudoElement(pseudo);
|
||||
isTreePseudo = (pseudoElementType == nsCSSPseudoElements::ePseudo_XULTree);
|
||||
// If a tree pseudo-element is using the function syntax, it will
|
||||
// get isTree set here and will pass the check below that only
|
||||
// allows functions if they are in our list of things allowed to be
|
||||
@ -3046,13 +3061,21 @@ CSSParserImpl::ParsePseudoSelector(PRInt32& aDataMask,
|
||||
// desired.
|
||||
PRBool isTree = (eCSSToken_Function == mToken.mType) && isTreePseudo;
|
||||
#endif
|
||||
PRBool isPseudoElement = nsCSSPseudoElements::IsPseudoElement(pseudo);
|
||||
PRBool isPseudoElement =
|
||||
(pseudoElementType < nsCSSPseudoElements::ePseudo_PseudoElementCount);
|
||||
// anonymous boxes are only allowed if they're the tree boxes or we have
|
||||
// enabled unsafe rules
|
||||
PRBool isAnonBox = nsCSSAnonBoxes::IsAnonBox(pseudo) &&
|
||||
(mUnsafeRulesEnabled || isTreePseudo);
|
||||
PRBool isAnonBox = isTreePseudo ||
|
||||
(pseudoElementType == nsCSSPseudoElements::ePseudo_AnonBox &&
|
||||
mUnsafeRulesEnabled);
|
||||
PRBool isPseudoClass = nsCSSPseudoClasses::IsPseudoClass(pseudo);
|
||||
|
||||
NS_ASSERTION(!isPseudoClass ||
|
||||
pseudoElementType == nsCSSPseudoElements::ePseudo_NotPseudoElement,
|
||||
"Why is this atom both a pseudo-class and a pseudo-element?");
|
||||
NS_ASSERTION(isPseudoClass + isPseudoElement + isAnonBox <= 1,
|
||||
"Shouldn't be more than one of these");
|
||||
|
||||
if (!isPseudoClass && !isPseudoElement && !isAnonBox) {
|
||||
// Not a pseudo-class, not a pseudo-element.... forget it
|
||||
REPORT_UNEXPECTED_TOKEN(PEPseudoSelUnknown);
|
||||
@ -3144,6 +3167,7 @@ CSSParserImpl::ParsePseudoSelector(PRInt32& aDataMask,
|
||||
if (0 == (aDataMask & SEL_MASK_PELEM)) {
|
||||
aDataMask |= SEL_MASK_PELEM;
|
||||
NS_ADDREF(*aPseudoElement = pseudo);
|
||||
*aPseudoElementType = pseudoElementType;
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
if (isTree) {
|
||||
@ -3235,7 +3259,7 @@ CSSParserImpl::ParseNegatedSimpleSelector(PRInt32& aDataMask,
|
||||
}
|
||||
else if (mToken.IsSymbol(':')) { // :pseudo
|
||||
parsingStatus = ParsePseudoSelector(aDataMask, *newSel, PR_TRUE,
|
||||
nsnull, nsnull);
|
||||
nsnull, nsnull, nsnull);
|
||||
}
|
||||
else if (mToken.IsSymbol('[')) { // [attribute
|
||||
parsingStatus = ParseAttributeSelector(aDataMask, *newSel);
|
||||
@ -3445,7 +3469,8 @@ CSSParserImpl::ParsePseudoClassWithNthPairArg(nsCSSSelector& aSelector,
|
||||
CSSParserImpl::nsSelectorParsingStatus
|
||||
CSSParserImpl::ParseSelector(nsCSSSelector& aSelector,
|
||||
nsIAtom** aPseudoElement,
|
||||
nsPseudoClassList** aPseudoElementArgs)
|
||||
nsPseudoClassList** aPseudoElementArgs,
|
||||
nsCSSPseudoElements::Type* aPseudoElementType)
|
||||
{
|
||||
if (! GetToken(PR_TRUE)) {
|
||||
REPORT_UNEXPECTED_EOF(PESelectorEOF);
|
||||
@ -3468,7 +3493,8 @@ CSSParserImpl::ParseSelector(nsCSSSelector& aSelector,
|
||||
}
|
||||
else if (mToken.IsSymbol(':')) { // :pseudo
|
||||
parsingStatus = ParsePseudoSelector(dataMask, aSelector, PR_FALSE,
|
||||
aPseudoElement, aPseudoElementArgs);
|
||||
aPseudoElement, aPseudoElementArgs,
|
||||
aPseudoElementType);
|
||||
}
|
||||
else if (mToken.IsSymbol('[')) { // [attribute
|
||||
parsingStatus = ParseAttributeSelector(dataMask, aSelector);
|
||||
|
@ -81,3 +81,8 @@ CSS_PSEUDO_ELEMENT(mozFocusOuter, ":-moz-focus-outer", 0)
|
||||
CSS_PSEUDO_ELEMENT(mozListBullet, ":-moz-list-bullet", 0)
|
||||
CSS_PSEUDO_ELEMENT(mozListNumber, ":-moz-list-number", 0)
|
||||
|
||||
#ifdef MOZ_MATHML
|
||||
CSS_PSEUDO_ELEMENT(mozMathStretchy, ":-moz-math-stretchy", 0)
|
||||
CSS_PSEUDO_ELEMENT(mozMathAnonymous, ":-moz-math-anonymous", 0)
|
||||
#endif
|
||||
|
||||
|
@ -82,6 +82,8 @@
|
||||
#include "nsContentErrors.h"
|
||||
#include "mozAutoDocUpdate.h"
|
||||
|
||||
#include "prlog.h"
|
||||
|
||||
#define NS_IF_CLONE(member_) \
|
||||
PR_BEGIN_MACRO \
|
||||
if (member_) { \
|
||||
@ -280,9 +282,12 @@ nsCSSSelector::nsCSSSelector(void)
|
||||
mNegations(nsnull),
|
||||
mNext(nsnull),
|
||||
mNameSpace(kNameSpaceID_Unknown),
|
||||
mOperator(0)
|
||||
mOperator(0),
|
||||
mPseudoType(nsCSSPseudoElements::ePseudo_NotPseudoElement)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsCSSSelector);
|
||||
// Make sure mPseudoType can hold all nsCSSPseudoElements::Type values
|
||||
PR_STATIC_ASSERT(nsCSSPseudoElements::ePseudo_MAX < PR_INT16_MAX);
|
||||
}
|
||||
|
||||
nsCSSSelector*
|
||||
@ -296,6 +301,7 @@ nsCSSSelector::Clone(PRBool aDeepNext, PRBool aDeepNegations) const
|
||||
result->mLowercaseTag = mLowercaseTag;
|
||||
result->mCasedTag = mCasedTag;
|
||||
result->mOperator = mOperator;
|
||||
result->mPseudoType = mPseudoType;
|
||||
|
||||
NS_IF_CLONE(mIDList);
|
||||
NS_IF_CLONE(mClassList);
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include "nsCSSProps.h"
|
||||
#include "nsCSSValue.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsCSSPseudoElements.h"
|
||||
|
||||
class nsIAtom;
|
||||
class nsCSSDeclaration;
|
||||
@ -199,6 +200,15 @@ private:
|
||||
PRInt32 CalcWeightWithoutNegations() const;
|
||||
|
||||
public:
|
||||
// Get and set the selector's pseudo type
|
||||
nsCSSPseudoElements::Type PseudoType() const {
|
||||
return static_cast<nsCSSPseudoElements::Type>(mPseudoType);
|
||||
}
|
||||
void SetPseudoType(nsCSSPseudoElements::Type aType) {
|
||||
NS_ASSERTION(aType > PR_INT16_MIN && aType < PR_INT16_MAX, "Out of bounds");
|
||||
mPseudoType = static_cast<PRInt16>(aType);
|
||||
}
|
||||
|
||||
// For case-sensitive documents, mLowercaseTag is the same as mCasedTag,
|
||||
// but in case-insensitive documents (HTML) mLowercaseTag is lowercase.
|
||||
// Also, for pseudo-elements mCasedTag will be null but mLowercaseTag
|
||||
@ -214,7 +224,9 @@ public:
|
||||
nsCSSSelector* mNext;
|
||||
PRInt32 mNameSpace;
|
||||
PRUnichar mOperator;
|
||||
private:
|
||||
private:
|
||||
// PRInt16 to make sure it packs well with mOperator
|
||||
PRInt16 mPseudoType;
|
||||
// These are not supported and are not implemented!
|
||||
nsCSSSelector(const nsCSSSelector& aCopy);
|
||||
nsCSSSelector& operator=(const nsCSSSelector& aCopy);
|
||||
|
Loading…
x
Reference in New Issue
Block a user