зеркало из https://github.com/mozilla/pjs.git
Bug 219829
Allow mixing length and percentage values with keyword values for the background-position property, which is now allowed per section 14.2.1 of CSS 2.1 r+sr=dbaron a=asa
This commit is contained in:
Родитель
5bef1e18e0
Коммит
626eea0b43
|
@ -3976,8 +3976,8 @@ PRBool CSSParserImpl::ParseProperty(nsresult& aErrorCode,
|
|||
#define BG_BOTTOM 0x04
|
||||
#define BG_LEFT 0x08
|
||||
#define BG_RIGHT 0x10
|
||||
#define BG_CENTER1 0x20
|
||||
#define BG_CENTER2 0x40
|
||||
#define BG_CTB (BG_CENTER | BG_TOP | BG_BOTTOM)
|
||||
#define BG_CLR (BG_CENTER | BG_LEFT | BG_RIGHT)
|
||||
|
||||
// Note: Don't change this table unless you update
|
||||
// parseBackgroundPosition!
|
||||
|
@ -4442,6 +4442,30 @@ PRBool CSSParserImpl::ParseAzimuth(nsresult& aErrorCode, nsCSSValue& aValue)
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
static nsCSSValue
|
||||
BackgroundPositionMaskToCSSValue(PRInt32 aMask, PRBool isX)
|
||||
{
|
||||
PRInt32 pct = 50;
|
||||
if (isX) {
|
||||
if (aMask & BG_LEFT) {
|
||||
pct = 0;
|
||||
}
|
||||
else if (aMask & BG_RIGHT) {
|
||||
pct = 100;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (aMask & BG_TOP) {
|
||||
pct = 0;
|
||||
}
|
||||
else if (aMask & BG_BOTTOM) {
|
||||
pct = 100;
|
||||
}
|
||||
}
|
||||
|
||||
return nsCSSValue(pct, eCSSUnit_Enumerated);
|
||||
}
|
||||
|
||||
PRBool CSSParserImpl::ParseBackground(nsresult& aErrorCode)
|
||||
{
|
||||
const PRInt32 numProps = 6;
|
||||
|
@ -4461,36 +4485,11 @@ PRBool CSSParserImpl::ParseBackground(nsresult& aErrorCode)
|
|||
}
|
||||
|
||||
if (0 != (found & 0x30)) { // found one or more position values, validate them
|
||||
if (0 == (found & 0x20)) { // x value only
|
||||
if (0 == (found & 0x20)) {
|
||||
if (eCSSUnit_Enumerated == values[4].GetUnit()) {
|
||||
switch (values[4].GetIntValue()) {
|
||||
case BG_CENTER:
|
||||
values[4].SetIntValue(50, eCSSUnit_Enumerated);
|
||||
values[5].SetIntValue(50, eCSSUnit_Enumerated);
|
||||
break;
|
||||
case BG_TOP:
|
||||
values[4].SetIntValue(50, eCSSUnit_Enumerated);
|
||||
values[5].SetIntValue(0, eCSSUnit_Enumerated);
|
||||
break;
|
||||
case BG_BOTTOM:
|
||||
values[4].SetIntValue(50, eCSSUnit_Enumerated);
|
||||
values[5].SetIntValue(100, eCSSUnit_Enumerated);
|
||||
break;
|
||||
case BG_LEFT:
|
||||
values[4].SetIntValue(0, eCSSUnit_Enumerated);
|
||||
values[5].SetIntValue(50, eCSSUnit_Enumerated);
|
||||
break;
|
||||
case BG_RIGHT:
|
||||
values[4].SetIntValue(100, eCSSUnit_Enumerated);
|
||||
values[5].SetIntValue(50, eCSSUnit_Enumerated);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (eCSSUnit_Inherit == values[4].GetUnit()) {
|
||||
values[5].SetInheritValue();
|
||||
}
|
||||
else if (eCSSUnit_Initial == values[4].GetUnit()) {
|
||||
values[5].SetInitialValue();
|
||||
PRInt32 mask = values[4].GetIntValue();
|
||||
values[4] = BackgroundPositionMaskToCSSValue(mask, PR_TRUE);
|
||||
values[5] = BackgroundPositionMaskToCSSValue(mask, PR_FALSE);
|
||||
}
|
||||
else {
|
||||
values[5].SetPercentValue(0.5f);
|
||||
|
@ -4499,9 +4498,9 @@ PRBool CSSParserImpl::ParseBackground(nsresult& aErrorCode)
|
|||
else { // both x & y values
|
||||
nsCSSUnit xUnit = values[4].GetUnit();
|
||||
nsCSSUnit yUnit = values[5].GetUnit();
|
||||
if (eCSSUnit_Enumerated == xUnit) { // if one is enumerated, both must be
|
||||
if (eCSSUnit_Enumerated == xUnit) {
|
||||
PRInt32 xValue = values[4].GetIntValue();
|
||||
if (eCSSUnit_Enumerated == yUnit) {
|
||||
PRInt32 xValue = values[4].GetIntValue();
|
||||
PRInt32 yValue = values[5].GetIntValue();
|
||||
if (0 != (xValue & (BG_LEFT | BG_RIGHT)) && // x is really an x value
|
||||
0 != (yValue & (BG_LEFT | BG_RIGHT))) { // y is also an x value
|
||||
|
@ -4517,40 +4516,27 @@ PRBool CSSParserImpl::ParseBackground(nsresult& aErrorCode)
|
|||
xValue = yValue;
|
||||
yValue = holdXValue;
|
||||
}
|
||||
switch (xValue) {
|
||||
case BG_LEFT:
|
||||
values[4].SetIntValue(0, eCSSUnit_Enumerated);
|
||||
break;
|
||||
case BG_CENTER:
|
||||
values[4].SetIntValue(50, eCSSUnit_Enumerated);
|
||||
break;
|
||||
case BG_RIGHT:
|
||||
values[4].SetIntValue(100, eCSSUnit_Enumerated);
|
||||
break;
|
||||
default:
|
||||
NS_ERROR("bad x value");
|
||||
}
|
||||
switch (yValue) {
|
||||
case BG_TOP:
|
||||
values[5].SetIntValue(0, eCSSUnit_Enumerated);
|
||||
break;
|
||||
case BG_CENTER:
|
||||
values[5].SetIntValue(50, eCSSUnit_Enumerated);
|
||||
break;
|
||||
case BG_BOTTOM:
|
||||
values[5].SetIntValue(100, eCSSUnit_Enumerated);
|
||||
break;
|
||||
default:
|
||||
NS_ERROR("bad y value");
|
||||
}
|
||||
NS_ASSERTION(xValue & BG_CLR, "bad x value");
|
||||
NS_ASSERTION(yValue & BG_CTB, "bad y value");
|
||||
values[4] = BackgroundPositionMaskToCSSValue(xValue, PR_TRUE);
|
||||
values[5] = BackgroundPositionMaskToCSSValue(yValue, PR_FALSE);
|
||||
}
|
||||
else {
|
||||
return PR_FALSE;
|
||||
if (!(xValue & BG_CLR)) {
|
||||
// The first keyword can only be 'center', 'left', or 'right'
|
||||
return PR_FALSE;
|
||||
}
|
||||
values[4] = BackgroundPositionMaskToCSSValue(xValue, PR_TRUE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (eCSSUnit_Enumerated == yUnit) {
|
||||
return PR_FALSE;
|
||||
PRInt32 yValue = values[5].GetIntValue();
|
||||
if (!(yValue & BG_CTB)) {
|
||||
// The second keyword can only be 'center', 'top', or 'bottom'
|
||||
return PR_FALSE;
|
||||
}
|
||||
values[5] = BackgroundPositionMaskToCSSValue(yValue, PR_FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4598,8 +4584,8 @@ PRBool CSSParserImpl::ParseBackground(nsresult& aErrorCode)
|
|||
|
||||
PRBool CSSParserImpl::ParseBackgroundPosition(nsresult& aErrorCode)
|
||||
{
|
||||
// First try a number or a length value
|
||||
nsCSSValue xValue;
|
||||
// First try a percentage or a length value
|
||||
nsCSSValue xValue, yValue;
|
||||
if (ParseVariant(aErrorCode, xValue, VARIANT_HLP, nsnull)) {
|
||||
if (eCSSUnit_Inherit == xValue.GetUnit() ||
|
||||
eCSSUnit_Initial == xValue.GetUnit()) { // both are inherited or both are set to initial
|
||||
|
@ -4610,8 +4596,8 @@ PRBool CSSParserImpl::ParseBackgroundPosition(nsresult& aErrorCode)
|
|||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
// We have one number/length. Get the optional second number/length.
|
||||
nsCSSValue yValue;
|
||||
// We have one percentage/length. Get the optional second
|
||||
// percentage/length/keyword.
|
||||
if (ParseVariant(aErrorCode, yValue, VARIANT_LP, nsnull)) {
|
||||
// We have two numbers
|
||||
if (ExpectEndProperty(aErrorCode, PR_TRUE)) {
|
||||
|
@ -4622,8 +4608,23 @@ PRBool CSSParserImpl::ParseBackgroundPosition(nsresult& aErrorCode)
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// We have one number which is the x position. Create an value for
|
||||
// the vertical position which is of value 50%
|
||||
if (ParseEnum(aErrorCode, yValue, kBackgroundXYPositionKTable)) {
|
||||
PRInt32 yVal = yValue.GetIntValue();
|
||||
if (!(yVal & BG_CTB)) {
|
||||
// The second keyword can only be 'center', 'top', or 'bottom'
|
||||
return PR_FALSE;
|
||||
}
|
||||
if (ExpectEndProperty(aErrorCode, PR_TRUE)) {
|
||||
yValue = BackgroundPositionMaskToCSSValue(yVal, PR_FALSE);
|
||||
AppendValue(eCSSProperty_background_x_position, xValue);
|
||||
AppendValue(eCSSProperty_background_y_position, yValue);
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// If only one percentage or length value is given, it sets the
|
||||
// horizontal position only, and the vertical position will be 50%.
|
||||
if (ExpectEndProperty(aErrorCode, PR_TRUE)) {
|
||||
AppendValue(eCSSProperty_background_x_position, xValue);
|
||||
AppendValue(eCSSProperty_background_y_position, nsCSSValue(0.5f, eCSSUnit_Percent));
|
||||
|
@ -4639,22 +4640,34 @@ PRBool CSSParserImpl::ParseBackgroundPosition(nsresult& aErrorCode)
|
|||
// 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++) {
|
||||
if (PR_FALSE == ParseEnum(aErrorCode, xValue, kBackgroundXYPositionKTable)) {
|
||||
break;
|
||||
}
|
||||
if (ParseEnum(aErrorCode, xValue, kBackgroundXYPositionKTable)) {
|
||||
PRInt32 bit = xValue.GetIntValue();
|
||||
if (BG_CENTER == bit) {
|
||||
// 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;
|
||||
if (ParseEnum(aErrorCode, xValue, kBackgroundXYPositionKTable)) {
|
||||
bit = xValue.GetIntValue();
|
||||
if (mask & (bit & ~BG_CENTER)) {
|
||||
// Only the 'center' keyword can be duplicated.
|
||||
return PR_FALSE;
|
||||
}
|
||||
mask |= bit;
|
||||
}
|
||||
else {
|
||||
// Only one keyword. See if we have a length or percentage.
|
||||
if (ParseVariant(aErrorCode, yValue, VARIANT_LP, nsnull)) {
|
||||
if (!(mask & BG_CLR)) {
|
||||
// The first keyword can only be 'center', 'left', or 'right'
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (ExpectEndProperty(aErrorCode, PR_TRUE)) {
|
||||
xValue = BackgroundPositionMaskToCSSValue(mask, PR_TRUE);
|
||||
AppendValue(eCSSProperty_background_x_position, xValue);
|
||||
AppendValue(eCSSProperty_background_y_position, yValue);
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for bad input. Bad input consists of no matching keywords,
|
||||
|
@ -4664,22 +4677,12 @@ PRBool CSSParserImpl::ParseBackgroundPosition(nsresult& aErrorCode)
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Map good input
|
||||
PRInt32 xEnumValue = 50;
|
||||
if ((mask & (BG_LEFT | BG_RIGHT)) != 0) {
|
||||
// We have an x value
|
||||
xEnumValue = ((mask & BG_LEFT) != 0) ? 0 : 100;
|
||||
}
|
||||
PRInt32 yEnumValue = 50;
|
||||
if ((mask & (BG_TOP | BG_BOTTOM)) != 0) {
|
||||
// We have a y value
|
||||
yEnumValue = ((mask & BG_TOP) != 0) ? 0 : 100;
|
||||
}
|
||||
|
||||
if (ExpectEndProperty(aErrorCode, PR_TRUE)) {
|
||||
// Create style values
|
||||
AppendValue(eCSSProperty_background_x_position, nsCSSValue(xEnumValue, eCSSUnit_Enumerated));
|
||||
AppendValue(eCSSProperty_background_y_position, nsCSSValue(yEnumValue, eCSSUnit_Enumerated));
|
||||
xValue = BackgroundPositionMaskToCSSValue(mask, PR_TRUE);
|
||||
yValue = BackgroundPositionMaskToCSSValue(mask, PR_FALSE);
|
||||
AppendValue(eCSSProperty_background_x_position, xValue);
|
||||
AppendValue(eCSSProperty_background_y_position, yValue);
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
|
|
|
@ -3976,8 +3976,8 @@ PRBool CSSParserImpl::ParseProperty(nsresult& aErrorCode,
|
|||
#define BG_BOTTOM 0x04
|
||||
#define BG_LEFT 0x08
|
||||
#define BG_RIGHT 0x10
|
||||
#define BG_CENTER1 0x20
|
||||
#define BG_CENTER2 0x40
|
||||
#define BG_CTB (BG_CENTER | BG_TOP | BG_BOTTOM)
|
||||
#define BG_CLR (BG_CENTER | BG_LEFT | BG_RIGHT)
|
||||
|
||||
// Note: Don't change this table unless you update
|
||||
// parseBackgroundPosition!
|
||||
|
@ -4442,6 +4442,30 @@ PRBool CSSParserImpl::ParseAzimuth(nsresult& aErrorCode, nsCSSValue& aValue)
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
static nsCSSValue
|
||||
BackgroundPositionMaskToCSSValue(PRInt32 aMask, PRBool isX)
|
||||
{
|
||||
PRInt32 pct = 50;
|
||||
if (isX) {
|
||||
if (aMask & BG_LEFT) {
|
||||
pct = 0;
|
||||
}
|
||||
else if (aMask & BG_RIGHT) {
|
||||
pct = 100;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (aMask & BG_TOP) {
|
||||
pct = 0;
|
||||
}
|
||||
else if (aMask & BG_BOTTOM) {
|
||||
pct = 100;
|
||||
}
|
||||
}
|
||||
|
||||
return nsCSSValue(pct, eCSSUnit_Enumerated);
|
||||
}
|
||||
|
||||
PRBool CSSParserImpl::ParseBackground(nsresult& aErrorCode)
|
||||
{
|
||||
const PRInt32 numProps = 6;
|
||||
|
@ -4461,36 +4485,11 @@ PRBool CSSParserImpl::ParseBackground(nsresult& aErrorCode)
|
|||
}
|
||||
|
||||
if (0 != (found & 0x30)) { // found one or more position values, validate them
|
||||
if (0 == (found & 0x20)) { // x value only
|
||||
if (0 == (found & 0x20)) {
|
||||
if (eCSSUnit_Enumerated == values[4].GetUnit()) {
|
||||
switch (values[4].GetIntValue()) {
|
||||
case BG_CENTER:
|
||||
values[4].SetIntValue(50, eCSSUnit_Enumerated);
|
||||
values[5].SetIntValue(50, eCSSUnit_Enumerated);
|
||||
break;
|
||||
case BG_TOP:
|
||||
values[4].SetIntValue(50, eCSSUnit_Enumerated);
|
||||
values[5].SetIntValue(0, eCSSUnit_Enumerated);
|
||||
break;
|
||||
case BG_BOTTOM:
|
||||
values[4].SetIntValue(50, eCSSUnit_Enumerated);
|
||||
values[5].SetIntValue(100, eCSSUnit_Enumerated);
|
||||
break;
|
||||
case BG_LEFT:
|
||||
values[4].SetIntValue(0, eCSSUnit_Enumerated);
|
||||
values[5].SetIntValue(50, eCSSUnit_Enumerated);
|
||||
break;
|
||||
case BG_RIGHT:
|
||||
values[4].SetIntValue(100, eCSSUnit_Enumerated);
|
||||
values[5].SetIntValue(50, eCSSUnit_Enumerated);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (eCSSUnit_Inherit == values[4].GetUnit()) {
|
||||
values[5].SetInheritValue();
|
||||
}
|
||||
else if (eCSSUnit_Initial == values[4].GetUnit()) {
|
||||
values[5].SetInitialValue();
|
||||
PRInt32 mask = values[4].GetIntValue();
|
||||
values[4] = BackgroundPositionMaskToCSSValue(mask, PR_TRUE);
|
||||
values[5] = BackgroundPositionMaskToCSSValue(mask, PR_FALSE);
|
||||
}
|
||||
else {
|
||||
values[5].SetPercentValue(0.5f);
|
||||
|
@ -4499,9 +4498,9 @@ PRBool CSSParserImpl::ParseBackground(nsresult& aErrorCode)
|
|||
else { // both x & y values
|
||||
nsCSSUnit xUnit = values[4].GetUnit();
|
||||
nsCSSUnit yUnit = values[5].GetUnit();
|
||||
if (eCSSUnit_Enumerated == xUnit) { // if one is enumerated, both must be
|
||||
if (eCSSUnit_Enumerated == xUnit) {
|
||||
PRInt32 xValue = values[4].GetIntValue();
|
||||
if (eCSSUnit_Enumerated == yUnit) {
|
||||
PRInt32 xValue = values[4].GetIntValue();
|
||||
PRInt32 yValue = values[5].GetIntValue();
|
||||
if (0 != (xValue & (BG_LEFT | BG_RIGHT)) && // x is really an x value
|
||||
0 != (yValue & (BG_LEFT | BG_RIGHT))) { // y is also an x value
|
||||
|
@ -4517,40 +4516,27 @@ PRBool CSSParserImpl::ParseBackground(nsresult& aErrorCode)
|
|||
xValue = yValue;
|
||||
yValue = holdXValue;
|
||||
}
|
||||
switch (xValue) {
|
||||
case BG_LEFT:
|
||||
values[4].SetIntValue(0, eCSSUnit_Enumerated);
|
||||
break;
|
||||
case BG_CENTER:
|
||||
values[4].SetIntValue(50, eCSSUnit_Enumerated);
|
||||
break;
|
||||
case BG_RIGHT:
|
||||
values[4].SetIntValue(100, eCSSUnit_Enumerated);
|
||||
break;
|
||||
default:
|
||||
NS_ERROR("bad x value");
|
||||
}
|
||||
switch (yValue) {
|
||||
case BG_TOP:
|
||||
values[5].SetIntValue(0, eCSSUnit_Enumerated);
|
||||
break;
|
||||
case BG_CENTER:
|
||||
values[5].SetIntValue(50, eCSSUnit_Enumerated);
|
||||
break;
|
||||
case BG_BOTTOM:
|
||||
values[5].SetIntValue(100, eCSSUnit_Enumerated);
|
||||
break;
|
||||
default:
|
||||
NS_ERROR("bad y value");
|
||||
}
|
||||
NS_ASSERTION(xValue & BG_CLR, "bad x value");
|
||||
NS_ASSERTION(yValue & BG_CTB, "bad y value");
|
||||
values[4] = BackgroundPositionMaskToCSSValue(xValue, PR_TRUE);
|
||||
values[5] = BackgroundPositionMaskToCSSValue(yValue, PR_FALSE);
|
||||
}
|
||||
else {
|
||||
return PR_FALSE;
|
||||
if (!(xValue & BG_CLR)) {
|
||||
// The first keyword can only be 'center', 'left', or 'right'
|
||||
return PR_FALSE;
|
||||
}
|
||||
values[4] = BackgroundPositionMaskToCSSValue(xValue, PR_TRUE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (eCSSUnit_Enumerated == yUnit) {
|
||||
return PR_FALSE;
|
||||
PRInt32 yValue = values[5].GetIntValue();
|
||||
if (!(yValue & BG_CTB)) {
|
||||
// The second keyword can only be 'center', 'top', or 'bottom'
|
||||
return PR_FALSE;
|
||||
}
|
||||
values[5] = BackgroundPositionMaskToCSSValue(yValue, PR_FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4598,8 +4584,8 @@ PRBool CSSParserImpl::ParseBackground(nsresult& aErrorCode)
|
|||
|
||||
PRBool CSSParserImpl::ParseBackgroundPosition(nsresult& aErrorCode)
|
||||
{
|
||||
// First try a number or a length value
|
||||
nsCSSValue xValue;
|
||||
// First try a percentage or a length value
|
||||
nsCSSValue xValue, yValue;
|
||||
if (ParseVariant(aErrorCode, xValue, VARIANT_HLP, nsnull)) {
|
||||
if (eCSSUnit_Inherit == xValue.GetUnit() ||
|
||||
eCSSUnit_Initial == xValue.GetUnit()) { // both are inherited or both are set to initial
|
||||
|
@ -4610,8 +4596,8 @@ PRBool CSSParserImpl::ParseBackgroundPosition(nsresult& aErrorCode)
|
|||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
// We have one number/length. Get the optional second number/length.
|
||||
nsCSSValue yValue;
|
||||
// We have one percentage/length. Get the optional second
|
||||
// percentage/length/keyword.
|
||||
if (ParseVariant(aErrorCode, yValue, VARIANT_LP, nsnull)) {
|
||||
// We have two numbers
|
||||
if (ExpectEndProperty(aErrorCode, PR_TRUE)) {
|
||||
|
@ -4622,8 +4608,23 @@ PRBool CSSParserImpl::ParseBackgroundPosition(nsresult& aErrorCode)
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// We have one number which is the x position. Create an value for
|
||||
// the vertical position which is of value 50%
|
||||
if (ParseEnum(aErrorCode, yValue, kBackgroundXYPositionKTable)) {
|
||||
PRInt32 yVal = yValue.GetIntValue();
|
||||
if (!(yVal & BG_CTB)) {
|
||||
// The second keyword can only be 'center', 'top', or 'bottom'
|
||||
return PR_FALSE;
|
||||
}
|
||||
if (ExpectEndProperty(aErrorCode, PR_TRUE)) {
|
||||
yValue = BackgroundPositionMaskToCSSValue(yVal, PR_FALSE);
|
||||
AppendValue(eCSSProperty_background_x_position, xValue);
|
||||
AppendValue(eCSSProperty_background_y_position, yValue);
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// If only one percentage or length value is given, it sets the
|
||||
// horizontal position only, and the vertical position will be 50%.
|
||||
if (ExpectEndProperty(aErrorCode, PR_TRUE)) {
|
||||
AppendValue(eCSSProperty_background_x_position, xValue);
|
||||
AppendValue(eCSSProperty_background_y_position, nsCSSValue(0.5f, eCSSUnit_Percent));
|
||||
|
@ -4639,22 +4640,34 @@ PRBool CSSParserImpl::ParseBackgroundPosition(nsresult& aErrorCode)
|
|||
// 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++) {
|
||||
if (PR_FALSE == ParseEnum(aErrorCode, xValue, kBackgroundXYPositionKTable)) {
|
||||
break;
|
||||
}
|
||||
if (ParseEnum(aErrorCode, xValue, kBackgroundXYPositionKTable)) {
|
||||
PRInt32 bit = xValue.GetIntValue();
|
||||
if (BG_CENTER == bit) {
|
||||
// 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;
|
||||
if (ParseEnum(aErrorCode, xValue, kBackgroundXYPositionKTable)) {
|
||||
bit = xValue.GetIntValue();
|
||||
if (mask & (bit & ~BG_CENTER)) {
|
||||
// Only the 'center' keyword can be duplicated.
|
||||
return PR_FALSE;
|
||||
}
|
||||
mask |= bit;
|
||||
}
|
||||
else {
|
||||
// Only one keyword. See if we have a length or percentage.
|
||||
if (ParseVariant(aErrorCode, yValue, VARIANT_LP, nsnull)) {
|
||||
if (!(mask & BG_CLR)) {
|
||||
// The first keyword can only be 'center', 'left', or 'right'
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (ExpectEndProperty(aErrorCode, PR_TRUE)) {
|
||||
xValue = BackgroundPositionMaskToCSSValue(mask, PR_TRUE);
|
||||
AppendValue(eCSSProperty_background_x_position, xValue);
|
||||
AppendValue(eCSSProperty_background_y_position, yValue);
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for bad input. Bad input consists of no matching keywords,
|
||||
|
@ -4664,22 +4677,12 @@ PRBool CSSParserImpl::ParseBackgroundPosition(nsresult& aErrorCode)
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Map good input
|
||||
PRInt32 xEnumValue = 50;
|
||||
if ((mask & (BG_LEFT | BG_RIGHT)) != 0) {
|
||||
// We have an x value
|
||||
xEnumValue = ((mask & BG_LEFT) != 0) ? 0 : 100;
|
||||
}
|
||||
PRInt32 yEnumValue = 50;
|
||||
if ((mask & (BG_TOP | BG_BOTTOM)) != 0) {
|
||||
// We have a y value
|
||||
yEnumValue = ((mask & BG_TOP) != 0) ? 0 : 100;
|
||||
}
|
||||
|
||||
if (ExpectEndProperty(aErrorCode, PR_TRUE)) {
|
||||
// Create style values
|
||||
AppendValue(eCSSProperty_background_x_position, nsCSSValue(xEnumValue, eCSSUnit_Enumerated));
|
||||
AppendValue(eCSSProperty_background_y_position, nsCSSValue(yEnumValue, eCSSUnit_Enumerated));
|
||||
xValue = BackgroundPositionMaskToCSSValue(mask, PR_TRUE);
|
||||
yValue = BackgroundPositionMaskToCSSValue(mask, PR_FALSE);
|
||||
AppendValue(eCSSProperty_background_x_position, xValue);
|
||||
AppendValue(eCSSProperty_background_y_position, yValue);
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
|
|
Загрузка…
Ссылка в новой задаче