--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/webengine/osswebengine/WebCore/css/CSSGrammar.y Mon Mar 30 12:54:55 2009 +0300
@@ -0,0 +1,1198 @@
+%{
+
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 2002-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc.
+ * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "config.h"
+
+#include "CSSMediaRule.h"
+#include "CSSParser.h"
+#include "CSSPrimitiveValue.h"
+#include "CSSRule.h"
+#include "CSSRuleList.h"
+#include "CSSSelector.h"
+#include "CSSStyleSheet.h"
+#include "Document.h"
+#include "HTMLNames.h"
+#include "MediaList.h"
+#include "MediaQuery.h"
+#include "MediaQueryExp.h"
+#include "PlatformString.h"
+#include <stdlib.h>
+#include <string.h>
+
+#if ENABLE(SVG)
+#include "ksvgcssproperties.h"
+#include "ksvgcssvalues.h"
+#endif
+
+using namespace WebCore;
+using namespace HTMLNames;
+
+// The following file defines the function
+// const struct props *findProp(const char *word, int len)
+//
+// with 'props->id' a CSS property in the range from CSS_PROP_MIN to
+// (and including) CSS_PROP_TOTAL-1
+
+#include "CSSPropertyNames.c"
+#include "CSSValueKeywords.c"
+
+namespace WebCore {
+
+int getPropertyID(const char* tagStr, int len)
+{
+ DeprecatedString prop;
+
+ if (len && tagStr[0] == '-') {
+ prop = DeprecatedString(tagStr, len);
+ if (prop.startsWith("-apple-")) {
+ prop = "-webkit-" + prop.mid(7);
+ tagStr = prop.ascii();
+ len++;
+ } else if (prop.startsWith("-khtml-")) {
+ prop = "-webkit-" + prop.mid(7);
+ len++;
+ tagStr = prop.ascii();
+ }
+
+ // Honor the use of old-style opacity (for Safari 1.1).
+ if (prop == "-webkit-opacity") {
+ const char * const opacity = "opacity";
+ tagStr = opacity;
+ len = strlen(opacity);
+ }
+ }
+
+ const struct props* propsPtr = findProp(tagStr, len);
+ if (!propsPtr)
+ return 0;
+
+ return propsPtr->id;
+}
+
+} // namespace WebCore
+
+static inline int getValueID(const char* tagStr, int len)
+{
+ DeprecatedString prop;
+ if (len && tagStr[0] == '-') {
+ prop = DeprecatedString(tagStr, len);
+ if (prop.startsWith("-apple-")) {
+ prop = "-webkit-" + prop.mid(7);
+ tagStr = prop.ascii();
+ len++;
+ } else if (prop.startsWith("-khtml-")) {
+ prop = "-webkit-" + prop.mid(7);
+ len++;
+ tagStr = prop.ascii();
+ }
+ }
+
+ const struct css_value* val = findValue(tagStr, len);
+ if (!val)
+ return 0;
+
+ return val->id;
+}
+
+#define YYENABLE_NLS 0
+#define YYLTYPE_IS_TRIVIAL 1
+#define YYMAXDEPTH 10000
+#define YYDEBUG 0
+#define YYPARSE_PARAM parser
+
+%}
+
+%pure_parser
+
+%union {
+ CSSRule* rule;
+ CSSSelector* selector;
+ bool ok;
+ MediaList *mediaList;
+ CSSMediaRule* mediaRule;
+ CSSRuleList* ruleList;
+ ParseString string;
+ float val;
+ int prop_id;
+ int attribute;
+ CSSSelector::Relation relation;
+ bool b;
+ int i;
+ char tok;
+ Value value;
+ ValueList* valueList;
+
+ MediaQuery* mediaQuery;
+ MediaQueryExp* mediaQueryExp;
+ Vector<MediaQueryExp*>* mediaQueryExpList;
+ MediaQuery::Restrictor mediaQueryRestrictor;
+}
+
+%{
+
+static inline int cssyyerror(const char*) { return 1; }
+static int cssyylex(YYSTYPE* yylval) { return CSSParser::current()->lex(yylval); }
+
+%}
+
+//%expect 37
+
+%left UNIMPORTANT_TOK
+
+%token WHITESPACE SGML_CD
+
+%token INCLUDES
+%token DASHMATCH
+%token BEGINSWITH
+%token ENDSWITH
+%token CONTAINS
+
+%token <string> STRING
+
+%right <string> IDENT
+
+%nonassoc <string> HEX
+%nonassoc <string> IDSEL
+%nonassoc ':'
+%nonassoc '.'
+%nonassoc '['
+%nonassoc <string> '*'
+%nonassoc error
+%left '|'
+
+%token IMPORT_SYM
+%token PAGE_SYM
+%token MEDIA_SYM
+%token FONT_FACE_SYM
+%token CHARSET_SYM
+%token NAMESPACE_SYM
+%token WEBKIT_RULE_SYM
+%token WEBKIT_DECLS_SYM
+%token WEBKIT_VALUE_SYM
+%token WEBKIT_MEDIAQUERY_SYM
+
+%token IMPORTANT_SYM
+%token MEDIA_ONLY
+%token MEDIA_NOT
+%token MEDIA_AND
+
+%token <val> QEMS
+%token <val> EMS
+%token <val> EXS
+%token <val> PXS
+%token <val> CMS
+%token <val> MMS
+%token <val> INS
+%token <val> PTS
+%token <val> PCS
+%token <val> DEGS
+%token <val> RADS
+%token <val> GRADS
+%token <val> MSECS
+%token <val> SECS
+%token <val> HERZ
+%token <val> KHERZ
+%token <string> DIMEN
+%token <val> PERCENTAGE
+%token <val> FLOATTOKEN
+%token <val> INTEGER
+
+%token <string> URI
+%token <string> FUNCTION
+%token <string> NOTFUNCTION
+
+%token <string> UNICODERANGE
+
+%type <relation> combinator
+
+%type <rule> charset
+%type <rule> ruleset
+%type <rule> ruleset_or_import
+%type <rule> media
+%type <rule> import
+%type <rule> page
+%type <rule> font_face
+%type <rule> invalid_rule
+%type <rule> invalid_at
+%type <rule> invalid_import
+%type <rule> rule
+
+%type <string> maybe_ns_prefix
+
+%type <string> namespace_selector
+
+%type <string> string_or_uri
+%type <string> ident_or_string
+%type <string> medium
+%type <string> hexcolor
+
+%type <string> media_feature
+%type <mediaList> media_list
+%type <mediaList> maybe_media_list
+%type <mediaQuery> media_query
+%type <mediaQueryRestrictor> maybe_media_restrictor
+%type <valueList> maybe_media_value
+%type <mediaQueryExp> media_query_exp
+%type <mediaQueryExpList> media_query_exp_list
+%type <mediaQueryExpList> maybe_media_query_exp_list
+
+%type <ruleList> ruleset_list
+
+%type <prop_id> property
+
+%type <selector> specifier
+%type <selector> specifier_list
+%type <selector> simple_selector
+%type <selector> selector
+%type <selector> selector_list
+%type <selector> class
+%type <selector> attrib
+%type <selector> pseudo
+
+%type <ok> declaration_list
+%type <ok> decl_list
+%type <ok> declaration
+
+%type <b> prio
+
+%type <i> match
+%type <i> unary_operator
+%type <tok> operator
+
+%type <valueList> expr
+%type <value> term
+%type <value> unary_term
+%type <value> function
+
+%type <string> element_name
+%type <string> attr_name
+
+%%
+
+stylesheet:
+ maybe_charset maybe_sgml import_list namespace_list rule_list
+ | webkit_rule maybe_space
+ | webkit_decls maybe_space
+ | webkit_value maybe_space
+ | webkit_mediaquery maybe_space
+ ;
+
+ruleset_or_import:
+ ruleset |
+ import
+;
+
+webkit_rule:
+ WEBKIT_RULE_SYM '{' maybe_space ruleset_or_import maybe_space '}' {
+ static_cast<CSSParser*>(parser)->rule = $4;
+ }
+;
+
+webkit_decls:
+ WEBKIT_DECLS_SYM '{' maybe_space declaration_list '}' {
+ /* can be empty */
+ }
+;
+
+webkit_value:
+ WEBKIT_VALUE_SYM '{' maybe_space expr '}' {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ if ($4) {
+ p->valueList = p->sinkFloatingValueList($4);
+ int oldParsedProperties = p->numParsedProperties;
+ if (!p->parseValue(p->id, p->important))
+ p->rollbackLastProperties(p->numParsedProperties - oldParsedProperties);
+ delete p->valueList;
+ p->valueList = 0;
+ }
+ }
+;
+
+webkit_mediaquery:
+ WEBKIT_MEDIAQUERY_SYM WHITESPACE maybe_space media_query '}' {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ p->mediaQuery = p->sinkFloatingMediaQuery($4);
+ }
+;
+
+maybe_space:
+ /* empty */ %prec UNIMPORTANT_TOK
+ | maybe_space WHITESPACE
+ ;
+
+maybe_sgml:
+ /* empty */
+ | maybe_sgml SGML_CD
+ | maybe_sgml WHITESPACE
+ ;
+
+maybe_charset:
+ /* empty */
+ | charset {
+ }
+;
+
+charset:
+ CHARSET_SYM maybe_space STRING maybe_space ';' {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ $$ = static_cast<CSSParser*>(parser)->createCharsetRule($3);
+ if ($$ && p->styleElement && p->styleElement->isCSSStyleSheet())
+ p->styleElement->append($$);
+ }
+ | CHARSET_SYM error invalid_block {
+ }
+ | CHARSET_SYM error ';' {
+ }
+;
+
+import_list:
+ /* empty */
+ | import_list import maybe_sgml {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ if ($2 && p->styleElement && p->styleElement->isCSSStyleSheet())
+ p->styleElement->append($2);
+ }
+ ;
+
+namespace_list:
+/* empty */
+| namespace_list namespace maybe_sgml
+;
+
+rule_list:
+ /* empty */
+ | rule_list rule maybe_sgml {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ if ($2 && p->styleElement && p->styleElement->isCSSStyleSheet())
+ p->styleElement->append($2);
+ }
+ ;
+
+rule:
+ ruleset
+ | media
+ | page
+ | font_face
+ | invalid_rule
+ | invalid_at
+ | invalid_import
+ ;
+
+import:
+ IMPORT_SYM maybe_space string_or_uri maybe_space maybe_media_list ';' {
+ $$ = static_cast<CSSParser*>(parser)->createImportRule($3, $5);
+ }
+ | IMPORT_SYM error invalid_block {
+ $$ = 0;
+ }
+ | IMPORT_SYM error ';' {
+ $$ = 0;
+ }
+ ;
+
+namespace:
+NAMESPACE_SYM maybe_space maybe_ns_prefix string_or_uri maybe_space ';' {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ if (p->styleElement && p->styleElement->isCSSStyleSheet())
+ static_cast<CSSStyleSheet*>(p->styleElement)->addNamespace(p, atomicString($3), atomicString($4));
+}
+| NAMESPACE_SYM error invalid_block
+| NAMESPACE_SYM error ';'
+;
+
+maybe_ns_prefix:
+/* empty */ { $$.characters = 0; }
+| IDENT WHITESPACE { $$ = $1; }
+;
+
+string_or_uri:
+STRING
+| URI
+;
+
+media_feature:
+ IDENT maybe_space {
+ $$ = $1;
+ }
+ ;
+
+maybe_media_value:
+ /*empty*/ {
+ $$ = 0;
+ }
+ | ':' maybe_space expr maybe_space {
+ $$ = $3;
+ }
+ ;
+
+media_query_exp:
+ MEDIA_AND maybe_space '(' maybe_space media_feature maybe_space maybe_media_value ')' maybe_space {
+ $5.lower();
+ $$ = static_cast<CSSParser*>(parser)->createFloatingMediaQueryExp(atomicString($5), $7);
+ }
+ ;
+
+media_query_exp_list:
+ media_query_exp {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ $$ = p->createFloatingMediaQueryExpList();
+ $$->append(p->sinkFloatingMediaQueryExp($1));
+ }
+ | media_query_exp_list media_query_exp {
+ $$ = $1;
+ $$->append(static_cast<CSSParser*>(parser)->sinkFloatingMediaQueryExp($2));
+ }
+ ;
+
+maybe_media_query_exp_list:
+ /*empty*/ {
+ $$ = static_cast<CSSParser*>(parser)->createFloatingMediaQueryExpList();
+ }
+ | media_query_exp_list
+ ;
+
+maybe_media_restrictor:
+ /*empty*/ {
+ $$ = MediaQuery::None;
+ }
+ | MEDIA_ONLY {
+ $$ = MediaQuery::Only;
+ }
+ | MEDIA_NOT {
+ $$ = MediaQuery::Not;
+ }
+ ;
+
+media_query:
+ maybe_media_restrictor maybe_space medium maybe_media_query_exp_list {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ $3.lower();
+ $$ = p->createFloatingMediaQuery($1, domString($3), p->sinkFloatingMediaQueryExpList($4));
+ }
+ ;
+
+maybe_media_list:
+ /* empty */ {
+ $$ = static_cast<CSSParser*>(parser)->createMediaList();
+ }
+ | media_list
+ ;
+
+media_list:
+ media_query {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ $$ = p->createMediaList();
+ $$->appendMediaQuery(p->sinkFloatingMediaQuery($1));
+ }
+ | media_list ',' maybe_space media_query {
+ $$ = $1;
+ if ($$)
+ $$->appendMediaQuery(static_cast<CSSParser*>(parser)->sinkFloatingMediaQuery($4));
+ }
+ | media_list error {
+ $$ = 0;
+ }
+ ;
+
+media:
+ MEDIA_SYM maybe_space media_list '{' maybe_space ruleset_list '}' {
+ $$ = static_cast<CSSParser*>(parser)->createMediaRule($3, $6);
+ }
+ | MEDIA_SYM maybe_space '{' maybe_space ruleset_list '}' {
+ $$ = static_cast<CSSParser*>(parser)->createMediaRule(0, $5);
+ }
+ ;
+
+ruleset_list:
+ /* empty */ { $$ = 0; }
+ | ruleset_list ruleset maybe_space {
+ $$ = $1;
+ if ($2) {
+ if (!$$)
+ $$ = static_cast<CSSParser*>(parser)->createRuleList();
+ $$->append($2);
+ }
+ }
+ ;
+
+medium:
+ IDENT maybe_space {
+ $$ = $1;
+ }
+ ;
+
+/*
+page:
+ PAGE_SYM maybe_space IDENT? pseudo_page? maybe_space
+ '{' maybe_space declaration [ ';' maybe_space declaration ]* '}' maybe_space
+ ;
+
+pseudo_page
+ : ':' IDENT
+ ;
+
+font_face
+ : FONT_FACE_SYM maybe_space
+ '{' maybe_space declaration [ ';' maybe_space declaration ]* '}' maybe_space
+ ;
+*/
+
+page:
+ PAGE_SYM error invalid_block {
+ $$ = 0;
+ }
+ | PAGE_SYM error ';' {
+ $$ = 0;
+ }
+ ;
+
+font_face:
+ FONT_FACE_SYM error invalid_block {
+ $$ = 0;
+ }
+ | FONT_FACE_SYM error ';' {
+ $$ = 0;
+ }
+;
+
+combinator:
+ '+' maybe_space { $$ = CSSSelector::DirectAdjacent; }
+ | '~' maybe_space { $$ = CSSSelector::IndirectAdjacent; }
+ | '>' maybe_space { $$ = CSSSelector::Child; }
+ | /* empty */ { $$ = CSSSelector::Descendant; }
+ ;
+
+unary_operator:
+ '-' { $$ = -1; }
+ | '+' { $$ = 1; }
+ ;
+
+ruleset:
+ selector_list '{' maybe_space declaration_list '}' {
+ $$ = static_cast<CSSParser*>(parser)->createStyleRule($1);
+ }
+ ;
+
+selector_list:
+ selector %prec UNIMPORTANT_TOK {
+ $$ = $1;
+ }
+ | selector_list ',' maybe_space selector %prec UNIMPORTANT_TOK {
+ if ($1 && $4) {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ $$ = $1;
+ $$->append(p->sinkFloatingSelector($4));
+ } else
+ $$ = 0;
+ }
+ | selector_list error {
+ $$ = 0;
+ }
+ ;
+
+selector:
+ simple_selector {
+ $$ = $1;
+ }
+ | selector combinator simple_selector {
+ $$ = $3;
+ if (!$1)
+ $$ = 0;
+ else if ($$) {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ CSSSelector* end = $$;
+ while (end->m_tagHistory)
+ end = end->m_tagHistory;
+ end->m_relation = $2;
+ end->m_tagHistory = p->sinkFloatingSelector($1);
+ if ($2 == CSSSelector::Descendant || $2 == CSSSelector::Child) {
+ if (Document* doc = p->document())
+ doc->setUsesDescendantRules(true);
+ } else if ($2 == CSSSelector::DirectAdjacent || $2 == CSSSelector::IndirectAdjacent) {
+ if (Document* doc = p->document())
+ doc->setUsesSiblingRules(true);
+ }
+ }
+ }
+ | selector error {
+ $$ = 0;
+ }
+ ;
+
+namespace_selector:
+ /* empty */ '|' { $$.characters = 0; $$.length = 0; }
+ | '*' '|' { static UChar star = '*'; $$.characters = ☆ $$.length = 1; }
+ | IDENT '|' { $$ = $1; }
+;
+
+simple_selector:
+ element_name maybe_space {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ $$ = p->createFloatingSelector();
+ $$->m_tag = QualifiedName(nullAtom, atomicString($1), p->defaultNamespace);
+ }
+ | element_name specifier_list maybe_space {
+ $$ = $2;
+ if ($$) {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ $$->m_tag = QualifiedName(nullAtom, atomicString($1), p->defaultNamespace);
+ }
+ }
+ | specifier_list maybe_space {
+ $$ = $1;
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ if ($$ && p->defaultNamespace != starAtom)
+ $$->m_tag = QualifiedName(nullAtom, starAtom, p->defaultNamespace);
+ }
+ | namespace_selector element_name maybe_space {
+ AtomicString namespacePrefix = atomicString($1);
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ $$ = p->createFloatingSelector();
+ if (p->styleElement && p->styleElement->isCSSStyleSheet())
+ $$->m_tag = QualifiedName(namespacePrefix,
+ atomicString($2),
+ static_cast<CSSStyleSheet*>(p->styleElement)->determineNamespace(namespacePrefix));
+ else // FIXME: Shouldn't this case be an error?
+ $$->m_tag = QualifiedName(nullAtom, atomicString($2), p->defaultNamespace);
+ }
+ | namespace_selector element_name specifier_list maybe_space {
+ $$ = $3;
+ if ($$) {
+ AtomicString namespacePrefix = atomicString($1);
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ if (p->styleElement && p->styleElement->isCSSStyleSheet())
+ $$->m_tag = QualifiedName(namespacePrefix,
+ atomicString($2),
+ static_cast<CSSStyleSheet*>(p->styleElement)->determineNamespace(namespacePrefix));
+ else // FIXME: Shouldn't this case be an error?
+ $$->m_tag = QualifiedName(nullAtom, atomicString($2), p->defaultNamespace);
+ }
+ }
+ | namespace_selector specifier_list maybe_space {
+ $$ = $2;
+ if ($$) {
+ AtomicString namespacePrefix = atomicString($1);
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ if (p->styleElement && p->styleElement->isCSSStyleSheet())
+ $$->m_tag = QualifiedName(namespacePrefix,
+ starAtom,
+ static_cast<CSSStyleSheet*>(p->styleElement)->determineNamespace(namespacePrefix));
+ }
+ }
+ ;
+
+element_name:
+ IDENT {
+ ParseString& str = $1;
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ Document* doc = p->document();
+ if (doc && doc->isHTMLDocument())
+ str.lower();
+ $$ = str;
+ }
+ | '*' {
+ static UChar star = '*';
+ $$.characters = ☆
+ $$.length = 1;
+ }
+ ;
+
+specifier_list:
+ specifier {
+ $$ = $1;
+ }
+ | specifier_list specifier {
+ if (!$2)
+ $$ = 0;
+ else if ($1) {
+ $$ = $1;
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ CSSSelector* end = $1;
+ while (end->m_tagHistory)
+ end = end->m_tagHistory;
+ end->m_relation = CSSSelector::SubSelector;
+ end->m_tagHistory = p->sinkFloatingSelector($2);
+ }
+ }
+ | specifier_list error {
+ $$ = 0;
+ }
+;
+
+specifier:
+ IDSEL {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ $$ = p->createFloatingSelector();
+ $$->m_match = CSSSelector::Id;
+ if (!p->strict)
+ $1.lower();
+ $$->m_attr = idAttr;
+ $$->m_value = atomicString($1);
+ }
+ | HEX {
+ if ($1.characters[0] >= '0' && $1.characters[0] <= '9') {
+ $$ = 0;
+ } else {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ $$ = p->createFloatingSelector();
+ $$->m_match = CSSSelector::Id;
+ if (!p->strict)
+ $1.lower();
+ $$->m_attr = idAttr;
+ $$->m_value = atomicString($1);
+ }
+ }
+ | class
+ | attrib
+ | pseudo
+ ;
+
+class:
+ '.' IDENT {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ $$ = p->createFloatingSelector();
+ $$->m_match = CSSSelector::Class;
+ if (!p->strict)
+ $2.lower();
+ $$->m_attr = classAttr;
+ $$->m_value = atomicString($2);
+ }
+ ;
+
+attr_name:
+ IDENT maybe_space {
+ ParseString& str = $1;
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ Document* doc = p->document();
+ if (doc && doc->isHTMLDocument())
+ str.lower();
+ $$ = str;
+ }
+ ;
+
+attrib:
+ '[' maybe_space attr_name ']' {
+ $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
+ $$->m_attr = QualifiedName(nullAtom, atomicString($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, atomicString($3), nullAtom);
+ $$->m_match = (CSSSelector::Match)$4;
+ $$->m_value = atomicString($6);
+ }
+ | '[' maybe_space namespace_selector attr_name ']' {
+ AtomicString namespacePrefix = atomicString($3);
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ $$ = p->createFloatingSelector();
+ $$->m_attr = QualifiedName(namespacePrefix,
+ atomicString($4),
+ static_cast<CSSStyleSheet*>(p->styleElement)->determineNamespace(namespacePrefix));
+ $$->m_match = CSSSelector::Set;
+ }
+ | '[' maybe_space namespace_selector attr_name match maybe_space ident_or_string maybe_space ']' {
+ AtomicString namespacePrefix = atomicString($3);
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ $$ = p->createFloatingSelector();
+ $$->m_attr = QualifiedName(namespacePrefix,
+ atomicString($4),
+ static_cast<CSSStyleSheet*>(p->styleElement)->determineNamespace(namespacePrefix));
+ $$->m_match = (CSSSelector::Match)$5;
+ $$->m_value = atomicString($7);
+ }
+ ;
+
+match:
+ '=' {
+ $$ = CSSSelector::Exact;
+ }
+ | INCLUDES {
+ $$ = CSSSelector::List;
+ }
+ | DASHMATCH {
+ $$ = CSSSelector::Hyphen;
+ }
+ | BEGINSWITH {
+ $$ = CSSSelector::Begin;
+ }
+ | ENDSWITH {
+ $$ = CSSSelector::End;
+ }
+ | CONTAINS {
+ $$ = CSSSelector::Contain;
+ }
+ ;
+
+ident_or_string:
+ IDENT
+ | STRING
+ ;
+
+pseudo:
+ ':' IDENT {
+ $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
+ $$->m_match = CSSSelector::PseudoClass;
+ $2.lower();
+ $$->m_value = atomicString($2);
+ CSSSelector::PseudoType type = $$->pseudoType();
+ if (type == CSSSelector::PseudoUnknown)
+ $$ = 0;
+ else if (type == CSSSelector::PseudoEmpty ||
+ type == CSSSelector::PseudoFirstChild) {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ Document* doc = p->document();
+ if (doc)
+ doc->setUsesSiblingRules(true);
+ } else if (type == CSSSelector::PseudoFirstLine) {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ if (Document* doc = p->document())
+ doc->setUsesFirstLineRules(true);
+ }
+ }
+ | ':' ':' IDENT {
+ $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
+ $$->m_match = CSSSelector::PseudoElement;
+ $3.lower();
+ $$->m_value = atomicString($3);
+ CSSSelector::PseudoType type = $$->pseudoType();
+ if (type == CSSSelector::PseudoUnknown)
+ $$ = 0;
+ else if (type == CSSSelector::PseudoFirstLine) {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ if (Document* doc = p->document())
+ doc->setUsesFirstLineRules(true);
+ }
+ }
+ // used by :lang
+ | ':' FUNCTION IDENT ')' {
+ $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
+ $$->m_match = CSSSelector::PseudoClass;
+ $$->m_argument = atomicString($3);
+ $2.lower();
+ $$->m_value = atomicString($2);
+ if ($$->pseudoType() == CSSSelector::PseudoUnknown)
+ $$ = 0;
+ }
+ // used by :not
+ | ':' NOTFUNCTION maybe_space simple_selector ')' {
+ if (!$4)
+ $$ = 0;
+ else {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ $$ = p->createFloatingSelector();
+ $$->m_match = CSSSelector::PseudoClass;
+ $$->m_simpleSelector = p->sinkFloatingSelector($4);
+ $2.lower();
+ $$->m_value = atomicString($2);
+ }
+ }
+ ;
+
+declaration_list:
+ declaration {
+ $$ = $1;
+ }
+ | decl_list declaration {
+ $$ = $1;
+ if ( $2 )
+ $$ = $2;
+ }
+ | decl_list {
+ $$ = $1;
+ }
+ | error invalid_block_list error {
+ $$ = false;
+ }
+ | error {
+ $$ = false;
+ }
+ | decl_list error {
+ $$ = $1;
+ }
+ | decl_list invalid_block_list {
+ $$ = $1;
+ }
+ ;
+
+decl_list:
+ declaration ';' maybe_space {
+ $$ = $1;
+ }
+ | declaration invalid_block_list ';' maybe_space {
+ $$ = false;
+ }
+ | error ';' maybe_space {
+ $$ = false;
+ }
+ | error invalid_block_list error ';' maybe_space {
+ $$ = false;
+ }
+ | decl_list declaration ';' maybe_space {
+ $$ = $1;
+ if ($2)
+ $$ = $2;
+ }
+ | decl_list error ';' maybe_space {
+ $$ = $1;
+ }
+ | decl_list error invalid_block_list error ';' maybe_space {
+ $$ = $1;
+ }
+ ;
+
+declaration:
+ property ':' maybe_space expr prio {
+ $$ = false;
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ if ($1 && $4) {
+ p->valueList = p->sinkFloatingValueList($4);
+ int oldParsedProperties = p->numParsedProperties;
+ $$ = p->parseValue($1, $5);
+ if (!$$)
+ p->rollbackLastProperties(p->numParsedProperties - oldParsedProperties);
+ delete p->valueList;
+ p->valueList = 0;
+ }
+ }
+ |
+ property error {
+ $$ = false;
+ }
+ |
+ property ':' maybe_space error expr prio {
+ /* The default movable type template has letter-spacing: .none; Handle this by looking for
+ error tokens at the start of an expr, recover the expr and then treat as an error, cleaning
+ up and deleting the shifted expr. */
+ $$ = false;
+ }
+ |
+ property ':' maybe_space expr prio error {
+ /* When we encounter something like p {color: red !important fail;} we should drop the declaration */
+ $$ = false;
+ }
+ |
+ IMPORTANT_SYM maybe_space {
+ /* Handle this case: div { text-align: center; !important } Just reduce away the stray !important. */
+ $$ = false;
+ }
+ |
+ property ':' maybe_space {
+ /* div { font-family: } Just reduce away this property with no value. */
+ $$ = false;
+ }
+ |
+ property ':' maybe_space error {
+ /* if we come across rules with invalid values like this case: p { weight: *; }, just discard the rule */
+ $$ = false;
+ }
+ |
+ property invalid_block {
+ /* if we come across: div { color{;color:maroon} }, ignore everything within curly brackets */
+ $$ = false;
+ }
+ ;
+
+property:
+ IDENT maybe_space {
+ $1.lower();
+ DeprecatedString str = deprecatedString($1);
+ const char* s = str.ascii();
+ int l = str.length();
+ $$ = getPropertyID(s, l);
+#if ENABLE(SVG)
+ if ($$ == 0)
+ $$ = SVG::getSVGCSSPropertyID(s, l);
+#endif
+ }
+ ;
+
+prio:
+ IMPORTANT_SYM maybe_space { $$ = true; }
+ | /* empty */ { $$ = false; }
+ ;
+
+expr:
+ term {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ $$ = p->createFloatingValueList();
+ $$->addValue(p->sinkFloatingValue($1));
+ }
+ | expr operator term {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ $$ = $1;
+ if ($$) {
+ if ($2) {
+ Value v;
+ v.id = 0;
+ v.unit = Value::Operator;
+ v.iValue = $2;
+ $$->addValue(v);
+ }
+ $$->addValue(p->sinkFloatingValue($3));
+ }
+ }
+ | expr error {
+ $$ = 0;
+ }
+ ;
+
+operator:
+ '/' maybe_space {
+ $$ = '/';
+ }
+ | ',' maybe_space {
+ $$ = ',';
+ }
+ | /* empty */ {
+ $$ = 0;
+ }
+ ;
+
+term:
+ unary_term { $$ = $1; }
+ | unary_operator unary_term { $$ = $2; $$.fValue *= $1; }
+ | STRING maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_STRING; }
+ | IDENT maybe_space {
+ DeprecatedString str = deprecatedString($1);
+ $$.id = getValueID(str.lower().latin1(), str.length());
+#if ENABLE(SVG)
+ if ($$.id == 0)
+ $$.id = SVG::getSVGCSSValueID(str.lower().latin1(), str.length());
+#endif
+ $$.unit = CSSPrimitiveValue::CSS_IDENT;
+ $$.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 }
+ | URI maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_URI; }
+ | UNICODERANGE maybe_space { $$.id = 0; $$.iValue = 0; $$.unit = CSSPrimitiveValue::CSS_UNKNOWN;/* ### */ }
+ | hexcolor { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_RGBCOLOR; }
+ | '#' maybe_space { $$.id = 0; $$.string = ParseString(); $$.unit = CSSPrimitiveValue::CSS_RGBCOLOR; } /* 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 */
+ | function {
+ $$ = $1;
+ }
+ ;
+
+unary_term:
+ INTEGER maybe_space { $$.id = 0; $$.isInt = true; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_NUMBER; }
+ | FLOATTOKEN maybe_space { $$.id = 0; $$.isInt = false; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_NUMBER; }
+ | PERCENTAGE maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PERCENTAGE; }
+ | PXS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PX; }
+ | CMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_CM; }
+ | MMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_MM; }
+ | INS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_IN; }
+ | PTS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PT; }
+ | PCS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PC; }
+ | 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; }
+ | 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; }
+ | KHERZ maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_KHZ; }
+ | EMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_EMS; }
+ | QEMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = Value::Q_EMS; }
+ | EXS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_EXS; }
+ ;
+
+
+function:
+ FUNCTION maybe_space expr ')' maybe_space {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ Function* f = p->createFloatingFunction();
+ f->name = $1;
+ f->args = p->sinkFloatingValueList($3);
+ $$.id = 0;
+ $$.unit = Value::Function;
+ $$.function = f;
+ } |
+ FUNCTION maybe_space error {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ Function* f = p->createFloatingFunction();
+ f->name = $1;
+ f->args = 0;
+ $$.id = 0;
+ $$.unit = Value::Function;
+ $$.function = f;
+ }
+ ;
+/*
+ * There is a constraint on the color that it must
+ * have either 3 or 6 hex-digits (i.e., [0-9a-fA-F])
+ * after the "#"; e.g., "#000" is OK, but "#abcd" is not.
+ */
+hexcolor:
+ HEX maybe_space { $$ = $1; }
+ | IDSEL maybe_space { $$ = $1; }
+ ;
+
+
+/* error handling rules */
+
+invalid_at:
+ '@' error invalid_block {
+ $$ = 0;
+ }
+ | '@' error ';' {
+ $$ = 0;
+ }
+ ;
+
+invalid_import:
+ import {
+ $$ = 0;
+ }
+ ;
+
+invalid_rule:
+ error invalid_block {
+ $$ = 0;
+ }
+/*
+ Seems like the two rules below are trying too much and violating
+ http://www.hixie.ch/tests/evil/mixed/csserrorhandling.html
+
+ | error ';' {
+ $$ = 0;
+ }
+ | error '}' {
+ $$ = 0;
+ }
+*/
+ ;
+
+invalid_block:
+ '{' error invalid_block_list error '}'
+ | '{' error '}'
+ ;
+
+invalid_block_list:
+ invalid_block
+ | invalid_block_list error invalid_block
+;
+
+%%