/// <summary> /// 从元素标签中获取路由的虚拟路径 /// </summary> /// <param name="element">要获取分析路由虚拟路径的元素</param> /// <param name="clearRouteAttributes">是否清理路由属性设置</param> /// <returns>获取的虚拟路径</returns> internal string GetRouteUrl(IHtmlElement element, bool clearRouteAttributes) { if (element == null) { throw new ArgumentNullException("element"); } if (element.Attribute("action") == null) { throw new InvalidOperationException(); } var action = element.Attribute("action").Value() ?? RouteData.Values["action"].CastTo <string>(); var controller = element.Attribute("controller").Value() ?? RouteData.Values["controller"].CastTo <string>(); var routeValues = GetRouteValues(element, clearRouteAttributes); if (clearRouteAttributes) { element.RemoveAttribute("action"); element.RemoveAttribute("controller"); element.RemoveAttribute("inherits"); } return(Url.Action(action, controller, routeValues)); }
/// <summary> /// 派生类重写此方法对拥有 Action URL 的元素进行处理 /// </summary> /// <param name="element">要处理的元素</param> /// <returns>元素是否包含 Action URL 并已经进行处理。</returns> protected virtual bool ProcessActionLink(IHtmlElement element) { if (element.Attribute("action") == null) { return(false); } string attributeName; if (element.Name.EqualsIgnoreCase("a")) { attributeName = "href"; } else if (element.Name.EqualsIgnoreCase("img") || element.Name.EqualsIgnoreCase("script")) { attributeName = "src"; } else if (element.Name.EqualsIgnoreCase("form") && element.Attribute("controller") != null) { attributeName = "action"; } else { return(false); } var action = element.Attribute("action").Value() ?? RouteData.Values["action"].CastTo <string>(); var controller = element.Attribute("controller").Value() ?? RouteData.Values["controller"].CastTo <string>(); var routeValues = UrlHelper.GetRouteValues(element); element.RemoveAttribute("action"); element.RemoveAttribute("controller"); element.RemoveAttribute("inherits"); var url = UrlHelper.Action(action, controller, routeValues); if (url == null) { element.Attribute(attributeName).Remove(); } else { element.SetAttribute(attributeName, url); } return(true); }
/// <summary> /// 更新 class 属性 /// </summary> private void UpdateClass() { if (_classes.Any()) { _element.SetAttribute("class", _rawValue = string.Join(" ", _classes.ToArray())); } else { _element.RemoveAttribute("class"); } }
/// <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); }
/// <summary> /// 尝试获取数据模型 /// </summary> /// <param name="element">当前正在处理的元素</param> /// <param name="dataModel">获取到的数据模型</param> /// <returns>是否成功获取数据模型</returns> protected virtual bool TryGetDataModel(IHtmlElement element, out object dataModel) { dataModel = null; var expression = BindingExpression.ParseExpression(element.Attribute("datamodel").Value()); if (expression == null)//若datamodel属性不是一个合法的数据绑定表达式,则忽略之。 { return(false); } element.RemoveAttribute("datamodel");//成功取得dataModel后,应删除该属性。 if (!TryGetValue(expression, out dataModel)) { throw new InvalidOperationException("处理元素数据上下文绑定时出现错误,绑定表达式不支持获取数据对象"); } //此处不检测dataContext是否等于当前dataContext的原因是,如果元素中写下datacontext属性并指向当前datacontext,表示需要在此处重新创建一个绑定上下文。 return(true); }
/// <summary> /// Sanitizes the style. /// </summary> /// <param name="element">The element.</param> /// <param name="baseUrl">The base URL.</param> protected void SanitizeStyle(IHtmlElement element, string baseUrl) { // filter out invalid CSS declarations // see https://github.com/AngleSharp/AngleSharp/issues/101 if (element.GetAttribute("style") == null) { return; } if (element.Style == null) { element.RemoveAttribute("style"); return; } element.SetAttribute("style", element.Style.ToCss()); var styles = element.Style; if (styles == null || styles.Length == 0) { return; } SanitizeStyleDeclaration(element, styles, baseUrl); }
/// <summary> /// 派生类重写此方法对拥有 Action URL 的元素进行处理 /// </summary> /// <param name="element">要处理的元素</param> /// <returns>元素是否包含 Action URL 并已经进行处理。</returns> protected virtual bool ProcessActionLink( IHtmlElement element ) { if ( element.Attribute( "action" ) == null ) return false; string attributeName; if ( element.Name.EqualsIgnoreCase( "a" ) ) attributeName = "href"; else if ( element.Name.EqualsIgnoreCase( "img" ) || element.Name.EqualsIgnoreCase( "script" ) ) attributeName = "src"; else if ( element.Name.EqualsIgnoreCase( "form" ) && element.Attribute( "controller" ) != null ) attributeName = "action"; else return false; var action = element.Attribute( "action" ).Value() ?? RouteData.Values["action"].CastTo<string>(); var controller = element.Attribute( "controller" ).Value() ?? RouteData.Values["controller"].CastTo<string>(); var routeValues = UrlHelper.GetRouteValues( element ); element.RemoveAttribute( "action" ); element.RemoveAttribute( "controller" ); element.RemoveAttribute( "inherits" ); var url = UrlHelper.Action( action, controller, routeValues ); if ( url == null ) element.Attribute( attributeName ).Remove(); else element.SetAttribute( attributeName, url ); return true; }
/// <summary> /// 从元素标签中获取路由的虚拟路径 /// </summary> /// <param name="element">要获取分析路由虚拟路径的元素</param> /// <param name="clearRouteAttributes">是否清理路由属性设置</param> /// <returns>获取的虚拟路径</returns> internal string GetRouteUrl( IHtmlElement element, bool clearRouteAttributes ) { if ( element == null ) throw new ArgumentNullException( "element" ); if ( element.Attribute( "action" ) == null ) throw new InvalidOperationException(); var action = element.Attribute( "action" ).Value() ?? RouteData.Values["action"].CastTo<string>(); var controller = element.Attribute( "controller" ).Value() ?? RouteData.Values["controller"].CastTo<string>(); var routeValues = GetRouteValues( element, clearRouteAttributes ); if ( clearRouteAttributes ) { element.RemoveAttribute( "action" ); element.RemoveAttribute( "controller" ); element.RemoveAttribute( "inherits" ); } return Url.Action( action, controller, routeValues ); }
/// <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> /// <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); }