/// <summary> /// Return true if an element matches a specific DOM position-type filter /// </summary> /// <param name="obj"></param> /// <param name="position"></param> /// <param name="criteria"></param> /// <returns></returns> protected bool MatchesDOMPosition(IDomElement obj, PositionType position, string criteria) { switch (position) { case PositionType.FirstChild: return(obj.PreviousElementSibling == null); case PositionType.LastChild: return(obj.NextElementSibling == null); case PositionType.Odd: return(obj.ElementIndex % 2 != 0); case PositionType.Even: return(obj.ElementIndex % 2 == 0); case PositionType.All: return(true); case PositionType.NthChild: return(NthChildMatcher.IndexMatches(obj.ElementIndex, criteria)); default: throw new NotImplementedException("Unimplemented position type selector"); } }
/// <summary> /// Return the index of obj within its siblings, including only elements with the same node name. /// </summary> /// /// <param name="obj"> /// The object to seek /// </param> /// <param name="onlyOfSameType"> /// true to only objects of the same NodeName should be considered /// </param> /// <param name="fromLast"> /// Count from the last element instead of the first. /// </param> /// /// <returns> /// The zero-based index of obj within its siblings (or its siblings of the same type) /// </returns> private int IndexOf(IDomElement obj, bool onlyOfSameType, bool fromLast = false) { // get the index just for this type int typeIndex = 0; var childNodes = obj.ParentNode.ChildNodes; int length = childNodes.Count; for (int index = 0; index < length; index++) { var el = NthChildMatcher.GetEffectiveChild(childNodes, index, fromLast); if (el.NodeType == NodeType.ELEMENT_NODE) { if (!onlyOfSameType || el.NodeNameID == obj.NodeNameID) { if (ReferenceEquals(el, obj)) { return(typeIndex); } typeIndex++; } } } return(-1); }
/// <summary> /// Determine if an element matches a position-type filter /// </summary> /// <param name="elm"></param> /// <param name="selector"></param> /// <returns></returns> protected IEnumerable <IDomObject> GetDomPositionMatches(IDomElement elm, Selector selector) { if (selector.PositionType == PositionType.NthChild) { return(NthChildMatcher.GetMatchingChildren(elm, selector.Criteria)); } else { return(GetSimpleDomPostionMatches(elm, selector.PositionType)); } }