w3c.css.properties.css1.CssBackgroundPosition Maven / Gradle / Ivy
//
// $Id$
// From Philippe Le Hegaret ([email protected])
//
// (c) COPYRIGHT MIT and INRIA, 1997.
// Please first read the full copyright statement in file COPYRIGHT.html
package org.w3c.css.properties.css1;
import org.w3c.css.util.ApplContext;
import org.w3c.css.util.InvalidParamException;
import org.w3c.css.values.CssExpression;
import org.w3c.css.values.CssIdent;
import org.w3c.css.values.CssPercentage;
import org.w3c.css.values.CssTypes;
import org.w3c.css.values.CssValue;
import static org.w3c.css.values.CssOperator.SPACE;
/**
* @spec http://www.w3.org/TR/2008/REC-CSS1-20080411/#background-position
*/
public class CssBackgroundPosition extends org.w3c.css.properties.css.CssBackgroundPosition {
public static CssIdent[] allowed_values;
public static CssIdent center, top, bottom, left, right;
private static CssPercentage defaultPercent0, defaultPercent50;
private static CssPercentage defaultPercent100;
static {
top = CssIdent.getIdent("top");
bottom = CssIdent.getIdent("bottom");
left = CssIdent.getIdent("left");
right = CssIdent.getIdent("right");
center = CssIdent.getIdent("center");
allowed_values = new CssIdent[5];
allowed_values[0] = top;
allowed_values[1] = bottom;
allowed_values[2] = left;
allowed_values[3] = right;
allowed_values[4] = center;
defaultPercent0 = new CssPercentage(0);
defaultPercent50 = new CssPercentage(50);
defaultPercent100 = new CssPercentage(100);
}
public static boolean checkMatchingIdent(CssIdent ident) {
for (CssIdent id : allowed_values) {
if (id.equals(ident)) {
return true;
}
}
return false;
}
public static CssIdent getMatchingIdent(CssIdent ident) {
for (CssIdent id : allowed_values) {
if (id.equals(ident)) {
return id;
}
}
return null;
}
/**
* Create a new CssBackgroundPosition
*/
public CssBackgroundPosition() {
}
/**
* Creates a new CssBackgroundPosition
*
* @param expression The expression for this property
* @throws InvalidParamException Values are incorrect
*/
public CssBackgroundPosition(ApplContext ac, CssExpression expression,
boolean check) throws InvalidParamException {
int nb_val = expression.getCount();
if (check && nb_val > 2) {
throw new InvalidParamException("unrecognize", ac);
}
setByUser();
setByUser();
CssValue val;
CssBackgroundPositionValue b_val = null;
char op;
// we just accumulate values and check at validation
while (!expression.end()) {
val = expression.getValue();
op = expression.getOperator();
if (inherit.equals(val)) {
if (expression.getCount() > 1) {
throw new InvalidParamException("value", val,
getPropertyName(), ac);
}
value = inherit;
expression.next();
return;
}
if (b_val == null) {
b_val = new CssBackgroundPositionValue();
}
// we will check later
b_val.add(val);
expression.next();
if (op != SPACE) {
throw new InvalidParamException("operator",
((new Character(op)).toString()), ac);
}
}
// if we reach the end in a value that can come in pair
if (b_val != null) {
check(b_val, ac);
value = b_val;
}
}
// check the value
public void check(CssBackgroundPositionValue v, ApplContext ac)
throws InvalidParamException {
int nb_keyword = 0;
int nb_percentage = 0;
int nb_length = 0;
int nb_values = v.value.size();
if (nb_values > 2) {
throw new InvalidParamException("unrecognize", ac);
}
// basic check
for (CssValue aValue : v.value) {
switch (aValue.getType()) {
case CssTypes.CSS_NUMBER:
aValue.getLength();
case CssTypes.CSS_LENGTH:
nb_length++;
break;
case CssTypes.CSS_PERCENTAGE:
nb_percentage++;
break;
case CssTypes.CSS_IDENT:
nb_keyword++;
break;
default:
throw new InvalidParamException("unrecognize", aValue,
ac);
}
}
// this is unnecessary complex, blame it on the CSS3 spec.
switch (nb_keyword) {
case 0:
// no keyword, so it's easy, it depends on the number
// of values :)
switch (nb_values) {
case 1:
// If only one value is specified, the second value
// is assumed to be 'center'.
v.horizontal = v.value.get(0);
if (v.horizontal.getType() == CssTypes.CSS_NUMBER) {
v.horizontal = defaultPercent0;
}
v.val_horizontal = v.horizontal;
v.val_vertical = defaultPercent50;
break;
case 2:
v.horizontal = v.value.get(0);
if (v.horizontal.getType() == CssTypes.CSS_NUMBER) {
v.horizontal = defaultPercent0;
}
v.val_horizontal = v.horizontal;
v.vertical = v.value.get(1);
if (v.vertical.getType() == CssTypes.CSS_NUMBER) {
v.vertical = defaultPercent0;
}
v.val_vertical = v.vertical;
break;
default:
// should never happen
throw new InvalidParamException("unrecognize",
ac);
}
break;
// we got one keyword... let's have fun...
case 1:
switch (nb_values) {
case 1:
CssIdent ident = (CssIdent) v.value.get(0);
// ugly as we need to set values for equality tests
v.val_vertical = defaultPercent50;
v.val_horizontal = defaultPercent50;
ident = getMatchingIdent(ident);
if (ident != null) {
if (isVertical(ident)) {
v.vertical = ident;
v.val_vertical = identToPercent(ident);
} else {
// horizontal || center
v.horizontal = ident;
v.val_horizontal = identToPercent(ident);
}
break;
}
throw new InvalidParamException("unrecognize",
ident, getPropertyName(), ac);
case 2:
// one ident, two values... first MUST be horizontal
// and second vertical
CssValue val0 = v.value.get(0);
if (val0.getType() == CssTypes.CSS_IDENT) {
ident = getMatchingIdent((CssIdent) val0);
if (ident == null) {
throw new InvalidParamException("unrecognize",
ident, getPropertyName(), ac);
}
if (isVertical(ident)) {
throw new InvalidParamException("incompatible",
ident, v.value.get(1), ac);
}
v.horizontal = ident;
v.val_horizontal = identToPercent(ident);
// and the vertical value...
v.vertical = v.value.get(1);
if (v.vertical.getType() == CssTypes.CSS_NUMBER) {
v.vertical = defaultPercent0;
}
v.val_vertical = v.vertical;
} else {
CssValue value1 = v.value.get(1);
if (value1.getType() != CssTypes.CSS_IDENT) {
throw new InvalidParamException("unrecognize",
value1, getPropertyName(), ac);
}
ident = getMatchingIdent((CssIdent) value1);
if (ident == null) {
throw new InvalidParamException("unrecognize",
ident, getPropertyName(), ac);
}
if (isHorizontal(ident)) {
throw new InvalidParamException("incompatible",
val0, value1, ac);
}
v.vertical = ident;
v.val_vertical = identToPercent(ident);
// and the first value
v.horizontal = val0;
if (v.horizontal.getType() == CssTypes.CSS_NUMBER) {
v.horizontal = defaultPercent0;
}
v.val_horizontal = v.horizontal;
}
break;
default:
// one ident, 3 or 4 values is not allowed
throw new InvalidParamException("unrecognize",
ac);
}
break;
default:
// we got two keywords for two values, yeah!
CssIdent id1 = (CssIdent) v.value.get(0);
CssIdent id2 = (CssIdent) v.value.get(1);
if (((isVertical(id1) && isVertical(id2))) ||
(isHorizontal(id1) && isHorizontal(id2))) {
throw new InvalidParamException("incompatible",
id1, id2, ac);
}
if (isVertical(id1) || isHorizontal(id2)) {
v.horizontal = id2;
v.val_horizontal = identToPercent(id2);
v.vertical = id1;
v.val_vertical = identToPercent(id1);
} else {
v.horizontal = id1;
v.val_horizontal = identToPercent(id1);
v.vertical = id2;
v.val_vertical = identToPercent(id2);
}
}
}
public CssBackgroundPosition(ApplContext ac, CssExpression expression)
throws InvalidParamException {
this(ac, expression, false);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy