Implement :-moz-empty-except-children-with-localname() pseudo-class. Bug

309067, r+sr=dbaron
This commit is contained in:
bzbarsky%mit.edu 2005-10-16 15:57:13 +00:00
Родитель 1693ba2210
Коммит 46dc7e29ca
4 изменённых файлов: 38 добавлений и 16 удалений

Просмотреть файл

@ -95,10 +95,10 @@ PENegationEOF=selector within negation
PENegationBadInner=Malformed simple selector as negation pseudo-class argument '%1$S'.
PENegationNoClose=Missing closing ')' in negation pseudo-class '%1$S'.
PENegationBadArg=Missing argument in negation pseudo-class '%1$S'.
PELangArgEOF=argument to :lang selector
PELangArgNotIdent=Expected identifier for lang pseudo-class parameter but found '%1$S'.
PELangNoClose=Missing closing ')' in lang pseudo-class '%1$S'.
PELangNoArg=Missing argument in lang pseudo-class '%1$S'.
PEPseudoClassArgEOF=argument to pseudo-class selector
PEPseudoClassArgNotIdent=Expected identifier for pseudo-class parameter but found '%1$S'.
PEPseudoClassNoClose=Missing closing ')' in pseudo-class, found '%1$S' instead.
PEPseudoClassNoArg=Missing argument in pseudo-class '%1$S'.
PESelectorEOF=selector
PEBadDeclBlockStart=Expected '{' to begin declaration block but found '%1$S'.
PEColorEOF=color

Просмотреть файл

@ -254,8 +254,9 @@ protected:
nsresult& aErrorCode,
PRBool aIsNegated);
nsSelectorParsingStatus ParseLangSelector(nsCSSSelector& aSelector,
nsresult& aErrorCode);
nsSelectorParsingStatus ParsePseudoClassWithIdentArg(nsCSSSelector& aSelector,
nsIAtom* aPseudo,
nsresult& aErrorCode);
nsSelectorParsingStatus ParseNegatedSimpleSelector(PRInt32& aDataMask,
nsCSSSelector& aSelector,
@ -2445,7 +2446,9 @@ CSSParserImpl::ParsePseudoSelector(PRInt32& aDataMask,
isTree ||
#endif
nsCSSPseudoClasses::notPseudo == pseudo ||
nsCSSPseudoClasses::lang == pseudo)) { // There are no other function pseudos
nsCSSPseudoClasses::lang == pseudo ||
nsCSSPseudoClasses::mozEmptyExceptChildrenWithLocalname == pseudo)) {
// There are no other function pseudos
REPORT_UNEXPECTED_TOKEN(PEPseudoSelNonFunc);
UngetToken();
return eSelectorParsingStatus_Error;
@ -2475,8 +2478,10 @@ CSSParserImpl::ParsePseudoSelector(PRInt32& aDataMask,
}
else if (!parsingPseudoElement && isPseudoClass) {
aDataMask |= SEL_MASK_PCLASS;
if (nsCSSPseudoClasses::lang == pseudo) {
nsSelectorParsingStatus parsingStatus = ParseLangSelector(aSelector, aErrorCode);
if (nsCSSPseudoClasses::lang == pseudo ||
nsCSSPseudoClasses::mozEmptyExceptChildrenWithLocalname == pseudo) {
nsSelectorParsingStatus parsingStatus =
ParsePseudoClassWithIdentArg(aSelector, pseudo, aErrorCode);
if (eSelectorParsingStatus_Continue != parsingStatus) {
return parsingStatus;
}
@ -2628,34 +2633,36 @@ CSSParserImpl::ParseNegatedSimpleSelector(PRInt32& aDataMask,
}
//
// Parse the argument of a pseudo-class :lang()
// Parse the argument of a pseudo-class that has an ident arg
//
CSSParserImpl::nsSelectorParsingStatus
CSSParserImpl::ParseLangSelector(nsCSSSelector& aSelector, nsresult& aErrorCode)
CSSParserImpl::ParsePseudoClassWithIdentArg(nsCSSSelector& aSelector,
nsIAtom* aPseudo,
nsresult& aErrorCode)
{
// Check if we have the first parenthesis
if (!ExpectSymbol(aErrorCode, '(', PR_FALSE)) {
REPORT_UNEXPECTED_TOKEN(PELangNoArg);
REPORT_UNEXPECTED_TOKEN(PEPseudoClassNoArg);
return eSelectorParsingStatus_Error;
}
if (! GetToken(aErrorCode, PR_TRUE)) { // premature eof
REPORT_UNEXPECTED_EOF(PELangArgEOF);
REPORT_UNEXPECTED_EOF(PEPseudoClassArgEOF);
return eSelectorParsingStatus_Error;
}
// We expect an identifier with a language abbreviation
if (eCSSToken_Ident != mToken.mType) {
REPORT_UNEXPECTED_TOKEN(PELangArgNotIdent);
REPORT_UNEXPECTED_TOKEN(PEPseudoClassArgNotIdent);
UngetToken();
return eSelectorParsingStatus_Error;
}
// Add the pseudo with the language parameter
aSelector.AddPseudoClass(nsCSSPseudoClasses::lang, mToken.mIdent.get());
aSelector.AddPseudoClass(aPseudo, mToken.mIdent.get());
// close the parenthesis
if (!ExpectSymbol(aErrorCode, ')', PR_TRUE)) {
REPORT_UNEXPECTED_TOKEN(PELangNoClose);
REPORT_UNEXPECTED_TOKEN(PEPseudoClassNoClose);
return eSelectorParsingStatus_Error;
}

Просмотреть файл

@ -52,6 +52,7 @@
CSS_PSEUDO_CLASS(empty, ":empty")
CSS_PSEUDO_CLASS(mozOnlyWhitespace, ":-moz-only-whitespace")
CSS_PSEUDO_CLASS(mozEmptyExceptChildrenWithLocalname, ":-moz-empty-except-children-with-localname")
CSS_PSEUDO_CLASS(lang, ":lang")
CSS_PSEUDO_CLASS(notPseudo, ":not")
CSS_PSEUDO_CLASS(mozBoundElement, ":-moz-bound-element")

Просмотреть файл

@ -2958,6 +2958,20 @@ static PRBool SelectorMatches(RuleProcessorData &data,
} while (child && !IsSignificantChild(child, PR_TRUE, isWhitespaceSignificant));
result = localTrue == (child == nsnull);
}
else if (nsCSSPseudoClasses::mozEmptyExceptChildrenWithLocalname == pseudoClass->mAtom) {
NS_ASSERTION(pseudoClass->mString, "Must have string!");
nsIContent *child = nsnull;
nsIContent *element = data.mContent;
PRInt32 index = -1;
do {
child = element->GetChildAt(++index);
} while (child &&
(!IsSignificantChild(child, PR_TRUE, PR_FALSE) ||
(child->GetNameSpaceID() == element->GetNameSpaceID() &&
child->Tag()->Equals(nsDependentString(pseudoClass->mString)))));
result = localTrue == (child == nsnull);
}
else if (nsCSSPseudoClasses::root == pseudoClass->mAtom) {
if (data.mParentContent) {
result = localFalse;