зеркало из https://github.com/mozilla/gecko-dev.git
Implement :-moz-empty-except-children-with-localname() pseudo-class. Bug
309067, r+sr=dbaron
This commit is contained in:
Родитель
1693ba2210
Коммит
46dc7e29ca
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче