CSSRuleList* ruleList;
CSSSelector* selector;
Vector<CSSSelector*>* selectorList;
+ CSSSelector::MarginBoxType marginBox;
CSSSelector::Relation relation;
MediaList* mediaList;
MediaQuery* mediaQuery;
%}
-%expect 48
+%expect 55
%nonassoc LOWEST_PREC
%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
%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 <string> ident_or_string
%type <string> medium
%type <string> hexcolor
+%type <marginBox> margin_sym
%type <string> media_feature
%type <mediaList> media_list
%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
;
rule:
- valid_rule
+ valid_rule {
+ static_cast<CSSParser*>(parser)->m_hadSyntacticallyValidCSSRule = true;
+ }
| invalid_rule
| invalid_at
;
}
;
-/*
-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 {
| '>' maybe_space { $$ = CSSSelector::Child; }
;
+maybe_unary_operator:
+ unary_operator { $$ = $1; }
+ | { $$ = 1; }
+ ;
+
unary_operator:
'-' { $$ = -1; }
| '+' { $$ = 1; }
ruleset:
selector_list '{' maybe_space declaration_list closing_brace {
- $$ = static_cast<CSSParser*>(parser)->createStyleRule($1);
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ $$ = p->createStyleRule($1);
}
;
deleteAllValues(*$$);
$$->shrink(0);
$$->append(p->sinkFloatingSelector($1));
+ p->updateLastSelectorLineAndPosition();
}
}
| selector_list ',' maybe_space selector %prec UNIMPORTANT_TOK {
CSSParser* p = static_cast<CSSParser*>(parser);
$$ = $1;
$$->append(p->sinkFloatingSelector($4));
+ p->updateLastSelectorLineAndPosition();
} else
$$ = 0;
}
| 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();
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 {
}
}
// used by :nth-*(ax+b)
- | ':' FUNCTION NTH ')' {
+ | ':' FUNCTION maybe_space NTH maybe_space ')' {
CSSParser *p = static_cast<CSSParser*>(parser);
$$ = p->createFloatingSelector();
$$->m_match = CSSSelector::PseudoClass;
- $$->setArgument($3);
+ $$->setArgument($4);
$$->m_value = $2;
CSSSelector::PseudoType type = $$->pseudoType();
if (type == CSSSelector::PseudoUnknown)
}
}
// used by :nth-*
- | ':' FUNCTION INTEGER ')' {
+ | ':' FUNCTION maybe_space maybe_unary_operator INTEGER maybe_space ')' {
CSSParser *p = static_cast<CSSParser*>(parser);
$$ = p->createFloatingSelector();
$$->m_match = CSSSelector::PseudoClass;
- $$->setArgument(String::number($3));
+ $$->setArgument(String::number($4 * $5));
$$->m_value = $2;
CSSSelector::PseudoType type = $$->pseudoType();
if (type == CSSSelector::PseudoUnknown)
}
}
// used by :nth-*(odd/even) and :lang
- | ':' FUNCTION IDENT ')' {
+ | ':' FUNCTION maybe_space IDENT maybe_space ')' {
CSSParser *p = static_cast<CSSParser*>(parser);
$$ = p->createFloatingSelector();
$$->m_match = CSSSelector::PseudoClass;
- $$->setArgument($3);
+ $$->setArgument($4);
$2.lower();
$$->m_value = $2;
CSSSelector::PseudoType type = $$->pseudoType();
}
// used by :not
| ':' NOTFUNCTION maybe_space simple_selector maybe_space ')' {
- if (!$4 || $4->simpleSelector() || $4->tagHistory())
+ if (!$4 || !$4->isSimple())
$$ = 0;
else {
CSSParser* p = static_cast<CSSParser*>(parser);
declaration ';' maybe_space {
$$ = $1;
}
+ | declaration invalid_block_list maybe_space {
+ $$ = false;
+ }
| declaration invalid_block_list ';' maybe_space {
$$ = false;
}
$$->addValue(p->sinkFloatingValue($3));
}
}
+ | expr invalid_block_list {
+ $$ = 0;
+ }
+ | expr invalid_block_list error {
+ $$ = 0;
+ }
| expr error {
$$ = 0;
}
;
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: