/// <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))); }
/// <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); }
/// <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); }
/// <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); } }
/// <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 ); }
/// <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); }
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()); } }
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(); } }
/// <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)); }
/// <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); }
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(); } } }
/// <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="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); }
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(); } }
/// <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; }
/// <summary> /// 从元素创建属性表达式 /// </summary> /// <param name="element">要创建属性表达式的元素</param> public AttributeExpression(IHtmlElement element) : this(element.Name, element.Attributes().ToDictionary(a => a.Name, a => a.AttributeValue, StringComparer.OrdinalIgnoreCase)) { }
/// <summary> /// 从元素创建属性表达式 /// </summary> /// <param name="element">要创建属性表达式的元素</param> public AttributeExpression( IHtmlElement element ) : this(element.Name, element.Attributes().ToDictionary( a => a.Name, a => a.AttributeValue, StringComparer.OrdinalIgnoreCase )) { }
private IBinding CreateElementBinding( IHtmlElement element ) { return new Binding( element, element.Attributes().ToDictionary( a => a.Name, a => a.AttributeValue ) ); }
/// <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 ) ); }
private IBinding CreateElementBinding(IHtmlElement element) { return(new Binding(element, element.Attributes().ToDictionary(a => a.Name, a => a.AttributeValue))); }
/// <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); }
/// <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 ); }