Example #1
0
        /// <summary>
        /// 尝试生成元素开始标签的HTML形式
        /// </summary>
        /// <param name="element">要生成HTML的元素</param>
        /// <param name="selfClosed">指示是否应产生自结束符号</param>
        /// <returns></returns>
        public static string GenerateTagHtml( IHtmlElement element, bool selfClosed )
        {
            if ( element == null )
            throw new ArgumentNullException( "element" );

              var builder = new StringBuilder( 20 );

              builder.Append( "<" );
              builder.Append( element.Name );

              foreach ( var attribute in element.Attributes() )
              {
            builder.Append( " " );
            builder.Append( attribute.Name );
            if ( attribute.AttributeValue != null )
            {
              var specification = element.Document.HtmlSpecification;

              if ( ( specification.IsUriValue( attribute ) || specification.IsScriptValue( attribute ) ) && !attribute.AttributeValue.Contains( '"' ) )
            builder.Append( "=\"" ).Append( attribute.AttributeValue ).Append( "\"" );
              else
            builder.Append( "=\"" ).Append( HtmlEncoding.HtmlAttributeEncode( attribute.AttributeValue ) ).Append( "\"" );
            }
              }

              if ( selfClosed )
            builder.Append( " /" );

              builder.Append( ">" );
              return builder.ToString();
        }
        /// <summary>
        /// 获取指定名称的属性对象
        /// </summary>
        /// <param name="element">元素</param>
        /// <param name="name">属性名</param>
        /// <returns>属性对象,如果没找到,则返回null</returns>
        /// <remarks>
        /// 如果有多个同名的属性,此方法将报错。
        /// </remarks>
        public static IHtmlAttribute Attribute(this IHtmlElement element, string name)
        {
            if (element == null)
            {
                throw new ArgumentNullException("element");
            }

            var attributes = element.Attributes();

            /*
             * //即使按字典检索,由于大部分元素属性都很少,也不见得有性能提升
             * var dictionary = attributes as IDictionary<string, IHtmlAttribute>;
             *
             * if ( dictionary != null )
             * return dictionary[name];
             */

            var attributeCollection = attributes as IHtmlAttributeCollection;

            if (attributeCollection != null)
            {
                return(attributeCollection.Get(name));
            }

            return(attributes.SingleOrDefault(a => a.Name.EqualsIgnoreCase(name)));
        }
Example #3
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);
        }
Example #4
0
        /// <summary>
        /// 从元素标签中获取所有的路由值
        /// </summary>
        /// <param name="element">要获取分析路由值的元素</param>
        /// <returns>获取的路由值</returns>
        protected RouteValueDictionary GetRouteValues(IHtmlElement element)
        {
            var routeValues = new RouteValueDictionary();

            var inherits = element.Attribute("inherits").Value();

            if (inherits != null)
            {
                var inheritsKeys = GetInheritsKeys(inherits).Distinct(StringComparer.OrdinalIgnoreCase);

                foreach (var key in inheritsKeys)
                {
                    routeValues.Add(key, RouteData.Values[key]);
                }
            }


            foreach (var attribute in element.Attributes().Where(a => a.Name.StartsWith("_")).ToArray())
            {
                var key   = attribute.Name.Substring(1);
                var value = attribute.Value() ?? RouteData.Values[key];

                routeValues.Remove(key);

                routeValues.Add(key, value);
                attribute.Remove();
            }

            return(routeValues);
        }
Example #5
0
        /// <summary>
        /// 对元素进行数据绑定
        /// </summary>
        /// <param name="element">要绑定数据的元素</param>
        private void BindElement(IHtmlElement element)
        {
            element.Attributes().ToArray().ForAll(a => BindAttribute(a));

            object dataContext = null;

            Binders.FirstOrDefault(b => b.BindElement(element, this, out dataContext));


            if (dataContext != null)
            {
                _bindingDataContexts.Push(new BindingDataContext {
                    DataContext = dataContext, Scope = element
                });

                var listData = dataContext as IEnumerable;
                if (listData != null && IsListItem(element))
                {
                    BindElementList(element, listData.Cast <object>().ToArray());
                }

                else
                {
                    BindChilds(element);
                }

                _bindingDataContexts.Pop();
            }
            else
            {
                BindChilds(element);
            }
        }
Example #6
0
    /// <summary>
    /// 对元素进行数据绑定
    /// </summary>
    /// <param name="element">需要绑定数据的元素</param>
    /// <param name="context">绑定上下文</param>
    /// <returns>返回是否对元素进行了不可逆转的操作(例如移除),故而禁止后续的绑定操作</returns>
    public void BindElement( HtmlBindingContext context, IHtmlElement element )
    {

      if ( element.Attribute( "binding-visible" ) != null )
      {
        var visible = element.Attribute( "binding-visible" ).Value();
        if ( visible.EqualsIgnoreCase( "false" ) || visible.EqualsIgnoreCase( "hidden" ) || visible.EqualsIgnoreCase( "invisible" ) )
        {
          element.Remove();

          context.CancelChildsBinding = context.BindCompleted = true;
        }
      }





      {
        //处理样式类
        var classAttribute = element.Attribute( classAttributePrefix );
        if ( classAttribute != null )
        {
          if ( !string.IsNullOrWhiteSpace( classAttribute.AttributeValue ) )
          {

            var classes = Regulars.whiteSpaceSeparatorRegex.Split( classAttribute.AttributeValue ).Where( c => c != "" ).ToArray();
            if ( classes.Any() )
              element.Class( classes );
          }

          element.RemoveAttribute( classAttributePrefix );
        }

      }

      {
        var classAttributes = element.Attributes().Where( a => a.Name.StartsWith( classAttributePrefix ) ).ToArray();
        BindElementClasses( element, classAttributes );
      }

      //处理CSS样式
      var styleAttributes = element.Attributes().Where( a => a.Name.StartsWith( styleAttributePrefix ) ).ToArray();
      BindElementStyles( element, styleAttributes );
    }
Example #7
0
        /// <summary>
        /// 对元素进行数据绑定
        /// </summary>
        /// <param name="element">需要绑定数据的元素</param>
        /// <param name="context">绑定上下文</param>
        /// <returns>返回是否对元素进行了不可逆转的操作(例如移除),故而禁止后续的绑定操作</returns>
        public void BindElement(HtmlBindingContext context, IHtmlElement element)
        {
            if (element.Attribute("binding-visible") != null)
            {
                var visible = element.Attribute("binding-visible").Value();
                if (visible.EqualsIgnoreCase("false") || visible.EqualsIgnoreCase("hidden") || visible.EqualsIgnoreCase("invisible"))
                {
                    element.Remove();

                    context.CancelChildsBinding = context.BindCompleted = true;
                }
            }



            {
                //处理样式类
                var classAttribute = element.Attribute(classAttributePrefix);
                if (classAttribute != null)
                {
                    if (!string.IsNullOrWhiteSpace(classAttribute.AttributeValue))
                    {
                        var classes = Regulars.whiteSpaceSeparatorRegex.Split(classAttribute.AttributeValue).Where(c => c != "").ToArray();
                        if (classes.Any())
                        {
                            element.Class(classes);
                        }
                    }

                    element.RemoveAttribute(classAttributePrefix);
                }
            }

            {
                var classAttributes = element.Attributes().Where(a => a.Name.StartsWith(classAttributePrefix)).ToArray();
                BindElementClasses(element, classAttributes);
            }

            //处理CSS样式
            var styleAttributes = element.Attributes().Where(a => a.Name.StartsWith(styleAttributePrefix)).ToArray();

            BindElementStyles(element, styleAttributes);
        }
Example #8
0
 public IEnumerable <IBinding> CreateBindings(BindingManager manager, IHtmlElement element)
 {
     if (element.Name.EqualsIgnoreCase("binding"))
     {
         return(new[] { CreateElementBinding(element) });
     }
     else
     {
         return(element.Attributes().Select(a => CreateAttributeBinding(a)).NotNull());
     }
 }
Example #9
0
 public IEnumerable<IBinding> CreateBindings( BindingManager manager, IHtmlElement element )
 {
   if ( element.Name.EqualsIgnoreCase( "binding" ) )
   {
     return new[] { CreateElementBinding( element ) };
   }
   else
   {
     return element.Attributes().Select( a => CreateAttributeBinding( a ) ).NotNull();
   }
 }
Example #10
0
        /// <summary>
        /// 实现 BindElement 方法对元素的 URL 属性进行处理
        /// </summary>
        /// <param name="context">当前绑定上下文</param>
        /// <param name="element">当前元素上下文</param>
        public void BindElement(HtmlBindingContext context, IHtmlElement element)
        {
            if (ProcessActionLink(element))//对元素进行 Action URL 处理,若处理成功,则跳过元素。
            {
                return;
            }

            element.Attributes().ToArray()
            .Where(attribute => Specification.IsUriValue(attribute))
            .ForAll(attribute => UrlHelper.ResolveUri(attribute, DocumentPath));
        }
Example #11
0
        /// <summary>
        /// 对元素进行数据绑定
        /// </summary>
        /// <param name="element">要绑定数据的元素</param>
        public virtual void DataBind(IHtmlElement element)
        {
            var attributes = element.Attributes().ToArray();

            attributes.ForAll(a => BindAttribute(a));

            if (BindExpressionElement(element))
            {
                return;
            }

            BindElement(element);
        }
Example #12
0
        private void CustomRouteValues(IHtmlElement element, string prefix, RouteValueDictionary routeValues, bool clearRouteAttributes)
        {
            foreach (var attribute in element.Attributes().Where(a => a.Name.StartsWith(prefix)).ToArray())
            {
                var key   = attribute.Name.Substring(prefix.Length);
                var value = attribute.Value() ?? RouteData.Values[key];

                routeValues.Remove(key);

                routeValues.Add(key, value);

                if (clearRouteAttributes)
                {
                    attribute.Remove();
                }
            }
        }
Example #13
0
        /// <summary>
        /// 尝试生成元素开始标签的HTML形式
        /// </summary>
        /// <param name="element">要生成HTML的元素</param>
        /// <param name="selfClosed">指示是否应产生自结束符号</param>
        /// <returns></returns>
        public static string GenerateTagHtml(IHtmlElement element, bool selfClosed)
        {
            if (element == null)
            {
                throw new ArgumentNullException("element");
            }


            var builder = new StringBuilder(20);

            builder.Append("<");
            builder.Append(element.Name);

            foreach (var attribute in element.Attributes())
            {
                builder.Append(" ");
                builder.Append(attribute.Name);
                if (attribute.AttributeValue != null)
                {
                    var specification = element.Document.HtmlSpecification;

                    if ((specification.IsUriValue(attribute) || specification.IsScriptValue(attribute)) && !attribute.AttributeValue.Contains('"'))
                    {
                        builder.Append("=\"").Append(attribute.AttributeValue).Append("\"");
                    }
                    else
                    {
                        builder.Append("=\"").Append(HtmlEncoding.HtmlAttributeEncode(attribute.AttributeValue)).Append("\"");
                    }
                }
            }

            if (selfClosed)
            {
                builder.Append(" /");
            }

            builder.Append(">");
            return(builder.ToString());
        }
Example #14
0
        /// <summary>
        /// 创建元素的副本
        /// </summary>
        /// <param name="factory">用于创建元素的构建器</param>
        /// <param name="element">需要被创建副本的元素</param>
        /// <returns>元素的未分配副本</returns>
        public static IFreeElement MakeCopy(this IHtmlNodeFactory factory, IHtmlElement element)
        {
            if (factory == null)
            {
                throw new ArgumentNullException("factory");
            }

            if (element == null)
            {
                throw new ArgumentNullException("element");
            }


            var free = factory.CreateElement(element.Name);

            foreach (var attribute in element.Attributes())
            {
                free.AddAttribute(attribute.Name, attribute.Value());
            }

            CopyChildNodes(element, free);

            return(free);
        }
Example #15
0
        private void CustomRouteValues( IHtmlElement element, string prefix, RouteValueDictionary routeValues, bool clearRouteAttributes )
        {
            foreach ( var attribute in element.Attributes().Where( a => a.Name.StartsWith( prefix ) ).ToArray() )
              {

            var key = attribute.Name.Substring( prefix.Length );
            var value = attribute.Value() ?? RouteData.Values[key];

            routeValues.Remove( key );

            routeValues.Add( key, value );

            if ( clearRouteAttributes )
              attribute.Remove();
              }
        }
Example #16
0
        /// <summary>
        /// 对元素进行数据绑定
        /// </summary>
        /// <param name="element">需要绑定数据的元素</param>
        /// <param name="context">绑定上下文</param>
        /// <param name="dataContext">数据上下文</param>
        /// <returns>是否进行了绑定</returns>
        public bool BindElement( IHtmlElement element, HtmlBindingContext context, out object dataContext )
        {
            dataContext = null;

              if ( element.Attribute( "binding-visible" ) != null )
              {
            var visible = element.Attribute( "binding-visible" ).Value();
            if ( visible.EqualsIgnoreCase( "false" ) || visible.EqualsIgnoreCase( "hidden" ) || visible.EqualsIgnoreCase( "invisible" ) )
              element.Remove();
            return true;
              }

              //处理样式类
              {
            var classAttribute = element.Attribute( classAttributeName );
            if ( classAttribute != null )
            {
              if ( !string.IsNullOrWhiteSpace( classAttribute.AttributeValue ) )
              {

            var classes = Regulars.whiteSpaceSeparatorRegex.Split( classAttribute.AttributeValue ).Where( c => c != "" ).ToArray();
            if ( classes.Any() )
              element.Class( classes );
              }

              element.RemoveAttribute( classAttributeName );
            }
              }

              //处理CSS样式
              var styleAttributes = element.Attributes().Where( a => a.Name.StartsWith( styleAttributePrefix ) ).ToArray();
              if ( styleAttributes.Any() )
            BindElementStyles( element, styleAttributes );

              if ( !element.Name.EqualsIgnoreCase( "view" ) && !element.Name.EqualsIgnoreCase( "binding" ) )
              {
            var dataContextExpression = AttributeExpression.ParseExpression( element.Attribute( "datacontext" ) );
            if ( dataContextExpression != null )
              dataContext = GetDataObject( dataContextExpression, context );

            return false;
              }

              var expression = new AttributeExpression( element );

              object dataObject = GetDataObject( expression, context );

              if ( dataObject == null )
            return false;

              var format = element.Attribute( "format" ).Value();

              //绑定到客户端脚本对象
              var variableName = element.Attribute( "var" ).Value() ?? element.Attribute( "variable" ).Value();
              if ( variableName != null )
              {

            if ( format != null )
              dataObject = string.Format( format, dataObject );

            var hostName = element.Attribute( "host" ).Value();

            var script = (string) null;

            if ( hostName == null )
              script = string.Format( "(function(){{ this['{0}'] = {1} }})();", variableName, ToJson( dataObject ) );

            else
              script = string.Format( "(function(){{ this['{0}'] = {1} }})();", variableName, ToJson( dataObject ) );

            element.ReplaceWith( string.Format( "<script type=\"text/javascript\">{0}</script>", script ) );
            return true;
              }

              //绑定为 HTML 文本
              var bindValue = string.Format( format ?? "{0}", dataObject );

              var attributeName = element.Attribute( "attribute" ).Value() ?? element.Attribute( "attr" ).Value();
              if ( attributeName != null )
              {
            var nextElement = element.NextElement();
            if ( nextElement == null )
              return false;

            nextElement.SetAttribute( attributeName, bindValue );
            return true;
              }

              element.ReplaceWith( bindValue );
              return true;
        }
Example #17
0
 /// <summary>
 /// 从元素创建属性表达式
 /// </summary>
 /// <param name="element">要创建属性表达式的元素</param>
 public AttributeExpression(IHtmlElement element) : this(element.Name, element.Attributes().ToDictionary(a => a.Name, a => a.AttributeValue, StringComparer.OrdinalIgnoreCase))
 {
 }
Example #18
0
 /// <summary>
 /// 从元素创建属性表达式
 /// </summary>
 /// <param name="element">要创建属性表达式的元素</param>
 public AttributeExpression( IHtmlElement element )
     : this(element.Name, element.Attributes().ToDictionary( a => a.Name, a => a.AttributeValue, StringComparer.OrdinalIgnoreCase ))
 {
 }
Example #19
0
 private IBinding CreateElementBinding( IHtmlElement element )
 {
   return new Binding( element, element.Attributes().ToDictionary( a => a.Name, a => a.AttributeValue ) );
 }
Example #20
0
    /// <summary>
    /// 实现 BindElement 方法对元素的 URL 属性进行处理
    /// </summary>
    /// <param name="context">当前绑定上下文</param>
    /// <param name="element">当前元素上下文</param>
    public void BindElement( HtmlBindingContext context, IHtmlElement element )
    {
      if ( ProcessActionLink( element ) )//对元素进行 Action URL 处理,若处理成功,则跳过元素。
        return;

      element.Attributes().ToArray()
        .Where( attribute => Specification.IsUriValue( attribute ) )
        .ForAll( attribute => UrlHelper.ResolveUri( attribute, DocumentPath ) );
    }
Example #21
0
 private IBinding CreateElementBinding(IHtmlElement element)
 {
     return(new Binding(element, element.Attributes().ToDictionary(a => a.Name, a => a.AttributeValue)));
 }
Example #22
0
        /// <summary>
        /// 对元素进行数据绑定
        /// </summary>
        /// <param name="element">需要绑定数据的元素</param>
        /// <param name="context">绑定上下文</param>
        /// <param name="dataContext">数据上下文</param>
        /// <returns>是否进行了绑定</returns>
        public bool BindElement(IHtmlElement element, HtmlBindingContext context, out object dataContext)
        {
            dataContext = null;

            if (element.Attribute("binding-visible") != null)
            {
                var visible = element.Attribute("binding-visible").Value();
                if (visible.EqualsIgnoreCase("false") || visible.EqualsIgnoreCase("hidden") || visible.EqualsIgnoreCase("invisible"))
                {
                    element.Remove();
                }
                return(true);
            }



            //处理样式类
            {
                var classAttribute = element.Attribute(classAttributeName);
                if (classAttribute != null)
                {
                    if (!string.IsNullOrWhiteSpace(classAttribute.AttributeValue))
                    {
                        var classes = Regulars.whiteSpaceSeparatorRegex.Split(classAttribute.AttributeValue).Where(c => c != "").ToArray();
                        if (classes.Any())
                        {
                            element.Class(classes);
                        }
                    }

                    element.RemoveAttribute(classAttributeName);
                }
            }


            //处理CSS样式
            var styleAttributes = element.Attributes().Where(a => a.Name.StartsWith(styleAttributePrefix)).ToArray();

            if (styleAttributes.Any())
            {
                BindElementStyles(element, styleAttributes);
            }



            if (!element.Name.EqualsIgnoreCase("view") && !element.Name.EqualsIgnoreCase("binding"))
            {
                var dataContextExpression = AttributeExpression.ParseExpression(element.Attribute("datacontext"));
                if (dataContextExpression != null)
                {
                    dataContext = GetDataObject(dataContextExpression, context);
                }

                return(false);
            }

            var expression = new AttributeExpression(element);

            object dataObject = GetDataObject(expression, context);

            if (dataObject == null)
            {
                return(false);
            }



            var format = element.Attribute("format").Value();


            //绑定到客户端脚本对象
            var variableName = element.Attribute("var").Value() ?? element.Attribute("variable").Value();

            if (variableName != null)
            {
                if (format != null)
                {
                    dataObject = string.Format(format, dataObject);
                }


                var hostName = element.Attribute("host").Value();

                var script = (string)null;

                if (hostName == null)
                {
                    script = string.Format("(function(){{ this['{0}'] = {1} }})();", variableName, ToJson(dataObject));
                }

                else
                {
                    script = string.Format("(function(){{ this['{0}'] = {1} }})();", variableName, ToJson(dataObject));
                }


                element.ReplaceWith(string.Format("<script type=\"text/javascript\">{0}</script>", script));
                return(true);
            }



            //绑定为 HTML 文本
            var bindValue = string.Format(format ?? "{0}", dataObject);

            var attributeName = element.Attribute("attribute").Value() ?? element.Attribute("attr").Value();

            if (attributeName != null)
            {
                var nextElement = element.NextElement();
                if (nextElement == null)
                {
                    return(false);
                }

                nextElement.SetAttribute(attributeName, bindValue);
                return(true);
            }

            element.ReplaceWith(bindValue);
            return(true);
        }
Example #23
0
        /// <summary>
        /// 对元素进行数据绑定
        /// </summary>
        /// <param name="element">要绑定数据的元素</param>
        private void BindElement( IHtmlElement element )
        {
            element.Attributes().ToArray().ForAll( a => BindAttribute( a ) );

              object dataContext = null;
              Binders.FirstOrDefault( b => b.BindElement( element, this, out dataContext ) );

              if ( dataContext != null )
              {
            _bindingDataContexts.Push( new BindingDataContext { DataContext = dataContext, Scope = element } );

            var listData = dataContext as IEnumerable;
            if ( listData != null && IsListItem( element ) )
              BindElementList( element, listData.Cast<object>().ToArray() );

            else
              BindChilds( element );

            _bindingDataContexts.Pop();
              }
              else
            BindChilds( element );
        }