public void Mark(IHtmlElement element) { Contract.RequiresNotNull(element, "element"); if (Element != null) { // unmark first - maybe it was marked with another color before Unmark(); } Element = element; var markerCountAttr = Element.GetAttribute(Attribute_MarkerCount); if (string.IsNullOrEmpty(markerCountAttr)) { Element.SetAttribute(Attribute_OrigStyle, Element.Style); myMarkerIdx = 0; } else { myMarkerIdx = int.Parse(markerCountAttr); } var markupStyle = string.Format(";color:black;background-color:{0}", ColorTranslator.ToHtml(Color)); Element.SetAttribute(Attribute_Marker + myMarkerIdx, markupStyle); Element.SetAttribute(Attribute_MarkerCount, (myMarkerIdx + 1).ToString()); Element.Style = Element.GetAttribute(Attribute_OrigStyle) + markupStyle; }
/// <summary> /// 设置样式值 /// </summary> /// <param name="name">样式名</param> /// <param name="value">样式值</param> /// <returns>样式管理器自身</returns> public virtual CssStyle SetValue(string name, string value) { settings[name] = value; _element.SetAttribute("style", GetStyleExpression(settings)); return(this); }
/// <summary> /// 设置样式值 /// </summary> /// <param name="name">样式名</param> /// <param name="value">样式值(若为 null 则移除样式)</param> /// <returns>样式管理器自身</returns> public virtual StyleManager SetValue(string name, string value) { lock (_element.SyncRoot) { EnsureStyle(); _style[name] = value; _element.SetAttribute("style", _style.ToString(), out _attribute); return(this); } }
/// <summary> /// 返回元素的唯一ID,没有ID属性,或者有但非唯一,返回null /// </summary> /// <param name="element">要标识的元素</param> /// <param name="create">指示当没有唯一ID时是否创建一个</param> /// <param name="ancestorsCreate">在创建ID的过程中,是否为没有唯一ID的父级也创建ID</param> /// <returns>元素的唯一ID。</returns> public static string Identity(this IHtmlElement element, bool create, bool ancestorsCreate) { if (element == null) { throw new ArgumentNullException("element"); } EnsureAllocated(element); var id = element.Attribute("id").Value(); if (string.IsNullOrEmpty(id) || !element.Document.AllElements().Where(e => e.Attribute("id").Value() == id).IsSingle()) { id = null; } if (create && id == null) { element.SetAttribute("id", id = CreateIdentity(element, ancestorsCreate)); } return(id); }
/// <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="context">绑定上下文</param> /// <param name="path">绑定路径</param> /// <param name="value">绑定值</param> /// <param name="nullBehavior">为空时执行的操作</param> private static void BindCore(this IHtmlElement element, string path, string value, BindingNullBehavior nullBehavior) { if (value == null) { switch (nullBehavior) { case BindingNullBehavior.Ignore: break; case BindingNullBehavior.Hidden: BindingContext.Action(element, e => e.Style().SetValue("visibility", "hidden")); break; case BindingNullBehavior.Remove: BindingContext.Action(element, e => e.Remove()); break; case BindingNullBehavior.DisplayNone: BindingContext.Action(element, e => e.Style().SetValue("display", "none")); break; default: throw new NotSupportedException(); } return; } var attributeMatch = attributePathRegex.Match(path); if (attributeMatch.Success) { string attributeName = attributeMatch.Groups["name"].Value; BindingContext.Action(element, e => element.SetAttribute(attributeName, value)); } if (path == "@:text") { BindingContext.Action(element, e => e.InnerText(value)); } if (path == "@:html") { BindingContext.Action(element, e => e.InnerHtml(value)); } return; }
/// <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; } 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> /// 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/FlorianRappl/AngleSharp/issues/101 if (element.GetAttribute("style") == null) return; element.SetAttribute("style", element.Style.ToCss()); var styles = element.Style; if (styles == null || styles.Length == 0) return; var removeStyles = new List<Tuple<ICssProperty, RemoveReason>>(); var setStyles = new Dictionary<string, string>(); foreach (var style in styles) { var key = DecodeCss(style.Name); var val = DecodeCss(style.Value); if (!AllowedCssProperties.Contains(key)) { removeStyles.Add(new Tuple<ICssProperty, RemoveReason>(style, RemoveReason.NotAllowedStyle)); continue; } if(CssExpression.IsMatch(val) || DisallowCssPropertyValue.IsMatch(val)) { removeStyles.Add(new Tuple<ICssProperty, RemoveReason>(style, RemoveReason.NotAllowedValue)); continue; } var urls = CssUrl.Matches(val); if (urls.Count > 0) { if (urls.Cast<Match>().Any(m => GetSafeUri(m.Groups[2].Value) == null || SanitizeUrl(m.Groups[2].Value, baseUrl) == null)) removeStyles.Add(new Tuple<ICssProperty, RemoveReason>(style, RemoveReason.NotAllowedUrlValue)); else { var s = CssUrl.Replace(val, m => "url(" + m.Groups[1].Value + SanitizeUrl(m.Groups[2].Value, baseUrl) + m.Groups[3].Value); if (s != val) { if (key != style.Name) { removeStyles.Add(new Tuple<ICssProperty, RemoveReason>(style, RemoveReason.NotAllowedUrlValue)); } setStyles[key] = s; } } } } foreach (var style in removeStyles) { RemoveStyle(element, styles, style.Item1, style.Item2); } foreach (var style in setStyles) { styles.SetProperty(style.Key, style.Value); } }
private static void ParseProperty(XamlProperty property, IHtmlDocument htmlDocument, IHtmlElement element) { if (property.IsCollection) { foreach (var prp in property.CollectionElements) { if (prp is XamlObject) { if (((XamlObject)prp).Instance is FrameworkElement) { ParseObject((XamlObject)prp, htmlDocument, element); } } } } else { if (!string.IsNullOrEmpty(property.ParentObject.ContentPropertyName) && property.PropertyName == property.ParentObject.ContentPropertyName) { ParseObject(property.PropertyValue, htmlDocument, element); } else { switch (property.PropertyName) { case "Row": { var rw = Convert.ToInt32(property.ValueOnInstance); //element.Style.SetProperty("grid-row", (rw + 1).ToString()); return; } case "RowSpan": { //element.Style.SetProperty("grid-row-span", property.ValueOnInstance.ToString()); return; } case "Column": { var rw = Convert.ToInt32(property.ValueOnInstance); //element.Style.SetProperty("grid-column", (rw + 1).ToString()); return; } case "ColumnSpan": { //element.Style.SetProperty("grid-column-span", property.ValueOnInstance.ToString()); return; } case "Orientation": { element.Style.FlexDirection = property.ValueOnInstance.ToString() == "Vertical" ? "Row" : "Column"; return; } case "Text": { //When ctrl is a TextBox / TranslateTextBlock element.TextContent = (property.ValueOnInstance ?? "").ToString(); return; } case "Stroke": { //When ctrl is a Rectangle element.Style.BorderColor = ParseXamlColor(property.ValueOnInstance); element.Style.BorderStyle = "solid"; return; } case "StrokeThickness": { //When ctrl is a Rectangle element.Style.BorderWidth = property.ValueOnInstance.ToString() + "px"; element.Style.BorderStyle = "solid"; return; } case "Width": { element.Style.Width = property.ValueOnInstance.ToString() + "px"; return; } case "Height": { element.Style.Height = property.ValueOnInstance.ToString() + "px"; return; } case "Background": case "Fill": { element.Style.Background = ParseXamlColor(property.ValueOnInstance); return; } case "Margin": { element.Style.Left = ((Thickness)property.ValueOnInstance).Left.ToString() + "px"; element.Style.Top = ((Thickness)property.ValueOnInstance).Top.ToString() + "px"; return; } case "Left": { //if (property.ParentObject.ParentObject.Instance is Canvas) //element.Style.Position = "absolute"; element.Style.Left = property.ValueOnInstance.ToString() + "px"; return; } case "Top": { //element.Style.Position = "absolute"; element.Style.Top = property.ValueOnInstance.ToString() + "px"; return; } case "FontSize": { element.Style.FontSize = property.ValueOnInstance.ToString() + "pt"; return; } case "FontWeight": { element.Style.FontWeight = property.ValueOnInstance.ToString(); return; } case "RenderTransform": { ParseTransform(element, property.ValueOnInstance as Transform); return; } case "Opacity": { element.Style.Opacity = property.ValueOnInstance.ToString(); return; } case "Ignorable": { return; } default: { if (property.ValueOnInstance != null) { var nm = property.PropertyName[0].ToString().ToLower() + property.PropertyName.Substring(1); nm = Regex.Replace(nm, @"(?<!_)([A-Z])", "-$1"); element.SetAttribute(nm, property.ValueOnInstance.ToString()); } return; } } } } }