Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(309)

Side by Side Diff: Source/core/css/CSSSelector.cpp

Issue 330043003: Add support for case-insensitive attribute value selectors (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: legacyCaseSensitive->legacyCaseInsensitive; Extend tests. Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 641 matching lines...) Expand 10 before | Expand all | Expand 10 after
652 652
653 if (cs->pseudoType() == PseudoContent) { 653 if (cs->pseudoType() == PseudoContent) {
654 if (cs->relation() == CSSSelector::SubSelector && cs->tagHistory ()) 654 if (cs->relation() == CSSSelector::SubSelector && cs->tagHistory ())
655 return cs->tagHistory()->selectorText() + str.toString() + r ightSide; 655 return cs->tagHistory()->selectorText() + str.toString() + r ightSide;
656 } 656 }
657 } else if (cs->isAttributeSelector()) { 657 } else if (cs->isAttributeSelector()) {
658 str.append('['); 658 str.append('[');
659 const AtomicString& prefix = cs->attribute().prefix(); 659 const AtomicString& prefix = cs->attribute().prefix();
660 if (!prefix.isNull()) { 660 if (!prefix.isNull()) {
661 str.append(prefix); 661 str.append(prefix);
662 str.append("|"); 662 str.append('|');
663 } 663 }
664 str.append(cs->attribute().localName()); 664 str.append(cs->attribute().localName());
665 switch (cs->m_match) { 665 switch (cs->m_match) {
666 case CSSSelector::Exact: 666 case CSSSelector::Exact:
667 str.append('='); 667 str.append('=');
668 break; 668 break;
669 case CSSSelector::Set: 669 case CSSSelector::Set:
670 // set has no operator or value, just the attrName 670 // set has no operator or value, just the attrName
671 str.append(']'); 671 str.append(']');
672 break; 672 break;
(...skipping 10 matching lines...) Expand all
683 str.appendLiteral("$="); 683 str.appendLiteral("$=");
684 break; 684 break;
685 case CSSSelector::Contain: 685 case CSSSelector::Contain:
686 str.appendLiteral("*="); 686 str.appendLiteral("*=");
687 break; 687 break;
688 default: 688 default:
689 break; 689 break;
690 } 690 }
691 if (cs->m_match != CSSSelector::Set) { 691 if (cs->m_match != CSSSelector::Set) {
692 serializeString(cs->value(), str); 692 serializeString(cs->value(), str);
693 if (cs->attributeFlags() & CaseInsensitive)
694 str.appendLiteral(" i");
693 str.append(']'); 695 str.append(']');
694 } 696 }
695 } 697 }
696 if (cs->relation() != CSSSelector::SubSelector || !cs->tagHistory()) 698 if (cs->relation() != CSSSelector::SubSelector || !cs->tagHistory())
697 break; 699 break;
698 cs = cs->tagHistory(); 700 cs = cs->tagHistory();
699 } 701 }
700 702
701 if (const CSSSelector* tagHistory = cs->tagHistory()) { 703 if (const CSSSelector* tagHistory = cs->tagHistory()) {
702 switch (cs->relation()) { 704 switch (cs->relation()) {
703 case CSSSelector::Descendant: 705 case CSSSelector::Descendant:
704 return tagHistory->selectorText(" " + str.toString() + rightSide); 706 return tagHistory->selectorText(" " + str.toString() + rightSide);
705 case CSSSelector::Child: 707 case CSSSelector::Child:
706 return tagHistory->selectorText(" > " + str.toString() + rightSide); 708 return tagHistory->selectorText(" > " + str.toString() + rightSide);
707 case CSSSelector::ShadowDeep: 709 case CSSSelector::ShadowDeep:
708 return tagHistory->selectorText(" /deep/ " + str.toString() + rightS ide); 710 return tagHistory->selectorText(" /deep/ " + str.toString() + rightS ide);
709 case CSSSelector::DirectAdjacent: 711 case CSSSelector::DirectAdjacent:
710 return tagHistory->selectorText(" + " + str.toString() + rightSide); 712 return tagHistory->selectorText(" + " + str.toString() + rightSide);
711 case CSSSelector::IndirectAdjacent: 713 case CSSSelector::IndirectAdjacent:
712 return tagHistory->selectorText(" ~ " + str.toString() + rightSide); 714 return tagHistory->selectorText(" ~ " + str.toString() + rightSide);
713 case CSSSelector::SubSelector: 715 case CSSSelector::SubSelector:
714 ASSERT_NOT_REACHED(); 716 ASSERT_NOT_REACHED();
715 case CSSSelector::ShadowPseudo: 717 case CSSSelector::ShadowPseudo:
716 return tagHistory->selectorText(str.toString() + rightSide); 718 return tagHistory->selectorText(str.toString() + rightSide);
717 } 719 }
718 } 720 }
719 return str.toString() + rightSide; 721 return str.toString() + rightSide;
720 } 722 }
721 723
722 void CSSSelector::setAttribute(const QualifiedName& value) 724 void CSSSelector::setAttribute(const QualifiedName& value, unsigned flags)
723 { 725 {
724 createRareData(); 726 createRareData();
725 m_data.m_rareData->m_attribute = value; 727 m_data.m_rareData->m_attribute = value;
728 m_data.m_rareData->m_bits.m_attributeFlags = flags;
726 } 729 }
727 730
728 void CSSSelector::setArgument(const AtomicString& value) 731 void CSSSelector::setArgument(const AtomicString& value)
729 { 732 {
730 createRareData(); 733 createRareData();
731 m_data.m_rareData->m_argument = value; 734 m_data.m_rareData->m_argument = value;
732 } 735 }
733 736
734 void CSSSelector::setSelectorList(PassOwnPtr<CSSSelectorList> selectorList) 737 void CSSSelector::setSelectorList(PassOwnPtr<CSSSelectorList> selectorList)
735 { 738 {
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
819 } 822 }
820 823
821 bool CSSSelector::matchNth(int count) const 824 bool CSSSelector::matchNth(int count) const
822 { 825 {
823 ASSERT(m_hasRareData); 826 ASSERT(m_hasRareData);
824 return m_data.m_rareData->matchNth(count); 827 return m_data.m_rareData->matchNth(count);
825 } 828 }
826 829
827 CSSSelector::RareData::RareData(const AtomicString& value) 830 CSSSelector::RareData::RareData(const AtomicString& value)
828 : m_value(value) 831 : m_value(value)
829 , m_a(0)
830 , m_b(0)
831 , m_attribute(anyQName()) 832 , m_attribute(anyQName())
832 , m_argument(nullAtom) 833 , m_argument(nullAtom)
833 { 834 {
834 } 835 }
835 836
836 CSSSelector::RareData::~RareData() 837 CSSSelector::RareData::~RareData()
837 { 838 {
838 } 839 }
839 840
840 // a helper function for parsing nth-arguments 841 // a helper function for parsing nth-arguments
841 bool CSSSelector::RareData::parseNth() 842 bool CSSSelector::RareData::parseNth()
842 { 843 {
843 String argument = m_argument.lower(); 844 String argument = m_argument.lower();
844 845
845 if (argument.isEmpty()) 846 if (argument.isEmpty())
846 return false; 847 return false;
847 848
848 m_a = 0; 849 int nthA = 0;
849 m_b = 0; 850 int nthB = 0;
850 if (argument == "odd") { 851 if (argument == "odd") {
851 m_a = 2; 852 nthA = 2;
852 m_b = 1; 853 nthB = 1;
853 } else if (argument == "even") { 854 } else if (argument == "even") {
854 m_a = 2; 855 nthA = 2;
855 m_b = 0; 856 nthB = 0;
856 } else { 857 } else {
857 size_t n = argument.find('n'); 858 size_t n = argument.find('n');
858 if (n != kNotFound) { 859 if (n != kNotFound) {
859 if (argument[0] == '-') { 860 if (argument[0] == '-') {
860 if (n == 1) 861 if (n == 1)
861 m_a = -1; // -n == -1n 862 nthA = -1; // -n == -1n
862 else 863 else
863 m_a = argument.substring(0, n).toInt(); 864 nthA = argument.substring(0, n).toInt();
864 } else if (!n) 865 } else if (!n) {
865 m_a = 1; // n == 1n 866 nthA = 1; // n == 1n
866 else 867 } else {
867 m_a = argument.substring(0, n).toInt(); 868 nthA = argument.substring(0, n).toInt();
869 }
868 870
869 size_t p = argument.find('+', n); 871 size_t p = argument.find('+', n);
870 if (p != kNotFound) 872 if (p != kNotFound) {
871 m_b = argument.substring(p + 1, argument.length() - p - 1).toInt (); 873 nthB = argument.substring(p + 1, argument.length() - p - 1).toIn t();
872 else { 874 } else {
873 p = argument.find('-', n); 875 p = argument.find('-', n);
874 if (p != kNotFound) 876 if (p != kNotFound)
875 m_b = -argument.substring(p + 1, argument.length() - p - 1). toInt(); 877 nthB = -argument.substring(p + 1, argument.length() - p - 1) .toInt();
876 } 878 }
877 } else 879 } else {
878 m_b = argument.toInt(); 880 nthB = argument.toInt();
881 }
879 } 882 }
883 m_bits.m_nth.m_a = nthA;
884 m_bits.m_nth.m_b = nthB;
eseidel 2014/07/29 15:43:22 We could wrap these in private accessors and then
fs 2014/07/29 17:14:32 Done.
880 return true; 885 return true;
881 } 886 }
882 887
883 // a helper function for checking nth-arguments 888 // a helper function for checking nth-arguments
884 bool CSSSelector::RareData::matchNth(int count) 889 bool CSSSelector::RareData::matchNth(int count)
885 { 890 {
886 if (!m_a) 891 if (!m_bits.m_nth.m_a)
eseidel 2014/07/29 15:43:22 nthAValue() might be shorter?
fs 2014/07/29 17:14:32 Yepp, and looks nicer as a bonus. Added.
887 return count == m_b; 892 return count == m_bits.m_nth.m_b;
888 else if (m_a > 0) { 893 if (m_bits.m_nth.m_a > 0) {
889 if (count < m_b) 894 if (count < m_bits.m_nth.m_b)
890 return false; 895 return false;
891 return (count - m_b) % m_a == 0; 896 return (count - m_bits.m_nth.m_b) % m_bits.m_nth.m_a == 0;
892 } else {
893 if (count > m_b)
894 return false;
895 return (m_b - count) % (-m_a) == 0;
896 } 897 }
898 if (count > m_bits.m_nth.m_b)
899 return false;
900 return (m_bits.m_nth.m_b - count) % (-m_bits.m_nth.m_a) == 0;
897 } 901 }
898 902
899 } // namespace blink 903 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698