W3C home > Mailing lists > Public > www-validator-cvs@w3.org > January 2010

2002/css-validator/org/w3c/css/properties/css2 CssBackgroundAttachmentCSS2.java,NONE,1.1 CssBackgroundCSS2.java,NONE,1.1 CssBackgroundColorCSS2.java,NONE,1.1 CssBackgroundImageCSS2.java,NONE,1.1 CssBackgroundPositionCSS2.java,NONE,1.1 CssBackgroundRepeatCSS2.java,NONE,1.1 CssDisplayCSS2.java,NONE,1.1 Css2Properties.java,1.2,1.3 Css2Property.java,1.2,1.3 Css2Style.java,1.2,1.3

From: Yves Lafon via cvs-syncmail <cvsmail@w3.org>
Date: Tue, 05 Jan 2010 13:49:48 +0000
To: www-validator-cvs@w3.org
Message-Id: <E1NS9ne-0006mV-Us@lionel-hutz.w3.org>
Update of /sources/public/2002/css-validator/org/w3c/css/properties/css2
In directory hutz:/tmp/cvs-serv25562/org/w3c/css/properties/css2

Modified Files:
	Css2Properties.java Css2Property.java Css2Style.java 
Added Files:
	CssBackgroundAttachmentCSS2.java CssBackgroundCSS2.java 
	CssBackgroundColorCSS2.java CssBackgroundImageCSS2.java 
	CssBackgroundPositionCSS2.java CssBackgroundRepeatCSS2.java 
	CssDisplayCSS2.java 
Log Message:
Implementation of css3-background (partial, missing background-color and background, also borders not done)
cf. http://www.w3.org/TR/2009/CR-css3-background-20091217/

moved and corrected implementation of css3-multicol 
cf. http://www.w3.org/TR/2009/CR-css3-multicol-20091217/

Some reorganization of code.



--- NEW FILE: CssBackgroundImageCSS2.java ---
//
// $Id: CssBackgroundImageCSS2.java,v 1.1 2010/01/05 13:49:46 ylafon Exp $
// From Philippe Le Hegaret (Philippe.Le_Hegaret@sophia.inria.fr)
//
// (c) COPYRIGHT MIT and INRIA, 1997.
// Please first read the full copyright statement in file COPYRIGHT.html

package org.w3c.css.properties.css2;

import org.w3c.css.parser.CssStyle;
import org.w3c.css.properties.css.CssBackgroundImage;
import org.w3c.css.properties.css.CssProperty;
import org.w3c.css.properties.css1.Css1Style;
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.CssTypes;
import org.w3c.css.values.CssValue;

/**
 * <H4>
 * &nbsp;&nbsp; 'background-image'
 * </H4>
 * <p/>
 * <EM>Value:</EM> &lt;url&gt; | none<BR>
 * <EM>Initial:</EM> none<BR>
 * <EM>Applies to:</EM> all elements<BR>
 * <EM>Inherited:</EM> no<BR>
 * <EM>Percentage values:</EM> N/A<BR>
 * <P> This property sets the background image of an element. When setting a
 * background image, one should also set a background color that will be used
 * when the image is unavailable. When the image is available, it is overlaid
 * on top of the background color.
 * <PRE>
 * BODY { background-image: url(marble.gif) }
 * P { background-image: none }
 * </PRE>
 *
 * @version $Revision: 1.1 $
 */
public class CssBackgroundImageCSS2 extends CssBackgroundImage {

    public CssValue url = null;

    static public boolean checkMatchingIdent(CssIdent idval) {
        return none.equals(idval);
    }

    /**
     * Create a new CssBackgroundImageCSS2
     */
    public CssBackgroundImageCSS2() {
        url = none;
    }

    /**
     * Creates a new CssBackgroundImageCSS2
     *
     * @param ac  The context
     * @param expression The expression for this property
     * @param check if count check must be performed
     * @throws InvalidParamException Values are incorrect
     */
    public CssBackgroundImageCSS2(ApplContext ac, CssExpression expression,
                                  boolean check) throws InvalidParamException {

        if (check && expression.getCount() > 1) {
            throw new InvalidParamException("unrecognize", ac);
        }

        setByUser();

        CssValue val = expression.getValue();
        switch (val.getType()) {
            case CssTypes.CSS_URL:
                url = val;
                break;
            case CssTypes.CSS_IDENT:
                if (inherit.equals(val)) {
                    url = inherit;
                    break;
                }
                if (none.equals(val)) {
                    url = none;
                    break;
                }
            default:
                throw new InvalidParamException("value", val,
                        getPropertyName(), ac);
        }
        expression.next();
    }

    public CssBackgroundImageCSS2(ApplContext ac, CssExpression expression)
            throws InvalidParamException {
        this(ac, expression, false);
    }

    /**
     * Returns the value of this property
     */
    public Object get() {
        return url;
    }

    /**
     * Returns true if this property is "softly" inherited
     * e.g. his value equals inherit
     */
    public boolean isSoftlyInherited() {
        return (url == inherit);
    }

    /**
     * Returns a string representation of the object.
     */
    public String toString() {
        return url.toString();
    }


    /**
     * Add this property to the CssStyle.
     *
     * @param style The CssStyle
     */
    public void addToStyle(ApplContext ac, CssStyle style) {
        CssBackgroundCSS2 cssBackground = ((Css1Style) style).cssBackgroundCSS2;
        if (cssBackground.image != null) {
            style.addRedefinitionWarning(ac, this);
        }
        cssBackground.image = this;
    }

    /**
     * Get this property in the style.
     *
     * @param style   The style where the property is
     * @param resolve if true, resolve the style to find this property
     */
    public CssProperty getPropertyInStyle(CssStyle style, boolean resolve) {
        if (resolve) {
            return ((Css1Style) style).getBackgroundImageCSS2();
        } else {
            return ((Css1Style) style).cssBackgroundCSS2.image;
        }
    }

    /**
     * Compares two properties for equality.
     *
     * @param property The other property.
     */
    public boolean equals(CssProperty property) {
        return ((property == null && url == null)
                || (property instanceof CssBackgroundImageCSS2 &&
                url != null &&
                url.equals(((CssBackgroundImageCSS2) property).url)));
    }

    /**
     * Is the value of this property is a default value.
     * It is used by all macro for the function <code>print</code>
     */
    public boolean isDefault() {
        return (url == none);
    }

}

--- NEW FILE: CssBackgroundRepeatCSS2.java ---
//
// $Id: CssBackgroundRepeatCSS2.java,v 1.1 2010/01/05 13:49:46 ylafon Exp $
// From Philippe Le Hegaret (Philippe.Le_Hegaret@sophia.inria.fr)
//
// (c) COPYRIGHT MIT and INRIA, 1997.
// Please first read the full copyright statement in file COPYRIGHT.html
package org.w3c.css.properties.css2;

import org.w3c.css.parser.CssStyle;
import org.w3c.css.properties.css.CssBackgroundRepeat;
import org.w3c.css.properties.css.CssProperty;
import org.w3c.css.properties.css1.Css1Style;
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.CssTypes;
import org.w3c.css.values.CssValue;

import java.util.HashMap;

/**
 * <H4>
 * <A NAME="background-repeat">5.3.4 &nbsp;&nbsp; 'background-repeat'</A>
 * </H4>
 * <p/>
 * <EM>Value:</EM> repeat | repeat-x | repeat-y | no-repeat<BR>
 * <EM>Initial:</EM> repeat<BR>
 * <EM>Applies to:</EM> all elements<BR>
 * <EM>Inherited:</EM> no<BR>
 * <EM>Percentage values:</EM> N/A<BR>
 * <p/>
 * If a background image is specified, the value of 'background-repeat' determines
 * how/if the image is repeated.
 * <p/>
 * A value of 'repeat' means that the image is repeated both horizontally and
 * vertically. The 'repeat-x' ('repeat-y') value makes the image repeat horizontally
 * (vertically), to create a single band of images from one side to the other.
 * With a value of 'no-repeat', the image is not repeated.
 * <PRE>
 * BODY {
 * background: red url(pendant.gif);
 * background-repeat: repeat-y;
 * }
 * </PRE>
 * <p/>
 * In the example above, the image will only be repeated vertically.
 *
 * @version $Revision: 1.1 $
 */
public class CssBackgroundRepeatCSS2 extends CssBackgroundRepeat {
    // FIXME TODO is that the best way ?
    
    public static boolean checkMatchingIdent(CssIdent ident) {
        return allowed_values.containsValue(ident);
    }
    
    public static HashMap<String, CssIdent> allowed_values;

    static {
        allowed_values = new HashMap<String, CssIdent>();
        String[] REPEAT = {"repeat", "repeat-x", "repeat-y", "no-repeat"};

        for (String aREPEAT : REPEAT) {
            allowed_values.put(aREPEAT, CssIdent.getIdent(aREPEAT));
        }
    }

    public CssValue value;

    /**
     * Create a new CssBackgroundRepeatCSS2
     */
    public CssBackgroundRepeatCSS2() {
        value = repeat;
    }

    /**
     * Set the value of the property
     *
     * @param expression The expression for this property
     * @throws InvalidParamException The expression is incorrect
     */
    public CssBackgroundRepeatCSS2(ApplContext ac, CssExpression expression,
                                   boolean check) throws InvalidParamException {

        if (check && expression.getCount() > 1) {
            throw new InvalidParamException("unrecognize", ac);
        }

        CssValue val = expression.getValue();
        setByUser();

        if (val.getType() != CssTypes.CSS_IDENT) {
            throw new InvalidParamException("value", expression.getValue(),
                    getPropertyName(), ac);
        }
        if (inherit.equals(val)) {
            value = inherit;
        } else {
            value = allowed_values.get(val.toString());
            if (value == null) {
                throw new InvalidParamException("value", expression.getValue(),
                        getPropertyName(), ac);
            }
        }
        expression.next();
    }

    public CssBackgroundRepeatCSS2(ApplContext ac, CssExpression expression)
            throws InvalidParamException {
        this(ac, expression, false);
    }

    /**
     * Returns the value of this property
     */
    public Object get() {
        return value;
    }

    /**
     * Returns a string representation of the object.
     */
    public String toString() {
        return value.toString();
    }

    // TODO FIXME get rid of this when Css1Style gets only one background
    /**
     * Add this property to the CssStyle.
     *
     * @param style The CssStyle
     */
    public void addToStyle(ApplContext ac, CssStyle style) {
        CssBackgroundCSS2 cssBackground = ((Css1Style) style).cssBackgroundCSS2;
        if (cssBackground.repeat != null)
            style.addRedefinitionWarning(ac, this);
        cssBackground.repeat = this;
    }

    /**
     * Get this property in the style.
     *
     * @param style   The style where the property is
     * @param resolve if true, resolve the style to find this property
     */
    public CssProperty getPropertyInStyle(CssStyle style, boolean resolve) {
        if (resolve) {
            return ((Css1Style) style).getBackgroundRepeatCSS2();
        } else {
            return ((Css1Style) style).cssBackgroundCSS2.repeat;
        }
    }

    /**
     * Compares two properties for equality.
     *
     * @param property The other property.
     */
    public boolean equals(CssProperty property) {
        return (property instanceof CssBackgroundRepeatCSS2 &&
                value == ((CssBackgroundRepeatCSS2) property).value);
    }

    /**
     * Is the value of this property is a default value.
     * It is used by all macro for the function <code>print</code>
     */
    public boolean isDefault() {
        return (repeat == value);
    }
}




Index: Css2Properties.java
===================================================================
RCS file: /sources/public/2002/css-validator/org/w3c/css/properties/css2/Css2Properties.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- Css2Properties.java	14 Sep 2005 15:14:58 -0000	1.2
+++ Css2Properties.java	5 Jan 2010 13:49:46 -0000	1.3
@@ -6,11 +6,11 @@
 // Please first read the full copyright statement in file COPYRIGHT.html
 package org.w3c.css.properties.css2;
 
-import java.net.URL;
-
-import org.w3c.css.properties.css1.CssProperty;
+import org.w3c.css.properties.css.CssProperty;
 import org.w3c.css.util.Utf8Properties;
 
+import java.net.URL;
+
 /**
  * @version $Revision$
  */
@@ -18,23 +18,23 @@
     public static Utf8Properties properties;
 
     public static String getString(CssProperty property, String prop) {
-	return properties.getProperty(property.getPropertyName() + "." + prop);
+        return properties.getProperty(property.getPropertyName() + "." + prop);
     }
 
     public static boolean getInheritance(CssProperty property) {
-	return getString(property, "inherited").equals("true");
+        return getString(property, "inherited").equals("true");
     }
 
     static {
-	properties = new Utf8Properties();
-	try {
-	    URL url = Css2Properties.class
-	    .getResource("CSS2Default.properties");
-	    properties.load(url.openStream());
-	} catch (Exception e) {
-	    System.err
-	    .println("org.w3c.css.properties2.Css2Properties: couldn't load properties ");
-	    System.err.println("  " + e.toString());
-	}
+        properties = new Utf8Properties();
+        try {
+            URL url;
+            url = Css2Properties.class.getResource("CSS2Default.properties");
+            properties.load(url.openStream());
+        } catch (Exception e) {
+            System.err.println("org.w3c.css.properties2.Css2Properties: " +
+                    "couldn't load properties ");
+            System.err.println("  " + e.toString());
+        }
     }
 }

--- NEW FILE: CssBackgroundColorCSS2.java ---
//
// $Id: CssBackgroundColorCSS2.java,v 1.1 2010/01/05 13:49:46 ylafon Exp $
// From Philippe Le Hegaret (Philippe.Le_Hegaret@sophia.inria.fr)
//
// (c) COPYRIGHT MIT and INRIA, 1997.
// Please first read the full copyright statement in file COPYRIGHT.html

package org.w3c.css.properties.css2;

import org.w3c.css.parser.CssStyle;
import org.w3c.css.properties.css.CssProperty;
import org.w3c.css.properties.css1.Css1Style;
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.CssTypes;
import org.w3c.css.values.CssValue;

/**
 * <H4>
 * &nbsp;&nbsp; 'background-color'
 * </H4>
 * <p/>
 * <EM>Value:</EM> &lt;color&gt; | transparent<BR>
 * <EM>Initial:</EM> transparent<BR>
 * <EM>Applies to:</EM> all elements<BR>
 * <EM>Inherited:</EM> no<BR>
 * <EM>Percentage values:</EM> N/A<BR>
 * <p/>
 * This property sets the background color of an element.
 * <PRE>
 * H1 { background-color: #F00 }
 * </PRE>
 *
 * @version $Revision: 1.1 $
 */
public class CssBackgroundColorCSS2 extends CssProperty {

    public CssValue color;

    public static CssIdent transparent = CssIdent.getIdent("transparent");

    /**
     * Create a new CssBackgroundColorCSS2
     */
    public CssBackgroundColorCSS2() {
        color = transparent;
    }

    /**
     * Create a new CssBackgroundColorCSS2
     *
     * @param expression The expression for this property
     * @throws InvalidParamException Values are incorrect
     */
    public CssBackgroundColorCSS2(ApplContext ac, CssExpression expression,
                                  boolean check) throws InvalidParamException {

        if (check && expression.getCount() > 1) {
            throw new InvalidParamException("unrecognize", ac);
        }

        setByUser();
        CssValue val = expression.getValue();

        switch (val.getType()) {
            case CssTypes.CSS_COLOR:
                setColor(val);
                break;
            case CssTypes.CSS_IDENT:
                if (transparent.equals(val)) {
                    setColor(transparent);
                    break;
                }
                if (inherit.equals(val)) {
                    setColor(inherit);
                    break;
                }
                setColor(new org.w3c.css.values.CssColorCSS2(ac,
                        (String) val.get()));
                break;
            default:
                throw new InvalidParamException("value", val.toString(),
                        getPropertyName(), ac);
        }
        expression.next();
    }

    public CssBackgroundColorCSS2(ApplContext ac, CssExpression expression)
            throws InvalidParamException {
        this(ac, expression, false);
    }

    /**
     * @param color The color to set.
     */
    public void setColor(CssValue color) {
        this.color = color;
    }

    /**
     * Returns the value of this property
     */
    public Object get() {
        return color;
    }

    /**
     * Returns the color
     */
    public final CssValue getColor() {
        return color;
    }

    /**
     * Returns true if this property is "softly" inherited
     * e.g. his value equals inherit
     */
    public boolean isSoftlyInherited() {
        return color.equals(inherit);
    }

    /**
     * Returns a string representation of the object.
     */
    public String toString() {
        if (color != null) {
            return color.toString();
        }
        return "";
    }


    /**
     * Add this property to the CssStyle.
     *
     * @param style The CssStyle
     */
    public void addToStyle(ApplContext ac, CssStyle style) {
        CssBackgroundCSS2 cssBackground = ((Css1Style) style).cssBackgroundCSS2;
        if (cssBackground.color != null)
            style.addRedefinitionWarning(ac, this);
        cssBackground.color = this;
    }

    /**
     * Get this property in the style.
     *
     * @param style   The style where the property is
     * @param resolve if true, resolve the style to find this property
     */
    public CssProperty getPropertyInStyle(CssStyle style, boolean resolve) {
        if (resolve) {
            return ((Css1Style) style).getBackgroundColorCSS2();
        } else {
            return ((Css1Style) style).cssBackgroundCSS2.color;
        }
    }

    /**
     * Compares two properties for equality.
     *
     * @param value The other property.
     */
    public boolean equals(CssProperty property) {
        return (property instanceof CssBackgroundColorCSS2 &&
                color.equals(((CssBackgroundColorCSS2) property).color));
    }

    /**
     * Returns the name of this property
     */
    public String getPropertyName() {
        return "background-color";
    }

    /**
     * Is the value of this property is a default value.
     * It is used by all macro for the function <code>print</code>
     */
    public boolean isDefault() {
        return color == transparent;
    }

}


--- NEW FILE: CssBackgroundAttachmentCSS2.java ---
//
// $Id: CssBackgroundAttachmentCSS2.java,v 1.1 2010/01/05 13:49:46 ylafon Exp $
// From Philippe Le Hegaret (Philippe.Le_Hegaret@sophia.inria.fr)
//
// (c) COPYRIGHT MIT and INRIA, 1997.
// Please first read the full copyright statement in file COPYRIGHT.html
package org.w3c.css.properties.css2;

import org.w3c.css.parser.CssStyle;
import org.w3c.css.properties.css.CssBackgroundAttachment;
import org.w3c.css.properties.css.CssProperty;
import org.w3c.css.properties.css1.Css1Style;
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.CssTypes;
import org.w3c.css.values.CssValue;

import java.util.HashMap;

/**
 * <H4>
 * &nbsp;&nbsp; 'background-attachment'
 * </H4>
 * <p/>
 * <EM>Value:</EM> scroll | fixed<BR>
 * <EM>Initial:</EM> scroll<BR>
 * <EM>Applies to:</EM> all elements<BR>
 * <EM>Inherited:</EM> no<BR>
 * <EM>Percentage values:</EM> N/A<BR>
 * <p/>
 * If a background image is specified, the value of 'background-attachment'
 * determines if it is fixed with regard to the canvas or if it scrolls along
 * with the content.
 * <PRE>
 * BODY {
 * background: red url(pendant.gif);
 * background-repeat: repeat-y;
 * background-attachment: fixed;
 * }
 * </PRE>
 *
 * @version $Revision: 1.1 $
 */
public class CssBackgroundAttachmentCSS2 extends CssBackgroundAttachment {

    public static boolean checkMatchingIdent(CssIdent ident) {
        return allowed_values.containsValue(ident);
    }
    
    static {
        allowed_values = new HashMap<String, CssIdent>();
        scroll = CssIdent.getIdent("scroll");
        allowed_values.put("scroll", scroll);
        allowed_values.put("fixed", CssIdent.getIdent("fixed"));
    }

    CssIdent value;

    /**
     * Create a new CssBackgroundAttachmentCSS2
     */
    public CssBackgroundAttachmentCSS2() {
        value = scroll;
    }

    /**
     * Creates a new CssBackgroundAttachmentCSS2
     *
     * @param expression The expression for this property
     * @throws InvalidParamException Values are incorrect
     */
    public CssBackgroundAttachmentCSS2(ApplContext ac, CssExpression expression,
                                       boolean check) throws InvalidParamException {

        if (check && expression.getCount() > 1) {
            throw new InvalidParamException("unrecognize", ac);
        }

        setByUser();

        CssValue val = expression.getValue();

        if (val.getType() == CssTypes.CSS_IDENT) {
            if (inherit.equals(val)) {
                value = inherit;
                expression.next();
                return;
            }
            CssIdent new_val = allowed_values.get(val.toString());
            if (new_val != null) {
                value = new_val;
                expression.next();
                return;
            }
        }


        throw new InvalidParamException("value", expression.getValue(),
                getPropertyName(), ac);
    }

    public CssBackgroundAttachmentCSS2(ApplContext ac, CssExpression expression)
            throws InvalidParamException {
        this(ac, expression, false);
    }

    /**
     * Returns the value of this property
     */
    public Object get() {
        return value;
    }

    /**
     * Returns true if this property is "softly" inherited
     * e.g. his value equals inherit
     */
    public boolean isSoftlyInherited() {
        return (inherit == value);
    }

    /**
     * Returns a string representation of the object.
     */
    public String toString() {
        return value.toString();
    }

    /**
     * Add this property to the CssStyle.
     *
     * @param style The CssStyle
     */
    public void addToStyle(ApplContext ac, CssStyle style) {
        CssBackgroundCSS2 cssBackground = ((Css1Style) style).cssBackgroundCSS2;
        if (cssBackground.attachment != null)
            style.addRedefinitionWarning(ac, this);
        cssBackground.attachment = this;
    }

    /**
     * Get this property in the style.
     *
     * @param style   The style where the property is
     * @param resolve if true, resolve the style to find this property
     */
    public CssProperty getPropertyInStyle(CssStyle style, boolean resolve) {
        if (resolve) {
            return ((Css1Style) style).getBackgroundAttachmentCSS2();
        } else {
            return ((Css1Style) style).cssBackgroundCSS2.attachment;
        }
    }

    /**
     * Compares two properties for equality.
     *
     * @param property The other property.
     */
    public boolean equals(CssProperty property) {
        return (property instanceof CssBackgroundAttachmentCSS2 &&
                value == ((CssBackgroundAttachmentCSS2) property).value);
    }

    /**
     * Is the value of this property is a default value.
     * It is used by all macro for the function <code>print</code>
     */
    public boolean isDefault() {
        return (scroll == value);
    }

}

--- NEW FILE: CssBackgroundCSS2.java ---
//
// $Id: CssBackgroundCSS2.java,v 1.1 2010/01/05 13:49:46 ylafon Exp $
// From Philippe Le Hegaret (Philippe.Le_Hegaret@sophia.inria.fr)
//
// (c) COPYRIGHT MIT and INRIA, 1997.
// Please first read the full copyright statement in file COPYRIGHT.html
package org.w3c.css.properties.css2;

import org.w3c.css.parser.CssPrinterStyle;
import org.w3c.css.parser.CssSelectors;
import org.w3c.css.parser.CssStyle;
import org.w3c.css.properties.css.CssBackgroundConstants;
import org.w3c.css.properties.css.CssProperty;
import org.w3c.css.properties.css1.Css1Style;
import org.w3c.css.util.ApplContext;
import org.w3c.css.util.InvalidParamException;
import org.w3c.css.values.CssExpression;
import org.w3c.css.values.CssOperator;
import org.w3c.css.values.CssString;
import org.w3c.css.values.CssValue;

/**
 *   <H4>
 *     <A NAME="background">5.3.7 &nbsp;&nbsp; 'background'</A>
 *   </H4>
 *   <P>
 *   <EM>Value:</EM> &lt;background-color&gt; || &lt;background-image&gt; ||
 *   &lt;background-repeat&gt; || &lt;background-attachment&gt; ||
 *   &lt;background-position&gt;<BR>
 *   <EM>Initial:</EM> not defined for shorthand properties<BR>
 *   <EM>Applies to:</EM> all elements<BR>
 *   <EM>Inherited:</EM> no<BR>
 *   <EM>Percentage values:</EM> allowed on &lt;background-position&gt;<BR>
 *   <P>
 *   The 'background' property is a shorthand property for setting the individual
 *   background properties (i.e., 'background-color', 'background-image',
 *   'background-repeat', 'background-attachment' and 'background-position') at
 *   the same place in the style sheet.
 *   <P>
 *   Possible values on the 'background' properties are the set of all possible
 *   values on the individual properties.
 *   <PRE>
 *   BODY { background: red }
 *   P { background: url(chess.png) gray 50% repeat fixed }
 * </PRE>
 *   <P> The 'background' property always sets all the individual background
 *   properties.  In the first rule of the above example, only a value for
 *   'background-color' has been given and the other individual properties are
 *   set to their initial value. In the second rule, all individual properties
 *   have been specified.
 *
 * @version $Revision: 1.1 $
 * @see org.w3c.css.properties.css.CssBackgroundColor
 * @see org.w3c.css.properties.css.CssBackgroundImage
 * @see org.w3c.css.properties.css.CssBackgroundRepeat
 * @see org.w3c.css.properties.css.CssBackgroundAttachment
 * @see org.w3c.css.properties.css.CssBackgroundPosition
 */
public class CssBackgroundCSS2 extends CssProperty
        implements CssOperator, CssBackgroundConstants {

    public CssBackgroundColorCSS2 color;
    public CssBackgroundImageCSS2 image;
    public CssBackgroundRepeatCSS2 repeat;
    public CssBackgroundAttachmentCSS2 attachment;
    public CssBackgroundPositionCSS2 position;

    public boolean same;

    /**
     * Duplicate this property.
     *
     * @see org.w3c.css.css.CssCascadingOrder#order
     */
    public CssProperty duplicate() {
	CssBackgroundCSS2 cloned = (CssBackgroundCSS2) super.duplicate();
	if (cloned != null) {
	    if (color != null) {
		cloned.color = (CssBackgroundColorCSS2) color.duplicate();
	    }
	    if (image != null) {
		cloned.image = (CssBackgroundImageCSS2) image.duplicate();
	    }
	    if (repeat != null) {
		cloned.repeat = (CssBackgroundRepeatCSS2) repeat.duplicate();
	    }
	    if (attachment != null) {
		cloned.attachment = (CssBackgroundAttachmentCSS2) attachment.duplicate();
	    }
	    if (position != null) {
		cloned.position = (CssBackgroundPositionCSS2) position.duplicate();
	    }
	}
	return cloned;
    }

    /**
     * Create a new CssBackgroundCSS2
     */
    public CssBackgroundCSS2() {
    }

    /**
     * Set the value of the property
     *
     * @param expression The expression for this property
     * @exception InvalidParamException The expression is incorrect
     */
    public CssBackgroundCSS2(ApplContext ac, CssExpression expression,
	    boolean check) throws InvalidParamException {

	CssValue val;
	char op;
	boolean find = true;

	// too many values
	if(check && expression.getCount() > 6) {
	    throw new InvalidParamException("unrecognize", ac);
	}

	setByUser();

	boolean manyValues = (expression.getCount() > 1);

	while (find) {
	    find = false;
	    val = expression.getValue();
	    op = expression.getOperator();

	    if (val == null) {
		break;
	    }

	    // if there are many values, we can't have inherit as one of them
	    if(manyValues && val != null && val.equals(inherit)) {
		throw new InvalidParamException("unrecognize", null, null, ac);
	    }
	    // quoted strings are not allowed (CssString)
	    if(check && (val instanceof CssString)) {
		throw new InvalidParamException("unrecognize", ac);
	    }

	    if (color == null) {
		try {
		    color = new CssBackgroundColorCSS2(ac, expression);
		    find = true;
		} catch (InvalidParamException e) {
		    // nothing to do, image will test this value
		}
	    }
	    if (!find && image == null) {
		try {
		    image = new CssBackgroundImageCSS2(ac, expression);
		    find = true;
		} catch (InvalidParamException e) {
		    // nothing to do, repeat will test this value
		}
	    }
	    if (!find && repeat == null) {
		try {
		    repeat = new CssBackgroundRepeatCSS2(ac, expression);
		    find = true;
		} catch (InvalidParamException e) {
		    // nothing to do, attachment will test this value
		}
	    }
	    if (!find && attachment == null) {
		try {
		    attachment = new CssBackgroundAttachmentCSS2(ac, expression);
		    find = true;
		} catch (InvalidParamException e) {
		    // nothing to do, position will test this value
		}
	    }
	    if (!find && position == null) {
		try {
		    position = new CssBackgroundPositionCSS2(ac, expression);
		    find = true;
		} catch (InvalidParamException e) {
		    // nothing to do
		}
	    }
	    if(check && val != null && !find) {
		throw new InvalidParamException("unrecognize", ac);
	    }
	    if (op != SPACE) {
		throw new InvalidParamException("operator",
						((new Character(op)).toString()),
						ac);
	    }
	    if(check && !find && val != null) {
		throw new InvalidParamException("unrecognize", ac);
	    }
	}
	/*
	if (color == null)
	    color = new CssBackgroundColorCSS2();
	if (image == null)
	    image = new CssBackgroundImageCSS2();
	if (repeat == null)
	    repeat = new CssBackgroundRepeatCSS2();
	if (attachment == null)
	    attachment = new CssBackgroundAttachmentCSS2();
	if (position == null)
	    position = new CssBackgroundPositionCSS2();
	*/
    }

    public CssBackgroundCSS2(ApplContext ac, CssExpression expression)
	throws InvalidParamException {
	this(ac, expression, false);
    }

    /**
     * @return Returns the attachment.
     */
    public CssBackgroundAttachmentCSS2 getAttachment() {
        return attachment;
    }

    /**
     * @param attachment The attachment to set.
     */
    public void setAttachment(CssBackgroundAttachmentCSS2 attachment) {
        this.attachment = attachment;
    }

    /**
     * @return Returns the image.
     */
    public CssBackgroundImageCSS2 getImage() {
        return image;
    }

    /**
     * @param image The image to set.
     */
    public void setImage(CssBackgroundImageCSS2 image) {
        this.image = image;
    }

    /**
     * @return Returns the repeat.
     */
    public CssBackgroundRepeatCSS2 getRepeat() {
        return repeat;
    }

    /**
     * @param repeat The repeat to set.
     */
    public void setRepeat(CssBackgroundRepeatCSS2 repeat) {
        this.repeat = repeat;
    }

    /**
     * @return Returns the same.
     */
    public boolean isSame() {
        return same;
    }

    /**
     * @param same The same to set.
     */
    public void setSame(boolean same) {
        this.same = same;
    }

    /**
     * Returns the color
     */
    public final CssBackgroundColorCSS2 getColor2() {
	return color;
    }

    /**
     * @param color The color to set.
     */
    public void setColor(CssBackgroundColorCSS2 color) {
        this.color = color;
    }

    /**
     * @return Returns the position.
     */
    public CssBackgroundPositionCSS2 getPosition() {
        return position;
    }

    /**
     * @param position The position to set.
     */
    public void setPosition(CssBackgroundPositionCSS2 position) {
        this.position = position;
    }

    /**
     * Returns the value of this property
     */
    public Object get() {
	return color;
    }

    /**
     * Returns the color
     */
    public final CssValue getColor() {
	if (color == null) {
	    return null;
	} else {
	    return color.getColor();
	}
    }

    /**
     * Returns the name of this property
     */
    public String getPropertyName() {
	return "background";
    }

    /**
     * Returns a string representation of the object.
     */
    public String toString() {
	/*
	if (same) {
	    return inherit.toString();
	} else {*/
	StringBuilder sb = new StringBuilder();
	boolean addspace = false;

	if (color != null) {
	    sb.append(color);
	    addspace = true;
	}
	if (image != null) {
	    if(addspace) {
		sb.append(' ');
	    }
	    sb.append(image);
	    addspace = true;
	}
	if (repeat != null) {
	    if (addspace) {
		sb.append(' ');
	    }
	    sb.append(repeat);
	    addspace = true;
	}
	if (attachment != null) {
	    if (addspace) {
		sb.append(' ');
	    }
	    sb.append(attachment);
	    addspace = true;
	}
	if (position != null) {
	    if (addspace) {
		sb.append(' ');
	    }
	    sb.append(position);
	}
	return sb.toString();
	/*
	if (color.byUser)
	    ret += " " + color.toString();
	if (image.byUser)
	    ret += " " + image.toString();
	if (image.byUser)
	    ret += " " + repeat.toString();
	if (attachment.byUser)
	    ret += " " + attachment.toString();
	if (position.byUser)
	    ret += " " + position.toString();
	return ret.trim();
	*/
	//}
    }

    /**
     * Set this property to be important.
     * Overrides this method for a macro
     */
    public void setImportant() {
	if(color != null) {
	    color.important = true;
	}
	if(image != null) {
	    image.important = true;
	}
	if(repeat != null) {
	    repeat.important = true;
	}
	if(attachment != null) {
	    attachment.important = true;
	}
	if(position != null) {
	    position.important = true;
	}
    }

    /**
     * Returns true if this property is important.
     * Overrides this method for a macro
     */
    public boolean getImportant() {
	return ((color == null || color.important) &&
		(image == null || image.important) &&
		(repeat == null || repeat.important) &&
		(attachment == null || attachment.important) &&
		(position == null || position.important));
    }

    /**
     * Print this property.
     *
     * @param printer The printer.
     * @see #toString()
     * @see #getPropertyName()
     */
    public void print(CssPrinterStyle printer) {
	if ((color != null && image != null &&
	     repeat != null && attachment !=null &&
	     position != null) &&
	    (getImportant() ||
	     (!image.important &&
	      !color.important &&
	      !repeat.important &&
	      !attachment.important &&
	      !position.important))) {
	    if (color.byUser || image.byUser || repeat.byUser
		|| attachment.byUser || position.byUser) {
		printer.print(this);
	    }
	} else {
	    if (color != null)
		color.print(printer);
	    if (image != null)
		image.print(printer);
	    if (repeat != null)
		repeat.print(printer);
	    if (attachment != null)
		attachment.print(printer);
	    if (position != null)
		position.print(printer);
	}
    }

    /**
     * Set the context.
     * Overrides this method for a macro
     *
     * @see org.w3c.css.css.CssCascadingOrder#order
     * @see org.w3c.css.css.StyleSheetParser#handleRule
     */
    public void setSelectors(CssSelectors selector) {
	super.setSelectors(selector);
	if (color != null) {
	    color.setSelectors(selector);
	}
	if (image != null) {
	    image.setSelectors(selector);
	}
	if (repeat != null) {
	    repeat.setSelectors(selector);
	}
	if (attachment != null) {
	    attachment.setSelectors(selector);
	}
	if (position != null) {
	    position.setSelectors(selector);
	}
    }

    /**
     * Add this property to the CssStyle
     *
     * @param style The CssStyle
     */
    public void addToStyle(ApplContext ac, CssStyle style) {
	((Css1Style) style).cssBackgroundCSS2.same = same;
	((Css1Style) style).cssBackgroundCSS2.byUser = byUser;

	if(color != null) {
	    color.addToStyle(ac, style);
	}
	if(image != null) {
	    image.addToStyle(ac, style);
	}
	if(repeat != null) {
	    repeat.addToStyle(ac, style);
	}
	if(attachment != null) {
	    attachment.addToStyle(ac, style);
	}
	if(position != null) {
	    position.addToStyle(ac, style);
	}
    }

    /**
     * Get this property in the style.
     *
     * @param style The style where the property is
     * @param resolve if true, resolve the style to find this property
     */
    public CssProperty getPropertyInStyle(CssStyle style, boolean resolve) {
	if (resolve) {
	    return ((Css1Style) style).getBackgroundCSS2();
	} else {
	    return ((Css1Style) style).cssBackgroundCSS2;
	}
    }

    /**
     * Compares two properties for equality.
     *
     * @param value The other property.
     */
    public boolean equals(CssProperty property) {
	return false; // FIXME
    }

    /**
     * Update the source file and the line.
     * Overrides this method for a macro
     *
     * @param line The line number where this property is defined
     * @param source The source file where this property is defined
     */
    public void setInfo(int line, String source) {
	super.setInfo(line, source);
	if(color != null) {
	    color.setInfo(line, source);
	}
	if(image != null) {
	    image.setInfo(line, source);
	}
	if(repeat != null) {
	    repeat.setInfo(line, source);
	}
	if(attachment != null) {
	    attachment.setInfo(line, source);
	}
	if(position != null) {
	    position.setInfo(line, source);
	}
    }

}

--- NEW FILE: CssDisplayCSS2.java ---
//
// $Id: CssDisplayCSS2.java,v 1.1 2010/01/05 13:49:46 ylafon Exp $
// From Philippe Le Hegaret (Philippe.Le_Hegaret@sophia.inria.fr)
//
// (c) COPYRIGHT MIT and INRIA, 1997.
// Please first read the full copyright statement in file COPYRIGHT.html
package org.w3c.css.properties.css2;

import org.w3c.css.properties.css.CssDisplay;
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.CssTypes;
import org.w3c.css.values.CssValue;

import java.util.HashMap;

/**
 *
 * http://www.w3.org/TR/2008/REC-CSS2-20080411/visuren.html#display-prop
 * 9.2.5 The 'display' property

'display'
    Value:  	inline | block | list-item | run-in | compact | marker |
                table | inline-table | table-row-group | table-header-group |
                table-footer-group | table-row | table-column-group |
                table-column | table-cell | table-caption | none | inherit
    Initial:  	inline
    Applies to:  	all elements
    Inherited:  	no
    Percentages:  	N/A
    Media:  	all

The values of this property have the following meanings:

block
    This value causes an element to generate a principal block box.
inline
    This value causes an element to generate one or more inline boxes.
list-item
    This value causes an element (e.g., LI in HTML) to generate a principal
    block box and a list-item inline box. For information about lists and
    examples of list formatting, please consult the section on lists.
marker
    This value declares generated content before or after a box to be a marker.
    This value should only be used with :before and :after pseudo-elements
    attached to block-level elements. In other cases, this value is interpreted
    as 'inline'. Please consult the section on markers for more information.
none
    This value causes an element to generate no boxes in the formatting
    structure (i.e., the element has no effect on layout). Descendant elements
    do not generate any boxes either; this behavior cannot be overridden by
    setting the 'display' property on the descendants.

    Please note that a display of 'none' does not create an invisible box; it
    creates no box at all. CSS includes mechanisms that enable an element to
    generate boxes in the formatting structure that affect formatting but are
    not visible themselves. Please consult the section on visibility for
    details.
run-in and compact
    These values create either block or inline boxes, depending on context.
    Properties apply to run-in and compact boxes based on their final status
    (inline-level or block-level). For example, the 'white-space' property only
    applies if the box becomes a block box.
table, inline-table, table-row-group, table-column, table-column-group,
table-header-group, table-footer-group, table-row, table-cell, and table-caption
    These values cause an element to behave like a table element (subject to
    restrictions described in the chapter on tables).

Note that although the initial value of 'display' is 'inline', rules in the
user agent's default style sheet may override this value. See the sample style
sheet for HTML 4.0 in the appendix.

Example(s):

Here are some examples of the 'display' property:

P   { display: block }
EM  { display: inline }
LI  { display: list-item }
IMG { display: none }

Conforming HTML user agents may ignore the 'display' property.
 * @version $Revision: 1.1 $
 */

public class CssDisplayCSS2 extends CssDisplay {

    public static CssIdent inline;
    public static HashMap<String, CssIdent> allowed_values;
    static {
        allowed_values = new HashMap<String, CssIdent>();
        String[] DISPLAY = {
                "inline", "block", "list-item", "run-in", "compact", "marker",
                "table", "inline-table", "table-row-group",
                "table-header-group", "table-footer-group",
                "table-row", "table-column-group", "table-column",
                "table-cell", "table-caption", "none"};

        for (String aDISPLAY : DISPLAY) {
            allowed_values.put(aDISPLAY, CssIdent.getIdent(aDISPLAY));
        }
        inline = CssIdent.getIdent("inline");
    }

    /**
     * Create a new CssDisplay
     */
    public CssDisplayCSS2() {
        // nothing to do
    }

    /**
     * Create a new CssDisplay
     *
     * @param ac         The context
     * @param expression The expression for this property
     * @param check      boolean, if check has to be enforced
     * @throws org.w3c.css.util.InvalidParamException Values are incorect
     */
    public CssDisplayCSS2(ApplContext ac, CssExpression expression,
                          boolean check) throws InvalidParamException {

        if (check && expression.getCount() > 1) {
            throw new InvalidParamException("unrecognize", ac);
        }

        CssValue val = expression.getValue();

        setByUser();

        if (val.getType() == CssTypes.CSS_IDENT) {
            CssIdent id_val = (CssIdent) val;
            String id_value = id_val.toString();
            if (inherit.equals(id_val)) {
                value = inherit;
            } else {
                value = allowed_values.get(id_value);
            }
            if (value != null) {
                expression.next();
                return;
            }
        }

        throw new InvalidParamException("value", expression.getValue(),
                getPropertyName(), ac);

    }

    public CssDisplayCSS2(ApplContext ac, CssExpression expression)
            throws InvalidParamException {
        this(ac, expression, false);
    }


    /**
     * Is the value of this property is a default value.
     * It is used by all macro for the function <code>print</code>
     */
    public boolean isDefault() {
        return (value == inline);
    }

}
--- NEW FILE: CssBackgroundPositionCSS2.java ---
//
// $Id: CssBackgroundPositionCSS2.java,v 1.1 2010/01/05 13:49:46 ylafon Exp $
// From Philippe Le Hegaret (Philippe.Le_Hegaret@sophia.inria.fr)
//
// (c) COPYRIGHT MIT and INRIA, 1997.
// Please first read the full copyright statement in file COPYRIGHT.html
package org.w3c.css.properties.css2;

import org.w3c.css.parser.CssStyle;
import org.w3c.css.properties.css.CssBackgroundPosition;
import org.w3c.css.properties.css.CssProperty;
import org.w3c.css.properties.css1.Css1Style;
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.CssNumber;
import org.w3c.css.values.CssPercentage;
import org.w3c.css.values.CssTypes;
import org.w3c.css.values.CssValue;

import java.util.ArrayList;
import java.util.HashMap;

import static org.w3c.css.values.CssOperator.COMMA;
import static org.w3c.css.values.CssOperator.SPACE;

/**
 * <H4>
 * &nbsp;&nbsp; 'background-position'
 * </H4>
 * <p/>
 * <EM>Value:</EM> [&lt;percentage&gt; | &lt;length&gt;]{1,2} | [top | center
 * | bottom] || [left | center | right]<BR>
 * <EM>Initial:</EM> 0% 0%<BR>
 * <EM>Applies to:</EM> block-level and replaced elements<BR>
 * <EM>Inherited:</EM> no<BR>
 * <EM>Percentage values:</EM> refer to the size of the element itself<BR>
 * <P> If a background image has been specified, the value of
 * 'background-position' specifies its initial position.
 * <P> With a value pair of '0% 0%', the upper left corner of the image is
 * placed in the upper left corner of the box that surrounds the content of
 * the element (i.e., not the box that surrounds the padding, border or
 * margin). A value pair of '100% 100%' places the lower right corner of the
 * image in the lower right corner of the element. With a value pair of '14%
 * 84%', the point 14% across and 84% down the image is to be placed at the
 * point 14% across and 84% down the element.
 * <P> With a value pair of '2cm 2cm', the upper left corner of the image is
 * placed 2cm to the right and 2cm below the upper left corner of the element.
 * <P> If only one percentage or length value is given, it sets the horizontal
 * position only, the vertical position will be 50%. If two values are given,
 * the horizontal position comes first. Combinations of length and percentage
 * values are allowed, e.g. '50% 2cm'. Negative positions are allowed.
 * <P> One can also use keyword values to indicate the position of the
 * background image. Keywords cannot be combined with percentage values, or
 * length values.  The possible combinations of keywords and their
 * interpretations are as follows:
 * <p/>
 * <UL>
 * <LI>
 * 'top left' and 'left top' both mean the same as '0% 0%'.
 * <LI>
 * 'top', 'top center' and 'center top' mean the same as '50% 0%'.
 * <LI>
 * 'right top' and 'top right' mean the same as '100% 0%'.
 * <LI>
 * 'left', 'left center' and 'center left' mean the same as '0% 50%'.
 * <LI>
 * 'center' and 'center center' mean the same as '50% 50%'.
 * <LI>
 * 'right', 'right center' and 'center right' mean the same as '100% 50%'.
 * <LI>
 * 'bottom left' and 'left bottom' mean the same as '0% 100%'.
 * <LI>
 * 'bottom', 'bottom center' and 'center bottom' mean the same as
 * '50% 100%'.
 * <LI>
 * 'bottom right' and 'right bottom' mean the same as '100% 100%'.
 * </UL>
 * <p/>
 * examples:
 * <PRE>
 * BODY { background: url(banner.jpeg) right top }    / * 100%   0% * /
 * BODY { background: url(banner.jpeg) top center }   / *  50%   0% * /
 * BODY { background: url(banner.jpeg) center }       / *  50%  50% * /
 * BODY { background: url(banner.jpeg) bottom }       / *  50% 100% * /
 * </PRE>
 * <p/>
 * If the background image is fixed with regard to the canvas (see the
 * 'background-attachment' property above), the image is placed relative to
 * the canvas instead of the element. E.g.:
 * <PRE>
 * BODY {
 * background-image: url(logo.png);
 * background-attachment: fixed;
 * background-position: 100% 100%;
 * }
 * </PRE>
 * <p/>
 * In the example above, the image is placed in the lower right corner of the
 * canvas.
 *
 * @version $Revision: 1.1 $
 * @see org.w3c.css.properties.css.CssBackgroundAttachment
 */
public class CssBackgroundPositionCSS2 extends CssBackgroundPosition {

    public static boolean checkMatchingIdent(CssIdent ident) {
        return allowed_values.containsValue(ident);
    }

    private static final String propertyName = "background-position";

    public static HashMap<String, 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 HashMap<String, CssIdent>();
        allowed_values.put("top", top);
        allowed_values.put("bottom", bottom);
        allowed_values.put("left", left);
        allowed_values.put("right", right);
        allowed_values.put("center", center);

        defaultPercent0 = new CssPercentage(0);
        defaultPercent50 = new CssPercentage(50);
        defaultPercent100 = new CssPercentage(100);
    }

    public CssValue value;

    /**
     * Create a new CssBackgroundPositionCSS2
     */
    public CssBackgroundPositionCSS2() {
        super();
    }

    /**
     * Creates a new CssBackgroundPositionCSS2
     *
     * @param expression The expression for this property
     * @throws InvalidParamException Values are incorrect
     */
    public CssBackgroundPositionCSS2(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 = ((CssNumber) 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 = allowed_values.get(ident.toString());
                        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, propertyName, 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 = allowed_values.get(val0.toString());
                            if (ident == null) {
                                throw new InvalidParamException("unrecognize",
                                        ident, propertyName, 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 {
                            ident = allowed_values.get(v.value.get(1).toString());
                            if (ident == null) {
                                throw new InvalidParamException("unrecognize",
                                        ident, propertyName, ac);
                            }
                            if (isHorizontal(ident)) {
                                throw new InvalidParamException("incompatible",
                                        val0, v.value.get(1), 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 CssBackgroundPositionCSS2(ApplContext ac, CssExpression expression)
            throws InvalidParamException {
        this(ac, expression, false);
    }

    public String toString() {
        return value.toString();
    }

    /**
     * Add this property to the CssStyle.
     *
     * @param style The CssStyle
     */
    public void addToStyle(ApplContext ac, CssStyle style) {
        CssBackgroundCSS2 cssBackground = ((Css1Style) style).cssBackgroundCSS2;
        if (cssBackground.position != null)
            style.addRedefinitionWarning(ac, this);
        cssBackground.position = this;
    }

    /**
     * Get this property in the style.
     *
     * @param style   The style where the property is
     * @param resolve if true, resolve the style to find this property
     */
    public CssProperty getPropertyInStyle(CssStyle style, boolean resolve) {
        if (resolve) {
            return ((Css1Style) style).getBackgroundPositionCSS2();
        } else {
            return ((Css1Style) style).cssBackgroundCSS2.position;
        }
    }
}
Received on Tuesday, 5 January 2010 13:50:23 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Thursday, 26 April 2012 12:55:18 GMT