CssXmlElement.cs :  » GUI » SharpVectorGraphics » SharpVectors » Dom » Css » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » GUI » SharpVectorGraphics 
SharpVectorGraphics » SharpVectors » Dom » Css » CssXmlElement.cs
using System;
using System.Xml;
using System.Xml.Serialization;

using SharpVectors.Dom;
using SharpVectors.Dom.Stylesheets;

#if TEST 
using NUnit.Framework;
#endif

namespace SharpVectors.Dom.Css{
  public delegate void NodeChangeHandler(Object src, XmlNodeChangedEventArgs args);
  public delegate void CssChangeHandler();
  
  public class CssXmlElement : Element, IElementCssInlineStyle
  {
    #region Constructors
    protected internal CssXmlElement(string prefix, string localname, string ns, CssXmlDocument doc) : base(prefix, localname, ns, doc) 
    {
    }
    #endregion

    #region Style attribute
    private ICssStyleDeclaration style;
    public ICssStyleDeclaration Style
    {
      get
      {
        if(style == null)
        {
          style = new CssStyleDeclaration(GetAttribute("style", String.Empty), null, false, CssStyleSheetType.Inline);
        }
        return style;
      }
    }
    #endregion

    #region GetComputedStyle
    protected ICssStyleDeclaration cachedCSD;
    public virtual ICssStyleDeclaration GetComputedStyle(string pseudoElt)
    {
      if(cachedCSD == null)
      {
        CssCollectedStyleDeclaration csd = new CssCollectedStyleDeclaration(this);
        MediaList currentMedia = OwnerDocument.Media;

        if(OwnerDocument.UserAgentStyleSheet != null)
        {
          OwnerDocument.UserAgentStyleSheet.GetStylesForElement(this, pseudoElt, currentMedia, csd);
        }
        ((StyleSheetList)OwnerDocument.StyleSheets).GetStylesForElement(this, pseudoElt, csd);

        ((CssStyleDeclaration)Style).GetStylesForElement(csd, 0);

        if(OwnerDocument.UserStyleSheet != null)
        {
          OwnerDocument.UserStyleSheet.GetStylesForElement(this, pseudoElt, currentMedia, csd);
        }

        cachedCSD = csd;
      }
      return cachedCSD;
    }

    public virtual string GetComputedStringValue(string propertyName, string pseudoElt)
    {
      ICssStyleDeclaration csd = GetComputedStyle(pseudoElt);
      return csd.GetPropertyValue(propertyName);

    }

    public virtual ICssValue GetComputedCssValue(string propertyName, string pseudoElt)
    {
      ICssStyleDeclaration csd = GetComputedStyle(pseudoElt);
      return csd.GetPropertyCssValue(propertyName);

    }
    #endregion

    #region OwnerDocument
    public new CssXmlDocument OwnerDocument
    {
      get
      {
        return (CssXmlDocument)base.OwnerDocument;
      }
    }
    #endregion

    #region Supports()
    public override bool Supports(string feature, string version)
    {
      if((feature == "StyleSheets" || feature == "CSS" ) && version == "2.0")
      {
        return true;
      }
            
      return base.Supports(feature, version);
    }
    #endregion

    #region Update handling
    public virtual void CssInvalidate()
    {
      // TODO: why is this being called during load?
      foreach(XmlNode child in ChildNodes)
      {
        if (child is CssXmlElement)
         ((CssXmlElement)child).CssInvalidate();
      }

      // Kill the cache
      cachedCSD = null;
      
      // Notify
      FireCssChange();
    }

    /// <summary>
    /// Called when this element is changing in one of the following ways
    /// <list type="">
    /// <item>Text child added/removed/changed</item>
    /// <item>Element moved in the tree</item>
    /// </list>
    /// </summary>
    public virtual void ElementChange(Object src, XmlNodeChangedEventArgs args)
    {
      // Invalidate the CSS, the cascade for the CSS heirarchy will need to be recomputed
      CssInvalidate();  
      
      // Notify any listeners
      FireElementChange(src, args);
      FireParentNodeChange(src, args, false);
      FireChildNodeChange(src, args, false);
    }
    
    /// <summary>
    /// Called when any parent element is changing. If an element is moved the CSS heirarchy for that element 
    /// will need to change.
    /// </summary>
    public virtual void ParentNodeChange(Object src, XmlNodeChangedEventArgs args)
    {
      FireParentNodeChange(src, args, true);
    }

    /// <summary>
    /// Called when any attribute is changing. This is typically triggered by calls to 
    /// setAttribute() and should only be called from the CssXmlDocument.
    /// </summary>
    /// <see cref="CssXmlDocument"/>
    public virtual void AttributeChange(Object src, XmlNodeChangedEventArgs args)
    {
      // Invalidate the CSS, the cascade for the CSS heirarchy will need to be recomputed
      // We do this before and after the change because we need to invalidate the old and new locations
      CssInvalidate();  

      XmlAttribute attribute = src as XmlAttribute;

      if(attribute != null)
      {
        HandleAttributeChange(attribute);
      }
    
      // Notify any listeners
      FireAttributeChange(src, args);
      FireParentNodeChange(src, args, false);
      FireChildNodeChange(src, args, false);

      // Invalidate the CSS, the cascade for the CSS heirarchy will need to be recomputed
      CssInvalidate();  
    }

    /// <summary>
    /// This function allows each element to handle it's own behaviors for
    /// attribute changing. By default, the cached computed style is invalidated
    /// because most attributes refer to style properties.
    /// </summary>
    /// <param name="attribute">The attribute that is changing.</param>
    public virtual void HandleAttributeChange(XmlAttribute attribute) 
    {
      if(attribute.NamespaceURI.Length == 0)
      {
        switch (attribute.LocalName)
        {
          case "style":
            style = null;
            break;
        }
      }              
    }

    /// <summary>
    /// Called when any child node is changing. If an element is moved the CSS heirarchy for that element 
    /// will need to change. This is mainly useful when one of the child nodes parent is a 
    /// referenced node (for example in a &lt;use&gt; element.
    /// </summary>
    public virtual void ChildNodeChange(Object src, XmlNodeChangedEventArgs args)
    {
      FireChildNodeChange(src, args, true);
    }

    protected void FireCssChange() 
    {
      if (cssChangeHandler != null)
      {
        cssChangeHandler();
      }
    }

    protected void FireAttributeChange(Object src, XmlNodeChangedEventArgs args) 
    {
      if (attributeChangeHandler != null)
      {
        attributeChangeHandler(src, args);
      }
    }

    protected void FireElementChange(Object src, XmlNodeChangedEventArgs args) 
    {
      if (elementChangeHandler != null)
      {
        elementChangeHandler(src, args);
      }
    }

    protected void FireParentNodeChange(Object src, XmlNodeChangedEventArgs args, bool fireEvent)
    {
      if (fireEvent && parentNodeChangeHandler != null)
      {
        parentNodeChangeHandler(src, args);
      }

      foreach(XmlNode child in ChildNodes)
      {
        if (child.NodeType != XmlNodeType.Element) continue;
        
        CssXmlElement cssChild = child as CssXmlElement;
        
        if(cssChild != null)
        {
          cssChild.ParentNodeChange(src, args);
        }
      }
    }

    protected void FireChildNodeChange(Object src, XmlNodeChangedEventArgs args, bool fireEvent)
    {
      if (fireEvent && childNodeChangeHandler != null)
      {
        childNodeChangeHandler(src, args);
      }
      
      CssXmlElement cssParent = ParentNode as CssXmlElement;
        
      if(cssParent != null)
      {
        cssParent.ChildNodeChange(src, args);
      }
    }

    public virtual event NodeChangeHandler attributeChangeHandler;
    public virtual event NodeChangeHandler elementChangeHandler;
    public virtual event NodeChangeHandler parentNodeChangeHandler;
    public virtual event NodeChangeHandler childNodeChangeHandler;
    public virtual event CssChangeHandler cssChangeHandler;

    #endregion

    #region Unit tests
    #if TEST
    [TestFixture]
    public class CssXmlElementTests
    {
      protected virtual XmlElement getElm(string content, string style, string localname)
      {
        return TestUtil.GetXmlElement(content, style, localname);
      }

      protected virtual Type elmType
      {
        get
        {
          return typeof(CssXmlElement);
        }
      }


      [Test]
      public virtual void TestTypeFromDocument()
      {
        CssXmlDocument doc = new CssXmlDocument();
        doc.LoadXml("<dummy />");
        XmlElement elm = doc.DocumentElement;
        Assert.AreEqual(elmType, elm.GetType());
      }

      [Test]
      public virtual void TestTypeFromCreateElement()
      {
        CssXmlDocument doc = new CssXmlDocument();
        XmlElement elm = doc.CreateElement("", "dummy", "");

        Assert.AreEqual(elm.GetType(), elmType);
      }


      private Object lastSrc;
      private XmlNode lastNode;
      private XmlNodeChangedAction lastAction;
      private void clearAllLast()
      {
        lastSrc = null;
        lastNode = null;
        lastAction = 0;
      }
      
      private void elementChangeEvent(Object src, XmlNodeChangedEventArgs args)
      {
        lastSrc = src;
        lastNode = args.Node;
        lastAction = args.Action;
      }

      /*[Test]
      public void TestElementChangeNewChild()
      {
        clearAllLast();
                CssXmlElement elm = getElm("<dummy />", "", "dummy") as CssXmlElement;
        //elm.ElementChange += new ElementChangeHandler(elementChangeEvent);

        elm.AppendChild(elm.OwnerDocument.CreateElement("dd"));

        Console.WriteLine("lastSrc: " + lastSrc);
        Console.WriteLine("lastAction: " + lastAction);
        Assert.AreEqual(elm, lastNode);


                
      }*/

      #region Style attribute tests
      [Test]
      public void TestStyleNoStyleAttr()
      {
        CssXmlElement elm = getElm("<a />", "", "a") as CssXmlElement;
        CssStyleDeclaration csd = (CssStyleDeclaration)elm.Style;
        Assert.AreEqual("", csd.CssText);
        Assert.AreEqual(0, csd.Length);
        Assert.AreEqual(CssStyleSheetType.Inline, csd.Origin);
      }

      [Test]
      public void TestStyleEmptyStyleAttr()
      {
        CssXmlElement elm = getElm("<a style='' />", "", "a") as CssXmlElement;
        CssStyleDeclaration csd = (CssStyleDeclaration)elm.Style;
        Assert.AreEqual("", csd.CssText);
        Assert.AreEqual(0, csd.Length);
        Assert.AreEqual(CssStyleSheetType.Inline, csd.Origin);
      }

      [Test]
      public void TestStyleSingle()
      {
        CssXmlElement elm = getElm("<a style='foo:bar' />", "", "a") as CssXmlElement;
        CssStyleDeclaration csd = (CssStyleDeclaration)elm.Style;
        Assert.AreEqual("foo:bar;", csd.CssText);
        Assert.AreEqual(1, csd.Length);
        Assert.AreEqual("foo", csd[0]);
        Assert.AreEqual("bar", csd.GetPropertyValue("foo"));
        Assert.AreEqual(CssStyleSheetType.Inline, csd.Origin);
      }

      [Test]
      public void TestStyleMultiple()
      {
        CssXmlElement elm = getElm("<a style='foo:bar; kalle:roffe' />", "", "a") as CssXmlElement;
        CssStyleDeclaration csd = (CssStyleDeclaration)elm.Style;
        if(!csd.CssText.Equals("foo:bar;kalle:roffe;") && 
          !csd.CssText.Equals("kalle:roffe;foo:bar;"))
        {
          Assert.Fail();
        }
        Assert.AreEqual(2, csd.Length);
        Assert.AreEqual("bar", csd.GetPropertyValue("foo"));
        Assert.AreEqual("roffe", csd.GetPropertyValue("kalle"));
        Assert.AreEqual(CssStyleSheetType.Inline, csd.Origin);
      }

      [Test]
      public void TestStyleMultipleWithSame()
      {
        CssXmlElement elm = getElm("<a style='foo:bar; kalle:roffe;foo:newvalue' />", "", "a") as CssXmlElement;
        ICssStyleDeclaration csd = elm.Style;
        if(!csd.CssText.Equals("kalle:roffe;foo:newvalue;") && 
          !csd.CssText.Equals("foo:newvalue;kalle:roffe;"))
        {
          Assert.Fail();
        }
        Assert.AreEqual(2, csd.Length);
        Assert.AreEqual("newvalue", csd.GetPropertyValue("foo"));
      }

      [Test]
      public void TestStyleUpdate()
      {
        CssXmlElement elm = getElm("<a style='foo:bar' />", "", "a") as CssXmlElement;
        Assert.AreEqual("foo:bar;", elm.Style.CssText);

        elm.SetAttribute("style", "run:ar");
        Assert.AreEqual("run:ar;", elm.Style.CssText);
      }

      [Test]
      public void TestStyleRemove()
      {
        CssXmlElement elm = getElm("<a style='foo:bar' />", "", "a") as CssXmlElement;

        Assert.AreEqual("foo:bar;", elm.Style.CssText);

        elm.RemoveAttribute("style");
        Assert.AreEqual("", elm.Style.CssText);
      }

      [Test]
      public void TestStyleCreate()
      {
        CssXmlElement elm = getElm("<a />", "", "a") as CssXmlElement;

        Assert.AreEqual("", elm.Style.CssText);

        elm.SetAttribute("style", "run:ar");
        Assert.AreEqual("run:ar;", elm.Style.CssText);
      }
      #endregion
    }
    #endif
    #endregion

  }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.