(0 < mToken.mIdent.Length()) && (nsString::IsAlpha(mToken.mIdent.CharAt(0)))) {
(0 < mToken.mIdent.Length())) {
PRBool CSSParserImpl::ParseSelector(PRInt32& aErrorCode,                                    nsCSSSelector& aSelector,                                    nsString& aSource){  PRInt32       dataMask = 0;  nsAutoString  buffer;  if (! GetToken(aErrorCode, PR_TRUE)) {    return PR_FALSE;  }  if (mToken.IsSymbol('*')) {  // universal element selector, or universal namespace    mToken.AppendToString(aSource);    if (ExpectSymbol(aErrorCode, '|', PR_FALSE)) {  // was namespace      mToken.AppendToString(aSource);      dataMask |= SEL_MASK_NSPACE;      aSelector.SetNameSpace(kNameSpaceID_Unknown); // namespace wildcard      if (! GetToken(aErrorCode, PR_FALSE)) {        return PR_FALSE;      }      mToken.AppendToString(aSource);      if (eCSSToken_Ident == mToken.mType) {  // element name        dataMask |= SEL_MASK_ELEM;        if (mCaseSensitive) {          aSelector.SetTag(mToken.mIdent);        }        else {          mToken.mIdent.ToLowerCase(buffer);          aSelector.SetTag(buffer);        }      }      else if (mToken.IsSymbol('*')) {  // universal selector        dataMask |= SEL_MASK_ELEM;        // don't set tag      }      else {        UngetToken();        return PR_FALSE;      }    }    else {  // was universal element selector      aSelector.SetNameSpace(kNameSpaceID_Unknown); // wildcard      if (mNameSpace) { // look for default namespace        nsINameSpace* defaultNameSpace = nsnull;        mNameSpace->FindNameSpace(nsnull, defaultNameSpace);        if (defaultNameSpace) {          PRInt32 defaultID;          defaultNameSpace->GetNameSpaceID(defaultID);          aSelector.SetNameSpace(defaultID);          NS_RELEASE(defaultNameSpace);        }      }      dataMask |= SEL_MASK_ELEM;      // don't set any tag in the selector    }    if (! GetToken(aErrorCode, PR_FALSE)) {   // premature eof is ok (here!)      return PR_TRUE;    }  }  else if (eCSSToken_Ident == mToken.mType) {    // element name or namespace name    mToken.AppendToString(aSource);    buffer = mToken.mIdent; // hang on to ident    if (ExpectSymbol(aErrorCode, '|', PR_FALSE)) {  // was namespace      mToken.AppendToString(aSource);      dataMask |= SEL_MASK_NSPACE;      PRInt32 nameSpaceID = kNameSpaceID_Unknown;      if (mNameSpace) {        nsIAtom* prefix;        if (mCaseSensitive) {          prefix = NS_NewAtom(buffer);        }        else {          buffer.ToLowerCase();          prefix = NS_NewAtom(buffer);        }        mNameSpace->FindNameSpaceID(prefix, nameSpaceID);        NS_IF_RELEASE(prefix);      } // else, no delcared namespaces      if (kNameSpaceID_Unknown == nameSpaceID) {  // unknown prefix, dump it        return PR_FALSE;      }      aSelector.SetNameSpace(nameSpaceID);      if (! GetToken(aErrorCode, PR_FALSE)) {        return PR_FALSE;      }      mToken.AppendToString(aSource);      if (eCSSToken_Ident == mToken.mType) {  // element name        dataMask |= SEL_MASK_ELEM;        if (mCaseSensitive) {          aSelector.SetTag(mToken.mIdent);        }        else {          mToken.mIdent.ToLowerCase(buffer);          aSelector.SetTag(buffer);        }      }      else if (mToken.IsSymbol('*')) {  // universal selector        dataMask |= SEL_MASK_ELEM;        // don't set tag      }      else {        UngetToken();        return PR_FALSE;      }    }    else {  // was element name      aSelector.SetNameSpace(kNameSpaceID_Unknown); // wildcard      if (mNameSpace) { // look for default namespace        nsINameSpace* defaultNameSpace = nsnull;        mNameSpace->FindNameSpace(nsnull, defaultNameSpace);        if (defaultNameSpace) {          PRInt32 defaultID;          defaultNameSpace->GetNameSpaceID(defaultID);          aSelector.SetNameSpace(defaultID);          NS_RELEASE(defaultNameSpace);        }      }      if (mCaseSensitive) {        aSelector.SetTag(buffer);      }      else {        buffer.ToLowerCase();        aSelector.SetTag(buffer);      }      dataMask |= SEL_MASK_ELEM;    }    if (! GetToken(aErrorCode, PR_FALSE)) {   // premature eof is ok (here!)      return PR_TRUE;    }  }  else if (mToken.IsSymbol('|')) {  // No namespace    mToken.AppendToString(aSource);    dataMask |= SEL_MASK_NSPACE;    aSelector.SetNameSpace(kNameSpaceID_None);  // explicit NO namespace    // get mandatory tag    if (! GetToken(aErrorCode, PR_FALSE)) {      return PR_FALSE;    }    mToken.AppendToString(aSource);    if (eCSSToken_Ident == mToken.mType) {  // element name      dataMask |= SEL_MASK_ELEM;      if (mCaseSensitive) {        aSelector.SetTag(mToken.mIdent);      }      else {        mToken.mIdent.ToLowerCase(buffer);        aSelector.SetTag(buffer);      }    }    else if (mToken.IsSymbol('*')) {  // universal selector      dataMask |= SEL_MASK_ELEM;      // don't set tag    }    else {      UngetToken();      return PR_FALSE;    }    if (! GetToken(aErrorCode, PR_FALSE)) {   // premature eof is ok (here!)      return PR_TRUE;    }  }  for (;;) {    if (eCSSToken_ID == mToken.mType) {   // #id      if ((0 == (dataMask & SEL_MASK_ID)) &&  // only one ID          (0 < mToken.mIdent.Length()) &&           (nsString::IsAlpha(mToken.mIdent.CharAt(0)))) { // verify is legal ID        mToken.AppendToString(aSource);        dataMask |= SEL_MASK_ID;        aSelector.SetID(mToken.mIdent);      }      else {        UngetToken();        return PR_FALSE;      }    }    else if (mToken.IsSymbol('.')) {  // .class      mToken.AppendToString(aSource);      if (! GetToken(aErrorCode, PR_FALSE)) { // get ident        return PR_FALSE;      }      if (eCSSToken_Ident != mToken.mType) {  // malformed selector (XXX what about leading digits?)        UngetToken();        return PR_FALSE;      }      mToken.AppendToString(aSource);      dataMask |= SEL_MASK_CLASS;      aSelector.AddClass(mToken.mIdent);  // class always case sensitive    }    else if (mToken.IsSymbol(':')) { // :pseudo      mToken.AppendToString(aSource);      if (! GetToken(aErrorCode, PR_FALSE)) { // premature eof        return PR_FALSE;      }      if (eCSSToken_Ident != mToken.mType) {  // malformed selector        UngetToken();        return PR_FALSE;      }      mToken.AppendToString(aSource);      buffer.Truncate();      buffer.Append(':');      buffer.Append(mToken.mIdent);      buffer.ToLowerCase();      nsIAtom* pseudo = NS_NewAtom(buffer);      if (IsPseudoClass(pseudo)) {        // XXX parse lang pseudo class        dataMask |= SEL_MASK_PCLASS;        aSelector.AddPseudoClass(pseudo);      }      else {        if (0 == (dataMask & SEL_MASK_PELEM)) {          dataMask |= SEL_MASK_PELEM;          aSelector.AddPseudoClass(pseudo); // store it here, it gets pulled later          // 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();              return PR_TRUE;            }            UngetToken();            return PR_FALSE;          }        }        else {  // multiple pseudo elements, not legal          UngetToken();          NS_RELEASE(pseudo);          return PR_FALSE;        }      }      NS_RELEASE(pseudo);    }    else if (mToken.IsSymbol('[')) {  // attribute      mToken.AppendToString(aSource);      if (! GetToken(aErrorCode, PR_TRUE)) { // premature EOF        return PR_FALSE;      }      mToken.AppendToString(aSource);      PRInt32 nameSpaceID = kNameSpaceID_None;      nsAutoString  attr;      if (mToken.IsSymbol('*')) { // wildcard namespace        nameSpaceID = kNameSpaceID_Unknown;        if (ExpectSymbol(aErrorCode, '|', PR_FALSE)) {          mToken.AppendToString(aSource);          if (! GetToken(aErrorCode, PR_FALSE)) { // premature EOF            return PR_FALSE;          }          mToken.AppendToString(aSource);          if (eCSSToken_Ident == mToken.mType) { // attr name            attr = mToken.mIdent;          }          else {            UngetToken();            return PR_FALSE;          }        }        else {          return PR_FALSE;        }      }      else if (mToken.IsSymbol('|')) { // NO namespace        if (! GetToken(aErrorCode, PR_FALSE)) { // premature EOF          return PR_FALSE;        }        mToken.AppendToString(aSource);        if (eCSSToken_Ident == mToken.mType) { // attr name          attr = mToken.mIdent;        }        else {          UngetToken();          return PR_FALSE;        }      }      else if (eCSSToken_Ident == mToken.mType) { // attr name or namespace        attr = mToken.mIdent; // hang on to it        if (ExpectSymbol(aErrorCode, '|', PR_FALSE)) {  // was a namespace          mToken.AppendToString(aSource);          nameSpaceID = kNameSpaceID_Unknown;          if (mNameSpace) {            nsIAtom* prefix;            if (mCaseSensitive) {              prefix = NS_NewAtom(attr);            }            else {              attr.ToLowerCase();              prefix = NS_NewAtom(attr);            }            mNameSpace->FindNameSpaceID(prefix, nameSpaceID);            NS_IF_RELEASE(prefix);          } // else, no delcared namespaces          if (kNameSpaceID_Unknown == nameSpaceID) {  // unknown prefix, dump it            return PR_FALSE;          }          if (! GetToken(aErrorCode, PR_FALSE)) { // premature EOF            return PR_FALSE;          }          mToken.AppendToString(aSource);          if (eCSSToken_Ident == mToken.mType) { // attr name            attr = mToken.mIdent;          }          else {            UngetToken();            return PR_FALSE;          }        }      }      else {  // malformed        UngetToken();        return PR_FALSE;      }      if (! mCaseSensitive) {        attr.ToLowerCase();      }      if (! GetToken(aErrorCode, PR_TRUE)) { // premature EOF        return PR_FALSE;      }      if (eCSSToken_Symbol == mToken.mType) {        mToken.AppendToString(aSource);        PRUint8 func;        if (']' == mToken.mSymbol) {          dataMask |= SEL_MASK_ATTRIB;          aSelector.AddAttribute(nameSpaceID, attr);          func = NS_ATTR_FUNC_SET;        }        else if ('=' == mToken.mSymbol) {          func = NS_ATTR_FUNC_EQUALS;        }        else if ('~' == mToken.mSymbol) {          if (! GetToken(aErrorCode, PR_FALSE)) { // premature EOF            return PR_FALSE;          }          mToken.AppendToString(aSource);          if (mToken.IsSymbol('=')) {            func = NS_ATTR_FUNC_INCLUDES;          }          else {            UngetToken();            return PR_FALSE;          }        }        else if ('|' == mToken.mSymbol) {          if (! GetToken(aErrorCode, PR_FALSE)) { // premature EOF            return PR_FALSE;          }          mToken.AppendToString(aSource);          if (mToken.IsSymbol('=')) {            func = NS_ATTR_FUNC_DASHMATCH;          }          else {            UngetToken();            return PR_FALSE;          }        }        else {          UngetToken(); // bad function          return PR_FALSE;        }        if (NS_ATTR_FUNC_SET != func) { // get value          if (! GetToken(aErrorCode, PR_TRUE)) { // premature EOF            return PR_FALSE;          }          if ((eCSSToken_Ident == mToken.mType) || (eCSSToken_String == mToken.mType)) {            mToken.AppendToString(aSource);            nsAutoString  value(mToken.mIdent);            if (! GetToken(aErrorCode, PR_TRUE)) { // premature EOF              return PR_FALSE;            }            if (mToken.IsSymbol(']')) {              mToken.AppendToString(aSource);              dataMask |= SEL_MASK_ATTRIB;              aSelector.AddAttribute(nameSpaceID, attr, func, value, mCaseSensitive);            }            else {              UngetToken();              return PR_FALSE;            }          }          else {            UngetToken();            return PR_FALSE;          }        }      }      else {        UngetToken(); // bad dog, no biscut!        return PR_FALSE;      }    }    else {  // not a selector token, we're done      break;    }    if (! GetToken(aErrorCode, PR_FALSE)) { // premature eof is ok (here!)      return PR_TRUE;    }  }  UngetToken();  return PRBool(0 != dataMask);}