public CssRuleMatch Match(HtmlTag tag) { var result = new CssRuleMatch(this); var selector = GetMatchingSelectors(tag).OrderByDescending(s => s.Specificity).FirstOrDefault(); result.Success = selector != null; if (selector != null) result.Specificity = selector.Specificity; return result; }
private static void AppendStyles(CssRule rule, HtmlTag tag) { var style = rule.Statements.ToSeparatedString(""); if (string.IsNullOrEmpty(style)) return; var styles = new HtmlStyleCollection(); styles.Parse(style); tag.Styles.Append(styles, true); }
private static KeyValuePair<string, string>? GetKeyValue(HtmlTag meta) { var name = meta.Attributes["name"]; var equiv = meta.Attributes["http-equiv"]; string key; if (!string.IsNullOrEmpty(name)) key = name; else if (!string.IsNullOrEmpty(equiv)) key = equiv; else return null; var value = meta.Attributes["content"] ?? string.Empty; return new KeyValuePair<string, string>(key.ToLower(), value); }
internal static void Parse(IHtmlElementCollection parent, Token token) { HtmlElement element = null; if (token.Peeks("</")) element = new HtmlEndTag(token); else if (token.Peeks("<!DOCTYPE")) element = new HtmlDocType(token); else if (token.Peeks("<!--")) element = new HtmlComment(token); else if (token.Current == '<') element = new HtmlTag(token); else element = new HtmlContent(token); element.Parent = parent; parent.ChildElements.Add(element); if (element is HtmlTag) { var tag = (HtmlTag)element; if (tag.IsType("script")) { HtmlContent script = new HtmlContent(token.ReadUntil("</script>")); tag.ChildElements.Add(script); } } if (element.ElementType != HtmlElementType.EndTag) return; var tagName = ((HtmlEndTag) element).TagName; int startTagIdex = parent.ChildElements.Count - 2; HtmlTag startTag = null; while (startTagIdex >= 0) { var tmp = parent.ChildElements[startTagIdex] as HtmlTag; if (tmp != null && !tmp.Closed && tmp.EndTag == null && tmp.Name.Equals(tagName, StringComparison.InvariantCultureIgnoreCase)) { startTag = tmp; break; } startTagIdex--; } if (startTag != null) { startTag.EndTag = (HtmlEndTag) element; ((HtmlEndTag) element).StartTag = startTag; int rangeStart = startTagIdex + 1; int rangeCount = parent.ChildElements.Count - startTagIdex - 2; startTag.AssignChildElements(parent.ChildElements.GetRange(rangeStart, rangeCount)); parent.ChildElements.RemoveRange(rangeStart, rangeCount); } }
private IEnumerable<CssSelectorStack> GetMatchingSelectors(HtmlTag tag) { foreach (var stack in _selectorStacks) { if (stack.IsMatch(tag)) yield return stack; //var tmp = tag; //var selectorIndex = stack.Selectors.Count - 1; //while (selectorIndex >= 0 && tmp != null) //{ // if (stack.Selectors[selectorIndex].Matches(tmp)) // selectorIndex--; // else if (selectorIndex == stack.Selectors.Count - 1) // { // break; // } // tmp = tmp.Parent as HtmlTag; //} //if (selectorIndex == -1) //{ // yield return stack; //} } }
private void Process(HtmlTag tag) { foreach (var match in _cssDocument.Rules.Select(r => r.Match(tag)).Where(m => m.Success).OrderBy(m => m.Specificity)) AppendStyles(match.Rule, tag); foreach (var childTag in tag.ChildElements.Where(c => c.ElementType == HtmlElementType.Tag)) Process((HtmlTag) childTag); }