cssselector: Reintroduce GOT_MATCH

I removed it in 14f5ce7108 because I
thought it was unnecessary, but it wasn't. When we build a tree like
this:

.matches ─┬─ .doesntmatch
          └─ .alsodoesntmatch

We would get the changes for the .matches part returned. This is however
only right if that node of the tree contains results. If results only
exist with the child nodes (all of which don't match), then this part
should not match either.
This commit is contained in:
Benjamin Otte 2015-01-05 21:15:19 +01:00
parent 506639add1
commit 78223932c5

View File

@ -1754,6 +1754,17 @@ _gtk_css_selector_tree_match_all (const GtkCssSelectorTree *tree,
return array; return array;
} }
/* When checking for changes via the tree we need to know if a rule further
down the tree matched, because if so we need to add "our bit" to the
Change. For instance in a a match like *.class:active we'll
get a tree that first checks :active, if that matches we continue down
to the tree, and if we get a match we add CHANGE_CLASS. However, the
end of the tree where we have a match is an ANY which doesn't actually
modify the change, so we don't know if we have a match or not. We fix
this by setting GTK_CSS_CHANGE_GOT_MATCH which lets us guarantee
that change != 0 on any match. */
#define GTK_CSS_CHANGE_GOT_MATCH GTK_CSS_CHANGE_RESERVED_BIT
static GtkCssChange static GtkCssChange
gtk_css_selector_tree_collect_change (const GtkCssSelectorTree *tree) gtk_css_selector_tree_collect_change (const GtkCssSelectorTree *tree)
{ {
@ -1781,14 +1792,15 @@ gtk_css_selector_tree_get_change (const GtkCssSelectorTree *tree,
return 0; return 0;
if (!tree->selector.class->is_simple) if (!tree->selector.class->is_simple)
return gtk_css_selector_tree_collect_change (tree); return gtk_css_selector_tree_collect_change (tree) | GTK_CSS_CHANGE_GOT_MATCH;
for (prev = gtk_css_selector_tree_get_previous (tree); for (prev = gtk_css_selector_tree_get_previous (tree);
prev != NULL; prev != NULL;
prev = gtk_css_selector_tree_get_sibling (prev)) prev = gtk_css_selector_tree_get_sibling (prev))
change |= gtk_css_selector_tree_get_change (prev, matcher); change |= gtk_css_selector_tree_get_change (prev, matcher);
change = tree->selector.class->get_change (&tree->selector, change); if (change || gtk_css_selector_tree_get_matches (tree))
change = tree->selector.class->get_change (&tree->selector, change & ~GTK_CSS_CHANGE_GOT_MATCH) | GTK_CSS_CHANGE_GOT_MATCH;
return change; return change;
} }
@ -1807,7 +1819,7 @@ _gtk_css_selector_tree_get_change_all (const GtkCssSelectorTree *tree,
change |= gtk_css_selector_tree_get_change (tree, matcher); change |= gtk_css_selector_tree_get_change (tree, matcher);
/* Never return reserved bit set */ /* Never return reserved bit set */
return change; return change & ~GTK_CSS_CHANGE_RESERVED_BIT;
} }
#ifdef PRINT_TREE #ifdef PRINT_TREE