css: Create and use a tree for css selector matching
This commit is contained in:
parent
daefb12a23
commit
1bfa6593c8
@ -1011,6 +1011,7 @@ struct _GtkCssProviderPrivate
|
|||||||
GHashTable *keyframes;
|
GHashTable *keyframes;
|
||||||
|
|
||||||
GArray *rulesets;
|
GArray *rulesets;
|
||||||
|
GtkCssSelectorTree *tree;
|
||||||
GResource *resource;
|
GResource *resource;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1506,17 +1507,41 @@ gtk_css_style_provider_lookup (GtkStyleProviderPrivate *provider,
|
|||||||
GtkCssProviderPrivate *priv;
|
GtkCssProviderPrivate *priv;
|
||||||
GtkCssRuleset *ruleset;
|
GtkCssRuleset *ruleset;
|
||||||
guint j;
|
guint j;
|
||||||
|
int i;
|
||||||
|
GPtrArray *tree_rules;
|
||||||
|
|
||||||
css_provider = GTK_CSS_PROVIDER (provider);
|
css_provider = GTK_CSS_PROVIDER (provider);
|
||||||
priv = css_provider->priv;
|
priv = css_provider->priv;
|
||||||
|
|
||||||
if (priv->rulesets->len == 0)
|
tree_rules = _gtk_css_selector_tree_match_all (priv->tree, matcher);
|
||||||
return;
|
|
||||||
|
|
||||||
for (ruleset = &g_array_index (priv->rulesets, GtkCssRuleset, priv->rulesets->len - 1);
|
#ifdef VERIFY_TREE
|
||||||
ruleset >= &g_array_index (priv->rulesets, GtkCssRuleset, 0);
|
for (i = 0; i < priv->rulesets->len; i++)
|
||||||
ruleset--)
|
|
||||||
{
|
{
|
||||||
|
gboolean found = FALSE;
|
||||||
|
|
||||||
|
ruleset = &g_array_index (priv->rulesets, GtkCssRuleset, i);
|
||||||
|
|
||||||
|
for (j = 0; j < tree_rules->len; j++)
|
||||||
|
{
|
||||||
|
if (ruleset == tree_rules->pdata[j])
|
||||||
|
{
|
||||||
|
found = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found)
|
||||||
|
g_assert (gtk_css_ruleset_matches (ruleset, matcher));
|
||||||
|
else
|
||||||
|
g_assert (!gtk_css_ruleset_matches (ruleset, matcher));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (i = tree_rules->len - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
ruleset = tree_rules->pdata[i];
|
||||||
|
|
||||||
if (ruleset->styles == NULL)
|
if (ruleset->styles == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -1524,9 +1549,6 @@ gtk_css_style_provider_lookup (GtkStyleProviderPrivate *provider,
|
|||||||
ruleset->set_styles))
|
ruleset->set_styles))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!gtk_css_ruleset_matches (ruleset, matcher))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (j = 0; j < ruleset->n_styles; j++)
|
for (j = 0; j < ruleset->n_styles; j++)
|
||||||
{
|
{
|
||||||
GtkCssStyleProperty *prop = ruleset->styles[j].property;
|
GtkCssStyleProperty *prop = ruleset->styles[j].property;
|
||||||
@ -1544,6 +1566,8 @@ gtk_css_style_provider_lookup (GtkStyleProviderPrivate *provider,
|
|||||||
if (_gtk_bitmask_is_empty (_gtk_css_lookup_get_missing (lookup)))
|
if (_gtk_bitmask_is_empty (_gtk_css_lookup_get_missing (lookup)))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_ptr_array_free (tree_rules, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GtkCssChange
|
static GtkCssChange
|
||||||
@ -1553,26 +1577,28 @@ gtk_css_style_provider_get_change (GtkStyleProviderPrivate *provider,
|
|||||||
GtkCssProvider *css_provider;
|
GtkCssProvider *css_provider;
|
||||||
GtkCssProviderPrivate *priv;
|
GtkCssProviderPrivate *priv;
|
||||||
GtkCssChange change = 0;
|
GtkCssChange change = 0;
|
||||||
|
GPtrArray *tree_rules;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
css_provider = GTK_CSS_PROVIDER (provider);
|
css_provider = GTK_CSS_PROVIDER (provider);
|
||||||
priv = css_provider->priv;
|
priv = css_provider->priv;
|
||||||
|
|
||||||
for (i = priv->rulesets->len - 1; i >= 0; i--)
|
tree_rules = _gtk_css_selector_tree_match_all (priv->tree, matcher);
|
||||||
|
|
||||||
|
for (i = tree_rules->len - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
GtkCssRuleset *ruleset;
|
GtkCssRuleset *ruleset;
|
||||||
|
|
||||||
ruleset = &g_array_index (priv->rulesets, GtkCssRuleset, i);
|
ruleset = tree_rules->pdata[i];
|
||||||
|
|
||||||
if (ruleset->styles == NULL)
|
if (ruleset->styles == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!gtk_css_ruleset_matches (ruleset, matcher))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
change |= gtk_css_ruleset_get_change (ruleset);
|
change |= gtk_css_ruleset_get_change (ruleset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_ptr_array_free (tree_rules, TRUE);
|
||||||
|
|
||||||
return change;
|
return change;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1599,6 +1625,7 @@ gtk_css_provider_finalize (GObject *object)
|
|||||||
gtk_css_ruleset_clear (&g_array_index (priv->rulesets, GtkCssRuleset, i));
|
gtk_css_ruleset_clear (&g_array_index (priv->rulesets, GtkCssRuleset, i));
|
||||||
|
|
||||||
g_array_free (priv->rulesets, TRUE);
|
g_array_free (priv->rulesets, TRUE);
|
||||||
|
_gtk_css_selector_tree_free (priv->tree);
|
||||||
|
|
||||||
g_hash_table_destroy (priv->symbolic_colors);
|
g_hash_table_destroy (priv->symbolic_colors);
|
||||||
g_hash_table_destroy (priv->keyframes);
|
g_hash_table_destroy (priv->keyframes);
|
||||||
@ -1736,6 +1763,9 @@ gtk_css_provider_reset (GtkCssProvider *css_provider)
|
|||||||
for (i = 0; i < priv->rulesets->len; i++)
|
for (i = 0; i < priv->rulesets->len; i++)
|
||||||
gtk_css_ruleset_clear (&g_array_index (priv->rulesets, GtkCssRuleset, i));
|
gtk_css_ruleset_clear (&g_array_index (priv->rulesets, GtkCssRuleset, i));
|
||||||
g_array_set_size (priv->rulesets, 0);
|
g_array_set_size (priv->rulesets, 0);
|
||||||
|
_gtk_css_selector_tree_free (priv->tree);
|
||||||
|
priv->tree = NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -2370,8 +2400,25 @@ static void
|
|||||||
gtk_css_provider_postprocess (GtkCssProvider *css_provider)
|
gtk_css_provider_postprocess (GtkCssProvider *css_provider)
|
||||||
{
|
{
|
||||||
GtkCssProviderPrivate *priv = css_provider->priv;
|
GtkCssProviderPrivate *priv = css_provider->priv;
|
||||||
|
GtkCssSelectorTreeBuilder *builder;
|
||||||
|
guint i;
|
||||||
|
|
||||||
g_array_sort (priv->rulesets, gtk_css_provider_compare_rule);
|
g_array_sort (priv->rulesets, gtk_css_provider_compare_rule);
|
||||||
|
|
||||||
|
builder = _gtk_css_selector_tree_builder_new ();
|
||||||
|
for (i = 0; i < priv->rulesets->len; i++)
|
||||||
|
{
|
||||||
|
GtkCssRuleset *ruleset;
|
||||||
|
|
||||||
|
ruleset = &g_array_index (priv->rulesets, GtkCssRuleset, i);
|
||||||
|
|
||||||
|
_gtk_css_selector_tree_builder_add (builder,
|
||||||
|
ruleset->selector,
|
||||||
|
ruleset);
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->tree = _gtk_css_selector_tree_builder_build (builder);
|
||||||
|
_gtk_css_selector_tree_builder_free (builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
Loading…
Reference in New Issue
Block a user