/// <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");
            }
        }
Example #2
0
        /// <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));
     }
 }