using System;
using System.Xml;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Diagnostics;
using SharpVectors.Dom.Css;
namespace SharpVectors.Dom.Svg
{
///
/// SvgStyleableElement is an extension to the Svg DOM to create a class for all elements that are styleable.
///
public abstract class SvgStyleableElement : SvgElement, ISvgStylable
{
#region Private static fields
private static Regex isImportant = new Regex(@"!\s*important$");
#endregion
#region Private Fields
#endregion
#region Constructors
internal SvgStyleableElement(string prefix, string localname, string ns, SvgDocument doc)
: base(prefix, localname, ns, doc)
{
}
#endregion
#region ISvgStylable Members
#region ClassName
private ISvgAnimatedString className;
public ISvgAnimatedString ClassName
{
get
{
if (className == null)
{
className = new SvgAnimatedString(GetAttribute("class", String.Empty));
}
return className;
}
}
#endregion
#region PresentationAttributes
private Dictionary presentationAttributes = new Dictionary();
public ICssValue GetPresentationAttribute(string name)
{
if (!presentationAttributes.ContainsKey(name))
{
ICssValue result;
string attValue = GetAttribute(name, String.Empty).Trim();
if (attValue != null && attValue.Length > 0)
{
if (isImportant.IsMatch(attValue))
{
result = null;
}
else
{
result = CssValue.GetCssValue(attValue, false);
}
}
else
{
result = null;
}
presentationAttributes[name] = result;
}
return presentationAttributes[name];
}
#endregion
#endregion
#region GetValues
public string GetPropertyValue(string name)
{
return GetComputedStyle(String.Empty).GetPropertyValue(name);
}
public string GetPropertyValue(string name1, string name2)
{
string cssString = GetComputedStyle(String.Empty).GetPropertyValue(name1);
if (cssString == null)
{
cssString = GetComputedStyle(String.Empty).GetPropertyValue(name2);
}
return cssString;
}
public override ICssStyleDeclaration GetComputedStyle(string pseudoElt)
{
if (cachedCSD == null)
{
CssCollectedStyleDeclaration csd = (CssCollectedStyleDeclaration)base.GetComputedStyle(pseudoElt);
IEnumerator cssPropNames = OwnerDocument.CssPropertyProfile.GetAllPropertyNames().GetEnumerator();
while (cssPropNames.MoveNext())
{
string cssPropName = cssPropNames.Current;
CssValue cssValue = (CssValue)GetPresentationAttribute(cssPropName);
if (cssValue != null)
{
csd.CollectProperty(cssPropName, 0, cssValue,
CssStyleSheetType.NonCssPresentationalHints, String.Empty);
}
}
cachedCSD = csd;
}
return cachedCSD;
}
#endregion
#region Update handling
public override void HandleAttributeChange(XmlAttribute attribute)
{
if (attribute.NamespaceURI.Length == 0)
{
string localName = attribute.LocalName;
if (presentationAttributes.ContainsKey(localName))
{
presentationAttributes.Remove(localName);
}
switch (attribute.LocalName)
{
case "class":
className = null;
// class changes need to propagate to children and invalidate CSS
break;
}
}
base.HandleAttributeChange(attribute);
}
#endregion
}
}