using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.Xna.Framework; using PlanB.Html.Utility; namespace PlanB.Html.Nodes { public abstract class HtmlNode { public List Children { get; set; } public HtmlNodeType Type { get; protected set; } public List> Attributes { get; set; } public List> Styles { get; set; } public HtmlNode() { Attributes = new List>(); Children = new List(); Styles = new List>(); } public virtual String InnerHtml { get { StringBuilder sb = new StringBuilder(); foreach (HtmlNode childNode in Children) { sb.Append(childNode.OuterHtml); } return sb.ToString(); } } public virtual String OuterHtml { get { string styles = GetStylesString(); string attributes = GetAttributesString(); StringBuilder sb = new StringBuilder(); sb.Append("<"); sb.Append(TagName); if (!String.IsNullOrEmpty(styles)) { sb.Append(" "); sb.Append(styles); } if (!String.IsNullOrEmpty(attributes)) { sb.Append(" "); sb.Append(attributes); } if (Children.Count > 0) { sb.Append(">"); sb.Append(InnerHtml); sb.Append(""); } else { sb.Append(" />"); } return sb.ToString(); } } public abstract String TagName{get;} protected virtual String GetAttributesString() { int numAttributes = Attributes.Count; if (numAttributes == 0) { return String.Empty; } else if (numAttributes == 1) { return Attributes[0].Key + "=\"" + Attributes[0].Value + "\""; } else { StringBuilder sb = new StringBuilder(); sb.Append(Attributes[0].Key + "=\"" + Attributes[0].Value + "\""); foreach (KeyValuePair attribute in Attributes.Skip(1)) { sb.Append(" " + attribute.Key + "=\"" + attribute.Value + "\""); } return sb.ToString(); } } protected virtual String GetStylesString() { int numStyles = Styles.Count; if (numStyles == 0) { return String.Empty; } else if (numStyles == 1) { return "style=\"" + Styles[0].Key + ":" + Styles[0].Value + ";\""; } else { StringBuilder sb = new StringBuilder(); sb.Append("style=\"" + Styles[0].Key + ":" + Styles[0].Value + ";\""); foreach (KeyValuePair style in Styles.Skip(1)) { sb.Append(";" + style.Key + ":" + style.Value); } sb.Append("\""); return sb.ToString(); } } public void AddAttribute(KeyValuePair attribute) { KeyValuePair newAttribute = new KeyValuePair(attribute.Key.ToLower(), attribute.Value); if (newAttribute.Key == "style") { ClearStyles(); String styleString = newAttribute.Value; string[] stylePairStrings = styleString.Split(new char[] { ';' }); KeyValuePair style; foreach (string stylePairString in stylePairStrings) { string[] temp = stylePairString.Split(new char[] { ':' }); if (temp.Length == 1) { style = new KeyValuePair(temp[0], String.Empty); } else if (temp.Length >= 2) { style = new KeyValuePair(temp[0], temp[1]); } else { style = new KeyValuePair(); } if (!String.IsNullOrEmpty(style.Key)) { AddStyle(style); } } } else { Attributes.RemoveAll(i => i.Key == newAttribute.Key); Attributes.Add(newAttribute); } } private void ClearStyles() { Styles.Clear(); } public void AddStyle(KeyValuePair style) { string key = style.Key.ToLower(); string value = style.Value; if (key == "color") { Color color = ColorHelper.FromCss(value); if (color.A == 0xff) { value = String.Format("rgb({0}, {1}, {2})", color.R, color.G, color.B); } else { value = String.Format("rgba({0}, {1}, {2}, {3})", color.R, color.G, color.B, color.A); } } KeyValuePair newStyle = new KeyValuePair(key, value); Styles.RemoveAll(i => i.Key == newStyle.Key); Styles.Add(newStyle); } } public enum HtmlNodeType { Document_, Text_, Br, Span, Img, Paragraph, Div } }