OSDN Git Service

am 3c54ece0: am 5dc34a85: activeDocumentLoader() causes crash in WebCoreFrameBridge.cpp
[android-x86/external-webkit.git] / WebCore / css / CSSGrammar.y
index f6b0c17..26b2ba8 100644 (file)
 
 #include "CSSMediaRule.h"
 #include "CSSParser.h"
+#include "CSSPrimitiveValue.h"
 #include "CSSPropertyNames.h"
 #include "CSSRuleList.h"
 #include "CSSSelector.h"
-#include "CSSNthSelector.h"
 #include "CSSStyleSheet.h"
 #include "Document.h"
 #include "HTMLNames.h"
 #include "MediaList.h"
 #include "WebKitCSSKeyframeRule.h"
 #include "WebKitCSSKeyframesRule.h"
+#include <wtf/FastMalloc.h>
 #include <stdlib.h>
 #include <string.h>
 
 using namespace WebCore;
 using namespace HTMLNames;
 
+#define YYMALLOC fastMalloc
+#define YYFREE fastFree
+
 #define YYENABLE_NLS 0
 #define YYLTYPE_IS_TRIVIAL 1
 #define YYMAXDEPTH 10000
@@ -65,6 +69,8 @@ using namespace HTMLNames;
     CSSRule* rule;
     CSSRuleList* ruleList;
     CSSSelector* selector;
+    Vector<CSSSelector*>* selectorList;
+    CSSSelector::MarginBoxType marginBox;
     CSSSelector::Relation relation;
     MediaList* mediaList;
     MediaQuery* mediaQuery;
@@ -92,7 +98,9 @@ static int cssyylex(YYSTYPE* yylval, void* parser)
 
 %}
 
-%expect 48
+%expect 55
+
+%nonassoc LOWEST_PREC
 
 %left UNIMPORTANT_TOK
 
@@ -135,6 +143,23 @@ static int cssyylex(YYSTYPE* yylval, void* parser)
 %token WEBKIT_DEFINE_SYM
 %token VARIABLES_FOR
 %token WEBKIT_VARIABLES_DECLS_SYM
+%token <marginBox> TOPLEFTCORNER_SYM
+%token <marginBox> TOPLEFT_SYM
+%token <marginBox> TOPCENTER_SYM
+%token <marginBox> TOPRIGHT_SYM
+%token <marginBox> TOPRIGHTCORNER_SYM
+%token <marginBox> BOTTOMLEFTCORNER_SYM
+%token <marginBox> BOTTOMLEFT_SYM
+%token <marginBox> BOTTOMCENTER_SYM
+%token <marginBox> BOTTOMRIGHT_SYM
+%token <marginBox> BOTTOMRIGHTCORNER_SYM
+%token <marginBox> LEFTTOP_SYM
+%token <marginBox> LEFTMIDDLE_SYM
+%token <marginBox> LEFTBOTTOM_SYM
+%token <marginBox> RIGHTTOP_SYM
+%token <marginBox> RIGHTMIDDLE_SYM
+%token <marginBox> RIGHTBOTTOM_SYM
+
 %token ATKEYWORD
 
 %token IMPORTANT_SYM
@@ -142,6 +167,7 @@ static int cssyylex(YYSTYPE* yylval, void* parser)
 %token MEDIA_NOT
 %token MEDIA_AND
 
+%token <number> REMS
 %token <number> QEMS
 %token <number> EMS
 %token <number> EXS
@@ -154,6 +180,7 @@ static int cssyylex(YYSTYPE* yylval, void* parser)
 %token <number> DEGS
 %token <number> RADS
 %token <number> GRADS
+%token <number> TURNS
 %token <number> MSECS
 %token <number> SECS
 %token <number> HERZ
@@ -175,18 +202,16 @@ static int cssyylex(YYSTYPE* yylval, void* parser)
 
 %type <rule> charset
 %type <rule> ruleset
-%type <rule> valid_rule_or_import
 %type <rule> media
 %type <rule> import
+%type <rule> namespace
 %type <rule> page
+%type <rule> margin_box
 %type <rule> font_face
 %type <rule> keyframes
 %type <rule> invalid_rule
 %type <rule> save_block
 %type <rule> invalid_at
-%type <rule> invalid_at_list
-%type <rule> invalid_import
-%type <rule> invalid_media
 %type <rule> rule
 %type <rule> valid_rule
 %type <ruleList> block_rule_list 
@@ -203,6 +228,7 @@ static int cssyylex(YYSTYPE* yylval, void* parser)
 %type <string> ident_or_string
 %type <string> medium
 %type <string> hexcolor
+%type <marginBox> margin_sym
 
 %type <string> media_feature
 %type <mediaList> media_list
@@ -226,20 +252,24 @@ static int cssyylex(YYSTYPE* yylval, void* parser)
 %type <selector> specifier_list
 %type <selector> simple_selector
 %type <selector> selector
-%type <selector> selector_list
+%type <selectorList> selector_list
 %type <selector> selector_with_trailing_whitespace
 %type <selector> class
 %type <selector> attrib
 %type <selector> pseudo
+%type <selector> pseudo_page
+%type <selector> page_selector
 
 %type <boolean> declaration_list
 %type <boolean> decl_list
 %type <boolean> declaration
+%type <boolean> declarations_and_margins
 
 %type <boolean> prio
 
 %type <integer> match
 %type <integer> unary_operator
+%type <integer> maybe_unary_operator
 %type <character> operator
 
 %type <valueList> expr
@@ -259,7 +289,7 @@ static int cssyylex(YYSTYPE* yylval, void* parser)
 %%
 
 stylesheet:
-    maybe_charset maybe_sgml import_list variables_list namespace_list rule_list
+    maybe_space maybe_charset maybe_sgml rule_list
   | webkit_rule maybe_space
   | webkit_decls maybe_space
   | webkit_value maybe_space
@@ -269,13 +299,8 @@ stylesheet:
   | webkit_keyframe_rule maybe_space
   ;
 
-valid_rule_or_import:
-    valid_rule
-  | import
-  ;
-
 webkit_rule:
-    WEBKIT_RULE_SYM '{' maybe_space valid_rule_or_import maybe_space '}' {
+    WEBKIT_RULE_SYM '{' maybe_space valid_rule maybe_space '}' {
         static_cast<CSSParser*>(parser)->m_rule = $4;
     }
 ;
@@ -321,8 +346,11 @@ webkit_mediaquery:
 
 webkit_selector:
     WEBKIT_SELECTOR_SYM '{' maybe_space selector_list '}' {
-        CSSParser* p = static_cast<CSSParser*>(parser);
-        p->m_floatingSelector = p->sinkFloatingSelector($4);
+        if ($4) {
+            CSSParser* p = static_cast<CSSParser*>(parser);
+            if (p->m_selectorListForParseSelector)
+                p->m_selectorListForParseSelector->adoptSelectorVector(*$4);
+        }
     }
 ;
 
@@ -345,7 +373,7 @@ maybe_charset:
 
 closing_brace:
     '}'
-  | %prec maybe_sgml TOKEN_EOF
+  | %prec LOWEST_PREC TOKEN_EOF
   ;
 
 charset:
@@ -361,31 +389,6 @@ charset:
   }
 ;
 
-import_list:
- /* empty */
- | import_list import maybe_sgml {
-     CSSParser* p = static_cast<CSSParser*>(parser);
-     if ($2 && p->m_styleSheet)
-         p->m_styleSheet->append($2);
- }
- | invalid_at_list {
- }
- ;
-
-variables_list:
-/* empty */
-| variables_list variables_rule maybe_sgml {
-    CSSParser* p = static_cast<CSSParser*>(parser);
-     if ($2 && p->m_styleSheet)
-         p->m_styleSheet->append($2);
-}
-;
-
-namespace_list:
-/* empty */
-| namespace_list namespace maybe_sgml
-;
-
 rule_list:
    /* empty */
  | rule_list rule maybe_sgml {
@@ -401,13 +404,17 @@ valid_rule:
   | page
   | font_face
   | keyframes
+  | namespace
+  | import
+  | variables_rule
   ;
 
 rule:
-    valid_rule
+    valid_rule {
+        static_cast<CSSParser*>(parser)->m_hadSyntacticallyValidCSSRule = true;
+    }
   | invalid_rule
   | invalid_at
-  | invalid_import
   ;
 
 block_rule_list: 
@@ -433,8 +440,10 @@ block_rule:
     block_valid_rule
   | invalid_rule
   | invalid_at
-  | invalid_import
-  | invalid_media
+  | namespace
+  | import
+  | variables_rule
+  | media
   ;
 
 
@@ -558,17 +567,23 @@ variable_name:
 
 namespace:
 NAMESPACE_SYM maybe_space maybe_ns_prefix string_or_uri maybe_space ';' {
-    CSSParser* p = static_cast<CSSParser*>(parser);
-    if (p->m_styleSheet)
-        p->m_styleSheet->addNamespace(p, $3, $4);
+    static_cast<CSSParser*>(parser)->addNamespace($3, $4);
+    $$ = 0;
+}
+| NAMESPACE_SYM maybe_space maybe_ns_prefix string_or_uri maybe_space invalid_block {
+    $$ = 0;
+}
+| NAMESPACE_SYM error invalid_block {
+    $$ = 0;
+}
+| NAMESPACE_SYM error ';' {
+    $$ = 0;
 }
-| NAMESPACE_SYM error invalid_block
-| NAMESPACE_SYM error ';'
 ;
 
 maybe_ns_prefix:
 /* empty */ { $$.characters = 0; }
-| IDENT WHITESPACE { $$ = $1; }
+| IDENT maybe_space { $$ = $1; }
 ;
 
 string_or_uri:
@@ -728,35 +743,127 @@ key:
     | IDENT {
         $$.id = 0; $$.isInt = false; $$.unit = CSSPrimitiveValue::CSS_NUMBER;
         CSSParserString& str = $1;
-        if (equalIgnoringCase(static_cast<const String&>(str), "from"))
+        if (equalIgnoringCase("from", str.characters, str.length))
             $$.fValue = 0;
-        else if (equalIgnoringCase(static_cast<const String&>(str), "to"))
+        else if (equalIgnoringCase("to", str.characters, str.length))
             $$.fValue = 100;
         else
             YYERROR;
     }
     ;
 
-/*
-page:
-    PAGE_SYM maybe_space IDENT? pseudo_page? maybe_space
-    '{' maybe_space declaration [ ';' maybe_space declaration ]* '}' maybe_space
-  ;
-
-pseudo_page
-  : ':' IDENT
-  ;
-*/
-
 page:
-    PAGE_SYM error invalid_block {
+    PAGE_SYM maybe_space page_selector maybe_space
+    '{' maybe_space declarations_and_margins closing_brace {
+        CSSParser* p = static_cast<CSSParser*>(parser);
+        if ($3)
+            $$ = p->createPageRule(p->sinkFloatingSelector($3));
+        else {
+            // Clear properties in the invalid @page rule.
+            p->clearProperties();
+            // Also clear margin at-rules here once we fully implement margin at-rules parsing.
+            $$ = 0;
+        }
+    }
+    | PAGE_SYM error invalid_block {
       $$ = 0;
     }
-  | PAGE_SYM error ';' {
+    | PAGE_SYM error ';' {
       $$ = 0;
     }
     ;
 
+page_selector:
+    IDENT {
+        CSSParser* p = static_cast<CSSParser*>(parser);
+        $$ = p->createFloatingSelector();
+        $$->m_tag = QualifiedName(nullAtom, $1, p->m_defaultNamespace);
+        $$->setForPage();
+    }
+    | IDENT pseudo_page {
+        CSSParser* p = static_cast<CSSParser*>(parser);
+        $$ = $2;
+        if ($$) {
+            $$->m_tag = QualifiedName(nullAtom, $1, p->m_defaultNamespace);
+            $$->setForPage();
+        }
+    }
+    | pseudo_page {
+        $$ = $1;
+        if ($$)
+            $$->setForPage();
+    }
+    | /* empty */ {
+        CSSParser* p = static_cast<CSSParser*>(parser);
+        $$ = p->createFloatingSelector();
+        $$->setForPage();
+    }
+    ;
+
+declarations_and_margins:
+    declaration_list
+    | declarations_and_margins margin_box maybe_space declaration_list
+    ;
+
+margin_box:
+    margin_sym {
+        static_cast<CSSParser*>(parser)->startDeclarationsForMarginBox();
+    } maybe_space '{' maybe_space declaration_list closing_brace {
+        $$ = static_cast<CSSParser*>(parser)->createMarginAtRule($1);
+    }
+    ;
+
+margin_sym :
+    TOPLEFTCORNER_SYM {
+        $$ = CSSSelector::TopLeftCornerMarginBox;
+    }
+    | TOPLEFT_SYM {
+        $$ = CSSSelector::TopLeftMarginBox;
+    }
+    | TOPCENTER_SYM {
+        $$ = CSSSelector::TopCenterMarginBox;
+    }
+    | TOPRIGHT_SYM {
+        $$ = CSSSelector::TopRightMarginBox;
+    }
+    | TOPRIGHTCORNER_SYM {
+        $$ = CSSSelector::TopRightCornerMarginBox;
+    }
+    | BOTTOMLEFTCORNER_SYM {
+        $$ = CSSSelector::BottomLeftCornerMarginBox;
+    }
+    | BOTTOMLEFT_SYM {
+        $$ = CSSSelector::BottomLeftMarginBox;
+    }
+    | BOTTOMCENTER_SYM {
+        $$ = CSSSelector::BottomCenterMarginBox;
+    }
+    | BOTTOMRIGHT_SYM {
+        $$ = CSSSelector::BottomRightMarginBox;
+    }
+    | BOTTOMRIGHTCORNER_SYM {
+        $$ = CSSSelector::BottomRightCornerMarginBox;
+    }
+    | LEFTTOP_SYM {
+        $$ = CSSSelector::LeftTopMarginBox;
+    }
+    | LEFTMIDDLE_SYM {
+        $$ = CSSSelector::LeftMiddleMarginBox;
+    }
+    | LEFTBOTTOM_SYM {
+        $$ = CSSSelector::LeftBottomMarginBox;
+    }
+    | RIGHTTOP_SYM {
+        $$ = CSSSelector::RightTopMarginBox;
+    }
+    | RIGHTMIDDLE_SYM {
+        $$ = CSSSelector::RightMiddleMarginBox;
+    }
+    | RIGHTBOTTOM_SYM {
+        $$ = CSSSelector::RightBottomMarginBox;
+    }
+    ;
+
 font_face:
     FONT_FACE_SYM maybe_space
     '{' maybe_space declaration_list '}'  maybe_space {
@@ -776,6 +883,11 @@ combinator:
   | '>' maybe_space { $$ = CSSSelector::Child; }
   ;
 
+maybe_unary_operator:
+    unary_operator { $$ = $1; }
+    | { $$ = 1; }
+    ;
+
 unary_operator:
     '-' { $$ = -1; }
   | '+' { $$ = 1; }
@@ -783,19 +895,28 @@ unary_operator:
 
 ruleset:
     selector_list '{' maybe_space declaration_list closing_brace {
-        $$ = static_cast<CSSParser*>(parser)->createStyleRule($1);
+        CSSParser* p = static_cast<CSSParser*>(parser);
+        $$ = p->createStyleRule($1);
     }
   ;
 
 selector_list:
     selector %prec UNIMPORTANT_TOK {
-        $$ = $1;
+        if ($1) {
+            CSSParser* p = static_cast<CSSParser*>(parser);
+            $$ = p->reusableSelectorVector();
+            deleteAllValues(*$$);
+            $$->shrink(0);
+            $$->append(p->sinkFloatingSelector($1));
+            p->updateLastSelectorLineAndPosition();
+        }
     }
     | selector_list ',' maybe_space selector %prec UNIMPORTANT_TOK {
         if ($1 && $4) {
             CSSParser* p = static_cast<CSSParser*>(parser);
             $$ = $1;
             $$->append(p->sinkFloatingSelector($4));
+            p->updateLastSelectorLineAndPosition();
         } else
             $$ = 0;
     }
@@ -826,10 +947,10 @@ selector:
         else if ($$) {
             CSSParser* p = static_cast<CSSParser*>(parser);
             CSSSelector* end = $$;
-            while (end->m_tagHistory)
-                end = end->m_tagHistory;
+            while (end->tagHistory())
+                end = end->tagHistory();
             end->m_relation = CSSSelector::Descendant;
-            end->m_tagHistory = p->sinkFloatingSelector($1);
+            end->setTagHistory(p->sinkFloatingSelector($1));
             if (Document* doc = p->document())
                 doc->setUsesDescendantRules(true);
         }
@@ -841,10 +962,10 @@ selector:
         else if ($$) {
             CSSParser* p = static_cast<CSSParser*>(parser);
             CSSSelector* end = $$;
-            while (end->m_tagHistory)
-                end = end->m_tagHistory;
+            while (end->tagHistory())
+                end = end->tagHistory();
             end->m_relation = $2;
-            end->m_tagHistory = p->sinkFloatingSelector($1);
+            end->setTagHistory(p->sinkFloatingSelector($1));
             if ($2 == CSSSelector::Child) {
                 if (Document* doc = p->document())
                     doc->setUsesDescendantRules(true);
@@ -945,10 +1066,10 @@ specifier_list:
             $$ = $1;
             CSSParser* p = static_cast<CSSParser*>(parser);
             CSSSelector* end = $1;
-            while (end->m_tagHistory)
-                end = end->m_tagHistory;
+            while (end->tagHistory())
+                end = end->tagHistory();
             end->m_relation = CSSSelector::SubSelector;
-            end->m_tagHistory = p->sinkFloatingSelector($2);
+            end->setTagHistory(p->sinkFloatingSelector($2));
         }
     }
     | specifier_list error {
@@ -963,7 +1084,6 @@ specifier:
         $$->m_match = CSSSelector::Id;
         if (!p->m_strict)
             $1.lower();
-        $$->m_attr = idAttr;
         $$->m_value = $1;
     }
   | HEX {
@@ -975,7 +1095,6 @@ specifier:
             $$->m_match = CSSSelector::Id;
             if (!p->m_strict)
                 $1.lower();
-            $$->m_attr = idAttr;
             $$->m_value = $1;
         }
     }
@@ -991,7 +1110,6 @@ class:
         $$->m_match = CSSSelector::Class;
         if (!p->m_strict)
             $2.lower();
-        $$->m_attr = classAttr;
         $$->m_value = $2;
     }
   ;
@@ -1010,12 +1128,12 @@ attr_name:
 attrib:
     '[' maybe_space attr_name ']' {
         $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
-        $$->m_attr = QualifiedName(nullAtom, $3, nullAtom);
+        $$->setAttribute(QualifiedName(nullAtom, $3, nullAtom));
         $$->m_match = CSSSelector::Set;
     }
     | '[' maybe_space attr_name match maybe_space ident_or_string maybe_space ']' {
         $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
-        $$->m_attr = QualifiedName(nullAtom, $3, nullAtom);
+        $$->setAttribute(QualifiedName(nullAtom, $3, nullAtom));
         $$->m_match = (CSSSelector::Match)$4;
         $$->m_value = $6;
     }
@@ -1023,16 +1141,16 @@ attrib:
         AtomicString namespacePrefix = $3;
         CSSParser* p = static_cast<CSSParser*>(parser);
         $$ = p->createFloatingSelector();
-        $$->m_attr = QualifiedName(namespacePrefix, $4,
-                                   p->m_styleSheet->determineNamespace(namespacePrefix));
+        $$->setAttribute(QualifiedName(namespacePrefix, $4,
+                                   p->m_styleSheet->determineNamespace(namespacePrefix)));
         $$->m_match = CSSSelector::Set;
     }
     | '[' maybe_space namespace_selector attr_name match maybe_space ident_or_string maybe_space ']' {
         AtomicString namespacePrefix = $3;
         CSSParser* p = static_cast<CSSParser*>(parser);
         $$ = p->createFloatingSelector();
-        $$->m_attr = QualifiedName(namespacePrefix, $4,
-                                   p->m_styleSheet->determineNamespace(namespacePrefix));
+        $$->setAttribute(QualifiedName(namespacePrefix, $4,
+                                   p->m_styleSheet->determineNamespace(namespacePrefix)));
         $$->m_match = (CSSSelector::Match)$5;
         $$->m_value = $7;
     }
@@ -1064,6 +1182,17 @@ ident_or_string:
   | STRING
     ;
 
+pseudo_page:
+    ':' IDENT {
+        $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
+        $$->m_match = CSSSelector::PagePseudoClass;
+        $2.lower();
+        $$->m_value = $2;
+        CSSSelector::PseudoType type = $$->pseudoType();
+        if (type == CSSSelector::PseudoUnknown)
+            $$ = 0;
+    }
+
 pseudo:
     ':' IDENT {
         $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
@@ -1088,6 +1217,15 @@ pseudo:
             CSSParser* p = static_cast<CSSParser*>(parser);
             if (Document* doc = p->document())
                 doc->setUsesFirstLineRules(true);
+        } else if (type == CSSSelector::PseudoBefore ||
+                   type == CSSSelector::PseudoAfter) {
+            CSSParser* p = static_cast<CSSParser*>(parser);
+            if (Document* doc = p->document())
+                doc->setUsesBeforeAfterRules(true);
+        } else if (type == CSSSelector::PseudoLink || type == CSSSelector::PseudoVisited) {
+            CSSParser* p = static_cast<CSSParser*>(parser);
+            if (Document* doc = p->document())
+                doc->setUsesLinkRules(true);
         }
     }
     | ':' ':' IDENT {
@@ -1102,14 +1240,19 @@ pseudo:
             CSSParser* p = static_cast<CSSParser*>(parser);
             if (Document* doc = p->document())
                 doc->setUsesFirstLineRules(true);
+        } else if (type == CSSSelector::PseudoBefore ||
+                   type == CSSSelector::PseudoAfter) {
+            CSSParser* p = static_cast<CSSParser*>(parser);
+            if (Document* doc = p->document())
+                doc->setUsesBeforeAfterRules(true);
         }
     }
     // used by :nth-*(ax+b)
-    | ':' FUNCTION NTH ')' {
+    | ':' FUNCTION maybe_space NTH maybe_space ')' {
         CSSParser *p = static_cast<CSSParser*>(parser);
-        $$ = static_cast<CSSSelector*>(p->createFloatingNthSelector());
+        $$ = p->createFloatingSelector();
         $$->m_match = CSSSelector::PseudoClass;
-        $$->m_argument = $3;
+        $$->setArgument($4);
         $$->m_value = $2;
         CSSSelector::PseudoType type = $$->pseudoType();
         if (type == CSSSelector::PseudoUnknown)
@@ -1123,11 +1266,11 @@ pseudo:
         }
     }
     // used by :nth-*
-    | ':' FUNCTION INTEGER ')' {
+    | ':' FUNCTION maybe_space maybe_unary_operator INTEGER maybe_space ')' {
         CSSParser *p = static_cast<CSSParser*>(parser);
-        $$ = static_cast<CSSSelector*>(p->createFloatingNthSelector());
+        $$ = p->createFloatingSelector();
         $$->m_match = CSSSelector::PseudoClass;
-        $$->m_argument = String::number($3);
+        $$->setArgument(String::number($4 * $5));
         $$->m_value = $2;
         CSSSelector::PseudoType type = $$->pseudoType();
         if (type == CSSSelector::PseudoUnknown)
@@ -1141,11 +1284,11 @@ pseudo:
         }
     }
     // used by :nth-*(odd/even) and :lang
-    | ':' FUNCTION IDENT ')' {
+    | ':' FUNCTION maybe_space IDENT maybe_space ')' {
         CSSParser *p = static_cast<CSSParser*>(parser);
-        $$ = static_cast<CSSSelector*>(p->createFloatingNthSelector());
+        $$ = p->createFloatingSelector();
         $$->m_match = CSSSelector::PseudoClass;
-        $$->m_argument = $3;
+        $$->setArgument($4);
         $2.lower();
         $$->m_value = $2;
         CSSSelector::PseudoType type = $$->pseudoType();
@@ -1161,13 +1304,13 @@ pseudo:
     }
     // used by :not
     | ':' NOTFUNCTION maybe_space simple_selector maybe_space ')' {
-        if (!$4)
+        if (!$4 || !$4->isSimple())
             $$ = 0;
         else {
             CSSParser* p = static_cast<CSSParser*>(parser);
             $$ = p->createFloatingSelector();
             $$->m_match = CSSSelector::PseudoClass;
-            $$->m_simpleSelector = p->sinkFloatingSelector($4);
+            $$->setSimpleSelector(p->sinkFloatingSelector($4));
             $2.lower();
             $$->m_value = $2;
         }
@@ -1204,6 +1347,9 @@ decl_list:
     declaration ';' maybe_space {
         $$ = $1;
     }
+    | declaration invalid_block_list maybe_space {
+        $$ = false;
+    }
     | declaration invalid_block_list ';' maybe_space {
         $$ = false;
     }
@@ -1321,6 +1467,12 @@ expr:
             $$->addValue(p->sinkFloatingValue($3));
         }
     }
+    | expr invalid_block_list {
+        $$ = 0;
+    }
+    | expr invalid_block_list error {
+        $$ = 0;
+    }
     | expr error {
         $$ = 0;
     }
@@ -1348,10 +1500,10 @@ term:
       $$.string = $1;
   }
   /* We might need to actually parse the number from a dimension, but we can't just put something that uses $$.string into unary_term. */
-  | DIMEN maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_DIMENSION }
-  | unary_operator DIMEN maybe_space { $$.id = 0; $$.string = $2; $$.unit = CSSPrimitiveValue::CSS_DIMENSION }
+  | DIMEN maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_DIMENSION; }
+  | unary_operator DIMEN maybe_space { $$.id = 0; $$.string = $2; $$.unit = CSSPrimitiveValue::CSS_DIMENSION; }
   | URI maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_URI; }
-  | UNICODERANGE maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_UNICODE_RANGE }
+  | UNICODERANGE maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_UNICODE_RANGE; }
   | hexcolor { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_PARSER_HEXCOLOR; }
   | '#' maybe_space { $$.id = 0; $$.string = CSSParserString(); $$.unit = CSSPrimitiveValue::CSS_PARSER_HEXCOLOR; } /* Handle error case: "color: #;" */
   /* FIXME: according to the specs a function can have a unary_operator in front. I know no case where this makes sense */
@@ -1361,7 +1513,9 @@ term:
   | variable_reference maybe_space {
       $$ = $1;
   }
-  | '%' maybe_space { $$.id = 0; $$.fValue = 0; $$.unit = CSSPrimitiveValue::CSS_PERCENTAGE; } /* Handle width: %; ANDROID: Fix an uninitialized Value object causing the device to crash */
+  | '%' maybe_space { /* Handle width: %; */
+      $$.id = 0; $$.unit = 0;
+  }
   ;
 
 unary_term:
@@ -1377,6 +1531,7 @@ unary_term:
   | DEGS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_DEG; }
   | RADS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_RAD; }
   | GRADS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_GRAD; }
+  | TURNS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_TURN; }
   | MSECS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_MS; }
   | SECS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_S; }
   | HERZ maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_HZ; }
@@ -1384,7 +1539,15 @@ unary_term:
   | EMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_EMS; }
   | QEMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSParserValue::Q_EMS; }
   | EXS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_EXS; }
-    ;
+  | REMS maybe_space {
+      $$.id = 0;
+      $$.fValue = $1;
+      $$.unit = CSSPrimitiveValue::CSS_REMS;
+      CSSParser* p = static_cast<CSSParser*>(parser);
+      if (Document* doc = p->document())
+          doc->setUsesRemUnits(true);
+  }
+  ;
 
 variable_reference:
   VARCALL {
@@ -1445,23 +1608,6 @@ invalid_at:
     }
     ;
 
-invalid_at_list:
-    invalid_at maybe_sgml
-  | invalid_at_list invalid_at maybe_sgml
-  ;
-
-invalid_import:
-    import {
-        $$ = 0;
-    }
-    ;
-
-invalid_media:
-    media {
-        $$ = 0;
-    }
-    ;
-
 invalid_rule:
     error invalid_block {
         $$ = 0;
@@ -1481,8 +1627,12 @@ invalid_rule:
     ;
 
 invalid_block:
-    '{' error invalid_block_list error closing_brace
-  | '{' error closing_brace
+    '{' error invalid_block_list error closing_brace {
+        static_cast<CSSParser*>(parser)->invalidBlockHit();
+    }
+  | '{' error closing_brace {
+        static_cast<CSSParser*>(parser)->invalidBlockHit();
+    }
     ;
 
 invalid_block_list: