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()->specificityForOneSelector(); | 112 return selectorList()->first()->specificityForOneSelector(); |
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 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
376 {"nth-child", CSSSelector::PseudoNthChild}, | 376 {"nth-child", CSSSelector::PseudoNthChild}, |
377 {"nth-last-child", CSSSelector::PseudoNthLastChild}, | 377 {"nth-last-child", CSSSelector::PseudoNthLastChild}, |
378 {"nth-last-of-type", CSSSelector::PseudoNthLastOfType}, | 378 {"nth-last-of-type", CSSSelector::PseudoNthLastOfType}, |
379 {"nth-of-type", CSSSelector::PseudoNthOfType}, | 379 {"nth-of-type", CSSSelector::PseudoNthOfType}, |
380 {"slotted", CSSSelector::PseudoSlotted}, | 380 {"slotted", CSSSelector::PseudoSlotted}, |
381 }; | 381 }; |
382 | 382 |
383 class NameToPseudoCompare { | 383 class NameToPseudoCompare { |
384 public: | 384 public: |
385 NameToPseudoCompare(const AtomicString& key) : m_key(key) { | 385 NameToPseudoCompare(const AtomicString& key) : m_key(key) { |
386 ASSERT(m_key.is8Bit()); | 386 DCHECK(m_key.is8Bit()); |
387 } | 387 } |
388 | 388 |
389 bool operator()(const NameToPseudoStruct& entry, const NameToPseudoStruct&) { | 389 bool operator()(const NameToPseudoStruct& entry, const NameToPseudoStruct&) { |
390 ASSERT(entry.string); | 390 DCHECK(entry.string); |
391 const char* key = reinterpret_cast<const char*>(m_key.characters8()); | 391 const char* key = reinterpret_cast<const char*>(m_key.characters8()); |
392 // If strncmp returns 0, then either the keys are equal, or |m_key| sorts | 392 // If strncmp returns 0, then either the keys are equal, or |m_key| sorts |
393 // before |entry|. | 393 // before |entry|. |
394 return strncmp(entry.string, key, m_key.length()) < 0; | 394 return strncmp(entry.string, key, m_key.length()) < 0; |
395 } | 395 } |
396 | 396 |
397 private: | 397 private: |
398 const AtomicString& m_key; | 398 const AtomicString& m_key; |
399 }; | 399 }; |
400 | 400 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
475 | 475 |
476 PseudoId CSSSelector::parsePseudoId(const String& name) { | 476 PseudoId CSSSelector::parsePseudoId(const String& name) { |
477 unsigned nameWithoutColonsStart = | 477 unsigned nameWithoutColonsStart = |
478 name[0] == ':' ? (name[1] == ':' ? 2 : 1) : 0; | 478 name[0] == ':' ? (name[1] == ':' ? 2 : 1) : 0; |
479 return pseudoId(parsePseudoType( | 479 return pseudoId(parsePseudoType( |
480 AtomicString(name.substring(nameWithoutColonsStart)), false)); | 480 AtomicString(name.substring(nameWithoutColonsStart)), false)); |
481 } | 481 } |
482 | 482 |
483 void CSSSelector::updatePseudoType(const AtomicString& value, | 483 void CSSSelector::updatePseudoType(const AtomicString& value, |
484 bool hasArguments) { | 484 bool hasArguments) { |
485 ASSERT(m_match == PseudoClass || m_match == PseudoElement || | 485 DCHECK(m_match == PseudoClass || m_match == PseudoElement || |
486 m_match == PagePseudoClass); | 486 m_match == PagePseudoClass); |
487 | 487 |
488 setValue(value); | 488 setValue(value); |
489 setPseudoType(parsePseudoType(value, hasArguments)); | 489 setPseudoType(parsePseudoType(value, hasArguments)); |
490 | 490 |
491 switch (m_pseudoType) { | 491 switch (m_pseudoType) { |
492 case PseudoAfter: | 492 case PseudoAfter: |
493 case PseudoBefore: | 493 case PseudoBefore: |
494 case PseudoFirstLetter: | 494 case PseudoFirstLetter: |
495 case PseudoFirstLine: | 495 case PseudoFirstLine: |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
677 | 677 |
678 str.append(')'); | 678 str.append(')'); |
679 break; | 679 break; |
680 } | 680 } |
681 case PseudoLang: | 681 case PseudoLang: |
682 str.append('('); | 682 str.append('('); |
683 str.append(cs->argument()); | 683 str.append(cs->argument()); |
684 str.append(')'); | 684 str.append(')'); |
685 break; | 685 break; |
686 case PseudoNot: | 686 case PseudoNot: |
687 ASSERT(cs->selectorList()); | 687 DCHECK(cs->selectorList()); |
688 break; | 688 break; |
689 case PseudoHost: | 689 case PseudoHost: |
690 case PseudoHostContext: | 690 case PseudoHostContext: |
691 case PseudoAny: | 691 case PseudoAny: |
692 break; | 692 break; |
693 default: | 693 default: |
694 break; | 694 break; |
695 } | 695 } |
696 } else if (cs->m_match == PseudoElement) { | 696 } else if (cs->m_match == PseudoElement) { |
697 str.append("::"); | 697 str.append("::"); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
760 case ShadowDeep: | 760 case ShadowDeep: |
761 return tagHistory->selectorText(" /deep/ " + str.toString() + | 761 return tagHistory->selectorText(" /deep/ " + str.toString() + |
762 rightSide); | 762 rightSide); |
763 case ShadowPiercingDescendant: | 763 case ShadowPiercingDescendant: |
764 return tagHistory->selectorText(" >>> " + str.toString() + rightSide); | 764 return tagHistory->selectorText(" >>> " + str.toString() + rightSide); |
765 case DirectAdjacent: | 765 case DirectAdjacent: |
766 return tagHistory->selectorText(" + " + str.toString() + rightSide); | 766 return tagHistory->selectorText(" + " + str.toString() + rightSide); |
767 case IndirectAdjacent: | 767 case IndirectAdjacent: |
768 return tagHistory->selectorText(" ~ " + str.toString() + rightSide); | 768 return tagHistory->selectorText(" ~ " + str.toString() + rightSide); |
769 case SubSelector: | 769 case SubSelector: |
770 ASSERT_NOT_REACHED(); | 770 NOTREACHED(); |
771 case ShadowPseudo: | 771 case ShadowPseudo: |
772 case ShadowSlot: | 772 case ShadowSlot: |
773 return tagHistory->selectorText(str.toString() + rightSide); | 773 return tagHistory->selectorText(str.toString() + rightSide); |
774 } | 774 } |
775 } | 775 } |
776 return str.toString() + rightSide; | 776 return str.toString() + rightSide; |
777 } | 777 } |
778 | 778 |
779 void CSSSelector::setAttribute(const QualifiedName& value, | 779 void CSSSelector::setAttribute(const QualifiedName& value, |
780 AttributeMatchType matchType) { | 780 AttributeMatchType matchType) { |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
870 | 870 |
871 // Determine if this selector will match a link in visited, unvisited or any | 871 // Determine if this selector will match a link in visited, unvisited or any |
872 // state, or never. | 872 // state, or never. |
873 // :visited never matches other elements than the innermost link element. | 873 // :visited never matches other elements than the innermost link element. |
874 for (const CSSSelector* current = this; current; | 874 for (const CSSSelector* current = this; current; |
875 current = current->tagHistory()) { | 875 current = current->tagHistory()) { |
876 switch (current->getPseudoType()) { | 876 switch (current->getPseudoType()) { |
877 case PseudoNot: { | 877 case PseudoNot: { |
878 // :not(:visited) is equivalent to :link. Parser enforces that :not | 878 // :not(:visited) is equivalent to :link. Parser enforces that :not |
879 // can't nest. | 879 // can't nest. |
880 ASSERT(current->selectorList()); | 880 DCHECK(current->selectorList()); |
881 for (const CSSSelector* subSelector = current->selectorList()->first(); | 881 for (const CSSSelector* subSelector = current->selectorList()->first(); |
882 subSelector; subSelector = subSelector->tagHistory()) { | 882 subSelector; subSelector = subSelector->tagHistory()) { |
883 PseudoType subType = subSelector->getPseudoType(); | 883 PseudoType subType = subSelector->getPseudoType(); |
884 if (subType == PseudoVisited) | 884 if (subType == PseudoVisited) |
885 linkMatchType &= ~MatchVisited; | 885 linkMatchType &= ~MatchVisited; |
886 else if (subType == PseudoLink) | 886 else if (subType == PseudoLink) |
887 linkMatchType &= ~MatchLink; | 887 linkMatchType &= ~MatchLink; |
888 } | 888 } |
889 } break; | 889 } break; |
890 case PseudoLink: | 890 case PseudoLink: |
(...skipping 17 matching lines...) Expand all Loading... |
908 return linkMatchType; | 908 return linkMatchType; |
909 } | 909 } |
910 | 910 |
911 void CSSSelector::setNth(int a, int b) { | 911 void CSSSelector::setNth(int a, int b) { |
912 createRareData(); | 912 createRareData(); |
913 m_data.m_rareData->m_bits.m_nth.m_a = a; | 913 m_data.m_rareData->m_bits.m_nth.m_a = a; |
914 m_data.m_rareData->m_bits.m_nth.m_b = b; | 914 m_data.m_rareData->m_bits.m_nth.m_b = b; |
915 } | 915 } |
916 | 916 |
917 bool CSSSelector::matchNth(int count) const { | 917 bool CSSSelector::matchNth(int count) const { |
918 ASSERT(m_hasRareData); | 918 DCHECK(m_hasRareData); |
919 return m_data.m_rareData->matchNth(count); | 919 return m_data.m_rareData->matchNth(count); |
920 } | 920 } |
921 | 921 |
922 bool CSSSelector::matchesPseudoElement() const { | 922 bool CSSSelector::matchesPseudoElement() const { |
923 for (const CSSSelector* current = this; current; | 923 for (const CSSSelector* current = this; current; |
924 current = current->tagHistory()) { | 924 current = current->tagHistory()) { |
925 if (current->match() == PseudoElement) | 925 if (current->match() == PseudoElement) |
926 return true; | 926 return true; |
927 if (current->relation() != SubSelector) | 927 if (current->relation() != SubSelector) |
928 return false; | 928 return false; |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1002 if (count < nthBValue()) | 1002 if (count < nthBValue()) |
1003 return false; | 1003 return false; |
1004 return (count - nthBValue()) % nthAValue() == 0; | 1004 return (count - nthBValue()) % nthAValue() == 0; |
1005 } | 1005 } |
1006 if (count > nthBValue()) | 1006 if (count > nthBValue()) |
1007 return false; | 1007 return false; |
1008 return (nthBValue() - count) % (-nthAValue()) == 0; | 1008 return (nthBValue() - count) % (-nthAValue()) == 0; |
1009 } | 1009 } |
1010 | 1010 |
1011 } // namespace blink | 1011 } // namespace blink |
OLD | NEW |