!nsCSSPseudoElements::IsCSS2PseudoElement(pseudo) && !IsTreePseudoElement(pseudo)) {
!nsCSSPseudoElements::IsCSS2PseudoElement(pseudo) #ifdef MOZ_XUL && !IsTreePseudoElement(pseudo) #endif ) {
void CSSParserImpl::ParsePseudoSelector(PRInt32&  aDataMask,                                      nsCSSSelector& aSelector,                                      PRInt32& aParsingStatus,                                      PRInt32& aErrorCode,                                      PRBool aIsNegated){  if (! GetToken(aErrorCode, PR_FALSE)) { // premature eof    REPORT_UNEXPECTED_EOF(NS_LITERAL_STRING("name of pseudo-class or pseudo-element"));    aParsingStatus = SELECTOR_PARSING_STOPPED_ERROR;    return;  }  // First, find out whether we are parsing a CSS3 pseudo-element  PRBool parsingPseudoElement = PR_FALSE;  if (mToken.IsSymbol(':')) {    parsingPseudoElement = PR_TRUE;    if (! GetToken(aErrorCode, PR_FALSE)) { // premature eof      REPORT_UNEXPECTED_EOF(NS_LITERAL_STRING("name of pseudo-class or pseudo-element"));      aParsingStatus = SELECTOR_PARSING_STOPPED_ERROR;      return;    }  }  // Do some sanity-checking on the token  if (eCSSToken_Ident != mToken.mType && eCSSToken_Function != mToken.mType) {    // malformed selector    REPORT_UNEXPECTED_TOKEN(NS_LITERAL_STRING("Expected identifier for pseudo-class or pseudo-element but found"));    UngetToken();    aParsingStatus = SELECTOR_PARSING_STOPPED_ERROR;    return;  }  // OK, now we know we have an mIdent.  Atomize it.  All the atoms, for  // pseudo-classes as well as pseudo-elements, start with a single ':'.  nsAutoString buffer;  buffer.Append(PRUnichar(':'));  buffer.Append(mToken.mIdent);  ToLowerCase(buffer);  nsCOMPtr<nsIAtom> pseudo = do_GetAtom(buffer);  // stash away some info about this pseudo so we only have to get it once.#ifdef MOZ_XUL  PRBool isTree = (eCSSToken_Function == mToken.mType) &&                  IsTreePseudoElement(pseudo);#endif  PRBool isPseudoElement = nsCSSPseudoElements::IsPseudoElement(pseudo);  PRBool isAnonBox = nsCSSAnonBoxes::IsAnonBox(pseudo);  // If it's a function token, it better be on our "ok" list  if (eCSSToken_Function == mToken.mType &&#ifdef MOZ_XUL      !isTree &&#endif      nsCSSPseudoClasses::notPseudo != pseudo &&      nsCSSPseudoClasses::lang != pseudo) { // There are no other function pseudos    REPORT_UNEXPECTED_TOKEN(NS_LITERAL_STRING("Expected identifier for function pseudo-class or pseudo-element but found"));    UngetToken();    aParsingStatus = SELECTOR_PARSING_STOPPED_ERROR;    return;  }    // If it starts with "::", it better be a pseudo-element  if (parsingPseudoElement &&      !isPseudoElement &&      !isAnonBox) {    REPORT_UNEXPECTED_TOKEN(NS_LITERAL_STRING("Expected pseudo-element but found"));    UngetToken();    aParsingStatus = SELECTOR_PARSING_STOPPED_ERROR;    return;  }  if (nsCSSPseudoClasses::notPseudo == pseudo) {    if (aIsNegated) { // :not() can't be itself negated      REPORT_UNEXPECTED_TOKEN(NS_LITERAL_STRING("Negation pseudo-class can't be negated"));      UngetToken();      aParsingStatus = SELECTOR_PARSING_STOPPED_ERROR;      return;    }    // CSS 3 Negation pseudo-class takes one simple selector as argument    ParseNegatedSimpleSelector(aDataMask, aSelector, aParsingStatus, aErrorCode);    if (SELECTOR_PARSING_ENDED_OK != aParsingStatus) {      return;    }  }      else if (!parsingPseudoElement &&           nsCSSPseudoClasses::IsPseudoClass(pseudo)) {    aDataMask |= SEL_MASK_PCLASS;    if (nsCSSPseudoClasses::lang == pseudo) {      ParseLangSelector(aSelector, aParsingStatus, aErrorCode);    }    // XXX are there more pseudo classes which accept arguments ?    else {      aSelector.AddPseudoClass(pseudo);    }    if (SELECTOR_PARSING_ENDED_OK != aParsingStatus) {      return;    }  }  else if (isPseudoElement || isAnonBox) {    // Pseudo-element.  Make some more sanity checks.        if (aIsNegated) { // pseudo-elements can't be negated      REPORT_UNEXPECTED_TOKEN(NS_LITERAL_STRING("Pseudo-elements can't be negated"));      UngetToken();      aParsingStatus = SELECTOR_PARSING_STOPPED_ERROR;      return;    }    // CSS2 pseudo-elements and -moz-tree-* pseudo-elements are allowed    // to have a single ':' on them.  Others (CSS3+ pseudo-elements and    // various -moz-* pseudo-elements) must have |parsingPseudoElement|    // set.    if (!parsingPseudoElement &&        !nsCSSPseudoElements::IsCSS2PseudoElement(pseudo) &&        !IsTreePseudoElement(pseudo)) {      REPORT_UNEXPECTED_TOKEN(NS_LITERAL_STRING("This pseudo-element must use the \"::\" form: "));      UngetToken();      aParsingStatus = SELECTOR_PARSING_STOPPED_ERROR;      return;          }    if (0 == (aDataMask & SEL_MASK_PELEM)) {      aDataMask |= SEL_MASK_PELEM;      aSelector.AddPseudoClass(pseudo); // store it here, it gets pulled later#ifdef MOZ_XUL      if (isTree) {        // We have encountered a pseudoelement of the form        // -moz-tree-xxxx(a,b,c).  We parse (a,b,c) and add each        // item in the list to the pseudoclass list.  They will be pulled        // from the list later along with the pseudo-element.        if (!ParseTreePseudoElement(aErrorCode, aSelector)) {          aParsingStatus = SELECTOR_PARSING_STOPPED_ERROR;          return;        }      }#endif      // ensure selector ends here, must be followed by EOF, space, '{' or ','      if (GetToken(aErrorCode, PR_FALSE)) { // premature eof is ok (here!)        if ((eCSSToken_WhiteSpace == mToken.mType) ||             (mToken.IsSymbol('{') || mToken.IsSymbol(','))) {          UngetToken();          aParsingStatus = SELECTOR_PARSING_STOPPED_OK;          return;        }        REPORT_UNEXPECTED_TOKEN(NS_LITERAL_STRING("Found trailing token after pseudo-element, which must be the last part of a selector: "));        UngetToken();        aParsingStatus = SELECTOR_PARSING_STOPPED_ERROR;        return;      }    }    else {  // multiple pseudo elements, not legal      REPORT_UNEXPECTED_TOKEN(NS_LITERAL_STRING("Extra pseudo-element"));      UngetToken();      aParsingStatus = SELECTOR_PARSING_STOPPED_ERROR;      return;    }  } else {    // Not a pseudo-class, not a pseudo-element.... forget it    REPORT_UNEXPECTED_TOKEN(NS_LITERAL_STRING("Unknown pseudo-class or pseudo-element"));    UngetToken();    aParsingStatus = SELECTOR_PARSING_STOPPED_ERROR;    return;  }  aParsingStatus = SELECTOR_PARSING_ENDED_OK;}