зеркало из 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_BOTTOM 0x04
|
||||||
#define BG_LEFT 0x08
|
#define BG_LEFT 0x08
|
||||||
#define BG_RIGHT 0x10
|
#define BG_RIGHT 0x10
|
||||||
#define BG_CENTER1 0x20
|
#define BG_CTB (BG_CENTER | BG_TOP | BG_BOTTOM)
|
||||||
#define BG_CENTER2 0x40
|
#define BG_CLR (BG_CENTER | BG_LEFT | BG_RIGHT)
|
||||||
|
|
||||||
// Note: Don't change this table unless you update
|
// Note: Don't change this table unless you update
|
||||||
// parseBackgroundPosition!
|
// parseBackgroundPosition!
|
||||||
|
@ -4442,6 +4442,30 @@ PRBool CSSParserImpl::ParseAzimuth(nsresult& aErrorCode, nsCSSValue& aValue)
|
||||||
return PR_FALSE;
|
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)
|
PRBool CSSParserImpl::ParseBackground(nsresult& aErrorCode)
|
||||||
{
|
{
|
||||||
const PRInt32 numProps = 6;
|
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 & 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()) {
|
if (eCSSUnit_Enumerated == values[4].GetUnit()) {
|
||||||
switch (values[4].GetIntValue()) {
|
PRInt32 mask = values[4].GetIntValue();
|
||||||
case BG_CENTER:
|
values[4] = BackgroundPositionMaskToCSSValue(mask, PR_TRUE);
|
||||||
values[4].SetIntValue(50, eCSSUnit_Enumerated);
|
values[5] = BackgroundPositionMaskToCSSValue(mask, PR_FALSE);
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
values[5].SetPercentValue(0.5f);
|
values[5].SetPercentValue(0.5f);
|
||||||
|
@ -4499,9 +4498,9 @@ PRBool CSSParserImpl::ParseBackground(nsresult& aErrorCode)
|
||||||
else { // both x & y values
|
else { // both x & y values
|
||||||
nsCSSUnit xUnit = values[4].GetUnit();
|
nsCSSUnit xUnit = values[4].GetUnit();
|
||||||
nsCSSUnit yUnit = values[5].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) {
|
if (eCSSUnit_Enumerated == yUnit) {
|
||||||
PRInt32 xValue = values[4].GetIntValue();
|
|
||||||
PRInt32 yValue = values[5].GetIntValue();
|
PRInt32 yValue = values[5].GetIntValue();
|
||||||
if (0 != (xValue & (BG_LEFT | BG_RIGHT)) && // x is really an x value
|
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
|
0 != (yValue & (BG_LEFT | BG_RIGHT))) { // y is also an x value
|
||||||
|
@ -4517,40 +4516,27 @@ PRBool CSSParserImpl::ParseBackground(nsresult& aErrorCode)
|
||||||
xValue = yValue;
|
xValue = yValue;
|
||||||
yValue = holdXValue;
|
yValue = holdXValue;
|
||||||
}
|
}
|
||||||
switch (xValue) {
|
NS_ASSERTION(xValue & BG_CLR, "bad x value");
|
||||||
case BG_LEFT:
|
NS_ASSERTION(yValue & BG_CTB, "bad y value");
|
||||||
values[4].SetIntValue(0, eCSSUnit_Enumerated);
|
values[4] = BackgroundPositionMaskToCSSValue(xValue, PR_TRUE);
|
||||||
break;
|
values[5] = BackgroundPositionMaskToCSSValue(yValue, PR_FALSE);
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
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 {
|
else {
|
||||||
if (eCSSUnit_Enumerated == yUnit) {
|
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)
|
PRBool CSSParserImpl::ParseBackgroundPosition(nsresult& aErrorCode)
|
||||||
{
|
{
|
||||||
// First try a number or a length value
|
// First try a percentage or a length value
|
||||||
nsCSSValue xValue;
|
nsCSSValue xValue, yValue;
|
||||||
if (ParseVariant(aErrorCode, xValue, VARIANT_HLP, nsnull)) {
|
if (ParseVariant(aErrorCode, xValue, VARIANT_HLP, nsnull)) {
|
||||||
if (eCSSUnit_Inherit == xValue.GetUnit() ||
|
if (eCSSUnit_Inherit == xValue.GetUnit() ||
|
||||||
eCSSUnit_Initial == xValue.GetUnit()) { // both are inherited or both are set to initial
|
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;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
// We have one number/length. Get the optional second number/length.
|
// We have one percentage/length. Get the optional second
|
||||||
nsCSSValue yValue;
|
// percentage/length/keyword.
|
||||||
if (ParseVariant(aErrorCode, yValue, VARIANT_LP, nsnull)) {
|
if (ParseVariant(aErrorCode, yValue, VARIANT_LP, nsnull)) {
|
||||||
// We have two numbers
|
// We have two numbers
|
||||||
if (ExpectEndProperty(aErrorCode, PR_TRUE)) {
|
if (ExpectEndProperty(aErrorCode, PR_TRUE)) {
|
||||||
|
@ -4622,8 +4608,23 @@ PRBool CSSParserImpl::ParseBackgroundPosition(nsresult& aErrorCode)
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have one number which is the x position. Create an value for
|
if (ParseEnum(aErrorCode, yValue, kBackgroundXYPositionKTable)) {
|
||||||
// the vertical position which is of value 50%
|
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)) {
|
if (ExpectEndProperty(aErrorCode, PR_TRUE)) {
|
||||||
AppendValue(eCSSProperty_background_x_position, xValue);
|
AppendValue(eCSSProperty_background_x_position, xValue);
|
||||||
AppendValue(eCSSProperty_background_y_position, nsCSSValue(0.5f, eCSSUnit_Percent));
|
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
|
// any duplicate keywords other than center. We try to get two
|
||||||
// keywords but it's okay if there is only one.
|
// keywords but it's okay if there is only one.
|
||||||
PRInt32 mask = 0;
|
PRInt32 mask = 0;
|
||||||
PRInt32 centerBit = BG_CENTER1;
|
if (ParseEnum(aErrorCode, xValue, kBackgroundXYPositionKTable)) {
|
||||||
for (PRInt32 i = 0; i < 2; i++) {
|
|
||||||
if (PR_FALSE == ParseEnum(aErrorCode, xValue, kBackgroundXYPositionKTable)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
PRInt32 bit = xValue.GetIntValue();
|
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;
|
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,
|
// Check for bad input. Bad input consists of no matching keywords,
|
||||||
|
@ -4664,22 +4677,12 @@ PRBool CSSParserImpl::ParseBackgroundPosition(nsresult& aErrorCode)
|
||||||
return PR_FALSE;
|
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)) {
|
if (ExpectEndProperty(aErrorCode, PR_TRUE)) {
|
||||||
// Create style values
|
// Create style values
|
||||||
AppendValue(eCSSProperty_background_x_position, nsCSSValue(xEnumValue, eCSSUnit_Enumerated));
|
xValue = BackgroundPositionMaskToCSSValue(mask, PR_TRUE);
|
||||||
AppendValue(eCSSProperty_background_y_position, nsCSSValue(yEnumValue, eCSSUnit_Enumerated));
|
yValue = BackgroundPositionMaskToCSSValue(mask, PR_FALSE);
|
||||||
|
AppendValue(eCSSProperty_background_x_position, xValue);
|
||||||
|
AppendValue(eCSSProperty_background_y_position, yValue);
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
|
|
|
@ -3976,8 +3976,8 @@ PRBool CSSParserImpl::ParseProperty(nsresult& aErrorCode,
|
||||||
#define BG_BOTTOM 0x04
|
#define BG_BOTTOM 0x04
|
||||||
#define BG_LEFT 0x08
|
#define BG_LEFT 0x08
|
||||||
#define BG_RIGHT 0x10
|
#define BG_RIGHT 0x10
|
||||||
#define BG_CENTER1 0x20
|
#define BG_CTB (BG_CENTER | BG_TOP | BG_BOTTOM)
|
||||||
#define BG_CENTER2 0x40
|
#define BG_CLR (BG_CENTER | BG_LEFT | BG_RIGHT)
|
||||||
|
|
||||||
// Note: Don't change this table unless you update
|
// Note: Don't change this table unless you update
|
||||||
// parseBackgroundPosition!
|
// parseBackgroundPosition!
|
||||||
|
@ -4442,6 +4442,30 @@ PRBool CSSParserImpl::ParseAzimuth(nsresult& aErrorCode, nsCSSValue& aValue)
|
||||||
return PR_FALSE;
|
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)
|
PRBool CSSParserImpl::ParseBackground(nsresult& aErrorCode)
|
||||||
{
|
{
|
||||||
const PRInt32 numProps = 6;
|
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 & 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()) {
|
if (eCSSUnit_Enumerated == values[4].GetUnit()) {
|
||||||
switch (values[4].GetIntValue()) {
|
PRInt32 mask = values[4].GetIntValue();
|
||||||
case BG_CENTER:
|
values[4] = BackgroundPositionMaskToCSSValue(mask, PR_TRUE);
|
||||||
values[4].SetIntValue(50, eCSSUnit_Enumerated);
|
values[5] = BackgroundPositionMaskToCSSValue(mask, PR_FALSE);
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
values[5].SetPercentValue(0.5f);
|
values[5].SetPercentValue(0.5f);
|
||||||
|
@ -4499,9 +4498,9 @@ PRBool CSSParserImpl::ParseBackground(nsresult& aErrorCode)
|
||||||
else { // both x & y values
|
else { // both x & y values
|
||||||
nsCSSUnit xUnit = values[4].GetUnit();
|
nsCSSUnit xUnit = values[4].GetUnit();
|
||||||
nsCSSUnit yUnit = values[5].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) {
|
if (eCSSUnit_Enumerated == yUnit) {
|
||||||
PRInt32 xValue = values[4].GetIntValue();
|
|
||||||
PRInt32 yValue = values[5].GetIntValue();
|
PRInt32 yValue = values[5].GetIntValue();
|
||||||
if (0 != (xValue & (BG_LEFT | BG_RIGHT)) && // x is really an x value
|
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
|
0 != (yValue & (BG_LEFT | BG_RIGHT))) { // y is also an x value
|
||||||
|
@ -4517,40 +4516,27 @@ PRBool CSSParserImpl::ParseBackground(nsresult& aErrorCode)
|
||||||
xValue = yValue;
|
xValue = yValue;
|
||||||
yValue = holdXValue;
|
yValue = holdXValue;
|
||||||
}
|
}
|
||||||
switch (xValue) {
|
NS_ASSERTION(xValue & BG_CLR, "bad x value");
|
||||||
case BG_LEFT:
|
NS_ASSERTION(yValue & BG_CTB, "bad y value");
|
||||||
values[4].SetIntValue(0, eCSSUnit_Enumerated);
|
values[4] = BackgroundPositionMaskToCSSValue(xValue, PR_TRUE);
|
||||||
break;
|
values[5] = BackgroundPositionMaskToCSSValue(yValue, PR_FALSE);
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
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 {
|
else {
|
||||||
if (eCSSUnit_Enumerated == yUnit) {
|
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)
|
PRBool CSSParserImpl::ParseBackgroundPosition(nsresult& aErrorCode)
|
||||||
{
|
{
|
||||||
// First try a number or a length value
|
// First try a percentage or a length value
|
||||||
nsCSSValue xValue;
|
nsCSSValue xValue, yValue;
|
||||||
if (ParseVariant(aErrorCode, xValue, VARIANT_HLP, nsnull)) {
|
if (ParseVariant(aErrorCode, xValue, VARIANT_HLP, nsnull)) {
|
||||||
if (eCSSUnit_Inherit == xValue.GetUnit() ||
|
if (eCSSUnit_Inherit == xValue.GetUnit() ||
|
||||||
eCSSUnit_Initial == xValue.GetUnit()) { // both are inherited or both are set to initial
|
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;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
// We have one number/length. Get the optional second number/length.
|
// We have one percentage/length. Get the optional second
|
||||||
nsCSSValue yValue;
|
// percentage/length/keyword.
|
||||||
if (ParseVariant(aErrorCode, yValue, VARIANT_LP, nsnull)) {
|
if (ParseVariant(aErrorCode, yValue, VARIANT_LP, nsnull)) {
|
||||||
// We have two numbers
|
// We have two numbers
|
||||||
if (ExpectEndProperty(aErrorCode, PR_TRUE)) {
|
if (ExpectEndProperty(aErrorCode, PR_TRUE)) {
|
||||||
|
@ -4622,8 +4608,23 @@ PRBool CSSParserImpl::ParseBackgroundPosition(nsresult& aErrorCode)
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have one number which is the x position. Create an value for
|
if (ParseEnum(aErrorCode, yValue, kBackgroundXYPositionKTable)) {
|
||||||
// the vertical position which is of value 50%
|
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)) {
|
if (ExpectEndProperty(aErrorCode, PR_TRUE)) {
|
||||||
AppendValue(eCSSProperty_background_x_position, xValue);
|
AppendValue(eCSSProperty_background_x_position, xValue);
|
||||||
AppendValue(eCSSProperty_background_y_position, nsCSSValue(0.5f, eCSSUnit_Percent));
|
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
|
// any duplicate keywords other than center. We try to get two
|
||||||
// keywords but it's okay if there is only one.
|
// keywords but it's okay if there is only one.
|
||||||
PRInt32 mask = 0;
|
PRInt32 mask = 0;
|
||||||
PRInt32 centerBit = BG_CENTER1;
|
if (ParseEnum(aErrorCode, xValue, kBackgroundXYPositionKTable)) {
|
||||||
for (PRInt32 i = 0; i < 2; i++) {
|
|
||||||
if (PR_FALSE == ParseEnum(aErrorCode, xValue, kBackgroundXYPositionKTable)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
PRInt32 bit = xValue.GetIntValue();
|
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;
|
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,
|
// Check for bad input. Bad input consists of no matching keywords,
|
||||||
|
@ -4664,22 +4677,12 @@ PRBool CSSParserImpl::ParseBackgroundPosition(nsresult& aErrorCode)
|
||||||
return PR_FALSE;
|
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)) {
|
if (ExpectEndProperty(aErrorCode, PR_TRUE)) {
|
||||||
// Create style values
|
// Create style values
|
||||||
AppendValue(eCSSProperty_background_x_position, nsCSSValue(xEnumValue, eCSSUnit_Enumerated));
|
xValue = BackgroundPositionMaskToCSSValue(mask, PR_TRUE);
|
||||||
AppendValue(eCSSProperty_background_y_position, nsCSSValue(yEnumValue, eCSSUnit_Enumerated));
|
yValue = BackgroundPositionMaskToCSSValue(mask, PR_FALSE);
|
||||||
|
AppendValue(eCSSProperty_background_x_position, xValue);
|
||||||
|
AppendValue(eCSSProperty_background_y_position, yValue);
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче