/// <summary> /// Convert idents to functions and remove comments /// </summary> private static IEnumerable <CssToken> Normalize1(this IEnumerable <CssToken> reader) { using (var e = reader.GetEnumerator()) { while (e.MoveNext()) { var idx = (e.Current.ToValue() ?? "").IndexOf('('); if (e.Current.Type == CssTokenType.Ident && idx > 0) { using (var sw = new StringWriter()) using (var writer = new CssWriter(sw)) { writer.Write(e.Current); while (!e.Current.ToValue().EndsWith(")") && e.MoveNext()) { writer.Write(e.Current); } sw.Flush(); var tokens = new CssTokenizer(sw.ToString()); foreach (var token in tokens) { yield return(token); } } } else if (e.Current.Type != CssTokenType.Comment && e.Current.Type != CssTokenType.Cdc && e.Current.Type != CssTokenType.Cdo) { yield return(e.Current); } } } }
private static string SanitizeCss(string css, HtmlSanitizeSettings settings, bool styleTag) { using (var sw = new StringWriter()) using (var writer = new CssWriter(sw)) { foreach (var token in new CssTokenizer(css).Normalize()) { var prop = token as CssPropertyToken; var group = token as CssAtGroupToken; if (prop != null) { if (settings.AllowedCssProps.Contains(prop.Data)) { var removeProp = false; foreach (var arg in prop) { if (arg.Type == CssTokenType.Function && !settings.AllowedCssFunctions.Contains(arg.Data)) { removeProp = true; } else if (arg.Type == CssTokenType.Url) { var url = SanitizeUrl(arg.Data, settings); if (url == null) { removeProp = true; } } else if (arg.Data.IndexOf('<') >= 0 || arg.Data.IndexOf('>') >= 0) { removeProp = true; } } if (!removeProp) { writer.Write(token); } } } else if (group != null) { if (settings.AllowedCssAtRules.Contains(group.Data)) { writer.Write(group); } } else if (styleTag && (token.Type != CssTokenType.Function || settings.AllowedCssFunctions.Contains(token.Data))) { writer.Write(token); } } sw.Flush(); return(sw.ToString()); } }
public static string ToValue(this CssToken token) { var sb = Pool.NewStringBuilder(); using (var sw = new StringWriter(sb)) using (var w = new CssWriter(sw)) { w.Write(token); sw.Flush(); return(sb.ToPool()); } }