OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) |
3 * 1999 Waldo Bastian (bastian@kde.org) | 3 * 1999 Waldo Bastian (bastian@kde.org) |
4 * 2001 Andreas Schlapbach (schlpbch@iam.unibe.ch) | 4 * 2001 Andreas Schlapbach (schlpbch@iam.unibe.ch) |
5 * 2001-2003 Dirk Mueller (mueller@kde.org) | 5 * 2001-2003 Dirk Mueller (mueller@kde.org) |
6 * Copyright (C) 2002, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserv
ed. | 6 * Copyright (C) 2002, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserv
ed. |
7 * Copyright (C) 2008 David Smith (catfish.man@gmail.com) | 7 * Copyright (C) 2008 David Smith (catfish.man@gmail.com) |
8 * Copyright (C) 2010 Google Inc. All rights reserved. | 8 * Copyright (C) 2010 Google Inc. All rights reserved. |
9 * | 9 * |
10 * This library is free software; you can redistribute it and/or | 10 * This library is free software; you can redistribute it and/or |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 | 93 |
94 inline unsigned CSSSelector::specificityForOneSelector() const | 94 inline unsigned CSSSelector::specificityForOneSelector() const |
95 { | 95 { |
96 // FIXME: Pseudo-elements and pseudo-classes do not have the same specificit
y. This function | 96 // FIXME: Pseudo-elements and pseudo-classes do not have the same specificit
y. This function |
97 // isn't quite correct. | 97 // isn't quite correct. |
98 // http://www.w3.org/TR/selectors/#specificity | 98 // http://www.w3.org/TR/selectors/#specificity |
99 switch (m_match) { | 99 switch (m_match) { |
100 case Id: | 100 case Id: |
101 return 0x010000; | 101 return 0x010000; |
102 case PseudoClass: | 102 case PseudoClass: |
103 switch (pseudoType()) { | 103 switch (getPseudoType()) { |
104 case PseudoHost: | 104 case PseudoHost: |
105 case PseudoHostContext: | 105 case PseudoHostContext: |
106 // We dynamically compute the specificity of :host and :host-context | 106 // We dynamically compute the specificity of :host and :host-context |
107 // during matching. | 107 // during matching. |
108 return 0; | 108 return 0; |
109 case PseudoNot: | 109 case PseudoNot: |
110 ASSERT(selectorList()); | 110 ASSERT(selectorList()); |
111 return selectorList()->first()->specificityForOneSelector(); | 111 return selectorList()->first()->specificityForOneSelector(); |
112 // FIXME: PseudoAny should base the specificity on the sub-selectors. | 112 // FIXME: PseudoAny should base the specificity on the sub-selectors. |
113 // See http://lists.w3.org/Archives/Public/www-style/2010Sep/0530.html | 113 // See http://lists.w3.org/Archives/Public/www-style/2010Sep/0530.html |
(...skipping 27 matching lines...) Expand all Loading... |
141 { | 141 { |
142 // See http://dev.w3.org/csswg/css3-page/#cascading-and-page-context | 142 // See http://dev.w3.org/csswg/css3-page/#cascading-and-page-context |
143 unsigned s = 0; | 143 unsigned s = 0; |
144 | 144 |
145 for (const CSSSelector* component = this; component; component = component->
tagHistory()) { | 145 for (const CSSSelector* component = this; component; component = component->
tagHistory()) { |
146 switch (component->m_match) { | 146 switch (component->m_match) { |
147 case Tag: | 147 case Tag: |
148 s += tagQName().localName() == starAtom ? 0 : 4; | 148 s += tagQName().localName() == starAtom ? 0 : 4; |
149 break; | 149 break; |
150 case PagePseudoClass: | 150 case PagePseudoClass: |
151 switch (component->pseudoType()) { | 151 switch (component->getPseudoType()) { |
152 case PseudoFirstPage: | 152 case PseudoFirstPage: |
153 s += 2; | 153 s += 2; |
154 break; | 154 break; |
155 case PseudoLeftPage: | 155 case PseudoLeftPage: |
156 case PseudoRightPage: | 156 case PseudoRightPage: |
157 s += 1; | 157 s += 1; |
158 break; | 158 break; |
159 default: | 159 default: |
160 ASSERT_NOT_REACHED(); | 160 ASSERT_NOT_REACHED(); |
161 } | 161 } |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 return static_cast<CSSSelector::PseudoType>(match->type); | 409 return static_cast<CSSSelector::PseudoType>(match->type); |
410 } | 410 } |
411 | 411 |
412 #ifndef NDEBUG | 412 #ifndef NDEBUG |
413 void CSSSelector::show(int indent) const | 413 void CSSSelector::show(int indent) const |
414 { | 414 { |
415 printf("%*sselectorText(): %s\n", indent, "", selectorText().ascii().data())
; | 415 printf("%*sselectorText(): %s\n", indent, "", selectorText().ascii().data())
; |
416 printf("%*sm_match: %d\n", indent, "", m_match); | 416 printf("%*sm_match: %d\n", indent, "", m_match); |
417 if (m_match != Tag) | 417 if (m_match != Tag) |
418 printf("%*svalue(): %s\n", indent, "", value().ascii().data()); | 418 printf("%*svalue(): %s\n", indent, "", value().ascii().data()); |
419 printf("%*spseudoType(): %d\n", indent, "", pseudoType()); | 419 printf("%*sgetPseudoType(): %d\n", indent, "", getPseudoType()); |
420 if (m_match == Tag) | 420 if (m_match == Tag) |
421 printf("%*stagQName().localName: %s\n", indent, "", tagQName().localName
().ascii().data()); | 421 printf("%*stagQName().localName: %s\n", indent, "", tagQName().localName
().ascii().data()); |
422 printf("%*sisAttributeSelector(): %d\n", indent, "", isAttributeSelector()); | 422 printf("%*sisAttributeSelector(): %d\n", indent, "", isAttributeSelector()); |
423 if (isAttributeSelector()) | 423 if (isAttributeSelector()) |
424 printf("%*sattribute(): %s\n", indent, "", attribute().localName().ascii
().data()); | 424 printf("%*sattribute(): %s\n", indent, "", attribute().localName().ascii
().data()); |
425 printf("%*sargument(): %s\n", indent, "", argument().ascii().data()); | 425 printf("%*sargument(): %s\n", indent, "", argument().ascii().data()); |
426 printf("%*sspecificity(): %u\n", indent, "", specificity()); | 426 printf("%*sspecificity(): %u\n", indent, "", specificity()); |
427 if (tagHistory()) { | 427 if (tagHistory()) { |
428 printf("\n%*s--> (relation == %d)\n", indent, "", relation()); | 428 printf("\n%*s--> (relation == %d)\n", indent, "", relation()); |
429 tagHistory()->show(indent + 2); | 429 tagHistory()->show(indent + 2); |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
562 bool CSSSelector::operator==(const CSSSelector& other) const | 562 bool CSSSelector::operator==(const CSSSelector& other) const |
563 { | 563 { |
564 const CSSSelector* sel1 = this; | 564 const CSSSelector* sel1 = this; |
565 const CSSSelector* sel2 = &other; | 565 const CSSSelector* sel2 = &other; |
566 | 566 |
567 while (sel1 && sel2) { | 567 while (sel1 && sel2) { |
568 if (sel1->attribute() != sel2->attribute() | 568 if (sel1->attribute() != sel2->attribute() |
569 || sel1->relation() != sel2->relation() | 569 || sel1->relation() != sel2->relation() |
570 || sel1->m_match != sel2->m_match | 570 || sel1->m_match != sel2->m_match |
571 || sel1->value() != sel2->value() | 571 || sel1->value() != sel2->value() |
572 || sel1->pseudoType() != sel2->pseudoType() | 572 || sel1->getPseudoType() != sel2->getPseudoType() |
573 || sel1->argument() != sel2->argument()) { | 573 || sel1->argument() != sel2->argument()) { |
574 return false; | 574 return false; |
575 } | 575 } |
576 if (sel1->m_match == Tag) { | 576 if (sel1->m_match == Tag) { |
577 if (sel1->tagQName() != sel2->tagQName()) | 577 if (sel1->tagQName() != sel2->tagQName()) |
578 return false; | 578 return false; |
579 } | 579 } |
580 sel1 = sel1->tagHistory(); | 580 sel1 = sel1->tagHistory(); |
581 sel2 = sel2->tagHistory(); | 581 sel2 = sel2->tagHistory(); |
582 } | 582 } |
(...skipping 23 matching lines...) Expand all Loading... |
606 if (cs->m_match == Id) { | 606 if (cs->m_match == Id) { |
607 str.append('#'); | 607 str.append('#'); |
608 serializeIdentifier(cs->serializingValue(), str); | 608 serializeIdentifier(cs->serializingValue(), str); |
609 } else if (cs->m_match == Class) { | 609 } else if (cs->m_match == Class) { |
610 str.append('.'); | 610 str.append('.'); |
611 serializeIdentifier(cs->serializingValue(), str); | 611 serializeIdentifier(cs->serializingValue(), str); |
612 } else if (cs->m_match == PseudoClass || cs->m_match == PagePseudoClass)
{ | 612 } else if (cs->m_match == PseudoClass || cs->m_match == PagePseudoClass)
{ |
613 str.append(':'); | 613 str.append(':'); |
614 str.append(cs->serializingValue()); | 614 str.append(cs->serializingValue()); |
615 | 615 |
616 switch (cs->pseudoType()) { | 616 switch (cs->getPseudoType()) { |
617 case PseudoNthChild: | 617 case PseudoNthChild: |
618 case PseudoNthLastChild: | 618 case PseudoNthLastChild: |
619 case PseudoNthOfType: | 619 case PseudoNthOfType: |
620 case PseudoNthLastOfType: { | 620 case PseudoNthLastOfType: { |
621 str.append('('); | 621 str.append('('); |
622 | 622 |
623 // http://dev.w3.org/csswg/css-syntax/#serializing-anb | 623 // http://dev.w3.org/csswg/css-syntax/#serializing-anb |
624 int a = cs->m_data.m_rareData->nthAValue(); | 624 int a = cs->m_data.m_rareData->nthAValue(); |
625 int b = cs->m_data.m_rareData->nthBValue(); | 625 int b = cs->m_data.m_rareData->nthBValue(); |
626 if (a == 0 && b == 0) | 626 if (a == 0 && b == 0) |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
684 str.appendLiteral("$="); | 684 str.appendLiteral("$="); |
685 break; | 685 break; |
686 case AttributeContain: | 686 case AttributeContain: |
687 str.appendLiteral("*="); | 687 str.appendLiteral("*="); |
688 break; | 688 break; |
689 default: | 689 default: |
690 break; | 690 break; |
691 } | 691 } |
692 if (cs->m_match != AttributeSet) { | 692 if (cs->m_match != AttributeSet) { |
693 serializeString(cs->serializingValue(), str); | 693 serializeString(cs->serializingValue(), str); |
694 if (cs->attributeMatchType() == CaseInsensitive) | 694 if (cs->attributeMatch() == CaseInsensitive) |
695 str.appendLiteral(" i"); | 695 str.appendLiteral(" i"); |
696 str.append(']'); | 696 str.append(']'); |
697 } | 697 } |
698 } | 698 } |
699 | 699 |
700 if (cs->selectorList()) { | 700 if (cs->selectorList()) { |
701 str.append('('); | 701 str.append('('); |
702 const CSSSelector* firstSubSelector = cs->selectorList()->first(); | 702 const CSSSelector* firstSubSelector = cs->selectorList()->first(); |
703 for (const CSSSelector* subSelector = firstSubSelector; subSelector;
subSelector = CSSSelectorList::next(*subSelector)) { | 703 for (const CSSSelector* subSelector = firstSubSelector; subSelector;
subSelector = CSSSelectorList::next(*subSelector)) { |
704 if (subSelector != firstSubSelector) | 704 if (subSelector != firstSubSelector) |
(...skipping 27 matching lines...) Expand all Loading... |
732 return tagHistory->selectorText(str.toString() + rightSide); | 732 return tagHistory->selectorText(str.toString() + rightSide); |
733 } | 733 } |
734 } | 734 } |
735 return str.toString() + rightSide; | 735 return str.toString() + rightSide; |
736 } | 736 } |
737 | 737 |
738 void CSSSelector::setAttribute(const QualifiedName& value, AttributeMatchType ma
tchType) | 738 void CSSSelector::setAttribute(const QualifiedName& value, AttributeMatchType ma
tchType) |
739 { | 739 { |
740 createRareData(); | 740 createRareData(); |
741 m_data.m_rareData->m_attribute = value; | 741 m_data.m_rareData->m_attribute = value; |
742 m_data.m_rareData->m_bits.m_attributeMatchType = matchType; | 742 m_data.m_rareData->m_bits.m_attributeMatch = matchType; |
743 } | 743 } |
744 | 744 |
745 void CSSSelector::setArgument(const AtomicString& value) | 745 void CSSSelector::setArgument(const AtomicString& value) |
746 { | 746 { |
747 createRareData(); | 747 createRareData(); |
748 m_data.m_rareData->m_argument = value; | 748 m_data.m_rareData->m_argument = value; |
749 } | 749 } |
750 | 750 |
751 void CSSSelector::setSelectorList(PassOwnPtr<CSSSelectorList> selectorList) | 751 void CSSSelector::setSelectorList(PassOwnPtr<CSSSelectorList> selectorList) |
752 { | 752 { |
(...skipping 16 matching lines...) Expand all Loading... |
769 case CSSSelector::AttributeEnd: | 769 case CSSSelector::AttributeEnd: |
770 return true; | 770 return true; |
771 case CSSSelector::PseudoElement: | 771 case CSSSelector::PseudoElement: |
772 case CSSSelector::Unknown: | 772 case CSSSelector::Unknown: |
773 return false; | 773 return false; |
774 case CSSSelector::PagePseudoClass: | 774 case CSSSelector::PagePseudoClass: |
775 case CSSSelector::PseudoClass: | 775 case CSSSelector::PseudoClass: |
776 break; | 776 break; |
777 } | 777 } |
778 | 778 |
779 switch (selector->pseudoType()) { | 779 switch (selector->getPseudoType()) { |
780 case CSSSelector::PseudoEmpty: | 780 case CSSSelector::PseudoEmpty: |
781 case CSSSelector::PseudoLink: | 781 case CSSSelector::PseudoLink: |
782 case CSSSelector::PseudoVisited: | 782 case CSSSelector::PseudoVisited: |
783 case CSSSelector::PseudoTarget: | 783 case CSSSelector::PseudoTarget: |
784 case CSSSelector::PseudoEnabled: | 784 case CSSSelector::PseudoEnabled: |
785 case CSSSelector::PseudoDisabled: | 785 case CSSSelector::PseudoDisabled: |
786 case CSSSelector::PseudoChecked: | 786 case CSSSelector::PseudoChecked: |
787 case CSSSelector::PseudoIndeterminate: | 787 case CSSSelector::PseudoIndeterminate: |
788 case CSSSelector::PseudoNthChild: | 788 case CSSSelector::PseudoNthChild: |
789 case CSSSelector::PseudoNthLastChild: | 789 case CSSSelector::PseudoNthLastChild: |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
826 return true; | 826 return true; |
827 } | 827 } |
828 | 828 |
829 unsigned CSSSelector::computeLinkMatchType() const | 829 unsigned CSSSelector::computeLinkMatchType() const |
830 { | 830 { |
831 unsigned linkMatchType = MatchAll; | 831 unsigned linkMatchType = MatchAll; |
832 | 832 |
833 // Determine if this selector will match a link in visited, unvisited or any
state, or never. | 833 // Determine if this selector will match a link in visited, unvisited or any
state, or never. |
834 // :visited never matches other elements than the innermost link element. | 834 // :visited never matches other elements than the innermost link element. |
835 for (const CSSSelector* current = this; current; current = current->tagHisto
ry()) { | 835 for (const CSSSelector* current = this; current; current = current->tagHisto
ry()) { |
836 switch (current->pseudoType()) { | 836 switch (current->getPseudoType()) { |
837 case PseudoNot: | 837 case PseudoNot: |
838 { | 838 { |
839 // :not(:visited) is equivalent to :link. Parser enforces that :
not can't nest. | 839 // :not(:visited) is equivalent to :link. Parser enforces that :
not can't nest. |
840 ASSERT(current->selectorList()); | 840 ASSERT(current->selectorList()); |
841 for (const CSSSelector* subSelector = current->selectorList()->f
irst(); subSelector; subSelector = subSelector->tagHistory()) { | 841 for (const CSSSelector* subSelector = current->selectorList()->f
irst(); subSelector; subSelector = subSelector->tagHistory()) { |
842 PseudoType subType = subSelector->pseudoType(); | 842 PseudoType subType = subSelector->getPseudoType(); |
843 if (subType == PseudoVisited) | 843 if (subType == PseudoVisited) |
844 linkMatchType &= ~MatchVisited; | 844 linkMatchType &= ~MatchVisited; |
845 else if (subType == PseudoLink) | 845 else if (subType == PseudoLink) |
846 linkMatchType &= ~MatchLink; | 846 linkMatchType &= ~MatchLink; |
847 } | 847 } |
848 } | 848 } |
849 break; | 849 break; |
850 case PseudoLink: | 850 case PseudoLink: |
851 linkMatchType &= ~MatchVisited; | 851 linkMatchType &= ~MatchVisited; |
852 break; | 852 break; |
853 case PseudoVisited: | 853 case PseudoVisited: |
854 linkMatchType &= ~MatchLink; | 854 linkMatchType &= ~MatchLink; |
855 break; | 855 break; |
856 default: | 856 default: |
857 // We don't support :link and :visited inside :-webkit-any. | 857 // We don't support :link and :visited inside :-webkit-any. |
858 break; | 858 break; |
859 } | 859 } |
860 Relation relation = current->relation(); | 860 RelationType relation = current->relation(); |
861 if (relation == SubSelector) | 861 if (relation == SubSelector) |
862 continue; | 862 continue; |
863 if (relation != Descendant && relation != Child) | 863 if (relation != Descendant && relation != Child) |
864 return linkMatchType; | 864 return linkMatchType; |
865 if (linkMatchType != MatchAll) | 865 if (linkMatchType != MatchAll) |
866 return linkMatchType; | 866 return linkMatchType; |
867 } | 867 } |
868 return linkMatchType; | 868 return linkMatchType; |
869 } | 869 } |
870 | 870 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
914 if (count < nthBValue()) | 914 if (count < nthBValue()) |
915 return false; | 915 return false; |
916 return (count - nthBValue()) % nthAValue() == 0; | 916 return (count - nthBValue()) % nthAValue() == 0; |
917 } | 917 } |
918 if (count > nthBValue()) | 918 if (count > nthBValue()) |
919 return false; | 919 return false; |
920 return (nthBValue() - count) % (-nthAValue()) == 0; | 920 return (nthBValue() - count) % (-nthAValue()) == 0; |
921 } | 921 } |
922 | 922 |
923 } // namespace blink | 923 } // namespace blink |
OLD | NEW |