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

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

Issue 270503006: Make pseudo-classes selector queries work on DocumentFragment (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 7 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 | Annotate | Revision Log
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. All rights reserved. 5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
6 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> 6 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
7 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> 7 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org>
8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/) 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/)
9 * Copyright (c) 2011, Code Aurora Forum. All rights reserved. 9 * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
10 * Copyright (C) Research In Motion Limited 2011. All rights reserved. 10 * Copyright (C) Research In Motion Limited 2011. All rights reserved.
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 if (!nextContext.element) 303 if (!nextContext.element)
304 return SelectorFailsCompletely; 304 return SelectorFailsCompletely;
305 return match(nextContext, siblingTraversalStrategy, result); 305 return match(nextContext, siblingTraversalStrategy, result);
306 } 306 }
307 case CSSSelector::DirectAdjacent: 307 case CSSSelector::DirectAdjacent:
308 // Shadow roots can't have sibling elements 308 // Shadow roots can't have sibling elements
309 if (selectorMatchesShadowRoot(nextContext.selector)) 309 if (selectorMatchesShadowRoot(nextContext.selector))
310 return SelectorFailsCompletely; 310 return SelectorFailsCompletely;
311 311
312 if (m_mode == ResolvingStyle) { 312 if (m_mode == ResolvingStyle) {
313 if (ContainerNode* parent = context.element->parentElementOrShadowRo ot()) 313 if (ContainerNode* parent = context.element->parentElementOrDocument Fragment())
esprehn 2014/05/08 05:25:11 This doesn't make sense, we never ResolveStyle in
Inactive 2014/05/08 13:17:36 Done.
314 parent->setChildrenAffectedByDirectAdjacentRules(); 314 parent->setChildrenAffectedByDirectAdjacentRules();
315 } 315 }
316 nextContext.element = ElementTraversal::previousSibling(*context.element ); 316 nextContext.element = ElementTraversal::previousSibling(*context.element );
317 if (!nextContext.element) 317 if (!nextContext.element)
318 return SelectorFailsAllSiblings; 318 return SelectorFailsAllSiblings;
319 nextContext.isSubSelector = false; 319 nextContext.isSubSelector = false;
320 nextContext.elementStyle = 0; 320 nextContext.elementStyle = 0;
321 return match(nextContext, siblingTraversalStrategy, result); 321 return match(nextContext, siblingTraversalStrategy, result);
322 322
323 case CSSSelector::IndirectAdjacent: 323 case CSSSelector::IndirectAdjacent:
324 // Shadow roots can't have sibling elements 324 // Shadow roots can't have sibling elements
325 if (selectorMatchesShadowRoot(nextContext.selector)) 325 if (selectorMatchesShadowRoot(nextContext.selector))
326 return SelectorFailsCompletely; 326 return SelectorFailsCompletely;
327 327
328 if (m_mode == ResolvingStyle) { 328 if (m_mode == ResolvingStyle) {
329 if (ContainerNode* parent = context.element->parentElementOrShadowRo ot()) 329 if (ContainerNode* parent = context.element->parentElementOrDocument Fragment())
esprehn 2014/05/08 05:25:11 same.
Inactive 2014/05/08 13:17:36 Done.
330 parent->setChildrenAffectedByIndirectAdjacentRules(); 330 parent->setChildrenAffectedByIndirectAdjacentRules();
331 } 331 }
332 nextContext.element = ElementTraversal::previousSibling(*context.element ); 332 nextContext.element = ElementTraversal::previousSibling(*context.element );
333 nextContext.isSubSelector = false; 333 nextContext.isSubSelector = false;
334 nextContext.elementStyle = 0; 334 nextContext.elementStyle = 0;
335 for (; nextContext.element; nextContext.element = ElementTraversal::prev iousSibling(*nextContext.element)) { 335 for (; nextContext.element; nextContext.element = ElementTraversal::prev iousSibling(*nextContext.element)) {
336 Match match = this->match(nextContext, siblingTraversalStrategy, res ult); 336 Match match = this->match(nextContext, siblingTraversalStrategy, res ult);
337 if (match == SelectorMatches || match == SelectorFailsAllSiblings || match == SelectorFailsCompletely) 337 if (match == SelectorMatches || match == SelectorFailsAllSiblings || match == SelectorFailsCompletely)
338 return match; 338 return match;
339 }; 339 };
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 element.setStyleAffectedByEmpty(); 600 element.setStyleAffectedByEmpty();
601 if (context.elementStyle) 601 if (context.elementStyle)
602 context.elementStyle->setEmptyState(result); 602 context.elementStyle->setEmptyState(result);
603 else if (element.renderStyle() && (element.document().styleE ngine()->usesSiblingRules() || element.renderStyle()->unique())) 603 else if (element.renderStyle() && (element.document().styleE ngine()->usesSiblingRules() || element.renderStyle()->unique()))
604 element.renderStyle()->setEmptyState(result); 604 element.renderStyle()->setEmptyState(result);
605 } 605 }
606 return result; 606 return result;
607 } 607 }
608 case CSSSelector::PseudoFirstChild: 608 case CSSSelector::PseudoFirstChild:
609 // first-child matches the first child that is an element 609 // first-child matches the first child that is an element
610 if (ContainerNode* parent = element.parentElementOrShadowRoot()) { 610 if (ContainerNode* parent = element.parentElementOrDocumentFragment( )) {
611 bool result = siblingTraversalStrategy.isFirstChild(element); 611 bool result = siblingTraversalStrategy.isFirstChild(element);
612 if (m_mode == ResolvingStyle) { 612 if (m_mode == ResolvingStyle) {
613 RenderStyle* childStyle = context.elementStyle ? context.ele mentStyle : element.renderStyle(); 613 RenderStyle* childStyle = context.elementStyle ? context.ele mentStyle : element.renderStyle();
614 parent->setChildrenAffectedByFirstChildRules(); 614 parent->setChildrenAffectedByFirstChildRules();
615 if (result && childStyle) 615 if (result && childStyle)
616 childStyle->setFirstChildState(); 616 childStyle->setFirstChildState();
617 } 617 }
618 return result; 618 return result;
619 } 619 }
620 break; 620 break;
621 case CSSSelector::PseudoFirstOfType: 621 case CSSSelector::PseudoFirstOfType:
622 // first-of-type matches the first element of its type 622 // first-of-type matches the first element of its type
623 if (ContainerNode* parent = element.parentElementOrShadowRoot()) { 623 if (ContainerNode* parent = element.parentElementOrDocumentFragment( )) {
624 bool result = siblingTraversalStrategy.isFirstOfType(element, el ement.tagQName()); 624 bool result = siblingTraversalStrategy.isFirstOfType(element, el ement.tagQName());
625 if (m_mode == ResolvingStyle) 625 if (m_mode == ResolvingStyle)
626 parent->setChildrenAffectedByForwardPositionalRules(); 626 parent->setChildrenAffectedByForwardPositionalRules();
627 return result; 627 return result;
628 } 628 }
629 break; 629 break;
630 case CSSSelector::PseudoLastChild: 630 case CSSSelector::PseudoLastChild:
631 // last-child matches the last child that is an element 631 // last-child matches the last child that is an element
632 if (ContainerNode* parent = element.parentElementOrShadowRoot()) { 632 if (ContainerNode* parent = element.parentElementOrDocumentFragment( )) {
633 bool result = parent->isFinishedParsingChildren() && siblingTrav ersalStrategy.isLastChild(element); 633 bool result = parent->isFinishedParsingChildren() && siblingTrav ersalStrategy.isLastChild(element);
634 if (m_mode == ResolvingStyle) { 634 if (m_mode == ResolvingStyle) {
635 RenderStyle* childStyle = context.elementStyle ? context.ele mentStyle : element.renderStyle(); 635 RenderStyle* childStyle = context.elementStyle ? context.ele mentStyle : element.renderStyle();
636 parent->setChildrenAffectedByLastChildRules(); 636 parent->setChildrenAffectedByLastChildRules();
637 if (result && childStyle) 637 if (result && childStyle)
638 childStyle->setLastChildState(); 638 childStyle->setLastChildState();
639 } 639 }
640 return result; 640 return result;
641 } 641 }
642 break; 642 break;
643 case CSSSelector::PseudoLastOfType: 643 case CSSSelector::PseudoLastOfType:
644 // last-of-type matches the last element of its type 644 // last-of-type matches the last element of its type
645 if (ContainerNode* parent = element.parentElementOrShadowRoot()) { 645 if (ContainerNode* parent = element.parentElementOrDocumentFragment( )) {
646 if (m_mode == ResolvingStyle) 646 if (m_mode == ResolvingStyle)
647 parent->setChildrenAffectedByBackwardPositionalRules(); 647 parent->setChildrenAffectedByBackwardPositionalRules();
648 if (!parent->isFinishedParsingChildren()) 648 if (!parent->isFinishedParsingChildren())
649 return false; 649 return false;
650 return siblingTraversalStrategy.isLastOfType(element, element.ta gQName()); 650 return siblingTraversalStrategy.isLastOfType(element, element.ta gQName());
651 } 651 }
652 break; 652 break;
653 case CSSSelector::PseudoOnlyChild: 653 case CSSSelector::PseudoOnlyChild:
654 if (ContainerNode* parent = element.parentElementOrShadowRoot()) { 654 if (ContainerNode* parent = element.parentElementOrDocumentFragment( )) {
655 bool firstChild = siblingTraversalStrategy.isFirstChild(element) ; 655 bool firstChild = siblingTraversalStrategy.isFirstChild(element) ;
656 bool onlyChild = firstChild && parent->isFinishedParsingChildren () && siblingTraversalStrategy.isLastChild(element); 656 bool onlyChild = firstChild && parent->isFinishedParsingChildren () && siblingTraversalStrategy.isLastChild(element);
657 if (m_mode == ResolvingStyle) { 657 if (m_mode == ResolvingStyle) {
658 RenderStyle* childStyle = context.elementStyle ? context.ele mentStyle : element.renderStyle(); 658 RenderStyle* childStyle = context.elementStyle ? context.ele mentStyle : element.renderStyle();
659 parent->setChildrenAffectedByFirstChildRules(); 659 parent->setChildrenAffectedByFirstChildRules();
660 parent->setChildrenAffectedByLastChildRules(); 660 parent->setChildrenAffectedByLastChildRules();
661 if (firstChild && childStyle) 661 if (firstChild && childStyle)
662 childStyle->setFirstChildState(); 662 childStyle->setFirstChildState();
663 if (onlyChild && childStyle) 663 if (onlyChild && childStyle)
664 childStyle->setLastChildState(); 664 childStyle->setLastChildState();
665 } 665 }
666 return onlyChild; 666 return onlyChild;
667 } 667 }
668 break; 668 break;
669 case CSSSelector::PseudoOnlyOfType: 669 case CSSSelector::PseudoOnlyOfType:
670 // FIXME: This selector is very slow. 670 // FIXME: This selector is very slow.
671 if (ContainerNode* parent = element.parentElementOrShadowRoot()) { 671 if (ContainerNode* parent = element.parentElementOrDocumentFragment( )) {
672 if (m_mode == ResolvingStyle) { 672 if (m_mode == ResolvingStyle) {
673 parent->setChildrenAffectedByForwardPositionalRules(); 673 parent->setChildrenAffectedByForwardPositionalRules();
674 parent->setChildrenAffectedByBackwardPositionalRules(); 674 parent->setChildrenAffectedByBackwardPositionalRules();
675 } 675 }
676 if (!parent->isFinishedParsingChildren()) 676 if (!parent->isFinishedParsingChildren())
677 return false; 677 return false;
678 return siblingTraversalStrategy.isFirstOfType(element, element.t agQName()) && siblingTraversalStrategy.isLastOfType(element, element.tagQName()) ; 678 return siblingTraversalStrategy.isFirstOfType(element, element.t agQName()) && siblingTraversalStrategy.isLastOfType(element, element.tagQName()) ;
679 } 679 }
680 break; 680 break;
681 case CSSSelector::PseudoNthChild: 681 case CSSSelector::PseudoNthChild:
682 if (!selector.parseNth()) 682 if (!selector.parseNth())
683 break; 683 break;
684 if (ContainerNode* parent = element.parentElementOrShadowRoot()) { 684 if (ContainerNode* parent = element.parentElementOrDocumentFragment( )) {
685 int count = 1 + siblingTraversalStrategy.countElementsBefore(ele ment); 685 int count = 1 + siblingTraversalStrategy.countElementsBefore(ele ment);
686 if (m_mode == ResolvingStyle) { 686 if (m_mode == ResolvingStyle) {
687 RenderStyle* childStyle = context.elementStyle ? context.ele mentStyle : element.renderStyle(); 687 RenderStyle* childStyle = context.elementStyle ? context.ele mentStyle : element.renderStyle();
688 if (childStyle) 688 if (childStyle)
689 childStyle->setUnique(); 689 childStyle->setUnique();
690 parent->setChildrenAffectedByForwardPositionalRules(); 690 parent->setChildrenAffectedByForwardPositionalRules();
691 } 691 }
692 692
693 if (selector.matchNth(count)) 693 if (selector.matchNth(count))
694 return true; 694 return true;
695 } 695 }
696 break; 696 break;
697 case CSSSelector::PseudoNthOfType: 697 case CSSSelector::PseudoNthOfType:
698 if (!selector.parseNth()) 698 if (!selector.parseNth())
699 break; 699 break;
700 if (ContainerNode* parent = element.parentElementOrShadowRoot()) { 700 if (ContainerNode* parent = element.parentElementOrDocumentFragment( )) {
701 int count = 1 + siblingTraversalStrategy.countElementsOfTypeBefo re(element, element.tagQName()); 701 int count = 1 + siblingTraversalStrategy.countElementsOfTypeBefo re(element, element.tagQName());
702 if (m_mode == ResolvingStyle) 702 if (m_mode == ResolvingStyle)
703 parent->setChildrenAffectedByForwardPositionalRules(); 703 parent->setChildrenAffectedByForwardPositionalRules();
704 704
705 if (selector.matchNth(count)) 705 if (selector.matchNth(count))
706 return true; 706 return true;
707 } 707 }
708 break; 708 break;
709 case CSSSelector::PseudoNthLastChild: 709 case CSSSelector::PseudoNthLastChild:
710 if (!selector.parseNth()) 710 if (!selector.parseNth())
711 break; 711 break;
712 if (ContainerNode* parent = element.parentElementOrShadowRoot()) { 712 if (ContainerNode* parent = element.parentElementOrDocumentFragment( )) {
713 if (m_mode == ResolvingStyle) 713 if (m_mode == ResolvingStyle)
714 parent->setChildrenAffectedByBackwardPositionalRules(); 714 parent->setChildrenAffectedByBackwardPositionalRules();
715 if (!parent->isFinishedParsingChildren()) 715 if (!parent->isFinishedParsingChildren())
716 return false; 716 return false;
717 int count = 1 + siblingTraversalStrategy.countElementsAfter(elem ent); 717 int count = 1 + siblingTraversalStrategy.countElementsAfter(elem ent);
718 if (selector.matchNth(count)) 718 if (selector.matchNth(count))
719 return true; 719 return true;
720 } 720 }
721 break; 721 break;
722 case CSSSelector::PseudoNthLastOfType: 722 case CSSSelector::PseudoNthLastOfType:
723 if (!selector.parseNth()) 723 if (!selector.parseNth())
724 break; 724 break;
725 if (ContainerNode* parent = element.parentElementOrShadowRoot()) { 725 if (ContainerNode* parent = element.parentElementOrDocumentFragment( )) {
726 if (m_mode == ResolvingStyle) 726 if (m_mode == ResolvingStyle)
727 parent->setChildrenAffectedByBackwardPositionalRules(); 727 parent->setChildrenAffectedByBackwardPositionalRules();
728 if (!parent->isFinishedParsingChildren()) 728 if (!parent->isFinishedParsingChildren())
729 return false; 729 return false;
730 730
731 int count = 1 + siblingTraversalStrategy.countElementsOfTypeAfte r(element, element.tagQName()); 731 int count = 1 + siblingTraversalStrategy.countElementsOfTypeAfte r(element, element.tagQName());
732 if (selector.matchNth(count)) 732 if (selector.matchNth(count))
733 return true; 733 return true;
734 } 734 }
735 break; 735 break;
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after
1142 return element.focused() && isFrameFocused(element); 1142 return element.focused() && isFrameFocused(element);
1143 } 1143 }
1144 1144
1145 template 1145 template
1146 SelectorChecker::Match SelectorChecker::match(const SelectorCheckingContext&, co nst DOMSiblingTraversalStrategy&, MatchResult*) const; 1146 SelectorChecker::Match SelectorChecker::match(const SelectorCheckingContext&, co nst DOMSiblingTraversalStrategy&, MatchResult*) const;
1147 1147
1148 template 1148 template
1149 SelectorChecker::Match SelectorChecker::match(const SelectorCheckingContext&, co nst ShadowDOMSiblingTraversalStrategy&, MatchResult*) const; 1149 SelectorChecker::Match SelectorChecker::match(const SelectorCheckingContext&, co nst ShadowDOMSiblingTraversalStrategy&, MatchResult*) const;
1150 1150
1151 } 1151 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698