Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1680)

Side by Side Diff: third_party/WebKit/Source/core/css/SelectorChecker.cpp

Issue 2588643004: Allow positional selectors to match elements without a parent. (Closed)
Patch Set: Changed the expectation instead of the crashtest, since it felt a bit saner. Created 3 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) 3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com) 4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com)
5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. 5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc.
6 * All rights reserved. 6 * All rights reserved.
7 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> 7 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
8 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> 8 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org>
9 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. 9 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved.
10 * (http://www.torchmobile.com/) 10 * (http://www.torchmobile.com/)
(...skipping 745 matching lines...) Expand 10 before | Expand all | Expand 10 after
756 if (context.inRightmostCompound) 756 if (context.inRightmostCompound)
757 m_elementStyle->setEmptyState(result); 757 m_elementStyle->setEmptyState(result);
758 else if (element.computedStyle() && 758 else if (element.computedStyle() &&
759 (element.document().styleEngine().usesSiblingRules() || 759 (element.document().styleEngine().usesSiblingRules() ||
760 element.computedStyle()->unique())) 760 element.computedStyle()->unique()))
761 element.mutableComputedStyle()->setEmptyState(result); 761 element.mutableComputedStyle()->setEmptyState(result);
762 } 762 }
763 return result; 763 return result;
764 } 764 }
765 case CSSSelector::PseudoFirstChild: 765 case CSSSelector::PseudoFirstChild:
766 if (ContainerNode* parent = element.parentElementOrDocumentFragment()) { 766 if (m_mode == ResolvingStyle) {
767 if (m_mode == ResolvingStyle) { 767 if (ContainerNode* parent = element.parentElementOrDocumentFragment())
768 parent->setChildrenAffectedByFirstChildRules(); 768 parent->setChildrenAffectedByFirstChildRules();
769 element.setAffectedByFirstChildRules(); 769 element.setAffectedByFirstChildRules();
770 }
771 return isFirstChild(element);
772 } 770 }
773 break; 771 return isFirstChild(element);
774 case CSSSelector::PseudoFirstOfType: 772 case CSSSelector::PseudoFirstOfType:
775 if (ContainerNode* parent = element.parentElementOrDocumentFragment()) { 773 if (m_mode == ResolvingStyle) {
776 if (m_mode == ResolvingStyle) 774 if (ContainerNode* parent = element.parentElementOrDocumentFragment())
777 parent->setChildrenAffectedByForwardPositionalRules(); 775 parent->setChildrenAffectedByForwardPositionalRules();
778 return isFirstOfType(element, element.tagQName());
779 } 776 }
780 break; 777 return isFirstOfType(element, element.tagQName());
781 case CSSSelector::PseudoLastChild: 778 case CSSSelector::PseudoLastChild: {
782 if (ContainerNode* parent = element.parentElementOrDocumentFragment()) { 779 ContainerNode* parent = element.parentElementOrDocumentFragment();
783 if (m_mode == ResolvingStyle) { 780 if (m_mode == ResolvingStyle) {
781 if (parent)
784 parent->setChildrenAffectedByLastChildRules(); 782 parent->setChildrenAffectedByLastChildRules();
785 element.setAffectedByLastChildRules(); 783 element.setAffectedByLastChildRules();
786 }
787 if (!m_isQuerySelector && !parent->isFinishedParsingChildren())
788 return false;
789 return isLastChild(element);
790 } 784 }
791 break; 785 if (!m_isQuerySelector && parent && !parent->isFinishedParsingChildren())
792 case CSSSelector::PseudoLastOfType: 786 return false;
793 if (ContainerNode* parent = element.parentElementOrDocumentFragment()) { 787 return isLastChild(element);
794 if (m_mode == ResolvingStyle) 788 }
789 case CSSSelector::PseudoLastOfType: {
790 ContainerNode* parent = element.parentElementOrDocumentFragment();
791 if (m_mode == ResolvingStyle) {
792 if (parent)
795 parent->setChildrenAffectedByBackwardPositionalRules(); 793 parent->setChildrenAffectedByBackwardPositionalRules();
796 if (!m_isQuerySelector && !parent->isFinishedParsingChildren())
797 return false;
798 return isLastOfType(element, element.tagQName());
799 } 794 }
800 break; 795 if (!m_isQuerySelector && parent && !parent->isFinishedParsingChildren())
801 case CSSSelector::PseudoOnlyChild: 796 return false;
802 if (ContainerNode* parent = element.parentElementOrDocumentFragment()) { 797 return isLastOfType(element, element.tagQName());
803 if (m_mode == ResolvingStyle) { 798 }
799 case CSSSelector::PseudoOnlyChild: {
800 ContainerNode* parent = element.parentElementOrDocumentFragment();
801 if (m_mode == ResolvingStyle) {
802 if (parent) {
804 parent->setChildrenAffectedByFirstChildRules(); 803 parent->setChildrenAffectedByFirstChildRules();
805 parent->setChildrenAffectedByLastChildRules(); 804 parent->setChildrenAffectedByLastChildRules();
806 element.setAffectedByFirstChildRules();
807 element.setAffectedByLastChildRules();
808 } 805 }
809 if (!m_isQuerySelector && !parent->isFinishedParsingChildren()) 806 element.setAffectedByFirstChildRules();
810 return false; 807 element.setAffectedByLastChildRules();
811 return isFirstChild(element) && isLastChild(element);
812 } 808 }
813 break; 809 if (!m_isQuerySelector && parent && !parent->isFinishedParsingChildren())
814 case CSSSelector::PseudoOnlyOfType: 810 return false;
811 return isFirstChild(element) && isLastChild(element);
812 }
813 case CSSSelector::PseudoOnlyOfType: {
815 // FIXME: This selector is very slow. 814 // FIXME: This selector is very slow.
816 if (ContainerNode* parent = element.parentElementOrDocumentFragment()) { 815 ContainerNode* parent = element.parentElementOrDocumentFragment();
817 if (m_mode == ResolvingStyle) { 816 if (m_mode == ResolvingStyle && parent) {
818 parent->setChildrenAffectedByForwardPositionalRules(); 817 parent->setChildrenAffectedByForwardPositionalRules();
819 parent->setChildrenAffectedByBackwardPositionalRules(); 818 parent->setChildrenAffectedByBackwardPositionalRules();
820 }
821 if (!m_isQuerySelector && !parent->isFinishedParsingChildren())
822 return false;
823 return isFirstOfType(element, element.tagQName()) &&
824 isLastOfType(element, element.tagQName());
825 } 819 }
826 break; 820 if (!m_isQuerySelector && parent && !parent->isFinishedParsingChildren())
821 return false;
822 return isFirstOfType(element, element.tagQName()) &&
823 isLastOfType(element, element.tagQName());
824 }
827 case CSSSelector::PseudoPlaceholderShown: 825 case CSSSelector::PseudoPlaceholderShown:
828 if (isTextControlElement(element)) 826 if (isTextControlElement(element))
829 return toTextControlElement(element).isPlaceholderVisible(); 827 return toTextControlElement(element).isPlaceholderVisible();
830 break; 828 break;
831 case CSSSelector::PseudoNthChild: 829 case CSSSelector::PseudoNthChild:
832 if (ContainerNode* parent = element.parentElementOrDocumentFragment()) { 830 if (m_mode == ResolvingStyle) {
833 if (m_mode == ResolvingStyle) 831 if (ContainerNode* parent = element.parentElementOrDocumentFragment())
834 parent->setChildrenAffectedByForwardPositionalRules(); 832 parent->setChildrenAffectedByForwardPositionalRules();
835 return selector.matchNth(NthIndexCache::nthChildIndex(element));
836 } 833 }
837 break; 834 return selector.matchNth(NthIndexCache::nthChildIndex(element));
838 case CSSSelector::PseudoNthOfType: 835 case CSSSelector::PseudoNthOfType:
839 if (ContainerNode* parent = element.parentElementOrDocumentFragment()) { 836 if (m_mode == ResolvingStyle) {
840 if (m_mode == ResolvingStyle) 837 if (ContainerNode* parent = element.parentElementOrDocumentFragment())
841 parent->setChildrenAffectedByForwardPositionalRules(); 838 parent->setChildrenAffectedByForwardPositionalRules();
842 return selector.matchNth(NthIndexCache::nthOfTypeIndex(element));
843 } 839 }
844 break; 840 return selector.matchNth(NthIndexCache::nthOfTypeIndex(element));
845 case CSSSelector::PseudoNthLastChild: 841 case CSSSelector::PseudoNthLastChild: {
846 if (ContainerNode* parent = element.parentElementOrDocumentFragment()) { 842 ContainerNode* parent = element.parentElementOrDocumentFragment();
847 if (m_mode == ResolvingStyle) 843 if (m_mode == ResolvingStyle && parent)
848 parent->setChildrenAffectedByBackwardPositionalRules(); 844 parent->setChildrenAffectedByBackwardPositionalRules();
849 if (!m_isQuerySelector && !parent->isFinishedParsingChildren()) 845 if (!m_isQuerySelector && parent && !parent->isFinishedParsingChildren())
850 return false; 846 return false;
851 return selector.matchNth(NthIndexCache::nthLastChildIndex(element)); 847 return selector.matchNth(NthIndexCache::nthLastChildIndex(element));
852 } 848 }
853 break; 849 case CSSSelector::PseudoNthLastOfType: {
854 case CSSSelector::PseudoNthLastOfType: 850 ContainerNode* parent = element.parentElementOrDocumentFragment();
855 if (ContainerNode* parent = element.parentElementOrDocumentFragment()) { 851 if (m_mode == ResolvingStyle && parent)
856 if (m_mode == ResolvingStyle) 852 parent->setChildrenAffectedByBackwardPositionalRules();
857 parent->setChildrenAffectedByBackwardPositionalRules(); 853 if (!m_isQuerySelector && parent && !parent->isFinishedParsingChildren())
858 if (!m_isQuerySelector && !parent->isFinishedParsingChildren()) 854 return false;
859 return false; 855 return selector.matchNth(NthIndexCache::nthLastOfTypeIndex(element));
860 return selector.matchNth(NthIndexCache::nthLastOfTypeIndex(element)); 856 }
861 }
862 break;
863 case CSSSelector::PseudoTarget: 857 case CSSSelector::PseudoTarget:
864 return element == element.document().cssTarget(); 858 return element == element.document().cssTarget();
865 case CSSSelector::PseudoAny: { 859 case CSSSelector::PseudoAny: {
866 SelectorCheckingContext subContext(context); 860 SelectorCheckingContext subContext(context);
867 subContext.isSubSelector = true; 861 subContext.isSubSelector = true;
868 DCHECK(selector.selectorList()); 862 DCHECK(selector.selectorList());
869 for (subContext.selector = selector.selectorList()->first(); 863 for (subContext.selector = selector.selectorList()->first();
870 subContext.selector; 864 subContext.selector;
871 subContext.selector = CSSSelectorList::next(*subContext.selector)) { 865 subContext.selector = CSSSelectorList::next(*subContext.selector)) {
872 if (match(subContext)) 866 if (match(subContext))
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after
1313 } 1307 }
1314 1308
1315 bool SelectorChecker::matchesFocusPseudoClass(const Element& element) { 1309 bool SelectorChecker::matchesFocusPseudoClass(const Element& element) {
1316 if (InspectorInstrumentation::forcePseudoState(const_cast<Element*>(&element), 1310 if (InspectorInstrumentation::forcePseudoState(const_cast<Element*>(&element),
1317 CSSSelector::PseudoFocus)) 1311 CSSSelector::PseudoFocus))
1318 return true; 1312 return true;
1319 return element.isFocused() && isFrameFocused(element); 1313 return element.isFocused() && isFrameFocused(element);
1320 } 1314 }
1321 1315
1322 } // namespace blink 1316 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698