示例#1
0
        private void parsePseudoClass()
        {
            pseudoClassSelector pseudoClass = new pseudoClassSelector();

            pseudoClass.wholeText = _selectorText;

            if (_buffer.Length > 0)
            {
                pseudoClass.elementE = AppendCleanBuffer(_buffer);
            }

            char current = ReadNext();

            bool InBracketState = false;

            while (!stop)
            {
                if (InBracketState)
                {
                    _buffer.Append(current);

                    if (current == ')')
                    {
                        InBracketState = false;
                        break;
                    }
                }
                else
                {
                    if (current == ':')
                    {
                        if (_buffer.Length > 0)
                        {
                            pseudoClass.elementE += AppendCleanBuffer(_buffer);
                        }
                    }

                    else
                    {
                        if (current == '(')
                        {
                            InBracketState = true;
                        }

                        _buffer.Append(current);
                    }
                }

                current = ReadNext();
            }

            pseudoClass.matchText = AppendCleanBuffer(_buffer);

            simple = pseudoClass;
        }
示例#2
0
        private static int _getSilbingCount(Element element, pseudoClassSelector pseudoClass, bool last, bool sametype)
        {
            int  counter = 0;
            Node siblingNode;

            if (last)
            {
                siblingNode = element.nextSibling();
            }
            else
            {
                siblingNode = element.previousSibling();
            }

            while (siblingNode != null)
            {
                if (siblingNode.nodeType == enumNodeType.ELEMENT)
                {
                    if (sametype)
                    {
                        if (siblingNode.nodeName == pseudoClass.elementE)
                        {
                            counter += 1;
                        }
                    }
                    else
                    {
                        counter += 1;
                    }
                }

                if (last)
                {
                    siblingNode = siblingNode.nextSibling();
                }
                else
                {
                    siblingNode = siblingNode.previousSibling();
                }
            }
            return(counter);
        }
示例#3
0
        private static bool _pseudoClassNthMatch(Element element, pseudoClassSelector pseudoClass, bool last, bool sametype)
        {
            int firstindex = pseudoClass.matchText.IndexOf("(");
            int lastindex  = pseudoClass.matchText.IndexOf(")");

            if (firstindex < 0 || lastindex < 0)
            {
                return(false);
            }

            string strnumber = pseudoClass.matchText.Substring(firstindex + 1, lastindex - firstindex - 1).Trim();

            int counter = _getSilbingCount(element, pseudoClass, last, sametype);

            if (CommonIdoms.isAsciiDigit(strnumber))
            {
                int nth = Convert.ToInt32(strnumber);
                return(nth == (counter + 1));
            }
            else
            {
                if (strnumber.Contains("n"))
                {
                    int    beforen   = 0;
                    int    aftern    = 0;
                    string strbefore = strnumber.Substring(0, strnumber.IndexOf("n")).Trim();
                    if (string.IsNullOrEmpty(strbefore))
                    {
                        return(false);
                    }
                    if (!int.TryParse(strbefore, out beforen))
                    {
                        return(false);
                    }

                    if (CommonIdoms.isAsciiDigit(strbefore))
                    {
                        beforen = Convert.ToInt32(strbefore);
                    }

                    if (strnumber.IndexOf("+") > 0)
                    {
                        string strafter = strnumber.Substring(strnumber.IndexOf("+") + 1).Trim();
                        if (!string.IsNullOrEmpty(strafter))
                        {
                            if (!int.TryParse(strafter, out aftern))
                            {
                                return(false);
                            }
                        }
                    }

                    if (beforen == 0)
                    {
                        return((counter + 1) == aftern);
                    }
                    else
                    {
                        return((counter + 1) % beforen == aftern);
                    }
                }
                else if (strnumber == "odd")
                {
                    return((counter + 1) % 2 == 1);
                }
                else if (strnumber == "even")
                {
                    return((counter + 1) % 2 == 0);
                }
                else
                {
                    return(false);
                }
            }
        }
示例#4
0
        private static bool matchPseudoClass(Element element, pseudoClassSelector pseudoClass)
        {
            if (!string.IsNullOrEmpty(pseudoClass.elementE))
            {
                if (!selectorMatch.Match(element, pseudoClass.ElementSelector))
                {
                    return(false);
                }
            }

            pseudoClass.matchText = pseudoClass.matchText.ToLower().Trim();

            // E:root	an E element, root of the document	Structural pseudo-classes	3
            if (pseudoClass.matchText == "root")
            {
                if (element.tagName == "html" && element.depth == 0)
                {
                    return(true);
                }
                else
                {
                    return(false);
                }
            }

            //E:nth-child(n)	an E element, the n-th child of its parent	Structural pseudo-classes	3
            else if (pseudoClass.matchText.Contains("nth-child"))
            {
                return(_pseudoClassNthMatch(element, pseudoClass, false, false));
            }
            else if (pseudoClass.matchText.Contains("not"))
            {
                if (pseudoClass.NotSelector == null)
                {
                    return(false);
                }

                var innermatch = selectorMatch.Match(element, pseudoClass.NotSelector);

                return(!innermatch);
            }
            //E:nth-last-child(n)	an E element, the n-th child of its parent, counting from the last one	Structural pseudo-classes	3
            else if (pseudoClass.matchText.Contains("nth-last-child"))
            {
                return(_pseudoClassNthMatch(element, pseudoClass, true, false));
            }

            //E:nth-of-type(n)	an E element, the n-th sibling of its type	Structural pseudo-classes	3
            else if (pseudoClass.matchText.Contains("nth-of-type"))
            {
                return(_pseudoClassNthMatch(element, pseudoClass, false, true));
            }
            //E:nth-last-of-type(n)	an E element, the n-th sibling of its type, counting from the last one	Structural pseudo-classes	3
            else if (pseudoClass.matchText.Contains("nth-last-of-type"))
            {
                return(_pseudoClassNthMatch(element, pseudoClass, true, true));
            }

            //E:first-child	an E element, first child of its parent	Structural pseudo-classes	2
            else if (pseudoClass.matchText == "first-child")
            {
                int counter = _getSilbingCount(element, pseudoClass, false, false);
                return(counter == 0);
            }
            //E:last-child	an E element, last child of its parent	Structural pseudo-classes	3

            else if (pseudoClass.matchText == "last-child")
            {
                int counter = _getSilbingCount(element, pseudoClass, true, false);

                return(counter == 0);
            }

            //E:first-of-type	an E element, first sibling of its type	Structural pseudo-classes	3
            else if (pseudoClass.matchText == "first-of-type")
            {
                int counter = _getSilbingCount(element, pseudoClass, false, true);

                return(counter == 0);
            }
            //E:last-of-type	an E element, last sibling of its type	Structural pseudo-classes	3
            else if (pseudoClass.matchText == "last-of-type")
            {
                int counter = _getSilbingCount(element, pseudoClass, true, true);
                return(counter == 0);
            }

            //E:only-child	an E element, only child of its parent	Structural pseudo-classes	3
            else if (pseudoClass.matchText == "only-child")
            {
                int counterbefore = _getSilbingCount(element, pseudoClass, false, false);
                int counterafter  = _getSilbingCount(element, pseudoClass, true, false);
                return(counterafter == 0 && counterbefore == 0);
            }
            //E:only-of-type	an E element, only sibling of its type	Structural pseudo-classes	3
            else if (pseudoClass.matchText == "only-of-type")
            {
                int counterbefore = _getSilbingCount(element, pseudoClass, false, true);
                int counterafter  = _getSilbingCount(element, pseudoClass, true, true);
                return(counterafter == 0 && counterbefore == 0);
            }

            //  E:empty	an E element that has no children (including text nodes)	Structural pseudo-classes	3
            else if (pseudoClass.matchText == "empty")
            {
                return(element.childNodes.length == 0);
            }
            //E:link
            //E:visited	an E element being the source anchor of a hyperlink of which the target is not yet visited (:link) or already visited (:visited)	The link pseudo-classes	1
            //E:active
            //E:hover
            //E:focus	an E element during certain user actions	The user action pseudo-classes	1 and 2

            //E:enabled
            //E:disabled	a user interface element E which is enabled or disabled	The UI element states pseudo-classes	3
            //E:checked	a user interface element E which is checked (for instance a radio-button or checkbox)	The UI element states pseudo-classes	3

            else if (pseudoClass.matchText.isOneOf("active", "hover", "focus"))
            {
                return(true);
            }
            else if (pseudoClass.matchText.isOneOf("link", "visited"))
            {
                return(element.tagName == "a" || element.tagName == "area");
            }
            else if (pseudoClass.matchText.isOneOf("enabled", "disabled"))
            {
                return(true);
            }
            else if (pseudoClass.matchText == "checked")
            {
                return(element.tagName == "input");
            }

            //E:target	an E element being the target of the referring URI	The target pseudo-class	3
            else if (pseudoClass.matchText == "target")
            {
                // Not supported.
                return(true);
            }

            //E:lang(fr)	an element of type E in language "fr" (the document language specifies how language is determined)	The :lang() pseudo-class	2
            else if (pseudoClass.matchText.StartsWith("lang"))
            {
                /// not supported, always return true because we do not know when the language will be switched. has to assume it will match.
                return(true);
            }

            else
            {
                //Unrecognized syntax.
                return(false);
            }
        }