Exemplo n.º 1
0
        /// <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);
            }
        }
Exemplo n.º 2
0
        /// <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);
        }
Exemplo n.º 3
0
        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);
            }
        }
Exemplo n.º 4
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);
            }
        }
Exemplo n.º 5
0
        /// <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());
        }
Exemplo n.º 6
0
        /// <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());
        }
Exemplo n.º 7
0
    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;

    }
Exemplo n.º 8
0
        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();
                }
            }
Exemplo n.º 10
0
        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;
        }
Exemplo n.º 11
0
        /// <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 );

              }
        }
Exemplo n.º 12
0
        /// <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();
        }
Exemplo n.º 13
0
      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();
        }
      }