Changeset 195311 in webkit
- Timestamp:
- Jan 19, 2016, 1:26:35 PM (10 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r195310 r195311 1 2016-01-19 Antti Koivisto <antti@apple.com> 2 3 Use references in SelectorChecker 4 https://bugs.webkit.org/show_bug.cgi?id=153240 5 6 Reviewed by Andreas Kling. 7 8 Element and selector can't be null in most places. 9 10 * css/ElementRuleCollector.cpp: 11 (WebCore::ElementRuleCollector::collectMatchingRules): 12 * css/SelectorChecker.cpp: 13 (WebCore::attributeValueMatches): 14 (WebCore::anyAttributeMatches): 15 (WebCore::SelectorChecker::checkOne): 16 (WebCore::SelectorChecker::matchSelectorList): 17 (WebCore::SelectorChecker::checkScrollbarPseudoClass): 18 (WebCore::SelectorChecker::determineLinkMatchType): 19 (WebCore::isFrameFocused): 20 (WebCore::SelectorChecker::matchesFocusPseudoClass): 21 * css/SelectorChecker.h: 22 (WebCore::SelectorChecker::isCommonPseudoClassSelector): 23 (WebCore::SelectorChecker::checkExactAttribute): Deleted. 24 * css/SelectorCheckerTestFunctions.h: 25 (WebCore::isAutofilled): 26 (WebCore::isDefaultButtonForForm): 27 (WebCore::isDisabled): 28 (WebCore::isEnabled): 29 (WebCore::isMediaDocument): 30 (WebCore::isChecked): 31 (WebCore::isInRange): 32 (WebCore::isOutOfRange): 33 (WebCore::isInvalid): 34 (WebCore::isOptionalFormControl): 35 (WebCore::isRequiredFormControl): 36 (WebCore::isValid): 37 (WebCore::isWindowInactive): 38 (WebCore::containslanguageSubtagMatchingRange): 39 (WebCore::matchesLangPseudoClass): 40 (WebCore::matchesReadOnlyPseudoClass): 41 (WebCore::matchesReadWritePseudoClass): 42 (WebCore::shouldAppearIndeterminate): 43 (WebCore::scrollbarMatchesEnabledPseudoClass): 44 (WebCore::scrollbarMatchesCornerPresentPseudoClass): 45 (WebCore::matchesFullScreenPseudoClass): 46 (WebCore::matchesFullScreenAnimatingFullScreenTransitionPseudoClass): 47 (WebCore::matchesFullScreenAncestorPseudoClass): 48 (WebCore::matchesFullScreenDocumentPseudoClass): 49 (WebCore::matchesFutureCuePseudoClass): 50 (WebCore::matchesPastCuePseudoClass): 51 1 52 2016-01-19 Chris Dumez <cdumez@apple.com> 2 53 -
trunk/Source/WebCore/css/ElementRuleCollector.cpp
r195293 r195311 150 150 if (m_element.isLink()) 151 151 collectMatchingRulesForList(matchRequest.ruleSet->linkPseudoClassRules(), matchRequest, ruleRange); 152 if (SelectorChecker::matchesFocusPseudoClass( &m_element))152 if (SelectorChecker::matchesFocusPseudoClass(m_element)) 153 153 collectMatchingRulesForList(matchRequest.ruleSet->focusPseudoClassRules(), matchRequest, ruleRange); 154 154 collectMatchingRulesForList(matchRequest.ruleSet->tagRules(m_element.localName().impl(), m_element.isHTMLElement() && m_element.document().isHTMLDocument()), matchRequest, ruleRange); -
trunk/Source/WebCore/css/SelectorChecker.cpp
r195293 r195311 505 505 } 506 506 507 static bool anyAttributeMatches(const Element * element, const CSSSelector*selector, const QualifiedName& selectorAttr, bool caseSensitive)508 { 509 ASSERT(element ->hasAttributesWithoutUpdate());510 for (const Attribute& attribute : element ->attributesIterator()) {511 if (!attribute.matches(selectorAttr.prefix(), element ->isHTMLElement() ? selector->attributeCanonicalLocalName() : selectorAttr.localName(), selectorAttr.namespaceURI()))507 static bool anyAttributeMatches(const Element& element, const CSSSelector& selector, const QualifiedName& selectorAttr, bool caseSensitive) 508 { 509 ASSERT(element.hasAttributesWithoutUpdate()); 510 for (const Attribute& attribute : element.attributesIterator()) { 511 if (!attribute.matches(selectorAttr.prefix(), element.isHTMLElement() ? selector.attributeCanonicalLocalName() : selectorAttr.localName(), selectorAttr.namespaceURI())) 512 512 continue; 513 513 514 if (attributeValueMatches(attribute, selector ->match(), selector->value(), caseSensitive))514 if (attributeValueMatches(attribute, selector.match(), selector.value(), caseSensitive)) 515 515 return true; 516 516 } … … 591 591 bool SelectorChecker::checkOne(CheckingContext& checkingContext, const LocalContext& context, PseudoIdSet& dynamicPseudoIdSet, MatchType& matchType, unsigned& specificity) const 592 592 { 593 const Element* element = context.element; 594 const CSSSelector* const & selector = context.selector; 595 ASSERT(element); 596 ASSERT(selector); 597 598 specificity = CSSSelector::addSpecificities(specificity, selector->simpleSelectorSpecificity()); 599 600 if (selector->match() == CSSSelector::Tag) 601 return tagMatches(*element, *selector); 602 603 if (selector->match() == CSSSelector::Class) 604 return element->hasClass() && element->classNames().contains(selector->value()); 605 606 if (selector->match() == CSSSelector::Id) 607 return element->hasID() && element->idForStyleResolution() == selector->value(); 608 609 if (selector->isAttributeSelector()) { 610 if (!element->hasAttributes()) 611 return false; 612 613 const QualifiedName& attr = selector->attribute(); 593 const Element& element = *context.element; 594 const CSSSelector& selector = *context.selector; 595 596 specificity = CSSSelector::addSpecificities(specificity, selector.simpleSelectorSpecificity()); 597 598 if (selector.match() == CSSSelector::Tag) 599 return tagMatches(element, selector); 600 601 if (selector.match() == CSSSelector::Class) 602 return element.hasClass() && element.classNames().contains(selector.value()); 603 604 if (selector.match() == CSSSelector::Id) 605 return element.hasID() && element.idForStyleResolution() == selector.value(); 606 607 if (selector.isAttributeSelector()) { 608 if (!element.hasAttributes()) 609 return false; 610 611 const QualifiedName& attr = selector.attribute(); 614 612 bool caseSensitive = true; 615 if (selector ->attributeValueMatchingIsCaseInsensitive())613 if (selector.attributeValueMatchingIsCaseInsensitive()) 616 614 caseSensitive = false; 617 else if (m_documentIsHTML && element ->isHTMLElement() && !HTMLDocument::isCaseSensitiveAttribute(attr))615 else if (m_documentIsHTML && element.isHTMLElement() && !HTMLDocument::isCaseSensitiveAttribute(attr)) 618 616 caseSensitive = false; 619 617 … … 621 619 } 622 620 623 if (selector ->match() == CSSSelector::PseudoClass) {621 if (selector.match() == CSSSelector::PseudoClass) { 624 622 // Handle :not up front. 625 if (selector ->pseudoClassType() == CSSSelector::PseudoClassNot) {626 const CSSSelectorList* selectorList = selector ->selectorList();623 if (selector.pseudoClassType() == CSSSelector::PseudoClassNot) { 624 const CSSSelectorList* selectorList = selector.selectorList(); 627 625 628 626 for (const CSSSelector* subselector = selectorList->first(); subselector; subselector = CSSSelectorList::next(subselector)) { … … 641 639 } 642 640 return true; 643 } else if (context.hasScrollbarPseudo) { 641 } 642 if (context.hasScrollbarPseudo) { 644 643 // CSS scrollbars match a specific subset of pseudo classes, and they have specialized rules for each 645 644 // (since there are no elements involved except with window-inactive). 646 return checkScrollbarPseudoClass(checkingContext, *context.element, selector);645 return checkScrollbarPseudoClass(checkingContext, element, selector); 647 646 } 648 647 649 648 // Normal element pseudo class checking. 650 switch (selector ->pseudoClassType()) {649 switch (selector.pseudoClassType()) { 651 650 // Pseudo classes: 652 651 case CSSSelector::PseudoClassNot: … … 655 654 { 656 655 bool result = true; 657 for (Node* node = element ->firstChild(); node; node = node->nextSibling()) {656 for (Node* node = element.firstChild(); node; node = node->nextSibling()) { 658 657 if (is<Element>(*node)) { 659 658 result = false; … … 674 673 case CSSSelector::PseudoClassFirstChild: 675 674 // first-child matches the first child that is an element 676 if (const Element* parentElement = element ->parentElement()) {677 bool isFirstChild = isFirstChildElement( *element);675 if (const Element* parentElement = element.parentElement()) { 676 bool isFirstChild = isFirstChildElement(element); 678 677 if (isFirstChild) 679 addStyleRelation(checkingContext, *element, StyleRelation::FirstChild);678 addStyleRelation(checkingContext, element, StyleRelation::FirstChild); 680 679 addStyleRelation(checkingContext, *parentElement, StyleRelation::ChildrenAffectedByFirstChildRules); 681 680 return isFirstChild; … … 684 683 case CSSSelector::PseudoClassFirstOfType: 685 684 // first-of-type matches the first element of its type 686 if (element ->parentElement()) {687 addStyleRelation(checkingContext, *element, StyleRelation::AffectedByPreviousSibling);688 return isFirstOfType(checkingContext, *element, element->tagQName());685 if (element.parentElement()) { 686 addStyleRelation(checkingContext, element, StyleRelation::AffectedByPreviousSibling); 687 return isFirstOfType(checkingContext, element, element.tagQName()); 689 688 } 690 689 break; 691 690 case CSSSelector::PseudoClassLastChild: 692 691 // last-child matches the last child that is an element 693 if (const Element* parentElement = element ->parentElement()) {694 bool isLastChild = parentElement->isFinishedParsingChildren() && isLastChildElement( *element);692 if (const Element* parentElement = element.parentElement()) { 693 bool isLastChild = parentElement->isFinishedParsingChildren() && isLastChildElement(element); 695 694 if (isLastChild) 696 addStyleRelation(checkingContext, *element, StyleRelation::LastChild);695 addStyleRelation(checkingContext, element, StyleRelation::LastChild); 697 696 addStyleRelation(checkingContext, *parentElement, StyleRelation::ChildrenAffectedByLastChildRules); 698 697 return isLastChild; … … 701 700 case CSSSelector::PseudoClassLastOfType: 702 701 // last-of-type matches the last element of its type 703 if (Element* parentElement = element ->parentElement()) {702 if (Element* parentElement = element.parentElement()) { 704 703 addStyleRelation(checkingContext, *parentElement, StyleRelation::ChildrenAffectedByBackwardPositionalRules); 705 704 if (!parentElement->isFinishedParsingChildren()) 706 705 return false; 707 return isLastOfType( *element, element->tagQName());706 return isLastOfType(element, element.tagQName()); 708 707 } 709 708 break; 710 709 case CSSSelector::PseudoClassOnlyChild: 711 if (Element* parentElement = element ->parentElement()) {712 bool firstChild = isFirstChildElement( *element);713 bool onlyChild = firstChild && parentElement->isFinishedParsingChildren() && isLastChildElement( *element);710 if (Element* parentElement = element.parentElement()) { 711 bool firstChild = isFirstChildElement(element); 712 bool onlyChild = firstChild && parentElement->isFinishedParsingChildren() && isLastChildElement(element); 714 713 addStyleRelation(checkingContext, *parentElement, StyleRelation::ChildrenAffectedByFirstChildRules); 715 714 addStyleRelation(checkingContext, *parentElement, StyleRelation::ChildrenAffectedByLastChildRules); 716 715 if (firstChild) 717 addStyleRelation(checkingContext, *element, StyleRelation::FirstChild);716 addStyleRelation(checkingContext, element, StyleRelation::FirstChild); 718 717 if (onlyChild) 719 addStyleRelation(checkingContext, *element, StyleRelation::LastChild);718 addStyleRelation(checkingContext, element, StyleRelation::LastChild); 720 719 return onlyChild; 721 720 } … … 723 722 case CSSSelector::PseudoClassOnlyOfType: 724 723 // FIXME: This selector is very slow. 725 if (Element* parentElement = element ->parentElement()) {726 addStyleRelation(checkingContext, *element, StyleRelation::AffectedByPreviousSibling);724 if (Element* parentElement = element.parentElement()) { 725 addStyleRelation(checkingContext, element, StyleRelation::AffectedByPreviousSibling); 727 726 addStyleRelation(checkingContext, *parentElement, StyleRelation::ChildrenAffectedByBackwardPositionalRules); 728 727 if (!parentElement->isFinishedParsingChildren()) 729 728 return false; 730 return isFirstOfType(checkingContext, *element, element->tagQName()) && isLastOfType(*element, element->tagQName());729 return isFirstOfType(checkingContext, element, element.tagQName()) && isLastOfType(element, element.tagQName()); 731 730 } 732 731 break; … … 737 736 738 737 MatchType localMatchType = MatchType::VirtualPseudoElementOnly; 739 for (const CSSSelector* subselector = selector ->selectorList()->first(); subselector; subselector = CSSSelectorList::next(subselector)) {738 for (const CSSSelector* subselector = selector.selectorList()->first(); subselector; subselector = CSSSelectorList::next(subselector)) { 740 739 LocalContext subcontext(context); 741 740 subcontext.inFunctionalPseudoClass = true; … … 763 762 } 764 763 case CSSSelector::PseudoClassPlaceholderShown: 765 if (is<HTMLTextFormControlElement>( *element)) {766 addStyleRelation(checkingContext, *element, StyleRelation::Unique);767 return downcast<HTMLTextFormControlElement>( *element).isPlaceholderVisible();764 if (is<HTMLTextFormControlElement>(element)) { 765 addStyleRelation(checkingContext, element, StyleRelation::Unique); 766 return downcast<HTMLTextFormControlElement>(element).isPlaceholderVisible(); 768 767 } 769 768 return false; 770 769 case CSSSelector::PseudoClassNthChild: 771 if (!selector ->parseNth())770 if (!selector.parseNth()) 772 771 break; 773 if (element ->parentElement()) {774 if (const CSSSelectorList* selectorList = selector ->selectorList()) {772 if (element.parentElement()) { 773 if (const CSSSelectorList* selectorList = selector.selectorList()) { 775 774 unsigned selectorListSpecificity; 776 if (matchSelectorList(checkingContext, context, *element, *selectorList, selectorListSpecificity)) 777 specificity = CSSSelector::addSpecificities(specificity, selectorListSpecificity); 778 else 775 if (!matchSelectorList(checkingContext, context, element, *selectorList, selectorListSpecificity)) 779 776 return false; 777 specificity = CSSSelector::addSpecificities(specificity, selectorListSpecificity); 780 778 } 781 779 782 addStyleRelation(checkingContext, *element, StyleRelation::AffectedByPreviousSibling);780 addStyleRelation(checkingContext, element, StyleRelation::AffectedByPreviousSibling); 783 781 784 782 int count = 1; 785 if (const CSSSelectorList* selectorList = selector ->selectorList()) {786 for (Element* sibling = ElementTraversal::previousSibling( *element); sibling; sibling = ElementTraversal::previousSibling(*sibling)) {783 if (const CSSSelectorList* selectorList = selector.selectorList()) { 784 for (Element* sibling = ElementTraversal::previousSibling(element); sibling; sibling = ElementTraversal::previousSibling(*sibling)) { 787 785 addStyleRelation(checkingContext, *sibling, StyleRelation::AffectsNextSibling); 788 786 … … 792 790 } 793 791 } else { 794 count += countElementsBefore(checkingContext, *element);795 addStyleRelation(checkingContext, *element, StyleRelation::NthChildIndex, count);792 count += countElementsBefore(checkingContext, element); 793 addStyleRelation(checkingContext, element, StyleRelation::NthChildIndex, count); 796 794 } 797 795 798 if (selector ->matchNth(count))796 if (selector.matchNth(count)) 799 797 return true; 800 798 } 801 799 break; 802 800 case CSSSelector::PseudoClassNthOfType: 803 if (!selector ->parseNth())801 if (!selector.parseNth()) 804 802 break; 805 803 806 if (element ->parentElement()) {807 addStyleRelation(checkingContext, *element, StyleRelation::AffectedByPreviousSibling);808 809 int count = 1 + countElementsOfTypeBefore(checkingContext, *element, element->tagQName());810 if (selector ->matchNth(count))804 if (element.parentElement()) { 805 addStyleRelation(checkingContext, element, StyleRelation::AffectedByPreviousSibling); 806 807 int count = 1 + countElementsOfTypeBefore(checkingContext, element, element.tagQName()); 808 if (selector.matchNth(count)) 811 809 return true; 812 810 } 813 811 break; 814 812 case CSSSelector::PseudoClassNthLastChild: 815 if (!selector ->parseNth())813 if (!selector.parseNth()) 816 814 break; 817 if (Element* parentElement = element ->parentElement()) {818 if (const CSSSelectorList* selectorList = selector ->selectorList()) {815 if (Element* parentElement = element.parentElement()) { 816 if (const CSSSelectorList* selectorList = selector.selectorList()) { 819 817 unsigned selectorListSpecificity; 820 if (matchSelectorList(checkingContext, context, *element, *selectorList, selectorListSpecificity)) 821 specificity = CSSSelector::addSpecificities(specificity, selectorListSpecificity); 822 else 818 if (!matchSelectorList(checkingContext, context, element, *selectorList, selectorListSpecificity)) 823 819 return false; 820 specificity = CSSSelector::addSpecificities(specificity, selectorListSpecificity); 824 821 825 822 addStyleRelation(checkingContext, *parentElement, StyleRelation::ChildrenAffectedByPropertyBasedBackwardPositionalRules); … … 831 828 832 829 int count = 1; 833 if (const CSSSelectorList* selectorList = selector ->selectorList()) {834 for (Element* sibling = ElementTraversal::nextSibling( *element); sibling; sibling = ElementTraversal::nextSibling(*sibling)) {830 if (const CSSSelectorList* selectorList = selector.selectorList()) { 831 for (Element* sibling = ElementTraversal::nextSibling(element); sibling; sibling = ElementTraversal::nextSibling(*sibling)) { 835 832 unsigned ignoredSpecificity; 836 833 if (matchSelectorList(checkingContext, context, *sibling, *selectorList, ignoredSpecificity)) … … 838 835 } 839 836 } else 840 count += countElementsAfter( *element);841 842 if (selector ->matchNth(count))837 count += countElementsAfter(element); 838 839 if (selector.matchNth(count)) 843 840 return true; 844 841 } 845 842 break; 846 843 case CSSSelector::PseudoClassNthLastOfType: 847 if (!selector ->parseNth())844 if (!selector.parseNth()) 848 845 break; 849 if (Element* parentElement = element ->parentElement()) {846 if (Element* parentElement = element.parentElement()) { 850 847 addStyleRelation(checkingContext, *parentElement, StyleRelation::ChildrenAffectedByBackwardPositionalRules); 851 848 … … 853 850 return false; 854 851 855 int count = 1 + countElementsOfTypeAfter( *element, element->tagQName());856 if (selector ->matchNth(count))852 int count = 1 + countElementsOfTypeAfter(element, element.tagQName()); 853 if (selector.matchNth(count)) 857 854 return true; 858 855 } 859 856 break; 860 857 case CSSSelector::PseudoClassTarget: 861 if ( element == element->document().cssTarget())858 if (&element == element.document().cssTarget()) 862 859 return true; 863 860 break; … … 867 864 subcontext.inFunctionalPseudoClass = true; 868 865 subcontext.pseudoElementEffective = false; 869 for (subcontext.selector = selector ->selectorList()->first(); subcontext.selector; subcontext.selector = CSSSelectorList::next(subcontext.selector)) {866 for (subcontext.selector = selector.selectorList()->first(); subcontext.selector; subcontext.selector = CSSSelectorList::next(subcontext.selector)) { 870 867 subcontext.firstSelectorOfTheFragment = subcontext.selector; 871 868 PseudoIdSet ignoreDynamicPseudo; … … 877 874 break; 878 875 case CSSSelector::PseudoClassAutofill: 879 return isAutofilled( *element);876 return isAutofilled(element); 880 877 case CSSSelector::PseudoClassAnyLink: 881 878 case CSSSelector::PseudoClassAnyLinkDeprecated: 882 879 case CSSSelector::PseudoClassLink: 883 880 // :visited and :link matches are separated later when applying the style. Here both classes match all links... 884 return element ->isLink();881 return element.isLink(); 885 882 case CSSSelector::PseudoClassVisited: 886 883 // ...except if :visited matching is disabled for ancestor/sibling matching. … … 888 885 if (context.inFunctionalPseudoClass) 889 886 return false; 890 return element ->isLink() && context.visitedMatchType == VisitedMatchType::Enabled;887 return element.isLink() && context.visitedMatchType == VisitedMatchType::Enabled; 891 888 case CSSSelector::PseudoClassDrag: 892 addStyleRelation(checkingContext, *element, StyleRelation::AffectedByDrag);893 894 if (element ->renderer() && element->renderer()->isDragging())889 addStyleRelation(checkingContext, element, StyleRelation::AffectedByDrag); 890 891 if (element.renderer() && element.renderer()->isDragging()) 895 892 return true; 896 893 break; … … 898 895 return matchesFocusPseudoClass(element); 899 896 case CSSSelector::PseudoClassHover: 900 if (m_strictParsing || element ->isLink() || canMatchHoverOrActiveInQuirksMode(context)) {901 addStyleRelation(checkingContext, *element, StyleRelation::AffectedByHover);902 903 if (element ->hovered() || InspectorInstrumentation::forcePseudoState(const_cast<Element&>(*element), CSSSelector::PseudoClassHover))897 if (m_strictParsing || element.isLink() || canMatchHoverOrActiveInQuirksMode(context)) { 898 addStyleRelation(checkingContext, element, StyleRelation::AffectedByHover); 899 900 if (element.hovered() || InspectorInstrumentation::forcePseudoState(const_cast<Element&>(element), CSSSelector::PseudoClassHover)) 904 901 return true; 905 902 } 906 903 break; 907 904 case CSSSelector::PseudoClassActive: 908 if (m_strictParsing || element ->isLink() || canMatchHoverOrActiveInQuirksMode(context)) {909 addStyleRelation(checkingContext, *element, StyleRelation::AffectedByActive);910 911 if (element ->active() || InspectorInstrumentation::forcePseudoState(const_cast<Element&>(*element), CSSSelector::PseudoClassActive))905 if (m_strictParsing || element.isLink() || canMatchHoverOrActiveInQuirksMode(context)) { 906 addStyleRelation(checkingContext, element, StyleRelation::AffectedByActive); 907 908 if (element.active() || InspectorInstrumentation::forcePseudoState(const_cast<Element&>(element), CSSSelector::PseudoClassActive)) 912 909 return true; 913 910 } … … 934 931 return isInvalid(element); 935 932 case CSSSelector::PseudoClassChecked: 936 return isChecked( *element);933 return isChecked(element); 937 934 case CSSSelector::PseudoClassIndeterminate: 938 935 return shouldAppearIndeterminate(element); 939 936 case CSSSelector::PseudoClassRoot: 940 if ( element == element->document().documentElement())937 if (&element == element.document().documentElement()) 941 938 return true; 942 939 break; 943 940 case CSSSelector::PseudoClassLang: 944 941 { 945 ASSERT(selector ->langArgumentList() && !selector->langArgumentList()->isEmpty());946 return matchesLangPseudoClass(element, *selector ->langArgumentList());942 ASSERT(selector.langArgumentList() && !selector.langArgumentList()->isEmpty()); 943 return matchesLangPseudoClass(element, *selector.langArgumentList()); 947 944 } 948 945 #if ENABLE(FULLSCREEN_API) … … 969 966 case CSSSelector::PseudoClassScope: 970 967 { 971 const Node* contextualReferenceNode = !checkingContext.scope ? element ->document().documentElement() : checkingContext.scope;972 if ( element == contextualReferenceNode)968 const Node* contextualReferenceNode = !checkingContext.scope ? element.document().documentElement() : checkingContext.scope; 969 if (&element == contextualReferenceNode) 973 970 return true; 974 971 break; … … 1011 1008 } 1012 1009 #if ENABLE(VIDEO_TRACK) 1013 if (selector ->match() == CSSSelector::PseudoElement && selector->pseudoElementType() == CSSSelector::PseudoElementCue) {1010 if (selector.match() == CSSSelector::PseudoElement && selector.pseudoElementType() == CSSSelector::PseudoElementCue) { 1014 1011 LocalContext subcontext(context); 1015 1012 … … 1055 1052 } 1056 1053 1057 bool SelectorChecker::checkScrollbarPseudoClass(const CheckingContext& checkingContext, const Element& element, const CSSSelector *selector) const1058 { 1059 ASSERT(selector ->match() == CSSSelector::PseudoClass);1060 1061 switch (selector ->pseudoClassType()) {1054 bool SelectorChecker::checkScrollbarPseudoClass(const CheckingContext& checkingContext, const Element& element, const CSSSelector& selector) const 1055 { 1056 ASSERT(selector.match() == CSSSelector::PseudoClass); 1057 1058 switch (selector.pseudoClassType()) { 1062 1059 case CSSSelector::PseudoClassWindowInactive: 1063 return isWindowInactive( &element);1060 return isWindowInactive(element); 1064 1061 case CSSSelector::PseudoClassEnabled: 1065 1062 return scrollbarMatchesEnabledPseudoClass(checkingContext); … … 1125 1122 } 1126 1123 1127 static bool isFrameFocused(const Element *element)1128 { 1129 return element ->document().frame() && element->document().frame()->selection().isFocusedAndActive();1130 } 1131 1132 bool SelectorChecker::matchesFocusPseudoClass(const Element *element)1133 { 1134 if (InspectorInstrumentation::forcePseudoState(const_cast<Element&>( *element), CSSSelector::PseudoClassFocus))1124 static bool isFrameFocused(const Element& element) 1125 { 1126 return element.document().frame() && element.document().frame()->selection().isFocusedAndActive(); 1127 } 1128 1129 bool SelectorChecker::matchesFocusPseudoClass(const Element& element) 1130 { 1131 if (InspectorInstrumentation::forcePseudoState(const_cast<Element&>(element), CSSSelector::PseudoClassFocus)) 1135 1132 return true; 1136 return element ->focused() && isFrameFocused(element);1137 } 1138 1139 } 1133 return element.focused() && isFrameFocused(element); 1134 } 1135 1136 } -
trunk/Source/WebCore/css/SelectorChecker.h
r195293 r195311 119 119 120 120 static bool isCommonPseudoClassSelector(const CSSSelector*); 121 static bool matchesFocusPseudoClass(const Element*); 122 static bool checkExactAttribute(const Element*, const CSSSelector*, const QualifiedName& selectorAttributeName, const AtomicStringImpl* value); 121 static bool matchesFocusPseudoClass(const Element&); 123 122 124 123 enum LinkMatchMask { MatchDefault = 0, MatchLink = 1, MatchVisited = 2, MatchAll = MatchLink | MatchVisited }; … … 132 131 bool matchSelectorList(CheckingContext&, const LocalContext&, const Element&, const CSSSelectorList&, unsigned& specificity) const; 133 132 134 bool checkScrollbarPseudoClass(const CheckingContext&, const Element&, const CSSSelector *) const;133 bool checkScrollbarPseudoClass(const CheckingContext&, const Element&, const CSSSelector&) const; 135 134 136 135 bool m_strictParsing; … … 150 149 } 151 150 152 inline bool SelectorChecker::checkExactAttribute(const Element* element, const CSSSelector* selector, const QualifiedName& selectorAttributeName, const AtomicStringImpl* value)153 {154 if (!element->hasAttributesWithoutUpdate())155 return false;156 const AtomicString& localName = element->isHTMLElement() ? selector->attributeCanonicalLocalName() : selectorAttributeName.localName();157 for (const Attribute& attribute : element->attributesIterator()) {158 if (attribute.matches(selectorAttributeName.prefix(), localName, selectorAttributeName.namespaceURI()) && (!value || attribute.value().impl() == value))159 return true;160 }161 return false;162 }163 164 151 } 165 152 -
trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h
r195293 r195311 47 47 } 48 48 49 ALWAYS_INLINE bool isDefaultButtonForForm(const Element *element)50 { 51 return element ->isDefaultButtonForForm();52 } 53 54 ALWAYS_INLINE bool isDisabled(const Element *element)55 { 56 return (is<HTMLFormControlElement>( *element) || is<HTMLOptionElement>(*element) || is<HTMLOptGroupElement>(*element))57 && element ->isDisabledFormControl();58 } 59 60 ALWAYS_INLINE bool isEnabled(const Element *element)61 { 62 return (is<HTMLFormControlElement>( *element) || is<HTMLOptionElement>(*element) || is<HTMLOptGroupElement>(*element))63 && !element ->isDisabledFormControl();64 } 65 66 ALWAYS_INLINE bool isMediaDocument(const Element *element)67 { 68 return element ->document().isMediaDocument();49 ALWAYS_INLINE bool isDefaultButtonForForm(const Element& element) 50 { 51 return element.isDefaultButtonForForm(); 52 } 53 54 ALWAYS_INLINE bool isDisabled(const Element& element) 55 { 56 return (is<HTMLFormControlElement>(element) || is<HTMLOptionElement>(element) || is<HTMLOptGroupElement>(element)) 57 && element.isDisabledFormControl(); 58 } 59 60 ALWAYS_INLINE bool isEnabled(const Element& element) 61 { 62 return (is<HTMLFormControlElement>(element) || is<HTMLOptionElement>(element) || is<HTMLOptGroupElement>(element)) 63 && !element.isDisabledFormControl(); 64 } 65 66 ALWAYS_INLINE bool isMediaDocument(const Element& element) 67 { 68 return element.document().isMediaDocument(); 69 69 } 70 70 … … 84 84 } 85 85 86 ALWAYS_INLINE bool isInRange(const Element *element)87 { 88 return element ->isInRange();89 } 90 91 ALWAYS_INLINE bool isOutOfRange(const Element *element)92 { 93 return element ->isOutOfRange();94 } 95 96 ALWAYS_INLINE bool isInvalid(const Element *element)97 { 98 return element ->matchesInvalidPseudoClass();99 } 100 101 ALWAYS_INLINE bool isOptionalFormControl(const Element *element)102 { 103 return element ->isOptionalFormControl();104 } 105 106 ALWAYS_INLINE bool isRequiredFormControl(const Element *element)107 { 108 return element ->isRequiredFormControl();109 } 110 111 ALWAYS_INLINE bool isValid(const Element *element)112 { 113 return element ->matchesValidPseudoClass();114 } 115 116 ALWAYS_INLINE bool isWindowInactive(const Element *element)117 { 118 auto* page = element ->document().page();86 ALWAYS_INLINE bool isInRange(const Element& element) 87 { 88 return element.isInRange(); 89 } 90 91 ALWAYS_INLINE bool isOutOfRange(const Element& element) 92 { 93 return element.isOutOfRange(); 94 } 95 96 ALWAYS_INLINE bool isInvalid(const Element& element) 97 { 98 return element.matchesInvalidPseudoClass(); 99 } 100 101 ALWAYS_INLINE bool isOptionalFormControl(const Element& element) 102 { 103 return element.isOptionalFormControl(); 104 } 105 106 ALWAYS_INLINE bool isRequiredFormControl(const Element& element) 107 { 108 return element.isRequiredFormControl(); 109 } 110 111 ALWAYS_INLINE bool isValid(const Element& element) 112 { 113 return element.matchesValidPseudoClass(); 114 } 115 116 ALWAYS_INLINE bool isWindowInactive(const Element& element) 117 { 118 auto* page = element.document().page(); 119 119 if (!page) 120 120 return false; … … 152 152 } 153 153 154 ALWAYS_INLINE bool matchesLangPseudoClass(const Element* element, const Vector<AtomicString>& argumentList) 155 { 156 ASSERT(element); 157 154 ALWAYS_INLINE bool matchesLangPseudoClass(const Element& element, const Vector<AtomicString>& argumentList) 155 { 158 156 AtomicString language; 159 157 #if ENABLE(VIDEO_TRACK) 160 if (is<WebVTTElement>( *element))161 language = downcast<WebVTTElement>( *element).language();158 if (is<WebVTTElement>(element)) 159 language = downcast<WebVTTElement>(element).language(); 162 160 else 163 161 #endif 164 language = element ->computeInheritedLanguage();162 language = element.computeInheritedLanguage(); 165 163 166 164 if (language.isEmpty()) … … 207 205 } 208 206 209 ALWAYS_INLINE bool matchesReadOnlyPseudoClass(const Element *element)210 { 211 return !element ->matchesReadWritePseudoClass();212 } 213 214 ALWAYS_INLINE bool matchesReadWritePseudoClass(const Element *element)215 { 216 return element ->matchesReadWritePseudoClass();217 } 218 219 ALWAYS_INLINE bool shouldAppearIndeterminate(const Element *element)220 { 221 return element ->shouldAppearIndeterminate();207 ALWAYS_INLINE bool matchesReadOnlyPseudoClass(const Element& element) 208 { 209 return !element.matchesReadWritePseudoClass(); 210 } 211 212 ALWAYS_INLINE bool matchesReadWritePseudoClass(const Element& element) 213 { 214 return element.matchesReadWritePseudoClass(); 215 } 216 217 ALWAYS_INLINE bool shouldAppearIndeterminate(const Element& element) 218 { 219 return element.shouldAppearIndeterminate(); 222 220 } 223 221 … … 326 324 327 325 #if ENABLE(FULLSCREEN_API) 328 ALWAYS_INLINE bool matchesFullScreenPseudoClass(const Element *element)326 ALWAYS_INLINE bool matchesFullScreenPseudoClass(const Element& element) 329 327 { 330 328 // While a Document is in the fullscreen state, and the document's current fullscreen … … 332 330 // that element. Also, an <iframe>, <object> or <embed> element whose child browsing 333 331 // context's Document is in the fullscreen state has the 'full-screen' pseudoclass applied. 334 if (element ->isFrameElementBase() && element->containsFullScreenElement())332 if (element.isFrameElementBase() && element.containsFullScreenElement()) 335 333 return true; 336 if (!element ->document().webkitIsFullScreen())337 return false; 338 return element == element->document().webkitCurrentFullScreenElement();339 } 340 341 ALWAYS_INLINE bool matchesFullScreenAnimatingFullScreenTransitionPseudoClass(const Element *element)342 { 343 if ( element != element->document().webkitCurrentFullScreenElement())344 return false; 345 return element ->document().isAnimatingFullScreen();346 } 347 348 ALWAYS_INLINE bool matchesFullScreenAncestorPseudoClass(const Element *element)349 { 350 return element ->containsFullScreenElement();351 } 352 353 ALWAYS_INLINE bool matchesFullScreenDocumentPseudoClass(const Element *element)334 if (!element.document().webkitIsFullScreen()) 335 return false; 336 return &element == element.document().webkitCurrentFullScreenElement(); 337 } 338 339 ALWAYS_INLINE bool matchesFullScreenAnimatingFullScreenTransitionPseudoClass(const Element& element) 340 { 341 if (&element != element.document().webkitCurrentFullScreenElement()) 342 return false; 343 return element.document().isAnimatingFullScreen(); 344 } 345 346 ALWAYS_INLINE bool matchesFullScreenAncestorPseudoClass(const Element& element) 347 { 348 return element.containsFullScreenElement(); 349 } 350 351 ALWAYS_INLINE bool matchesFullScreenDocumentPseudoClass(const Element& element) 354 352 { 355 353 // While a Document is in the fullscreen state, the 'full-screen-document' pseudoclass applies 356 354 // to all elements of that Document. 357 if (!element ->document().webkitIsFullScreen())355 if (!element.document().webkitIsFullScreen()) 358 356 return false; 359 357 return true; … … 362 360 363 361 #if ENABLE(VIDEO_TRACK) 364 ALWAYS_INLINE bool matchesFutureCuePseudoClass(const Element *element)365 { 366 return is<WebVTTElement>( *element) && !downcast<WebVTTElement>(*element).isPastNode();367 } 368 369 ALWAYS_INLINE bool matchesPastCuePseudoClass(const Element *element)370 { 371 return is<WebVTTElement>( *element) && downcast<WebVTTElement>(*element).isPastNode();362 ALWAYS_INLINE bool matchesFutureCuePseudoClass(const Element& element) 363 { 364 return is<WebVTTElement>(element) && !downcast<WebVTTElement>(element).isPastNode(); 365 } 366 367 ALWAYS_INLINE bool matchesPastCuePseudoClass(const Element& element) 368 { 369 return is<WebVTTElement>(element) && downcast<WebVTTElement>(element).isPastNode(); 372 370 } 373 371 #endif
Note:
See TracChangeset
for help on using the changeset viewer.