
w3c.css.values.CssAttr Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cssvalidator Show documentation
Show all versions of cssvalidator Show documentation
Backend for the W3C CSS Validation Service
//
// @author Yves Lafon
//
// (c) COPYRIGHT MIT, ERCIM, Keio, Beihang, 2016.
// Please first read the full copyright statement in file COPYRIGHT.html
package org.w3c.css.values;
import org.w3c.css.properties.css.CssProperty;
import org.w3c.css.util.ApplContext;
import org.w3c.css.util.CssVersion;
import org.w3c.css.util.InvalidParamException;
import java.math.BigDecimal;
import java.util.HashMap;
import static org.w3c.css.values.CssOperator.COMMA;
import static org.w3c.css.values.CssOperator.SPACE;
/**
* A CSS Attr.
*
* @spec https://www.w3.org/TR/2015/CR-css-values-3-20150611/#attr-notation
*/
public class CssAttr extends CssCheckableValue {
public static HashMap typeMap;
static {
/* @spec https://www.w3.org/TR/2015/CR-css-values-3-20150611/#typedef-type-or-unit */
typeMap = new HashMap<>();
typeMap.put(CssIdent.getIdent("color"), CssTypes.CSS_COLOR);
typeMap.put(CssIdent.getIdent("string"), CssTypes.CSS_STRING);
typeMap.put(CssIdent.getIdent("url"), CssTypes.CSS_URL);
typeMap.put(CssIdent.getIdent("integer"), CssTypes.CSS_NUMBER);
typeMap.put(CssIdent.getIdent("number"), CssTypes.CSS_NUMBER);
typeMap.put(CssIdent.getIdent("%"), CssTypes.CSS_PERCENTAGE);
// length
String[] _length_tokens = {"length", "em", "ex", "ch", "rem",
"vw", "vh", "vmin", "vmax",
"mm", "cm", "q", "in", "pt", "pc", "px"};
for (String s : _length_tokens) {
typeMap.put(CssIdent.getIdent(s), CssTypes.CSS_LENGTH);
}
// angle
String[] _angle_tokens = {"angle", "deg", "rad", "grad", "turn"};
for (String s : _angle_tokens) {
typeMap.put(CssIdent.getIdent(s), CssTypes.CSS_ANGLE);
}
// time
String[] _time_tokens = {"time", "ms", "s"};
for (String s : _time_tokens) {
typeMap.put(CssIdent.getIdent(s), CssTypes.CSS_TIME);
}
// frequency
String[] _frequency_tokens = {"frequency", "Hz", "kHz"};
for (String s : _frequency_tokens) {
typeMap.put(CssIdent.getIdent(s), CssTypes.CSS_FREQUENCY);
}
}
public static final int type = CssTypes.CSS_ATTR;
public final int getRawType() {
return type;
}
public final int getType() {
if (computed_type == CssTypes.CSS_UNKNOWN) {
return type;
}
return computed_type;
}
ApplContext ac;
int computed_type = CssTypes.CSS_UNKNOWN;
CssValue value = null;
CssValue value_type = null;
CssValue fallback_value = null;
String _ts = null;
/**
* Create a new CssAttr
*/
public CssAttr() {
}
public void set(String s, ApplContext ac) throws InvalidParamException {
// we don't support this way of setting the value
// as we rely on the parsing a CssExpression
throw new InvalidParamException("unrecognize", s, ac);
}
public void setValue(BigDecimal d) {
// we don't support this way of setting the value
// as we rely on the parsing a CssExpression
}
public void setValue(CssExpression exp, ApplContext ac)
throws InvalidParamException {
CssValue val;
char op;
int count = exp.getCount();
// for levels before CSS3, attr only got a single value
if (count > 3 || (count > 1 && ac.getCssVersion().compareTo(CssVersion.CSS3) < 0)) {
throw new InvalidParamException("unrecognize", ac);
}
val = exp.getValue();
op = exp.getOperator();
if (val.getType() != CssTypes.CSS_IDENT) {
throw new InvalidParamException("value",
val.toString(), "attr()", ac);
}
value = val;
// by default we have a Css_String
computed_type = CssTypes.CSS_STRING;
exp.next();
// check the
while (!exp.end()) {
val = exp.getValue();
switch (op) {
case SPACE:
// first we must ensure that we didn't get the fallback value first
if (fallback_value != null || value_type != null) {
throw new InvalidParamException("unrecognize", ac);
}
if (val.getType() == CssTypes.CSS_IDENT) {
computed_type = _checkType((CssIdent) val);
value_type = val;
break;
}
throw new InvalidParamException("value",
val.toString(), "attr()", ac);
case COMMA:
fallback_value = val;
// we should have a computed_type by then.
// let's check the value.
if (fallback_value.getType() != computed_type) {
// deal with percentage and numbers
int fb_type = fallback_value.getType();
if (fb_type == CssTypes.CSS_NUMBER) {
// number can be another type only when its value is zero
fallback_value.getCheckableValue().checkEqualsZero(ac, "");
}
if (fb_type == CssTypes.CSS_PERCENTAGE || fb_type == CssTypes.CSS_NUMBER) {
if ((computed_type == CssTypes.CSS_LENGTH) ||
(computed_type == CssTypes.CSS_ANGLE) ||
(computed_type == CssTypes.CSS_FREQUENCY) ||
(computed_type == CssTypes.CSS_NUMBER) ||
(computed_type == CssTypes.CSS_TIME)) {
break;
}
}
// else, invalid type
throw new InvalidParamException("typevaluemismatch",
fallback_value, value_type, ac);
}
break;
default:
throw new InvalidParamException("operator",
Character.toString(op),
ac);
}
op = exp.getOperator();
exp.next();
}
}
private int _checkType(CssIdent ident)
throws InvalidParamException {
Integer t = typeMap.get(ident);
if (t == null) {
throw new InvalidParamException("invalidtype", ident.toString(), "attr()", ac);
}
return t;
}
/**
* Returns the value
*/
public Object get() {
return toString();
}
public String toString() {
if (_ts == null) {
StringBuilder sb = new StringBuilder();
sb.append("attr(").append(value);
if (value_type != null) {
sb.append(' ').append(value_type);
}
if (fallback_value != null) {
sb.append(", ").append(fallback_value);
}
sb.append(')');
_ts = sb.toString();
}
return _ts;
}
public boolean isInteger() {
return false;
}
/**
* Returns true is the value is positive of null
*
* @return a boolean
*/
public boolean isPositive() {
// TODO do our best...
return false;
}
/**
* Returns true is the value is positive of null
*
* @return a boolean
*/
public boolean isStrictlyPositive() {
return false;
// TODO do our best...
}
/**
* Returns true is the value is zero
*
* @return a boolean
*/
public boolean isZero() {
// TODO do our best...
return false;
}
/**
* Compares two values for equality.
*
* @param value The other value.
*/
public boolean equals(Object value) {
return (value instanceof CssAttr &&
toString().equals(((CssAttr) value).toString()));
}
/**
* check if the value is positive or null
*
* @param ac the validation context
* @param callername the property the value is defined in
* @throws org.w3c.css.util.InvalidParamException
*
*/
public void checkPositiveness(ApplContext ac, String callername)
throws InvalidParamException {
// TODO do our best...
if (false /*!isPositive()*/) {
throw new InvalidParamException("negative-value",
toString(), callername, ac);
}
}
/**
* check if the value is strictly positive
*
* @param ac the validation context
* @param callername the property the value is defined in
* @throws org.w3c.css.util.InvalidParamException
*
*/
public void checkStrictPositiveness(ApplContext ac, String callername)
throws InvalidParamException {
// TODO do our best...
if (false/*!isStrictlyPositive()*/) {
throw new InvalidParamException("strictly-positive",
toString(), callername, ac);
}
}
/**
* check if the value is an integer
*
* @param ac the validation context
* @param callername the property the value is defined in
* @throws org.w3c.css.util.InvalidParamException
*
*/
public void checkInteger(ApplContext ac, String callername)
throws InvalidParamException {
// TODO do our best...
if (false/*!isInteger()*/) {
throw new InvalidParamException("integer",
toString(), callername, ac);
}
}
/**
* warn if the value is not positive or null
*
* @param ac the validation context
* @param property the property the value is defined in
*/
public boolean warnPositiveness(ApplContext ac, CssProperty property) {
// TODO do our best...
if (false/*!isPositive()*/) {
ac.getFrame().addWarning("negative", toString());
return false;
}
return true;
}
public CssLength getLength() throws InvalidParamException {
if (computed_type == CssTypes.CSS_LENGTH) {
// TODO fixme...
// we might change this to CssCheckableValue instead.
}
throw new ClassCastException("unknown");
}
public CssPercentage getPercentage() throws InvalidParamException {
if (computed_type == CssTypes.CSS_PERCENTAGE) {
// TODO
}
throw new ClassCastException("unknown");
}
public CssNumber getNumber() throws InvalidParamException {
if (computed_type == CssTypes.CSS_NUMBER) {
//TODO
}
throw new ClassCastException("unknown");
}
public CssTime getTime() throws InvalidParamException {
if (computed_type == CssTypes.CSS_TIME) {
//TODO
}
throw new ClassCastException("unknown");
}
public CssAngle getAngle() throws InvalidParamException {
if (computed_type == CssTypes.CSS_ANGLE) {
//TODO
}
throw new ClassCastException("unknown");
}
public CssFrequency getFrequency() throws InvalidParamException {
if (computed_type == CssTypes.CSS_FREQUENCY) {
//TODO
}
throw new ClassCastException("unknown");
}
/**
* check if the value is equal to zero
*
* @param ac the validation context
* @param callername the property the value is defined in
* @throws InvalidParamException
*/
public void checkEqualsZero(ApplContext ac, String callername)
throws InvalidParamException {
// we can't check so we only warn.
// TODO should we do that only for CSS_NUMBER type?
warnEqualsZero(ac, callername);
}
/**
* warn if the value is not zero
*
* @param ac the validation context
* @param callername the property the value is defined in
*/
public boolean warnEqualsZero(ApplContext ac, String callername) {
// TODO should we do that only for CSS_NUMBER type?
if (!isZero()) {
ac.getFrame().addWarning("dynamic", new String[]{toString(), callername});
return false;
}
return true;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy