if (PRUnichar('+') == selector->mOperator) {
if (PRUnichar('+') == selector->mOperator || PRUnichar('~') == selector->mOperator) {
static PRBool SelectorMatchesTree(RuleProcessorData& aPrevData,                                  nsCSSSelector* aSelector) {  nsCSSSelector* selector = aSelector;  RuleProcessorData* prevdata = &aPrevData;  while (selector) { // check compound selectors    // If we don't already have a RuleProcessorData for the next    // appropriate content (whether parent or previous sibling), create    // one.    // for adjacent sibling combinators, the content to test against the    // selector is the previous sibling *element*    RuleProcessorData* data;    if (PRUnichar('+') == selector->mOperator) {      data = prevdata->mPreviousSiblingData;      if (!data) {        nsIContent* content = prevdata->mContent;        nsIContent* parent = content->GetParent();        if (parent) {          PRInt32 index = parent->IndexOf(content);          while (0 <= --index) {            content = parent->GetChildAt(index);            if (content->IsContentOfType(nsIContent::eELEMENT)) {              data = new (prevdata->mPresContext)                          RuleProcessorData(prevdata->mPresContext, content,                                            prevdata->mRuleWalker,                                            &prevdata->mCompatMode);              prevdata->mPreviousSiblingData = data;                  break;            }          }        }      }    }    // for descendant combinators and child combinators, the content    // to test against is the parent    else {      data = prevdata->mParentData;      if (!data) {        nsIContent *content = prevdata->mContent->GetParent();        if (content) {          data = new (prevdata->mPresContext)                      RuleProcessorData(prevdata->mPresContext, content,                                        prevdata->mRuleWalker,                                        &prevdata->mCompatMode);          prevdata->mParentData = data;            }      }    }    if (! data) {      return PR_FALSE;    }    if (SelectorMatches(*data, selector, 0, nsnull, 0)) {      // to avoid greedy matching, we need to recur if this is a      // descendant combinator and the next combinator is not      if ((NS_IS_GREEDY_OPERATOR(selector->mOperator)) &&          (selector->mNext) &&          (!NS_IS_GREEDY_OPERATOR(selector->mNext->mOperator))) {        // pretend the selector didn't match, and step through content        // while testing the same selector        // This approach is slightly strange in that when it recurs        // it tests from the top of the content tree, down.  This        // doesn't matter much for performance since most selectors        // don't match.  (If most did, it might be faster...)        if (SelectorMatchesTree(*data, selector)) {          return PR_TRUE;        }      }      selector = selector->mNext;    }    else {      // for adjacent sibling and child combinators, if we didn't find      // a match, we're done      if (!NS_IS_GREEDY_OPERATOR(selector->mOperator)) {        return PR_FALSE;  // parent was required to match      }    }    prevdata = data;  }  return PR_TRUE; // all the selectors matched.}