private bool IsMatch(IQueryableNode node, AttributeRestriction elem) { string value; if (node.TryGetAttributeValue(elem.Name, this.Comparison, out value)) { switch (elem.Comparison) { case Selector.AttributeComparison.Contains: return !string.IsNullOrEmpty(elem.Value) && value.IndexOf(elem.Value, this.Comparison) >= 0; case Selector.AttributeComparison.EndsWith: return !string.IsNullOrEmpty(elem.Value) && value.EndsWith(elem.Value, this.Comparison); case Selector.AttributeComparison.Equals: return string.Compare(value, elem.Value ?? "", this.Comparison) == 0; case Selector.AttributeComparison.Exists: return true; case Selector.AttributeComparison.HyphenatedListStartsWith: return string.IsNullOrEmpty(elem.Value) || string.Compare(value, elem.Value, this.Comparison) == 0 || value.StartsWith(elem.Value + '-', this.Comparison); case Selector.AttributeComparison.NotEquals: return string.Compare(value, elem.Value ?? "", this.Comparison) != 0; case Selector.AttributeComparison.StartsWith: return !string.IsNullOrEmpty(elem.Value) && value.StartsWith(elem.Value, this.Comparison); case Selector.AttributeComparison.WhitespaceListContains: return !string.IsNullOrEmpty(elem.Value) && value.Split(' ').Contains(elem.Value, GetComparer(this.Comparison)); } } return false; }
public IEnumerable<IQueryableNode> Parents(IQueryableNode node) { var result = node.Parent(); while (result != null) { yield return result; result = result.Parent(); } }
public IEnumerable<IQueryableNode> FollowingSiblings(IQueryableNode node) { var result = node.FollowingSibling(); while (result != null) { yield return result; result = result.FollowingSibling(); } }
public void Initialize(IQueryableNode node) { _matches = Enumerable.Repeat(node, 1); this.MatchSpecificity = 0; }
public static IEnumerable<Property> ApplicableProperties(this IEnumerable<StyleRule> rules, IQueryableNode node, IQueryEngine engine, StringComparison comparison, GlobalStyleContext settings) { var visitor = new MatchVisitor(engine); visitor.Comparison = comparison; var terms = new Dictionary<string, TermSpecificity>(); TermSpecificity existing; int specificity = 0; int propSpecificity; foreach (var style in rules) { if (style.Selector != null) { visitor.Initialize(node); style.Selector.Visit(visitor); } if (style.Selector == null || visitor.IsMatch()) { specificity = style.Selector == null ? 0 : (visitor.MatchSpecificity > 0 ? visitor.MatchSpecificity : style.Selector.GetSpecificity()); foreach (var prop in style.Declarations.SelectMany(p => p.Expand(settings.LeftToRight))) { propSpecificity = specificity + (prop.Important ? (1 << 20) : 0); if (terms.TryGetValue(prop.Name, out existing)) { if (propSpecificity >= existing.Specificity) { existing.Property = prop; } } else { terms[prop.Name] = new TermSpecificity() { Property = prop, Specificity = propSpecificity }; } } } } return terms.Values.Select(v => v.Property); }