diff options
-rw-r--r-- | include/libcss/select.h | 21 | ||||
-rw-r--r-- | src/select/select.c | 9 | ||||
-rw-r--r-- | test/data/select/tests1.dat | 18 | ||||
-rw-r--r-- | test/select-auto.c | 20 |
4 files changed, 48 insertions, 20 deletions
diff --git a/include/libcss/select.h b/include/libcss/select.h index fa9a7c2..cb12b76 100644 --- a/include/libcss/select.h +++ b/include/libcss/select.h @@ -13,16 +13,15 @@ #include <libcss/types.h> enum css_pseudo_class { - CSS_PSEUDO_CLASS_FIRST_CHILD = (1<<0), - CSS_PSEUDO_CLASS_LINK = (1<<1), - CSS_PSEUDO_CLASS_VISITED = (1<<2), - CSS_PSEUDO_CLASS_HOVER = (1<<3), - CSS_PSEUDO_CLASS_ACTIVE = (1<<4), - CSS_PSEUDO_CLASS_FOCUS = (1<<5), - /** \todo CSS_PSEUDO_CLASS_LANG = (1<<6), */ - CSS_PSEUDO_CLASS_LEFT = (1<<7), - CSS_PSEUDO_CLASS_RIGHT = (1<<8), - CSS_PSEUDO_CLASS_FIRST = (1<<9) + CSS_PSEUDO_CLASS_LINK = (1<<0), + CSS_PSEUDO_CLASS_VISITED = (1<<1), + CSS_PSEUDO_CLASS_HOVER = (1<<2), + CSS_PSEUDO_CLASS_ACTIVE = (1<<3), + CSS_PSEUDO_CLASS_FOCUS = (1<<4), + /** \todo CSS_PSEUDO_CLASS_LANG = (1<<5), */ + CSS_PSEUDO_CLASS_LEFT = (1<<6), + CSS_PSEUDO_CLASS_RIGHT = (1<<7), + CSS_PSEUDO_CLASS_FIRST = (1<<8) }; enum css_pseudo_element { @@ -70,6 +69,8 @@ typedef struct css_select_handler { const uint8_t *name, size_t nlen, const uint8_t *value, size_t vlen, bool *match); + + css_error (*node_is_first_child)(void *pw, void *node, bool *match); } css_select_handler; css_error css_select_ctx_create(css_alloc alloc, void *pw, diff --git a/src/select/select.c b/src/select/select.c index 2057e04..542f82d 100644 --- a/src/select/select.c +++ b/src/select/select.c @@ -925,11 +925,10 @@ css_error match_detail(css_select_ctx *ctx, void *node, match); break; case CSS_SELECTOR_PSEUDO_CLASS: - if (detail->name == state->first_child && - (state->pseudo_classes & - CSS_PSEUDO_CLASS_FIRST_CHILD)) - *match = true; - else if (detail->name == state->link && + if (detail->name == state->first_child) { + error = state->handler->node_is_first_child(state->pw, + node, match); + } else if (detail->name == state->link && (state->pseudo_classes & CSS_PSEUDO_CLASS_LINK)) *match = true; diff --git a/test/data/select/tests1.dat b/test/data/select/tests1.dat index 5b415f3..dc9f3c7 100644 --- a/test/data/select/tests1.dat +++ b/test/data/select/tests1.dat @@ -64,3 +64,21 @@ border-left-color: #00000000 display: inline #reset +#tree +| div +| p* +#author +p:first-child { background-color: #bbc; } +#errors +#expected +background-attachment: scroll +background-color: #bbbbcc00 +background-image: none +background-position: 0% 0% +background-repeat: repeat +border-top-color: #00000000 +border-right-color: #00000000 +border-bottom-color: #00000000 +border-left-color: #00000000 +display: inline +#reset diff --git a/test/select-auto.c b/test/select-auto.c index 19af180..f07b5c9 100644 --- a/test/select-auto.c +++ b/test/select-auto.c @@ -101,6 +101,7 @@ static css_error node_has_attribute_includes(void *pw, void *node, const uint8_t *name, size_t nlen, const uint8_t *value, size_t vlen, bool *match); +static css_error node_is_first_child(void *pw, void *node, bool *match); static css_select_handler select_handler = { node_name, @@ -114,7 +115,8 @@ static css_select_handler select_handler = { node_has_attribute, node_has_attribute_equal, node_has_attribute_dashmatch, - node_has_attribute_includes + node_has_attribute_includes, + node_is_first_child }; static void *myrealloc(void *data, size_t len, void *pw) @@ -357,6 +359,7 @@ void parse_tree_data(line_ctx *ctx, const char *data, size_t len) ctx->current->last_child = n; } + n->parent = ctx->current; } ctx->current = n; @@ -532,10 +535,7 @@ void parse_pseudo_list(const char **data, size_t *len, uint64_t *elements, p++; /* Pseudo classes */ - if (p - start == 11 && - strncasecmp(start, "first-child", 11) == 0) - *classes |= CSS_PSEUDO_CLASS_FIRST_CHILD; - else if (p - start == 7 && + if (p - start == 7 && strncasecmp(start, "visited", 7) == 0) *classes |= CSS_PSEUDO_CLASS_VISITED; else if (p - start == 6 && @@ -958,3 +958,13 @@ css_error node_has_attribute_includes(void *pw, void *n, return CSS_OK; } +css_error node_is_first_child(void *pw, void *n, bool *match) +{ + node *node = n; + + UNUSED(pw); + + *match = (node->parent != NULL && node->parent->children == node); + + return CSS_OK; +} |