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