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 | 6 * Copyright (C) 2002, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights |
7 * reserved. | 7 * reserved. |
8 * Copyright (C) 2008 David Smith (catfish.man@gmail.com) | 8 * Copyright (C) 2008 David Smith (catfish.man@gmail.com) |
9 * Copyright (C) 2010 Google Inc. All rights reserved. | 9 * Copyright (C) 2010 Google Inc. All rights reserved. |
10 * | 10 * |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 | 47 |
48 struct SameSizeAsCSSSelector { | 48 struct SameSizeAsCSSSelector { |
49 unsigned bitfields; | 49 unsigned bitfields; |
50 void* pointers[1]; | 50 void* pointers[1]; |
51 }; | 51 }; |
52 | 52 |
53 static_assert(sizeof(CSSSelector) == sizeof(SameSizeAsCSSSelector), | 53 static_assert(sizeof(CSSSelector) == sizeof(SameSizeAsCSSSelector), |
54 "CSSSelector should stay small"); | 54 "CSSSelector should stay small"); |
55 | 55 |
56 void CSSSelector::createRareData() { | 56 void CSSSelector::createRareData() { |
57 ASSERT(m_match != Tag); | 57 DCHECK_NE(m_match, Tag); |
58 if (m_hasRareData) | 58 if (m_hasRareData) |
59 return; | 59 return; |
60 AtomicString value(m_data.m_value); | 60 AtomicString value(m_data.m_value); |
61 if (m_data.m_value) | 61 if (m_data.m_value) |
62 m_data.m_value->deref(); | 62 m_data.m_value->deref(); |
63 m_data.m_rareData = RareData::create(value).leakRef(); | 63 m_data.m_rareData = RareData::create(value).leakRef(); |
64 m_hasRareData = true; | 64 m_hasRareData = true; |
65 } | 65 } |
66 | 66 |
67 unsigned CSSSelector::specificity() const { | 67 unsigned CSSSelector::specificity() const { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 case Id: | 101 case Id: |
102 return 0x010000; | 102 return 0x010000; |
103 case PseudoClass: | 103 case PseudoClass: |
104 switch (getPseudoType()) { | 104 switch (getPseudoType()) { |
105 case PseudoHost: | 105 case PseudoHost: |
106 case PseudoHostContext: | 106 case PseudoHostContext: |
107 // We dynamically compute the specificity of :host and :host-context | 107 // We dynamically compute the specificity of :host and :host-context |
108 // during matching. | 108 // during matching. |
109 return 0; | 109 return 0; |
110 case PseudoNot: | 110 case PseudoNot: |
111 ASSERT(selectorList()); | 111 DCHECK(selectorList()); |
112 return selectorList()->first()->specificity(); | 112 return selectorList()->first()->specificity(); |
113 // FIXME: PseudoAny should base the specificity on the sub-selectors. | 113 // FIXME: PseudoAny should base the specificity on the sub-selectors. |
114 // See http://lists.w3.org/Archives/Public/www-style/2010Sep/0530.html | 114 // See http://lists.w3.org/Archives/Public/www-style/2010Sep/0530.html |
115 case PseudoAny: | 115 case PseudoAny: |
116 default: | 116 default: |
117 break; | 117 break; |
118 } | 118 } |
119 return 0x000100; | 119 return 0x000100; |
120 case Class: | 120 case Class: |
121 case PseudoElement: | 121 case PseudoElement: |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 {"nth-child", CSSSelector::PseudoNthChild}, | 381 {"nth-child", CSSSelector::PseudoNthChild}, |
382 {"nth-last-child", CSSSelector::PseudoNthLastChild}, | 382 {"nth-last-child", CSSSelector::PseudoNthLastChild}, |
383 {"nth-last-of-type", CSSSelector::PseudoNthLastOfType}, | 383 {"nth-last-of-type", CSSSelector::PseudoNthLastOfType}, |
384 {"nth-of-type", CSSSelector::PseudoNthOfType}, | 384 {"nth-of-type", CSSSelector::PseudoNthOfType}, |
385 {"slotted", CSSSelector::PseudoSlotted}, | 385 {"slotted", CSSSelector::PseudoSlotted}, |
386 }; | 386 }; |
387 | 387 |
388 class NameToPseudoCompare { | 388 class NameToPseudoCompare { |
389 public: | 389 public: |
390 NameToPseudoCompare(const AtomicString& key) : m_key(key) { | 390 NameToPseudoCompare(const AtomicString& key) : m_key(key) { |
391 ASSERT(m_key.is8Bit()); | 391 DCHECK(m_key.is8Bit()); |
392 } | 392 } |
393 | 393 |
394 bool operator()(const NameToPseudoStruct& entry, const NameToPseudoStruct&) { | 394 bool operator()(const NameToPseudoStruct& entry, const NameToPseudoStruct&) { |
395 ASSERT(entry.string); | 395 DCHECK(entry.string); |
396 const char* key = reinterpret_cast<const char*>(m_key.characters8()); | 396 const char* key = reinterpret_cast<const char*>(m_key.characters8()); |
397 // If strncmp returns 0, then either the keys are equal, or |m_key| sorts | 397 // If strncmp returns 0, then either the keys are equal, or |m_key| sorts |
398 // before |entry|. | 398 // before |entry|. |
399 return strncmp(entry.string, key, m_key.length()) < 0; | 399 return strncmp(entry.string, key, m_key.length()) < 0; |
400 } | 400 } |
401 | 401 |
402 private: | 402 private: |
403 const AtomicString& m_key; | 403 const AtomicString& m_key; |
404 }; | 404 }; |
405 | 405 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
480 | 480 |
481 PseudoId CSSSelector::parsePseudoId(const String& name) { | 481 PseudoId CSSSelector::parsePseudoId(const String& name) { |
482 unsigned nameWithoutColonsStart = | 482 unsigned nameWithoutColonsStart = |
483 name[0] == ':' ? (name[1] == ':' ? 2 : 1) : 0; | 483 name[0] == ':' ? (name[1] == ':' ? 2 : 1) : 0; |
484 return pseudoId(parsePseudoType( | 484 return pseudoId(parsePseudoType( |
485 AtomicString(name.substring(nameWithoutColonsStart)), false)); | 485 AtomicString(name.substring(nameWithoutColonsStart)), false)); |
486 } | 486 } |
487 | 487 |
488 void CSSSelector::updatePseudoType(const AtomicString& value, | 488 void CSSSelector::updatePseudoType(const AtomicString& value, |
489 bool hasArguments) { | 489 bool hasArguments) { |
490 ASSERT(m_match == PseudoClass || m_match == PseudoElement || | 490 DCHECK(m_match == PseudoClass || m_match == PseudoElement || |
491 m_match == PagePseudoClass); | 491 m_match == PagePseudoClass); |
492 | 492 |
493 setValue(value); | 493 setValue(value); |
494 setPseudoType(parsePseudoType(value, hasArguments)); | 494 setPseudoType(parsePseudoType(value, hasArguments)); |
495 | 495 |
496 switch (m_pseudoType) { | 496 switch (m_pseudoType) { |
497 case PseudoAfter: | 497 case PseudoAfter: |
498 case PseudoBefore: | 498 case PseudoBefore: |
499 case PseudoFirstLetter: | 499 case PseudoFirstLetter: |
500 case PseudoFirstLine: | 500 case PseudoFirstLine: |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
684 | 684 |
685 str.append(')'); | 685 str.append(')'); |
686 break; | 686 break; |
687 } | 687 } |
688 case PseudoLang: | 688 case PseudoLang: |
689 str.append('('); | 689 str.append('('); |
690 str.append(cs->argument()); | 690 str.append(cs->argument()); |
691 str.append(')'); | 691 str.append(')'); |
692 break; | 692 break; |
693 case PseudoNot: | 693 case PseudoNot: |
694 ASSERT(cs->selectorList()); | 694 DCHECK(cs->selectorList()); |
695 break; | 695 break; |
696 case PseudoHost: | 696 case PseudoHost: |
697 case PseudoHostContext: | 697 case PseudoHostContext: |
698 case PseudoAny: | 698 case PseudoAny: |
699 break; | 699 break; |
700 default: | 700 default: |
701 break; | 701 break; |
702 } | 702 } |
703 } else if (cs->m_match == PseudoElement) { | 703 } else if (cs->m_match == PseudoElement) { |
704 str.append("::"); | 704 str.append("::"); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
767 case ShadowDeep: | 767 case ShadowDeep: |
768 return tagHistory->selectorText(" /deep/ " + str.toString() + | 768 return tagHistory->selectorText(" /deep/ " + str.toString() + |
769 rightSide); | 769 rightSide); |
770 case ShadowPiercingDescendant: | 770 case ShadowPiercingDescendant: |
771 return tagHistory->selectorText(" >>> " + str.toString() + rightSide); | 771 return tagHistory->selectorText(" >>> " + str.toString() + rightSide); |
772 case DirectAdjacent: | 772 case DirectAdjacent: |
773 return tagHistory->selectorText(" + " + str.toString() + rightSide); | 773 return tagHistory->selectorText(" + " + str.toString() + rightSide); |
774 case IndirectAdjacent: | 774 case IndirectAdjacent: |
775 return tagHistory->selectorText(" ~ " + str.toString() + rightSide); | 775 return tagHistory->selectorText(" ~ " + str.toString() + rightSide); |
776 case SubSelector: | 776 case SubSelector: |
777 ASSERT_NOT_REACHED(); | 777 NOTREACHED(); |
778 case ShadowPseudo: | 778 case ShadowPseudo: |
779 case ShadowSlot: | 779 case ShadowSlot: |
780 return tagHistory->selectorText(str.toString() + rightSide); | 780 return tagHistory->selectorText(str.toString() + rightSide); |
781 } | 781 } |
782 } | 782 } |
783 return str.toString() + rightSide; | 783 return str.toString() + rightSide; |
784 } | 784 } |
785 | 785 |
786 void CSSSelector::setAttribute(const QualifiedName& value, | 786 void CSSSelector::setAttribute(const QualifiedName& value, |
787 AttributeMatchType matchType) { | 787 AttributeMatchType matchType) { |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
877 | 877 |
878 // Determine if this selector will match a link in visited, unvisited or any | 878 // Determine if this selector will match a link in visited, unvisited or any |
879 // state, or never. | 879 // state, or never. |
880 // :visited never matches other elements than the innermost link element. | 880 // :visited never matches other elements than the innermost link element. |
881 for (const CSSSelector* current = this; current; | 881 for (const CSSSelector* current = this; current; |
882 current = current->tagHistory()) { | 882 current = current->tagHistory()) { |
883 switch (current->getPseudoType()) { | 883 switch (current->getPseudoType()) { |
884 case PseudoNot: { | 884 case PseudoNot: { |
885 // :not(:visited) is equivalent to :link. Parser enforces that :not | 885 // :not(:visited) is equivalent to :link. Parser enforces that :not |
886 // can't nest. | 886 // can't nest. |
887 ASSERT(current->selectorList()); | 887 DCHECK(current->selectorList()); |
888 for (const CSSSelector* subSelector = current->selectorList()->first(); | 888 for (const CSSSelector* subSelector = current->selectorList()->first(); |
889 subSelector; subSelector = subSelector->tagHistory()) { | 889 subSelector; subSelector = subSelector->tagHistory()) { |
890 PseudoType subType = subSelector->getPseudoType(); | 890 PseudoType subType = subSelector->getPseudoType(); |
891 if (subType == PseudoVisited) | 891 if (subType == PseudoVisited) |
892 linkMatchType &= ~MatchVisited; | 892 linkMatchType &= ~MatchVisited; |
893 else if (subType == PseudoLink) | 893 else if (subType == PseudoLink) |
894 linkMatchType &= ~MatchLink; | 894 linkMatchType &= ~MatchLink; |
895 } | 895 } |
896 } break; | 896 } break; |
897 case PseudoLink: | 897 case PseudoLink: |
(...skipping 17 matching lines...) Expand all Loading... |
915 return linkMatchType; | 915 return linkMatchType; |
916 } | 916 } |
917 | 917 |
918 void CSSSelector::setNth(int a, int b) { | 918 void CSSSelector::setNth(int a, int b) { |
919 createRareData(); | 919 createRareData(); |
920 m_data.m_rareData->m_bits.m_nth.m_a = a; | 920 m_data.m_rareData->m_bits.m_nth.m_a = a; |
921 m_data.m_rareData->m_bits.m_nth.m_b = b; | 921 m_data.m_rareData->m_bits.m_nth.m_b = b; |
922 } | 922 } |
923 | 923 |
924 bool CSSSelector::matchNth(int count) const { | 924 bool CSSSelector::matchNth(int count) const { |
925 ASSERT(m_hasRareData); | 925 DCHECK(m_hasRareData); |
926 return m_data.m_rareData->matchNth(count); | 926 return m_data.m_rareData->matchNth(count); |
927 } | 927 } |
928 | 928 |
929 bool CSSSelector::matchesPseudoElement() const { | 929 bool CSSSelector::matchesPseudoElement() const { |
930 for (const CSSSelector* current = this; current; | 930 for (const CSSSelector* current = this; current; |
931 current = current->tagHistory()) { | 931 current = current->tagHistory()) { |
932 if (current->match() == PseudoElement) | 932 if (current->match() == PseudoElement) |
933 return true; | 933 return true; |
934 if (current->relation() != SubSelector) | 934 if (current->relation() != SubSelector) |
935 return false; | 935 return false; |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1009 if (count < nthBValue()) | 1009 if (count < nthBValue()) |
1010 return false; | 1010 return false; |
1011 return (count - nthBValue()) % nthAValue() == 0; | 1011 return (count - nthBValue()) % nthAValue() == 0; |
1012 } | 1012 } |
1013 if (count > nthBValue()) | 1013 if (count > nthBValue()) |
1014 return false; | 1014 return false; |
1015 return (nthBValue() - count) % (-nthAValue()) == 0; | 1015 return (nthBValue() - count) % (-nthAValue()) == 0; |
1016 } | 1016 } |
1017 | 1017 |
1018 } // namespace blink | 1018 } // namespace blink |
OLD | NEW |