/// <summary> /// 渲染元素和其子节点 /// </summary> /// <param name="element">要渲染的元素</param> /// <param name="context">渲染上下文</param> private static void RenderElementAndChilds(IHtmlElement element, IHtmlRenderContext context) { var writer = context.Writer; var specification = element.Document.HtmlSpecification; if (specification.IsForbiddenEndTag(element.Name)) { var builder = new StringBuilder(); builder.Append(GenerateTagHtml(element, true)); if (element.Nodes().Any()) { throw new FormatException(string.Format(CultureInfo.InvariantCulture, "HTML元素 {0} 不能有任何内容", element.Name)); } writer.Write(builder); } else { writer.Write(GenerateTagHtml(element, false)); RenderChilds(element, context); writer.Write("</{0}>", element.Name); } }
/// <summary> /// 添加元素的副本 /// </summary> /// <param name="container">要添加副本的容器</param> /// <param name="index">要添加的位置</param> /// <param name="element">要创作副本的元素</param> /// <returns>添加后的元素</returns> public static IHtmlElement AddCopy(this IHtmlContainer container, int index, IHtmlElement element) { if (container == null) { throw new ArgumentNullException("container"); } if (element == null) { throw new ArgumentNullException("element"); } var _element = container.AddElement(index, element.Name); foreach (var attribute in element.Attributes()) { _element.AddAttribute(attribute.Name, attribute.AttributeValue); } foreach (var node in element.Nodes()) { AddCopy(_element, node); } return(_element); }
private static void CopyChildNodes(IHtmlElement element, IFreeElement freeElement) { foreach (var node in element.Nodes().Reverse()) { var freeNode = freeElement.Factory.MakeCopy(node); freeNode.Into(freeElement, 0); } }
/* * /// <summary> * /// 设置元素的InnerHTML * /// </summary> * /// <param name="element">要设置InnerHTML的元素</param> * /// <param name="html">要设置的HTML文本</param> * /// <exception cref="System.InvalidOperationException">如果元素不能被安全的修改内容</exception> * public static void InnerHtml( this IHtmlElement element, string html ) * { * * if ( element == null ) * throw new ArgumentNullException( "element" ); * * lock ( element.SyncRoot ) * { * if ( !IsSafeBindable( element ) ) * throw new InvalidOperationException( "不能对元素设置InnerHTML,因为该元素不能被安全的修改内容。如果确信要改变HTML文档结构,请使用ReplaceChildsWithHtml扩展方法。" ); * * ReplaceChildsWithHtml( element, html ); * } * } * * * /// <summary> * /// 将元素内容替换为指定文本 * /// </summary> * /// <param name="element">要替换的文本</param> * /// <param name="text">要设置的文本</param> * /// <exception cref="System.InvalidOperationException">如果元素不能被安全的修改内容</exception> * public static void InnerText( this IHtmlElement element, string text ) * { * * if ( element == null ) * throw new ArgumentNullException( "element" ); * * lock ( element.SyncRoot ) * { * if ( !IsSafeBindable( element ) ) * throw new InvalidOperationException( "不能对元素设置InnerText,因为该元素不能被安全的修改内容。如果确信要改变HTML文档结构,请使用ReplaceChildsWithText扩展方法。" ); * * ReplaceChildsWithText( element, text ); * } * } */ /// <summary> /// 内部方法,用于确定一个元素的内容是否可以安全数据绑定(不破坏文档结构)。 /// </summary> /// <param name="element">要判断的元素</param> /// <returns></returns> internal static bool IsSafeBindable(this IHtmlElement element) { lock (element.SyncRoot) { var specification = element.Document.HtmlSpecification; if (element.Nodes().All(n => n is IHtmlTextNode || n is IHtmlComment))//只有文本和注释的元素是可以被安全数据绑定的。 { return(true); } if (!element.Nodes().All(n => n is IHtmlTextNode || n is IHtmlComment || n is IHtmlElement))//内容只能由文本、注释和元素三者组成 { return(false); } var childs = element.Elements(); //如果有任何一个子元素有ID属性,那么它是不安全的 if (childs.Any(e => e.Attribute("id").Value() != null)) { return(false); } //如果有任何一个子元素是不安全的,那么它是不安全的 if (childs.Any(e => e.IsSafeBindable() == false)) { return(false); } //如果元素内部只有设置文本样式的子元素,那么它是安全的。 if (childs.All(e => specification.IsStylingElement(e) || specification.IsPhraseElement(e))) { return(true); } return(false); } }
/// <summary> /// 尝试生成元素的HTML表现形式 /// </summary> /// <param name="element">要生成HTML的元素</param> /// <returns></returns> private static string GenerateElementHtml(IHtmlElement element) { var builder = new StringBuilder(); if (HtmlSpecification.selfCloseTags.Contains(element.Name, StringComparer.OrdinalIgnoreCase)) { if (element.Nodes().Any()) { throw new FormatException(string.Format(CultureInfo.InvariantCulture, "HTML元素 {0} 不能有任何内容", element.Name)); } builder.Append(GenerateTagHtml(element, true)); } else { builder.Append(GenerateTagHtml(element, false)); element.Nodes().ForAll(node => builder.Append(GenerateHtml(node))); builder.AppendFormat("</{0}>", element.Name); } return(builder.ToString()); }
/// <summary> /// 尝试生成元素的HTML表现形式 /// </summary> /// <param name="element">要生成HTML的元素</param> /// <returns></returns> private static string GenerateElementHtml(IHtmlElement element) { var builder = new StringBuilder(); var specification = element.Document.HtmlSpecification; if (specification.IsForbiddenEndTag(element.Name)) { if (element.Nodes().Any()) { throw new FormatException(string.Format(CultureInfo.InvariantCulture, "HTML元素 {0} 不能有任何内容", element.Name)); } builder.Append(GenerateTagHtml(element, true)); } else { builder.Append(GenerateTagHtml(element, false)); element.Nodes().ForAll(node => builder.Append(GenerateHtml(node))); builder.AppendFormat("</{0}>", element.Name); } return(builder.ToString()); }
public HtmlList( IHtmlElement element ) { if ( element == null ) throw new ArgumentNullException( "element" ); if ( !HtmlSpecification.listElements.Contains( element.Name.ToLowerInvariant() ) ) throw new ArgumentException( "只能从列表元素创建 HtmlList 对象" ); if ( element.Elements().Any( e => !e.Name.EqualsIgnoreCase( "li" ) ) ) throw new FormatException( "HTML 文档格式不正确,列表元素只能包含 li 元素" ); if ( element.Nodes().OfType<IHtmlTextNode>().Any( n => !n.IsWhiteSpace() ) ) throw new FormatException( "HTML 文档格式不正确,列表元素只能包含 li 元素,不能包含文本。" ); _element = element; }
private static void RenderElementAndChilds(IHtmlElement element, TextWriter writer, params IHtmlAdapter[] adapters) { if (HtmlSpecification.selfCloseTags.Contains(element.Name, StringComparer.OrdinalIgnoreCase)) { var builder = new StringBuilder(); builder.Append(GenerateTagHtml(element, true)); if (element.Nodes().Any()) { throw new FormatException(string.Format(CultureInfo.InvariantCulture, "HTML元素 {0} 不能有任何内容", element.Name)); } writer.Write(builder); } else { writer.Write(GenerateTagHtml(element, false)); RenderChilds(element, writer, adapters); writer.Write("</{0}>", element.Name); } }
bool ICssPseudoClassSelector.IsEligible(IHtmlElement element) { if (element == null) { throw new ArgumentNullException("element"); } switch (_name) { case "only-child": return(element.Siblings().Count() == 1); case "only-of-type": return(element.Siblings(element.Name).Count() == 1); case "empty": return(element.Nodes().Count(n => n is IHtmlElement || n is IHtmlTextNode) == 0);//只有元素和文本节点视为有内容 http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#empty-pseudo default: throw new InvalidOperationException(); } }
public HtmlList(IHtmlElement element) { if (element == null) { throw new ArgumentNullException("element"); } if (!HtmlSpecification.listElements.Contains(element.Name.ToLowerInvariant())) { throw new ArgumentException("只能从列表元素创建 HtmlList 对象"); } if (element.Elements().Any(e => !e.Name.EqualsIgnoreCase("li"))) { throw new FormatException("HTML 文档格式不正确,列表元素只能包含 li 元素"); } if (element.Nodes().OfType <IHtmlTextNode>().Any(n => !n.IsWhiteSpace())) { throw new FormatException("HTML 文档格式不正确,列表元素只能包含 li 元素,不能包含文本。"); } _element = element; }
/// <summary> /// 渲染元素和其子节点 /// </summary> /// <param name="element">要渲染的元素</param> /// <param name="context">渲染上下文</param> private static void RenderElementAndChilds( IHtmlElement element, IHtmlRenderContext context ) { var writer = context.Writer; var specification = element.Document.HtmlSpecification; if ( specification.IsForbiddenEndTag( element.Name ) ) { var builder = new StringBuilder(); builder.Append( GenerateTagHtml( element, true ) ); if ( element.Nodes().Any() ) throw new FormatException( string.Format( CultureInfo.InvariantCulture, "HTML元素 {0} 不能有任何内容", element.Name ) ); writer.Write( builder ); } else { writer.Write( GenerateTagHtml( element, false ) ); RenderChilds( element, context ); writer.Write( "</{0}>", element.Name ); } }
/// <summary> /// 尝试生成元素的HTML表现形式 /// </summary> /// <param name="element">要生成HTML的元素</param> /// <returns></returns> private static string GenerateElementHtml( IHtmlElement element ) { var builder = new StringBuilder(); var specification = element.Document.HtmlSpecification; if ( specification.IsForbiddenEndTag( element.Name ) ) { if ( element.Nodes().Any() ) throw new FormatException( string.Format( CultureInfo.InvariantCulture, "HTML元素 {0} 不能有任何内容", element.Name ) ); builder.Append( GenerateTagHtml( element, true ) ); } else { builder.Append( GenerateTagHtml( element, false ) ); element.Nodes().ForAll( node => builder.Append( GenerateHtml( node ) ) ); builder.AppendFormat( "</{0}>", element.Name ); } return builder.ToString(); }
bool ICssPseudoClassSelector.IsEligible( IHtmlElement element ) { if ( element == null ) throw new ArgumentNullException( "element" ); switch ( _name ) { case "only-child": return element.Siblings().Count() == 1; case "only-of-type": return element.Siblings( element.Name ).Count() == 1; case "empty": return element.Nodes().Count( n => n is IHtmlElement || n is IHtmlTextNode ) == 0;//只有元素和文本节点视为有内容 http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#empty-pseudo default: throw new InvalidOperationException(); } }