// niklas@protocol7.com // 80 using System; using System.Xml; using System.Globalization; using System.Text.RegularExpressions; namespace SharpVectors.Dom.Css { /// /// The CSSValue interface represents a simple or a complex value. A CSSValue object only occurs in a context of a CSS property /// public class CssValue : ICssValue { #region Static members private static string numberPattern = @"[\-\+]?[0-9]*\.?[0-9]+"; public static string LengthUnitPattern = "(?in|cm|mm|px|em|ex|pc|pt|%)?"; public static string AngleUnitPattern = "(?deg|rad|grad)?"; public static string LengthPattern = @"(?" + numberPattern + ")" + LengthUnitPattern; public static string AnglePattern = @"(?" + numberPattern + ")" + AngleUnitPattern; private static string cssPrimValuePattern = @"^(?" + @"(?(?attr|url|counter|rect|rgb)\((?[^\)]+)\))" + @"|(?" + LengthPattern + ")" + @"|(?" + AnglePattern + ")" + @"|(?(?" + numberPattern + ")(?Hz|kHz|in|s|ms|%)?)" + @"|(?[""'](?(.|\n)*?)[""'])" + @"|(?([A-Za-z]+)|(\#[A-Fa-f0-9]{6})|(\#[A-Fa-f0-9]{3}))" + @")"; private static Regex reCssPrimitiveValue = new Regex(cssPrimValuePattern + "$"); private static Regex reCssValueList = new Regex(cssPrimValuePattern + @"(\s*,\s*)+$"); /// /// Detects what kind of value cssText contains and returns an instance of the correct CssValue class /// /// The text to parse for a CSS value /// Specifies if this instance is read-only /// The correct type of CSS value static public CssValue GetCssValue(string cssText, bool readOnly) { if(cssText == "inherit") { // inherit return new CssValue(CssValueType.Inherit, cssText, readOnly); } else { Match match = reCssPrimitiveValue.Match(cssText); if(match.Success) { // single primitive value return CssPrimitiveValue.Create(match, readOnly); } match = reCssValueList.Match(cssText); if(match.Success) { // list of primitive values throw new NotImplementedException("Value lists not implemented"); } else { // custom value return new CssValue(CssValueType.Custom, cssText, readOnly); } } } #endregion #region Constructors /// /// Constructor for CssValue /// /// The type of value /// The entire content of the value /// Specifies if the instance is read-only public CssValue(CssValueType type, string cssText, bool readOnly) { _cssText = cssText.Trim(); _cssValueType = type; _readOnly = readOnly; } /// /// Only for internal use /// protected CssValue() { _readOnly = true; } #endregion #region Public methods public virtual CssValue GetAbsoluteValue(string propertyName, XmlElement elm) { return new CssAbsValue(this, propertyName, elm); } #endregion private bool _readOnly; public virtual bool ReadOnly { get { return _readOnly; } } #region ICssValue Members private string _cssText; protected CssValueType _cssValueType; /// /// A string representation of the current value. /// /// SYNTAX_ERR: Raised if the specified CSS string value has a syntax error (according to the attached property) or is unparsable. /// INVALID_MODIFICATION_ERR: Raised if the specified CSS string value represents a different type of values than the values allowed by the CSS property /// NO_MODIFICATION_ALLOWED_ERR: Raised if this value is readonly. public virtual string CssText { get { return _cssText; } set { if(ReadOnly) { throw new DomException(DomExceptionType.InvalidModificationErr, "The CssValue is read-only"); } else { _cssText = value; } } } /// /// A code defining the type of the value as defined above /// public virtual CssValueType CssValueType { get { return _cssValueType; } } #endregion } }