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

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: Allow positional selectors to match elements without a parent. Created 3 years, 11 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 746 matching lines...) Expand 10 before | Expand all | Expand 10 after
757 if (context.inRightmostCompound) 757 if (context.inRightmostCompound)
758 m_elementStyle->setEmptyState(result); 758 m_elementStyle->setEmptyState(result);
759 else if (element.computedStyle() && 759 else if (element.computedStyle() &&
760 (element.document().styleEngine().usesSiblingRules() || 760 (element.document().styleEngine().usesSiblingRules() ||
761 element.computedStyle()->unique())) 761 element.computedStyle()->unique()))
762 element.mutableComputedStyle()->setEmptyState(result); 762 element.mutableComputedStyle()->setEmptyState(result);
763 } 763 }
764 return result; 764 return result;
765 } 765 }
766 case CSSSelector::PseudoFirstChild: 766 case CSSSelector::PseudoFirstChild:
767 if (ContainerNode* parent = element.parentElementOrDocumentFragment()) { 767 if (m_mode == ResolvingStyle) {
768 if (m_mode == ResolvingStyle) { 768 if (ContainerNode* parent = element.parentElementOrDocumentFragment())
769 parent->setChildrenAffectedByFirstChildRules(); 769 parent->setChildrenAffectedByFirstChildRules();
770 element.setAffectedByFirstChildRules(); 770 element.setAffectedByFirstChildRules();
771 }
772 return isFirstChild(element);
773 } 771 }
774 break; 772 return isFirstChild(element);
775 case CSSSelector::PseudoFirstOfType: 773 case CSSSelector::PseudoFirstOfType:
776 if (ContainerNode* parent = element.parentElementOrDocumentFragment()) { 774 if (m_mode == ResolvingStyle) {
777 if (m_mode == ResolvingStyle) 775 if (ContainerNode* parent = element.parentElementOrDocumentFragment())
778 parent->setChildrenAffectedByForwardPositionalRules(); 776 parent->setChildrenAffectedByForwardPositionalRules();
779 return isFirstOfType(element, element.tagQName());
780 } 777 }
781 break; 778 return isFirstOfType(element, element.tagQName());
782 case CSSSelector::PseudoLastChild: 779 case CSSSelector::PseudoLastChild: {
783 if (ContainerNode* parent = element.parentElementOrDocumentFragment()) { 780 ContainerNode* parent = element.parentElementOrDocumentFragment();
784 if (m_mode == ResolvingStyle) { 781 if (m_mode == ResolvingStyle) {
782 if (parent)
785 parent->setChildrenAffectedByLastChildRules(); 783 parent->setChildrenAffectedByLastChildRules();
786 element.setAffectedByLastChildRules(); 784 element.setAffectedByLastChildRules();
787 }
788 if (!m_isQuerySelector && !parent->isFinishedParsingChildren())
789 return false;
790 return isLastChild(element);
791 } 785 }
792 break; 786 if (!m_isQuerySelector && parent && !parent->isFinishedParsingChildren())
793 case CSSSelector::PseudoLastOfType: 787 return false;
794 if (ContainerNode* parent = element.parentElementOrDocumentFragment()) { 788 return isLastChild(element);
795 if (m_mode == ResolvingStyle) 789 }
790 case CSSSelector::PseudoLastOfType: {
791 ContainerNode* parent = element.parentElementOrDocumentFragment();
792 if (m_mode == ResolvingStyle) {
793 if (parent)
796 parent->setChildrenAffectedByBackwardPositionalRules(); 794 parent->setChildrenAffectedByBackwardPositionalRules();
797 if (!m_isQuerySelector && !parent->isFinishedParsingChildren())
798 return false;
799 return isLastOfType(element, element.tagQName());
800 } 795 }
801 break; 796 if (!m_isQuerySelector && parent && !parent->isFinishedParsingChildren())
802 case CSSSelector::PseudoOnlyChild: 797 return false;
803 if (ContainerNode* parent = element.parentElementOrDocumentFragment()) { 798 return isLastOfType(element, element.tagQName());
804 if (m_mode == ResolvingStyle) { 799 }
800 case CSSSelector::PseudoOnlyChild: {
801 ContainerNode* parent = element.parentElementOrDocumentFragment();
802 if (m_mode == ResolvingStyle) {
803 if (parent) {
805 parent->setChildrenAffectedByFirstChildRules(); 804 parent->setChildrenAffectedByFirstChildRules();
806 parent->setChildrenAffectedByLastChildRules(); 805 parent->setChildrenAffectedByLastChildRules();
807 element.setAffectedByFirstChildRules();
808 element.setAffectedByLastChildRules();
809 } 806 }
810 if (!m_isQuerySelector && !parent->isFinishedParsingChildren()) 807 element.setAffectedByFirstChildRules();
811 return false; 808 element.setAffectedByLastChildRules();
812 return isFirstChild(element) && isLastChild(element);
813 } 809 }
814 break; 810 if (!m_isQuerySelector && parent && !parent->isFinishedParsingChildren())
815 case CSSSelector::PseudoOnlyOfType: 811 return false;
812 return isFirstChild(element) && isLastChild(element);
813 }
814 case CSSSelector::PseudoOnlyOfType: {
816 // FIXME: This selector is very slow. 815 // FIXME: This selector is very slow.
817 if (ContainerNode* parent = element.parentElementOrDocumentFragment()) { 816 ContainerNode* parent = element.parentElementOrDocumentFragment();
818 if (m_mode == ResolvingStyle) { 817 if (m_mode == ResolvingStyle && parent) {
819 parent->setChildrenAffectedByForwardPositionalRules(); 818 parent->setChildrenAffectedByForwardPositionalRules();
820 parent->setChildrenAffectedByBackwardPositionalRules(); 819 parent->setChildrenAffectedByBackwardPositionalRules();
821 }
822 if (!m_isQuerySelector && !parent->isFinishedParsingChildren())
823 return false;
824 return isFirstOfType(element, element.tagQName()) &&
825 isLastOfType(element, element.tagQName());
826 } 820 }
827 break; 821 if (!m_isQuerySelector && parent && !parent->isFinishedParsingChildren())
822 return false;
823 return isFirstOfType(element, element.tagQName()) &&
824 isLastOfType(element, element.tagQName());
825 }
828 case CSSSelector::PseudoPlaceholderShown: 826 case CSSSelector::PseudoPlaceholderShown:
829 if (isTextControlElement(element)) 827 if (isTextControlElement(element))
830 return toTextControlElement(element).isPlaceholderVisible(); 828 return toTextControlElement(element).isPlaceholderVisible();
831 break; 829 break;
832 case CSSSelector::PseudoNthChild: 830 case CSSSelector::PseudoNthChild:
833 if (ContainerNode* parent = element.parentElementOrDocumentFragment()) { 831 if (m_mode == ResolvingStyle) {
834 if (m_mode == ResolvingStyle) 832 if (ContainerNode* parent = element.parentElementOrDocumentFragment())
835 parent->setChildrenAffectedByForwardPositionalRules(); 833 parent->setChildrenAffectedByForwardPositionalRules();
836 return selector.matchNth(NthIndexCache::nthChildIndex(element));
837 } 834 }
838 break; 835 return selector.matchNth(NthIndexCache::nthChildIndex(element));
839 case CSSSelector::PseudoNthOfType: 836 case CSSSelector::PseudoNthOfType:
840 if (ContainerNode* parent = element.parentElementOrDocumentFragment()) { 837 if (m_mode == ResolvingStyle) {
841 if (m_mode == ResolvingStyle) 838 if (ContainerNode* parent = element.parentElementOrDocumentFragment())
842 parent->setChildrenAffectedByForwardPositionalRules(); 839 parent->setChildrenAffectedByForwardPositionalRules();
843 return selector.matchNth(NthIndexCache::nthOfTypeIndex(element));
844 } 840 }
845 break; 841 return selector.matchNth(NthIndexCache::nthOfTypeIndex(element));
846 case CSSSelector::PseudoNthLastChild: 842 case CSSSelector::PseudoNthLastChild: {
847 if (ContainerNode* parent = element.parentElementOrDocumentFragment()) { 843 ContainerNode* parent = element.parentElementOrDocumentFragment();
848 if (m_mode == ResolvingStyle) 844 if (m_mode == ResolvingStyle && parent)
849 parent->setChildrenAffectedByBackwardPositionalRules(); 845 parent->setChildrenAffectedByBackwardPositionalRules();
850 if (!m_isQuerySelector && !parent->isFinishedParsingChildren()) 846 if (!m_isQuerySelector && parent && !parent->isFinishedParsingChildren())
851 return false; 847 return false;
852 return selector.matchNth(NthIndexCache::nthLastChildIndex(element)); 848 return selector.matchNth(NthIndexCache::nthLastChildIndex(element));
853 } 849 }
854 break; 850 case CSSSelector::PseudoNthLastOfType: {
855 case CSSSelector::PseudoNthLastOfType: 851 ContainerNode* parent = element.parentElementOrDocumentFragment();
856 if (ContainerNode* parent = element.parentElementOrDocumentFragment()) { 852 if (m_mode == ResolvingStyle && parent)
857 if (m_mode == ResolvingStyle) 853 parent->setChildrenAffectedByBackwardPositionalRules();
858 parent->setChildrenAffectedByBackwardPositionalRules(); 854 if (!m_isQuerySelector && parent && !parent->isFinishedParsingChildren())
859 if (!m_isQuerySelector && !parent->isFinishedParsingChildren()) 855 return false;
860 return false; 856 return selector.matchNth(NthIndexCache::nthLastOfTypeIndex(element));
861 return selector.matchNth(NthIndexCache::nthLastOfTypeIndex(element)); 857 }
862 }
863 break;
864 case CSSSelector::PseudoTarget: 858 case CSSSelector::PseudoTarget:
865 return element == element.document().cssTarget(); 859 return element == element.document().cssTarget();
866 case CSSSelector::PseudoAny: { 860 case CSSSelector::PseudoAny: {
867 SelectorCheckingContext subContext(context); 861 SelectorCheckingContext subContext(context);
868 subContext.isSubSelector = true; 862 subContext.isSubSelector = true;
869 DCHECK(selector.selectorList()); 863 DCHECK(selector.selectorList());
870 for (subContext.selector = selector.selectorList()->first(); 864 for (subContext.selector = selector.selectorList()->first();
871 subContext.selector; 865 subContext.selector;
872 subContext.selector = CSSSelectorList::next(*subContext.selector)) { 866 subContext.selector = CSSSelectorList::next(*subContext.selector)) {
873 if (match(subContext)) 867 if (match(subContext))
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after
1314 } 1308 }
1315 1309
1316 bool SelectorChecker::matchesFocusPseudoClass(const Element& element) { 1310 bool SelectorChecker::matchesFocusPseudoClass(const Element& element) {
1317 if (InspectorInstrumentation::forcePseudoState(const_cast<Element*>(&element), 1311 if (InspectorInstrumentation::forcePseudoState(const_cast<Element*>(&element),
1318 CSSSelector::PseudoFocus)) 1312 CSSSelector::PseudoFocus))
1319 return true; 1313 return true;
1320 return element.isFocused() && isFrameFocused(element); 1314 return element.isFocused() && isFrameFocused(element);
1321 } 1315 }
1322 1316
1323 } // namespace blink 1317 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/LayoutTests/http/tests/misc/acid3.html ('k') | third_party/WebKit/Source/core/dom/NthIndexCache.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698