aDeclaration->AddValue(bxp, nsCSSValue(xValue, eCSSUnit_Enumerated)); aDeclaration->AddValue(byp, nsCSSValue(yValue, eCSSUnit_Enumerated));
aDeclaration->AppendValue(bxp, nsCSSValue(xValue, eCSSUnit_Enumerated)); aDeclaration->AppendValue(byp, nsCSSValue(yValue, eCSSUnit_Enumerated));
PRBool CSSParserImpl::ParseBackgroundPosition(PRInt32* aErrorCode,                                              nsICSSDeclaration* aDeclaration,                                              const char* aName){  static PRInt32 kBackgroundPositionNames[] = {    PROP_BACKGROUND_X_POSITION,    PROP_BACKGROUND_Y_POSITION,  };  // Note: Don't change this table unless you update  // parseBackgroundPosition!  static PRInt32 kBackgroundXYPositionKTable[] = {    KEYWORD_CENTER, BG_CENTER,    KEYWORD_TOP, BG_TOP,    KEYWORD_BOTTOM, BG_BOTTOM,    KEYWORD_LEFT, BG_LEFT,    KEYWORD_RIGHT, BG_RIGHT,    -1,  };  const char* bxp = "background-x-position";  const char* byp = "background-y-position";  // First try a number or a length value  if (ParseVariant(aErrorCode, aDeclaration, bxp, VARIANT_LP, nsnull)) {    // We have one number/length. Get the optional second number/length.    if (ParseVariant(aErrorCode, aDeclaration, byp, VARIANT_LP, nsnull)) {      // We have two numbers      return PR_TRUE;    }    // We have one number which is the x position. Create an value for    // the vertical position which is of value 50%    aDeclaration->AddValue(byp, nsCSSValue(0.5f, eCSSUnit_Percent));    // XXX shouldn't this be CENTER enum instead?    return PR_TRUE;  }  // Now try keywords. We do this manually to allow for the first  // appearance of "center" to apply to the either the x or y  // position (it's ambiguous so we have to disambiguate). Each  // allowed keyword value is assigned it's own bit. We don't allow  // any duplicate keywords other than center. We try to get two  // keywords but it's okay if there is only one.  PRInt32 mask = 0;  PRInt32 centerBit = BG_CENTER1;  for (PRInt32 i = 0; i < 2; i++) {    nsString* ident = NextIdent(aErrorCode);    if (nsnull == ident) {      break;    }    char cbuf[50];    ident->ToCString(cbuf, sizeof(cbuf));    PRInt32 ix = SearchKeywordTable(nsCSSKeywords::LookupName(cbuf),                                       kBackgroundXYPositionKTable);    if (ix >= 0) {      PRInt32 bit = kBackgroundXYPositionKTable[ix + 1];      if (bit == 0) {        // Special hack for center bits: We can have two of them        mask |= centerBit;        centerBit <<= 1;        continue;      } else if ((mask & bit) != 0) {        // no duplicate values allowed (other than center)        return PR_FALSE;      }      mask |= bit;    } else {      UngetToken();      break;    }  }  // Check for bad input. Bad input consists of no matching keywords,  // or pairs of x keywords or pairs of y keywords.  if ((mask == 0) || (mask == (BG_TOP | BG_BOTTOM)) ||      (mask == (BG_LEFT | BG_RIGHT))) {    return PR_FALSE;  }  // Map good input  int xValue = 50;  if ((mask & (BG_LEFT | BG_RIGHT)) != 0) {    // We have an x value    xValue = ((mask & BG_LEFT) != 0) ? 0 : 100;  }  int yValue = 50;  if ((mask & (BG_TOP | BG_BOTTOM)) != 0) {    // We have a y value    yValue = ((mask & BG_TOP) != 0) ? 0 : 100;  }  // Create style values  aDeclaration->AddValue(bxp, nsCSSValue(xValue, eCSSUnit_Enumerated));  aDeclaration->AddValue(byp, nsCSSValue(yValue, eCSSUnit_Enumerated));  return PR_TRUE;}