css: No more special code for regions

Just treat regions the same as elements.
This commit is contained in:
Benjamin Otte 2011-05-14 23:54:37 +02:00
parent fc88b0f47c
commit e875c619ef
2 changed files with 122 additions and 117 deletions

View File

@ -1615,50 +1615,6 @@ parse_at_keyword (GtkCssScanner *scanner)
} }
} }
static gboolean
parse_selector_pseudo_class (GtkCssScanner *scanner,
GtkStateFlags *flags_to_modify)
{
struct {
const char *name;
GtkStateFlags flag;
} classes[] = {
{ "active", GTK_STATE_FLAG_ACTIVE },
{ "prelight", GTK_STATE_FLAG_PRELIGHT },
{ "hover", GTK_STATE_FLAG_PRELIGHT },
{ "selected", GTK_STATE_FLAG_SELECTED },
{ "insensitive", GTK_STATE_FLAG_INSENSITIVE },
{ "inconsistent", GTK_STATE_FLAG_INCONSISTENT },
{ "focused", GTK_STATE_FLAG_FOCUSED },
{ "focus", GTK_STATE_FLAG_FOCUSED }
};
guint i;
for (i = 0; i < G_N_ELEMENTS (classes); i++)
{
if (_gtk_css_parser_try (scanner->parser, classes[i].name, FALSE))
{
if (*flags_to_modify & classes[i].flag)
{
gtk_css_provider_error (scanner->provider,
scanner,
GTK_CSS_PROVIDER_ERROR,
GTK_CSS_PROVIDER_ERROR_SYNTAX,
"Duplicate pseudo-class %s in selector", classes[i].name);
}
*flags_to_modify |= classes[i].flag;
return TRUE;
}
}
gtk_css_provider_error_literal (scanner->provider,
scanner,
GTK_CSS_PROVIDER_ERROR,
GTK_CSS_PROVIDER_ERROR_SYNTAX,
"Expected a valid state name");
return FALSE;
}
static gboolean static gboolean
parse_selector_class (GtkCssScanner *scanner, GArray *classes) parse_selector_class (GtkCssScanner *scanner, GArray *classes)
{ {
@ -1708,67 +1664,134 @@ parse_selector_name (GtkCssScanner *scanner, GArray *names)
} }
static gboolean static gboolean
parse_selector_pseudo_class_for_region (GtkCssScanner *scanner, parse_selector_pseudo_class (GtkCssScanner *scanner,
GtkRegionFlags *flags_to_modify, GtkRegionFlags *region_to_modify,
GtkStateFlags *state_to_modify) GtkStateFlags *state_to_modify)
{ {
struct { struct {
const char *name; const char *name;
GtkRegionFlags flag; GtkRegionFlags region_flag;
} classes[] = { GtkStateFlags state_flag;
{ "first", GTK_REGION_FIRST }, } pseudo_classes[] = {
{ "last", GTK_REGION_LAST }, { "first", GTK_REGION_FIRST, 0 },
{ "sorted", GTK_REGION_SORTED } { "last", GTK_REGION_LAST, 0 },
}, nth_child[] = { { "sorted", GTK_REGION_SORTED, 0 },
{ "first", GTK_REGION_FIRST }, { "active", 0, GTK_STATE_FLAG_ACTIVE },
{ "last", GTK_REGION_LAST }, { "prelight", 0, GTK_STATE_FLAG_PRELIGHT },
{ "even", GTK_REGION_EVEN }, { "hover", 0, GTK_STATE_FLAG_PRELIGHT },
{ "odd", GTK_REGION_ODD } { "selected", 0, GTK_STATE_FLAG_SELECTED },
}; { "insensitive", 0, GTK_STATE_FLAG_INSENSITIVE },
{ "inconsistent", 0, GTK_STATE_FLAG_INCONSISTENT },
{ "focused", 0, GTK_STATE_FLAG_FOCUSED },
{ "focus", 0, GTK_STATE_FLAG_FOCUSED },
{ NULL, }
}, nth_child_classes[] = {
{ "first", GTK_REGION_FIRST, 0 },
{ "last", GTK_REGION_LAST, 0 },
{ "even", GTK_REGION_EVEN, 0 },
{ "odd", GTK_REGION_ODD, 0 },
{ NULL, }
}, *classes;
guint i; guint i;
char *name;
for (i = 0; i < G_N_ELEMENTS (classes); i++) name = _gtk_css_parser_try_ident (scanner->parser, FALSE);
if (name == NULL)
{ {
if (_gtk_css_parser_try (scanner->parser, classes[i].name, FALSE)) gtk_css_provider_error_literal (scanner->provider,
scanner,
GTK_CSS_PROVIDER_ERROR,
GTK_CSS_PROVIDER_ERROR_SYNTAX,
"Missing name of pseudo-class");
return FALSE;
}
if (_gtk_css_parser_try (scanner->parser, "(", TRUE))
{
char *function = name;
name = _gtk_css_parser_try_ident (scanner->parser, TRUE);
if (!_gtk_css_parser_try (scanner->parser, ")", FALSE))
{ {
*flags_to_modify |=classes[i].flag; gtk_css_provider_error_literal (scanner->provider,
scanner,
GTK_CSS_PROVIDER_ERROR,
GTK_CSS_PROVIDER_ERROR_SYNTAX,
"Missing closing bracket for pseudo-class");
return FALSE;
}
if (g_ascii_strcasecmp (function, "nth-child") != 0)
{
gtk_css_provider_error (scanner->provider,
scanner,
GTK_CSS_PROVIDER_ERROR,
GTK_CSS_PROVIDER_ERROR_UNKNOWN_VALUE,
"Unknown pseudo-class '%s(%s)'", function, name ? name : "");
g_free (function);
g_free (name);
return FALSE;
}
g_free (function);
if (name == NULL)
{
gtk_css_provider_error (scanner->provider,
scanner,
GTK_CSS_PROVIDER_ERROR,
GTK_CSS_PROVIDER_ERROR_UNKNOWN_VALUE,
"nth-child() requires an argument");
return FALSE;
}
classes = nth_child_classes;
}
else
classes = pseudo_classes;
for (i = 0; classes[i].name != NULL; i++)
{
if (g_ascii_strcasecmp (name, classes[i].name) == 0)
{
if ((*region_to_modify & classes[i].region_flag) ||
(*state_to_modify & classes[i].state_flag))
{
if (classes == nth_child_classes)
gtk_css_provider_error (scanner->provider,
scanner,
GTK_CSS_PROVIDER_ERROR,
GTK_CSS_PROVIDER_ERROR_SYNTAX,
"Duplicate pseudo-class 'nth-child(%s)'", name);
else
gtk_css_provider_error (scanner->provider,
scanner,
GTK_CSS_PROVIDER_ERROR,
GTK_CSS_PROVIDER_ERROR_SYNTAX,
"Duplicate pseudo-class '%s'", name);
}
*region_to_modify |= classes[i].region_flag;
*state_to_modify |= classes[i].state_flag;
g_free (name);
return TRUE; return TRUE;
} }
} }
if (!_gtk_css_parser_try (scanner->parser, "nth-child(", TRUE)) if (classes == nth_child_classes)
return parse_selector_pseudo_class (scanner, state_to_modify); gtk_css_provider_error (scanner->provider,
scanner,
for (i = 0; i < G_N_ELEMENTS (nth_child); i++) GTK_CSS_PROVIDER_ERROR,
{ GTK_CSS_PROVIDER_ERROR_UNKNOWN_VALUE,
if (_gtk_css_parser_try (scanner->parser, nth_child[i].name, TRUE)) "Unknown pseudo-class 'nth-child(%s)'", name);
{ else
*flags_to_modify |= nth_child[i].flag; gtk_css_provider_error (scanner->provider,
break; scanner,
} GTK_CSS_PROVIDER_ERROR,
} GTK_CSS_PROVIDER_ERROR_UNKNOWN_VALUE,
"Unknown pseudo-class '%s'", name);
if (i == G_N_ELEMENTS (nth_child)) g_free (name);
{ return FALSE;
gtk_css_provider_error_literal (scanner->provider,
scanner,
GTK_CSS_PROVIDER_ERROR,
GTK_CSS_PROVIDER_ERROR_SYNTAX,
"Not a valid value for nth-child");
return FALSE;
}
if (!_gtk_css_parser_try (scanner->parser, ")", FALSE))
{
gtk_css_provider_error_literal (scanner->provider,
scanner,
GTK_CSS_PROVIDER_ERROR,
GTK_CSS_PROVIDER_ERROR_SYNTAX,
"Missing closing bracket");
return FALSE;
}
return TRUE;
} }
static gboolean static gboolean
@ -1783,28 +1806,9 @@ parse_simple_selector (GtkCssScanner *scanner,
*name = _gtk_css_parser_try_ident (scanner->parser, FALSE); *name = _gtk_css_parser_try_ident (scanner->parser, FALSE);
if (*name) if (*name)
{ parsed_something = TRUE;
if (_gtk_style_context_check_region_name (*name))
{
while (_gtk_css_parser_try (scanner->parser, ":", FALSE))
{
if (!parse_selector_pseudo_class_for_region (scanner, pseudo_classes, state))
{
g_free (name);
return FALSE;
}
}
_gtk_css_parser_skip_whitespace (scanner->parser);
return TRUE;
}
parsed_something = TRUE;
}
else else
{ parsed_something = _gtk_css_parser_try (scanner->parser, "*", FALSE);
parsed_something = _gtk_css_parser_try (scanner->parser, "*", FALSE);
}
do { do {
if (_gtk_css_parser_try (scanner->parser, "#", FALSE)) if (_gtk_css_parser_try (scanner->parser, "#", FALSE))
@ -1819,7 +1823,7 @@ parse_simple_selector (GtkCssScanner *scanner,
} }
else if (_gtk_css_parser_try (scanner->parser, ":", FALSE)) else if (_gtk_css_parser_try (scanner->parser, ":", FALSE))
{ {
if (!parse_selector_pseudo_class (scanner, state)) if (!parse_selector_pseudo_class (scanner, pseudo_classes, state))
return FALSE; return FALSE;
} }
else if (!parsed_something) else if (!parsed_something)

View File

@ -39,7 +39,8 @@ typedef enum
GTK_CSS_PROVIDER_ERROR_SYNTAX, GTK_CSS_PROVIDER_ERROR_SYNTAX,
GTK_CSS_PROVIDER_ERROR_IMPORT, GTK_CSS_PROVIDER_ERROR_IMPORT,
GTK_CSS_PROVIDER_ERROR_NAME, GTK_CSS_PROVIDER_ERROR_NAME,
GTK_CSS_PROVIDER_ERROR_DEPRECATED GTK_CSS_PROVIDER_ERROR_DEPRECATED,
GTK_CSS_PROVIDER_ERROR_UNKNOWN_VALUE,
} GtkCssProviderError; } GtkCssProviderError;
GQuark gtk_css_provider_error_quark (void); GQuark gtk_css_provider_error_quark (void);