| 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 |