Merge pull request #34 from leonsenft/backwards-compatible-pseudos

Handles CSS2.1 pseudo element syntax
diff --git a/lib/parser.dart b/lib/parser.dart
index fa5cce8..205011f 100644
--- a/lib/parser.dart
+++ b/lib/parser.dart
@@ -171,6 +171,14 @@
   StyleSheet parse() => _parser.parse();
 }
 
+// CSS2.1 pseudo-elements which were defined with a single ':'.
+final _legacyPseudoElements = new Set<String>.from(const [
+  'after',
+  'before',
+  'first-letter',
+  'first-line',
+]);
+
 /** A simple recursive descent parser for CSS. */
 class _Parser {
   final Tokenizer tokenizer;
@@ -1456,11 +1464,10 @@
     } else {
       return null;
     }
+    var name = pseudoName.name.toLowerCase();
 
     // Functional pseudo?
-
     if (_peekToken.kind == TokenKind.LPAREN) {
-      var name = pseudoName.name.toLowerCase();
       if (!pseudoElement && name == 'not') {
         _eat(TokenKind.LPAREN);
 
@@ -1504,14 +1511,11 @@
       }
     }
 
-    // TODO(terry): Need to handle specific pseudo class/element name and
-    // backward compatible names that are : as well as :: as well as
-    // parameters.  Current, spec uses :: for pseudo-element and : for
-    // pseudo-class.  However, CSS2.1 allows for : to specify old
-    // pseudo-elements (:first-line, :first-letter, :before and :after) any
-    // new pseudo-elements defined would require a ::.
-    return pseudoElement
-        ? new PseudoElementSelector(pseudoName, _makeSpan(start))
+    // Treat CSS2.1 pseudo-elements defined with pseudo class syntax as pseudo-
+    // elements for backwards compatibility.
+    return pseudoElement || _legacyPseudoElements.contains(name)
+        ? new PseudoElementSelector(pseudoName, _makeSpan(start),
+            isLegacy: !pseudoElement)
         : new PseudoClassSelector(pseudoName, _makeSpan(start));
   }
 
diff --git a/lib/src/tree.dart b/lib/src/tree.dart
index 9b6e462..c3709d2 100644
--- a/lib/src/tree.dart
+++ b/lib/src/tree.dart
@@ -299,12 +299,17 @@
 
 // ::pseudoElement
 class PseudoElementSelector extends SimpleSelector {
-  PseudoElementSelector(Identifier name, SourceSpan span) : super(name, span);
+  // If true, this is a CSS2.1 pseudo-element with only a single ':'.
+  final bool isLegacy;
+
+  PseudoElementSelector(Identifier name, SourceSpan span,
+      {this.isLegacy: false})
+      : super(name, span);
   visit(VisitorBase visitor) => visitor.visitPseudoElementSelector(this);
 
   PseudoElementSelector clone() => new PseudoElementSelector(_name, span);
 
-  String toString() => "::$name";
+  String toString() => "${isLegacy ? ':' : '::'}$name";
 }
 
 // :pseudoClassFunction(argument)