Adding :lang support, patch by Nicholas Shanks, review by Hyatt
authorjdevalk <jdevalk@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 15 Jun 2006 21:37:13 +0000 (21:37 +0000)
committerjdevalk <jdevalk@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 15 Jun 2006 21:37:13 +0000 (21:37 +0000)
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@14879 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/css/css3-modsel-22-expected.txt [new file with mode: 0644]
LayoutTests/fast/css/css3-modsel-22.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/css/CSSGrammar.y
WebCore/css/CSSSelector.cpp
WebCore/css/CSSSelector.h
WebCore/css/cssparser.cpp
WebCore/css/cssstyleselector.cpp
WebCore/css/tokenizer.flex

index 55ef21b..35dd4d4 100644 (file)
@@ -1,3 +1,12 @@
+2006-06-15  Nicholas Shanks  <contact@nickshanks.com>
+
+        Reviewed by Hyatt, landed by Joost de Valk.
+
+        Testcases for fix to bug http://bugzilla.opendarwin.org/show_bug.cgi?id=3233
+
+        * fast/css/css3-modsel-22-expected.txt: Added.
+        * fast/css/css3-modsel-22.html: Added.
+
 2006-06-15  Justin Garcia  <justin.garcia@apple.com>
 
         Reviewed by harrison
diff --git a/LayoutTests/fast/css/css3-modsel-22-expected.txt b/LayoutTests/fast/css/css3-modsel-22-expected.txt
new file mode 100644 (file)
index 0000000..c30d32d
--- /dev/null
@@ -0,0 +1,27 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x120
+  RenderBlock {HTML} at (0,0) size 800x120
+    RenderBody {BODY} at (8,16) size 784x88
+      RenderBlock {UL} at (0,0) size 784x36
+        RenderListItem {LI} at (40,0) size 744x18 [bgcolor=#00FF00]
+          RenderListMarker at (-17,0) size 7x18
+          RenderText {#text} at (0,0) size 430x18
+            text run at (0,0) width 336: "This list item should be green because its language is "
+            text run at (336,0) width 94: "British English"
+        RenderListItem {LI} at (40,18) size 744x18 [bgcolor=#00FF00]
+          RenderListMarker at (-17,0) size 7x18
+          RenderText {#text} at (0,0) size 483x18
+            text run at (0,0) width 322: "This list item should be green because its language "
+            text run at (322,0) width 161: "is British English (Wales)"
+      RenderBlock {OL} at (0,52) size 784x36
+        RenderListItem {LI} at (40,0) size 744x18
+          RenderListMarker at (-20,0) size 16x18
+          RenderText {#text} at (0,0) size 447x18
+            text run at (0,0) width 360: "This list item should NOT be green because its language "
+            text run at (360,0) width 87: "is US English"
+        RenderListItem {LI} at (40,18) size 744x18
+          RenderListMarker at (-20,0) size 16x18
+          RenderText {#text} at (0,0) size 418x18
+            text run at (0,0) width 374: "This list item should NOT be green because its language is "
+            text run at (374,0) width 44: "French"
diff --git a/LayoutTests/fast/css/css3-modsel-22.html b/LayoutTests/fast/css/css3-modsel-22.html
new file mode 100644 (file)
index 0000000..73eaedc
--- /dev/null
@@ -0,0 +1,29 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
+<html>
+ <head>
+  <title>:lang() pseudo-class</title>
+  <style type="text/css">ul > li { background-color : red }
+li:lang(en-GB) { background-color : lime }</style>
+  <link rel="first" href="css3-modsel-1.html" title="Groups of selectors">
+  <link rel="prev" href="css3-modsel-21c.html" title=":target pseudo-class">
+  <link rel="next" href="css3-modsel-23.html" title=":enabled pseudo-class">
+  <link rel="last" href="css3-modsel-d5e.html" title="NEGATED :indeterminate with :checked">
+  <link rel="up" href="./index.html">
+  <link rel="top" href="../../index.html">
+ </head>
+ <body>
+<ul>
+  <li lang="en-GB">This list item should be green because its language is
+        British English</li>
+  <li lang="en-GB-wa">This list item should be green because its language
+        is British English (Wales)</li>
+</ul>
+<ol>
+  <li lang="en-US">This list item should NOT be green because its language
+       is US English</li>
+  <li lang="fr">This list item should NOT be green because its language is
+       French</li>
+</ol>
+</body>
+</html>
+\ No newline at end of file
index eedb697..df51bec 100644 (file)
@@ -1,3 +1,22 @@
+2006-06-15  Nicholas Shanks  <contact@nickshanks.com>
+
+        Reviewed by Hyatt, landed by Joost de Valk.
+
+        Fix http://bugzilla.opendarwin.org/show_bug.cgi?id=3233
+
+        Add support for the :lang pseudo-class.
+
+        * css/CSSGrammar.y:
+        * css/CSSSelector.cpp:
+        (WebCore::CSSSelector::operator == ):
+        * css/CSSSelector.h:
+        (WebCore::CSSSelector::CSSSelector):
+        * css/cssparser.cpp:
+        (WebCore::CSSParser::lex):
+        * css/cssstyleselector.cpp:
+        (WebCore::CSSStyleSelector::checkOneSelector):
+        * css/tokenizer.flex:
+
 2006-06-15  Justin Garcia  <justin.garcia@apple.com>
 
         Reviewed by harrison
index a93d375..f99dd3b 100644 (file)
@@ -218,6 +218,7 @@ static int cssyylex(YYSTYPE *yylval) { return CSSParser::current()->lex(yylval);
 
 %token <string> URI
 %token <string> FUNCTION
+%token <string> NOTFUNCTION
 
 %token <string> UNICODERANGE
 
@@ -835,7 +836,16 @@ pseudo:
         $3.lower();
         $$->value = atomicString($3);
     }
-    | ':' FUNCTION maybe_space simple_selector maybe_space ')' {
+    // used by :lang
+    | ':' FUNCTION IDENT ')' {
+        $$ = new CSSSelector();
+        $$->match = CSSSelector::PseudoClass;
+        $$->argument = atomicString($3);
+        $2.lower();
+        $$->value = atomicString($2);
+    }
+    // used by :not
+    | ':' NOTFUNCTION maybe_space simple_selector ')' {
         CSSParser* p = static_cast<CSSParser*>(parser);
         $$ = p->createFloatingSelector();
         $$->match = CSSSelector::PseudoClass;
index b244720..3c024e2 100644 (file)
@@ -180,7 +180,8 @@ bool CSSSelector::operator == (const CSSSelector &other)
         if (sel1->tag != sel2->tag || sel1->attr != sel2->attr ||
              sel1->relation() != sel2->relation() || sel1->match != sel2->match ||
              sel1->value != sel2->value ||
-             sel1->pseudoType() != sel2->pseudoType())
+             sel1->pseudoType() != sel2->pseudoType() ||
+             sel1->argument != sel2->argument)
             return false;
         sel1 = sel1->tagHistory;
         sel2 = sel2->tagHistory;
index afbaf9d..b301b20 100644 (file)
@@ -36,6 +36,7 @@ namespace WebCore {
             : tagHistory(0)
             , simpleSelector(0)
             , nextSelector(0)
+            , argument(nullAtom)
             , attr(anyQName())
             , tag(anyQName())
             , m_relation(Descendant)
@@ -48,6 +49,7 @@ namespace WebCore {
             : tagHistory(0)
             , simpleSelector(0)
             , nextSelector(0)
+            , argument(nullAtom)
             , attr(anyQName())
             , tag(qName)
             , m_relation(Descendant)
@@ -158,6 +160,7 @@ namespace WebCore {
         CSSSelector* tagHistory;
         CSSSelector* simpleSelector; // Used for :not.
         CSSSelector* nextSelector; // used for ,-chained selectors
+        AtomicString argument; // Used for :contains, :lang and :nth-*
         
         QualifiedName attr;
         QualifiedName tag;
index f22e69d..92c347b 100644 (file)
@@ -2671,6 +2671,7 @@ int CSSParser::lex(void* yylvalWithoutType)
     case DIMEN:
     case UNICODERANGE:
     case FUNCTION:
+    case NOTFUNCTION:
         yylval->string.characters = t;
         yylval->string.length = length;
         break;
index cfc1318..ceed725 100644 (file)
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
  *           (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
+ *           (C) 2006 Nicholas Shanks (webkit@nickshanks.com)
  * Copyright (C) 2005, 2006 Apple Computer, Inc.
  *
  * This library is free software; you can redistribute it and/or
@@ -1520,12 +1521,19 @@ bool CSSStyleSelector::checkOneSelector(CSSSelector* sel, Element* e, bool isSub
                 if (e == e->document()->documentElement())
                     return true;
                 break;
+            case CSSSelector::PseudoLang: {
+                const AtomicString& value = e->getAttribute(langAttr);
+                if (value.isEmpty() || !value.startsWith(sel->argument, false))
+                    break;
+                if (value.length() != sel->argument.length() && value[sel->argument.length()] != '-')
+                    break;
+                return true;
+            }
             case CSSSelector::PseudoNot: {
                 // check the simple selector
-                for (CSSSelector* subSel = sel->simpleSelector; subSel;
-                     subSel = subSel->tagHistory) {
-                    // :not cannot nest.  I don't really know why this is a restriction in CSS3,
-                    // but it is, so let's honor it.
+                for (CSSSelector* subSel = sel->simpleSelector; subSel; subSel = subSel->tagHistory) {
+                    // :not cannot nest. I don't really know why this is a
+                    // restriction in CSS3, but it is, so let's honour it.
                     if (subSel->simpleSelector)
                         break;
                     if (!checkOneSelector(subSel, e))
@@ -1533,8 +1541,6 @@ bool CSSStyleSelector::checkOneSelector(CSSSelector* sel, Element* e, bool isSub
                 }
                 break;
             }
-            case CSSSelector::PseudoLang:
-                /* not supported for now */
             case CSSSelector::PseudoOther:
                 break;
             
@@ -1565,7 +1571,7 @@ bool CSSStyleSelector::checkOneSelector(CSSSelector* sel, Element* e, bool isSub
                 assert(false);
                 break;
         }
-            return false;
+        return false;
     }
     // ### add the rest of the checks...
     return true;
index c0691b8..2d21f99 100644 (file)
@@ -80,6 +80,7 @@ range           \?{1,6}|{h}(\?{0,5}|{h}(\?{0,4}|{h}(\?{0,3}|{h}(\?{0,2}|{h}(\??|
 {intnum}                {yyTok = INTEGER; return yyTok;}
 {num}                   {yyTok = FLOAT; return yyTok;}
 
+"not("                  {yyTok = NOTFUNCTION; return yyTok;}
 "url("{w}{string}{w}")" {yyTok = URI; return yyTok;}
 "url("{w}{url}{w}")"    {yyTok = URI; return yyTok;}
 {ident}"("              {yyTok = FUNCTION; return yyTok;}