Exemplo n.º 1
0
        /// <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);
        }