//public CQ ToggleClass(bool addRemoveSwitch) //{ //} /// <summary> /// Determine whether any of the matched elements are assigned the given class. /// </summary> /// /// <param name="className"> /// The class name to search for. /// </param> /// /// <returns> /// true if the class exists on any of the elements, false if not. /// </returns> /// /// <url> /// http://api.jquery.com/hasclass/ /// </url> public bool HasClass(string className) { IDomElement el = FirstElement(); return(el == null ? false : el.HasClass(className)); }
/// <summary> /// Return true if an object matches a specific selector. If the selector has a desecendant or child traversal type, it must also /// match the specificed depth. /// </summary> /// <param name="selector">The jQuery/CSS selector</param> /// <param name="obj">The target object</param> /// <param name="depth">The depth at which the target must appear for descendant or child selectors</param> /// <returns></returns> protected bool Matches(SelectorClause selector, IDomElement obj, int depth) { switch (selector.TraversalType) { case TraversalType.Child: if (selector.ChildDepth != depth) { return(false); } break; case TraversalType.Descendent: // Special case because this code is jacked up: when only "AttributeValue" it's ALWAYS a filter, it means // the AttributeExists was handled previously by the index. // This engine at some point should be reworked so that the "And" combinator is just a subselector, this logic has // become too brittle. if (depth == 0) { return(false); } break; } if (selector.SelectorType.HasFlag(SelectorType.All)) { return(true); } if (selector.SelectorType.HasFlag(SelectorType.PseudoClass)) { return(MatchesPseudoClass(obj, selector)); } if (obj.NodeType != NodeType.ELEMENT_NODE) { return(false); } // Check each selector from easier/more specific to harder. e.g. ID is going to eliminate a lot of things. if (selector.SelectorType.HasFlag(SelectorType.ID) && selector.ID != obj.Id) { return(false); } if (selector.SelectorType.HasFlag(SelectorType.Class) && !obj.HasClass(selector.Class)) { return(false); } if (selector.SelectorType.HasFlag(SelectorType.Tag) && !String.Equals(obj.NodeName, selector.Tag, StringComparison.CurrentCultureIgnoreCase)) { return(false); } if ((selector.SelectorType & SelectorType.AttributeValue) > 0) { return(AttributeSelectors.Matches((IDomElement)obj, selector)); } if (selector.SelectorType == SelectorType.None) { return(false); } return(true); }
/// <summary> /// Return true if an object matches a specific selector. If the selector has a desecendant or child traversal type, it must also /// match the specificed depth. /// </summary> /// <param name="selector">The jQuery/CSS selector</param> /// <param name="obj">The target object</param> /// <param name="depth">The depth at which the target must appear for descendant or child selectors</param> /// <returns></returns> protected bool Matches(SelectorClause selector, IDomElement obj, int depth) { switch (selector.TraversalType) { case TraversalType.Child: if (selector.ChildDepth != depth) { return false; } break; case TraversalType.Descendent: // Special case because this code is jacked up: when only "AttributeValue" it's ALWAYS a filter, it means // the AttributeExists was handled previously by the index. // This engine at some point should be reworked so that the "And" combinator is just a subselector, this logic has // become too brittle. if (depth == 0) { return false; } break; } if (selector.SelectorType.HasFlag(SelectorType.All)) { return true; } if (selector.SelectorType.HasFlag(SelectorType.PseudoClass)) { return MatchesPseudoClass(obj, selector); } if (obj.NodeType != NodeType.ELEMENT_NODE) { return false; } // Check each selector from easier/more specific to harder. e.g. ID is going to eliminate a lot of things. if (selector.SelectorType.HasFlag(SelectorType.ID) && selector.ID != obj.Id) { return false; } if (selector.SelectorType.HasFlag(SelectorType.Class) && !obj.HasClass(selector.Class)) { return false; } if (selector.SelectorType.HasFlag(SelectorType.Tag) && !String.Equals(obj.NodeName, selector.Tag, StringComparison.CurrentCultureIgnoreCase)) { return false; } if ((selector.SelectorType & SelectorType.AttributeValue)>0) { return AttributeSelectors.Matches((IDomElement)obj,selector); } if (selector.SelectorType == SelectorType.None) { return false; } return true; }
/// <summary> /// Test /// </summary> /// <param name="selector"></param> /// <param name="obj"></param> /// <param name="matchIndex"></param> /// <param name="depth"></param> /// <returns></returns> protected bool Matches(Selector selector, IDomObject obj, int depth) { bool match = true; switch (selector.TraversalType) { case TraversalType.Child: if (selector.ChildDepth != depth) { return(false); } break; case TraversalType.Descendent: if (depth == 0) { return(false); } break; } if (selector.SelectorType.HasFlag(SelectorType.All)) { return(true); } if (!(obj is IDomElement)) { return(false); } IDomElement elm = (IDomElement)obj; // Check each selector from easier/more specific to harder. e.g. ID is going to eliminate a lot of things. if (selector.SelectorType.HasFlag(SelectorType.ID) && selector.ID != elm.Id) { return(false); } if (selector.SelectorType.HasFlag(SelectorType.Class) && !elm.HasClass(selector.Class)) { return(false); } if (selector.SelectorType.HasFlag(SelectorType.Tag) && !String.Equals(elm.NodeName, selector.Tag, StringComparison.CurrentCultureIgnoreCase)) { return(false); } if (selector.SelectorType.HasFlag(SelectorType.Attribute)) { string value; match = elm.TryGetAttribute(selector.AttributeName, out value); if (!match || (match && selector.AttributeSelectorType.IsOneOf(AttributeSelectorType.NotExists, AttributeSelectorType.NotEquals))) { return(false); } switch (selector.AttributeSelectorType) { case AttributeSelectorType.Exists: break; case AttributeSelectorType.Equals: match = selector.AttributeValue == value; break; case AttributeSelectorType.StartsWith: match = value.Length >= selector.AttributeValue.Length && value.Substring(0, selector.AttributeValue.Length) == selector.AttributeValue; break; case AttributeSelectorType.Contains: match = value.IndexOf(selector.AttributeValue) >= 0; break; case AttributeSelectorType.ContainsWord: match = ContainsWord(value, selector.AttributeValue); break; case AttributeSelectorType.NotEquals: match = value.IndexOf(selector.AttributeValue) == 0; break; case AttributeSelectorType.EndsWith: int len = selector.AttributeValue.Length; match = value.Length >= len && value.Substring(value.Length - len) == selector.AttributeValue; break; default: throw new InvalidOperationException("No AttributeSelectorType set"); } if (!match) { return(false); } } if (selector.SelectorType.HasFlag(SelectorType.Other)) { return(IsVisible(elm)); } if (selector.SelectorType.HasFlag(SelectorType.Position) && selector.TraversalType == TraversalType.Filter && !MatchesDOMPosition(elm, selector.PositionType, selector.PositionType == PositionType.NthChild ? selector.Criteria : null)) { return(false); } // remove this so it doesn't get re-run // selector.SelectorType &= ~SelectorType.Position; if (selector.SelectorType.HasFlag(SelectorType.Contains) && !ContainsText(elm, selector.Criteria)) { return(false); } return(true); }