mirror of
https://github.com/lexborisov/Modest
synced 2024-11-22 05:41:32 +03:00
Merge pull request #42 from f34nk/support-for-pseudo-class-contains
New CSS selector ":contains(text)"
This commit is contained in:
commit
87d75c9585
@ -43,6 +43,7 @@ bool modest_finder_selector_sub_type_pseudo_class_function_nth_last_child(modest
|
||||
bool modest_finder_selector_sub_type_pseudo_class_function_nth_last_column(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector, mycss_selectors_specificity_t* spec);
|
||||
bool modest_finder_selector_sub_type_pseudo_class_function_nth_last_of_type(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector, mycss_selectors_specificity_t* spec);
|
||||
bool modest_finder_selector_sub_type_pseudo_class_function_nth_of_type(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector, mycss_selectors_specificity_t* spec);
|
||||
bool modest_finder_selector_sub_type_pseudo_class_function_contains(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector, mycss_selectors_specificity_t* spec);
|
||||
|
||||
/* classes */
|
||||
bool modest_finder_selector_sub_type_pseudo_class_undef(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector, mycss_selectors_specificity_t* spec);
|
||||
|
@ -41,6 +41,7 @@ static const modest_finder_selector_type_f modest_finder_static_selector_sub_typ
|
||||
{
|
||||
modest_finder_selector_sub_type_pseudo_class_function_undef, /* UNDEF */
|
||||
modest_finder_selector_sub_type_pseudo_class_function_undef, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_UNKNOWN */
|
||||
modest_finder_selector_sub_type_pseudo_class_function_contains, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_CONTAINS */
|
||||
modest_finder_selector_sub_type_pseudo_class_function_current, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_CURRENT */
|
||||
modest_finder_selector_sub_type_pseudo_class_function_dir, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_DIR */
|
||||
modest_finder_selector_sub_type_pseudo_class_function_drop, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_DROP */
|
||||
@ -54,7 +55,6 @@ static const modest_finder_selector_type_f modest_finder_static_selector_sub_typ
|
||||
modest_finder_selector_sub_type_pseudo_class_function_nth_last_column, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_LAST_COLUMN */
|
||||
modest_finder_selector_sub_type_pseudo_class_function_nth_last_of_type, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_LAST_OF_TYPE */
|
||||
modest_finder_selector_sub_type_pseudo_class_function_nth_of_type /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_OF_TYPE */
|
||||
|
||||
};
|
||||
|
||||
/* see enum mycss_selectors_sub_type (mycss_selectors_sub_type_t) on mycss/selectors/myosi.h */
|
||||
|
@ -65,6 +65,7 @@ void mycss_selectors_function_begin_nth_last_child(mycss_entry_t* entry, mycss_s
|
||||
void mycss_selectors_function_begin_nth_last_of_type(mycss_entry_t* entry, mycss_selectors_entry_t* selector);
|
||||
void mycss_selectors_function_begin_has(mycss_entry_t* entry, mycss_selectors_entry_t* selector);
|
||||
void mycss_selectors_function_begin_nth_column(mycss_entry_t* entry, mycss_selectors_entry_t* selector);
|
||||
void mycss_selectors_function_begin_contains(mycss_entry_t* entry, mycss_selectors_entry_t* selector);
|
||||
|
||||
void mycss_selectors_begin_unknown(mycss_entry_t* entry, mycss_selectors_entry_t* selector);
|
||||
|
||||
|
@ -38,6 +38,8 @@ bool mycss_selectors_unknown_parser(mycss_entry_t* entry, mycss_token_t* token,
|
||||
bool mycss_selectors_function_parser_not_or_matches_or_current_parser(mycss_entry_t* entry, mycss_token_t* token, bool last_response);
|
||||
bool mycss_selectors_function_parser_has(mycss_entry_t* entry, mycss_token_t* token, bool last_response);
|
||||
|
||||
bool mycss_selectors_function_parser_contains(mycss_entry_t* entry, mycss_token_t* token, bool last_response);
|
||||
|
||||
bool mycss_selectors_function_parser_nth_with_selectors(mycss_entry_t* entry, mycss_token_t* token, bool last_response);
|
||||
bool mycss_selectors_function_parser_nth_with_selectors_need_of(mycss_entry_t* entry, mycss_token_t* token, bool last_response);
|
||||
bool mycss_selectors_function_parser_nth_with_selectors_need_of_after(mycss_entry_t* entry, mycss_token_t* token, bool last_response);
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
#define MyCSS_SELECTORS_FUNCTION_NAME_STATIC_SIZE 57
|
||||
|
||||
static const mycss_selectots_function_begin_entry_t mycss_selectors_function_begin_map_index[] =
|
||||
static const mycss_selectots_function_begin_entry_t mycss_selectors_function_begin_map_index[] =
|
||||
{
|
||||
{NULL, 0, NULL, 0, 0},
|
||||
{"dir", 3, mycss_selectors_function_begin_dir, 0, 1},
|
||||
@ -78,7 +78,7 @@ static const mycss_selectots_function_begin_entry_t mycss_selectors_function_beg
|
||||
{"nth-child", 9, mycss_selectors_function_begin_nth_child, 0, 49},
|
||||
{NULL, 0, NULL, 0, 0},
|
||||
{NULL, 0, NULL, 0, 0},
|
||||
{NULL, 0, NULL, 0, 0},
|
||||
{"contains", 8, mycss_selectors_function_begin_contains, 0, 52},
|
||||
{NULL, 0, NULL, 0, 0},
|
||||
{NULL, 0, NULL, 0, 0},
|
||||
{NULL, 0, NULL, 0, 0},
|
||||
|
@ -99,20 +99,21 @@ typedef mycss_selectors_sub_type_t;
|
||||
enum mycss_selectors_sub_type_pseudo_class_function {
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_UNDEF = 0x00,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_UNKNOWN = 0x01,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_CURRENT = 0x02,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_DIR = 0x03,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_DROP = 0x04,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_HAS = 0x05,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_LANG = 0x06,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_MATCHES = 0x07,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NOT = 0x08,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_CHILD = 0x09,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_COLUMN = 0x0a,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_LAST_CHILD = 0x0b,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_LAST_COLUMN = 0x0c,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_LAST_OF_TYPE = 0x0d,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_OF_TYPE = 0x0e,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_LAST_ENTRY = 0x0f
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_CONTAINS = 0x02,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_CURRENT = 0x03,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_DIR = 0x04,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_DROP = 0x05,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_HAS = 0x06,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_LANG = 0x07,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_MATCHES = 0x08,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NOT = 0x09,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_CHILD = 0x0a,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_COLUMN = 0x0b,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_LAST_CHILD = 0x0c,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_LAST_COLUMN = 0x0d,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_LAST_OF_TYPE = 0x0e,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_OF_TYPE = 0x0f,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_LAST_ENTRY = 0x10
|
||||
}
|
||||
typedef mycss_selectors_sub_type_pseudo_class_function_t;
|
||||
|
||||
|
@ -83,6 +83,7 @@ void * mycss_selectors_value_pseudo_class_function_nth_last_child_create(mycss_e
|
||||
void * mycss_selectors_value_pseudo_class_function_nth_last_column_create(mycss_entry_t* entry, bool set_clean);
|
||||
void * mycss_selectors_value_pseudo_class_function_nth_last_of_type_create(mycss_entry_t* entry, bool set_clean);
|
||||
void * mycss_selectors_value_pseudo_class_function_nth_of_type_create(mycss_entry_t* entry, bool set_clean);
|
||||
void * mycss_selectors_value_pseudo_class_function_contains_create(mycss_entry_t* entry, bool set_clean);
|
||||
|
||||
/* pseudo class function destroy */
|
||||
void * mycss_selectors_value_pseudo_class_function_undef_destroy(mycss_entry_t* entry, void* value, bool self_destroy);
|
||||
@ -99,6 +100,7 @@ void * mycss_selectors_value_pseudo_class_function_nth_last_child_destroy(mycss_
|
||||
void * mycss_selectors_value_pseudo_class_function_nth_last_column_destroy(mycss_entry_t* entry, void* value, bool self_destroy);
|
||||
void * mycss_selectors_value_pseudo_class_function_nth_last_of_type_destroy(mycss_entry_t* entry, void* value, bool self_destroy);
|
||||
void * mycss_selectors_value_pseudo_class_function_nth_of_type_destroy(mycss_entry_t* entry, void* value, bool self_destroy);
|
||||
void * mycss_selectors_value_pseudo_class_function_contains_destroy(mycss_entry_t* entry, void* value, bool self_destroy);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -39,6 +39,7 @@ static const mycss_selectors_value_destroy_f mycss_selectors_value_destroy_map[M
|
||||
static const mycss_selectors_value_function_destroy_f mycss_selectors_value_function_destroy_map[MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_LAST_ENTRY] = {
|
||||
mycss_selectors_value_pseudo_class_function_undef_destroy,
|
||||
mycss_selectors_value_pseudo_class_function_undef_destroy,
|
||||
mycss_selectors_value_pseudo_class_function_contains_destroy,
|
||||
mycss_selectors_value_pseudo_class_function_current_destroy,
|
||||
mycss_selectors_value_pseudo_class_function_dir_destroy,
|
||||
mycss_selectors_value_pseudo_class_function_drop_destroy,
|
||||
|
@ -161,7 +161,7 @@ mystatus_t modest_finder_by_selectors_list(modest_finder_t* finder, myhtml_tree_
|
||||
if(status)
|
||||
return MODEST_STATUS_ERROR_MEMORY_ALLOCATION;
|
||||
}
|
||||
|
||||
|
||||
for(size_t i = 0; i < selector_list->entries_list_length; i++) {
|
||||
mycss_selectors_specificity_t spec = selector_list->entries_list[i].specificity;
|
||||
|
||||
@ -179,6 +179,7 @@ myhtml_tree_node_t * modest_finder_node_combinator_begin(modest_finder_t* finder
|
||||
if(selector == NULL)
|
||||
return NULL;
|
||||
|
||||
|
||||
myhtml_tree_node_t *node = base_node;
|
||||
|
||||
while(node) {
|
||||
@ -191,7 +192,7 @@ myhtml_tree_node_t * modest_finder_node_combinator_begin(modest_finder_t* finder
|
||||
}
|
||||
else {
|
||||
myhtml_tree_node_t *find_node = modest_finder_static_selector_combinator_map[selector->next->combinator](finder, node, selector_list, selector->next, spec, callback_found, ctx);
|
||||
|
||||
|
||||
if(find_node == NULL) {
|
||||
while(node != base_node && node->next == NULL)
|
||||
node = node->parent;
|
||||
@ -217,7 +218,7 @@ myhtml_tree_node_t * modest_finder_node_combinator_begin(modest_finder_t* finder
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -77,6 +77,72 @@ bool modest_finder_selector_sub_type_pseudo_class_function_has(modest_finder_t*
|
||||
return false;
|
||||
}
|
||||
|
||||
bool modest_finder_selector_sub_type_pseudo_class_function_contains(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector, mycss_selectors_specificity_t* spec)
|
||||
{
|
||||
if(base_node == NULL)
|
||||
return false;
|
||||
|
||||
myhtml_tree_node_t *text_node = myhtml_node_child(base_node);
|
||||
if(text_node == NULL)
|
||||
return false;
|
||||
|
||||
const char* text = myhtml_node_text(text_node, NULL);
|
||||
if(text == NULL)
|
||||
return false;
|
||||
|
||||
mycss_selectors_list_t *list = (mycss_selectors_list_t*)selector->value;
|
||||
for(size_t i = 0; i < list->entries_list_length; i++) {
|
||||
char *data = NULL;
|
||||
data = mycore_malloc(0);
|
||||
if(data == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mycss_selectors_entry_t *sel_entry = list->entries_list[i].entry;
|
||||
if(sel_entry->key->data){
|
||||
const char *str = sel_entry->key->data;
|
||||
int length = strlen(str) + 1;
|
||||
|
||||
char *new_data = mycore_realloc(data, length);
|
||||
if(new_data == NULL) {
|
||||
mycore_free(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
snprintf(new_data, length, "%s", str);
|
||||
data = new_data;
|
||||
}
|
||||
|
||||
mycss_selectors_entry_t *next = sel_entry->next;
|
||||
while(next) {
|
||||
if(next->key->data) {
|
||||
int prev = strlen(data);
|
||||
const char *whitespace = (prev > 0) ? " " : "";
|
||||
const char *str = next->key->data;
|
||||
int length = strlen(whitespace) + strlen(str) + 1;
|
||||
|
||||
char *new_data = mycore_realloc(data, prev + length);
|
||||
if(new_data == NULL) {
|
||||
mycore_free(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
snprintf(&new_data[prev], length, "%s%s", whitespace, str);
|
||||
data = new_data;
|
||||
}
|
||||
next = next->next;
|
||||
}
|
||||
|
||||
if(strstr(text, data) != NULL) {
|
||||
mycore_free(data);
|
||||
return true;
|
||||
}
|
||||
mycore_free(data);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool modest_finder_selector_sub_type_pseudo_class_function_lang(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector, mycss_selectors_specificity_t* spec)
|
||||
{
|
||||
return false;
|
||||
|
@ -43,6 +43,7 @@ bool modest_finder_selector_sub_type_pseudo_class_function_nth_last_child(modest
|
||||
bool modest_finder_selector_sub_type_pseudo_class_function_nth_last_column(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector, mycss_selectors_specificity_t* spec);
|
||||
bool modest_finder_selector_sub_type_pseudo_class_function_nth_last_of_type(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector, mycss_selectors_specificity_t* spec);
|
||||
bool modest_finder_selector_sub_type_pseudo_class_function_nth_of_type(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector, mycss_selectors_specificity_t* spec);
|
||||
bool modest_finder_selector_sub_type_pseudo_class_function_contains(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector, mycss_selectors_specificity_t* spec);
|
||||
|
||||
/* classes */
|
||||
bool modest_finder_selector_sub_type_pseudo_class_undef(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector, mycss_selectors_specificity_t* spec);
|
||||
|
@ -41,6 +41,7 @@ static const modest_finder_selector_type_f modest_finder_static_selector_sub_typ
|
||||
{
|
||||
modest_finder_selector_sub_type_pseudo_class_function_undef, /* UNDEF */
|
||||
modest_finder_selector_sub_type_pseudo_class_function_undef, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_UNKNOWN */
|
||||
modest_finder_selector_sub_type_pseudo_class_function_contains, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_CONTAINS */
|
||||
modest_finder_selector_sub_type_pseudo_class_function_current, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_CURRENT */
|
||||
modest_finder_selector_sub_type_pseudo_class_function_dir, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_DIR */
|
||||
modest_finder_selector_sub_type_pseudo_class_function_drop, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_DROP */
|
||||
@ -53,7 +54,7 @@ static const modest_finder_selector_type_f modest_finder_static_selector_sub_typ
|
||||
modest_finder_selector_sub_type_pseudo_class_function_nth_last_child, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_LAST_CHILD */
|
||||
modest_finder_selector_sub_type_pseudo_class_function_nth_last_column, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_LAST_COLUMN */
|
||||
modest_finder_selector_sub_type_pseudo_class_function_nth_last_of_type, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_LAST_OF_TYPE */
|
||||
modest_finder_selector_sub_type_pseudo_class_function_nth_of_type /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_OF_TYPE */
|
||||
modest_finder_selector_sub_type_pseudo_class_function_nth_of_type /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_OF_TYPE */
|
||||
|
||||
};
|
||||
|
||||
|
@ -110,6 +110,25 @@ void mycss_selectors_function_begin_has(mycss_entry_t* entry, mycss_selectors_en
|
||||
mycss_entry_parser_list_push(entry, mycss_selectors_function_parser_has, entry->parser_switch, entry->parser_ending_token, false);
|
||||
}
|
||||
|
||||
void mycss_selectors_function_begin_contains(mycss_entry_t* entry, mycss_selectors_entry_t* selector)
|
||||
{
|
||||
selector->sub_type = MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_CONTAINS;
|
||||
|
||||
mycss_selectors_t *selectors = entry->selectors;
|
||||
mycss_selectors_list_t **new_list = (mycss_selectors_list_t**)(&selectors->entry_last->value);
|
||||
mycss_selectors_list_t *current_list = selectors->list_last;
|
||||
|
||||
selectors->list = new_list;
|
||||
selectors->list_last = NULL;
|
||||
selectors->ending_token = entry->parser_ending_token;
|
||||
|
||||
mycss_selectors_state_relative_selector_list(entry, NULL, true);
|
||||
|
||||
(*new_list)->parent = current_list;
|
||||
|
||||
mycss_entry_parser_list_push(entry, mycss_selectors_function_parser_contains, entry->parser_switch, entry->parser_ending_token, false);
|
||||
}
|
||||
|
||||
void mycss_selectors_function_begin_nth_last_child(mycss_entry_t* entry, mycss_selectors_entry_t* selector)
|
||||
{
|
||||
selector->sub_type = MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_LAST_CHILD;
|
||||
|
@ -65,6 +65,7 @@ void mycss_selectors_function_begin_nth_last_child(mycss_entry_t* entry, mycss_s
|
||||
void mycss_selectors_function_begin_nth_last_of_type(mycss_entry_t* entry, mycss_selectors_entry_t* selector);
|
||||
void mycss_selectors_function_begin_has(mycss_entry_t* entry, mycss_selectors_entry_t* selector);
|
||||
void mycss_selectors_function_begin_nth_column(mycss_entry_t* entry, mycss_selectors_entry_t* selector);
|
||||
void mycss_selectors_function_begin_contains(mycss_entry_t* entry, mycss_selectors_entry_t* selector);
|
||||
|
||||
void mycss_selectors_begin_unknown(mycss_entry_t* entry, mycss_selectors_entry_t* selector);
|
||||
|
||||
|
@ -223,6 +223,67 @@ bool mycss_selectors_function_parser_has(mycss_entry_t* entry, mycss_token_t* to
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
////// CONTAINS
|
||||
//////
|
||||
///////////////////////////////////////////////////////////
|
||||
void mycss_selectors_function_parser_contains_find_bad_selector(mycss_selectors_list_t* selectors_list)
|
||||
{
|
||||
for(size_t i = 0; i < selectors_list->entries_list_length; i++) {
|
||||
mycss_selectors_entry_t* selector = selectors_list->entries_list[i].entry;
|
||||
|
||||
while(selector) {
|
||||
if(selector->type == MyCSS_SELECTORS_TYPE_PSEUDO_ELEMENT) {
|
||||
if((selectors_list->flags & MyCSS_SELECTORS_FLAGS_SELECTOR_BAD) == 0)
|
||||
selectors_list->flags |= MyCSS_SELECTORS_FLAGS_SELECTOR_BAD;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
selector = selector->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool mycss_selectors_function_parser_contains(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
|
||||
{
|
||||
mycss_selectors_t *selectors = entry->selectors;
|
||||
mycss_selectors_list_t *selectors_list = selectors->list_last;
|
||||
mycss_selectors_list_t *parent_list = selectors->list_last->parent;
|
||||
|
||||
selectors->entry_last = mycss_selectors_list_last_entry(parent_list);
|
||||
selectors->list_last = parent_list;
|
||||
selectors->specificity = &parent_list->entries_list[ (parent_list->entries_list_length - 1) ].specificity;
|
||||
|
||||
mycss_selectors_function_parser_contains_find_bad_selector(selectors_list);
|
||||
selectors_list = mycss_selectors_parser_check_selector_list(selectors, selectors_list);
|
||||
|
||||
if(selectors_list == NULL) {
|
||||
if(selectors->entry_last) {
|
||||
selectors->entry_last->value = NULL;
|
||||
selectors->entry_last->flags |= MyCSS_SELECTORS_FLAGS_SELECTOR_BAD;
|
||||
}
|
||||
}
|
||||
else if((selectors_list->flags & MyCSS_SELECTORS_FLAGS_SELECTOR_BAD) && selectors->entry_last) {
|
||||
selectors->entry_last->flags |= MyCSS_SELECTORS_FLAGS_SELECTOR_BAD;
|
||||
}
|
||||
|
||||
if(token->type == entry->parser_ending_token) {
|
||||
mycss_entry_parser_list_pop(entry);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(selectors_list)
|
||||
selectors_list->flags |= MyCSS_SELECTORS_FLAGS_SELECTOR_BAD;
|
||||
|
||||
if(selectors->entry_last)
|
||||
selectors->entry_last->flags |= MyCSS_SELECTORS_FLAGS_SELECTOR_BAD;
|
||||
|
||||
entry->parser = mycss_selectors_function_parser_state_drop_component_value;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
////// NTH OF SELECTORS
|
||||
//////
|
||||
|
@ -38,6 +38,8 @@ bool mycss_selectors_unknown_parser(mycss_entry_t* entry, mycss_token_t* token,
|
||||
bool mycss_selectors_function_parser_not_or_matches_or_current_parser(mycss_entry_t* entry, mycss_token_t* token, bool last_response);
|
||||
bool mycss_selectors_function_parser_has(mycss_entry_t* entry, mycss_token_t* token, bool last_response);
|
||||
|
||||
bool mycss_selectors_function_parser_contains(mycss_entry_t* entry, mycss_token_t* token, bool last_response);
|
||||
|
||||
bool mycss_selectors_function_parser_nth_with_selectors(mycss_entry_t* entry, mycss_token_t* token, bool last_response);
|
||||
bool mycss_selectors_function_parser_nth_with_selectors_need_of(mycss_entry_t* entry, mycss_token_t* token, bool last_response);
|
||||
bool mycss_selectors_function_parser_nth_with_selectors_need_of_after(mycss_entry_t* entry, mycss_token_t* token, bool last_response);
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
#define MyCSS_SELECTORS_FUNCTION_NAME_STATIC_SIZE 57
|
||||
|
||||
static const mycss_selectots_function_begin_entry_t mycss_selectors_function_begin_map_index[] =
|
||||
static const mycss_selectots_function_begin_entry_t mycss_selectors_function_begin_map_index[] =
|
||||
{
|
||||
{NULL, 0, NULL, 0, 0},
|
||||
{"dir", 3, mycss_selectors_function_begin_dir, 0, 1},
|
||||
@ -78,7 +78,7 @@ static const mycss_selectots_function_begin_entry_t mycss_selectors_function_beg
|
||||
{"nth-child", 9, mycss_selectors_function_begin_nth_child, 0, 49},
|
||||
{NULL, 0, NULL, 0, 0},
|
||||
{NULL, 0, NULL, 0, 0},
|
||||
{NULL, 0, NULL, 0, 0},
|
||||
{"contains", 8, mycss_selectors_function_begin_contains, 0, 52},
|
||||
{NULL, 0, NULL, 0, 0},
|
||||
{NULL, 0, NULL, 0, 0},
|
||||
{NULL, 0, NULL, 0, 0},
|
||||
|
@ -127,7 +127,7 @@ mycss_selectors_list_t * mycss_selectors_parse_by_function(mycss_selectors_t* se
|
||||
|
||||
mycss_selectors_list_t *list = NULL;
|
||||
selectors->list = &list;
|
||||
|
||||
|
||||
/* parsing */
|
||||
mycss_encoding_set(entry, encoding);
|
||||
|
||||
@ -146,7 +146,7 @@ mycss_selectors_list_t * mycss_selectors_parse_by_function(mycss_selectors_t* se
|
||||
|
||||
if(list)
|
||||
return list;
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -99,20 +99,21 @@ typedef mycss_selectors_sub_type_t;
|
||||
enum mycss_selectors_sub_type_pseudo_class_function {
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_UNDEF = 0x00,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_UNKNOWN = 0x01,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_CURRENT = 0x02,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_DIR = 0x03,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_DROP = 0x04,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_HAS = 0x05,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_LANG = 0x06,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_MATCHES = 0x07,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NOT = 0x08,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_CHILD = 0x09,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_COLUMN = 0x0a,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_LAST_CHILD = 0x0b,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_LAST_COLUMN = 0x0c,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_LAST_OF_TYPE = 0x0d,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_OF_TYPE = 0x0e,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_LAST_ENTRY = 0x0f
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_CONTAINS = 0x02,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_CURRENT = 0x03,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_DIR = 0x04,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_DROP = 0x05,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_HAS = 0x06,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_LANG = 0x07,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_MATCHES = 0x08,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NOT = 0x09,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_CHILD = 0x0a,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_COLUMN = 0x0b,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_LAST_CHILD = 0x0c,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_LAST_COLUMN = 0x0d,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_LAST_OF_TYPE = 0x0e,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_OF_TYPE = 0x0f,
|
||||
MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_LAST_ENTRY = 0x10
|
||||
}
|
||||
typedef mycss_selectors_sub_type_pseudo_class_function_t;
|
||||
|
||||
|
@ -49,6 +49,7 @@ bool mycss_selectors_serialization_list(mycss_selectors_t* selectors, mycss_sele
|
||||
mycore_callback_serialize_f callback, void* context)
|
||||
{
|
||||
while(selectors_list) {
|
||||
|
||||
for(size_t i = 0; i < selectors_list->entries_list_length; i++)
|
||||
{
|
||||
mycss_selectors_entries_list_t *entries = &selectors_list->entries_list[i];
|
||||
@ -149,8 +150,9 @@ bool mycss_selectors_serialization_selector(mycss_selectors_t* selectors, mycss_
|
||||
}
|
||||
|
||||
callback("(", 1, context);
|
||||
|
||||
|
||||
switch (selector->sub_type) {
|
||||
case MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_CONTAINS:
|
||||
case MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_HAS:
|
||||
case MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NOT:
|
||||
case MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_MATCHES:
|
||||
|
@ -147,6 +147,11 @@ void * mycss_selectors_value_pseudo_class_function_has_create(mycss_entry_t* ent
|
||||
return mycss_selectors_list_create(entry->selectors);
|
||||
}
|
||||
|
||||
void * mycss_selectors_value_pseudo_class_function_contains_create(mycss_entry_t* entry, bool set_clean)
|
||||
{
|
||||
return mycss_selectors_list_create(entry->selectors);
|
||||
}
|
||||
|
||||
void * mycss_selectors_value_pseudo_class_function_lang_create(mycss_entry_t* entry, bool set_clean)
|
||||
{
|
||||
mycss_selectors_value_lang_t* lang = (mycss_selectors_value_lang_t*)
|
||||
@ -245,6 +250,11 @@ void * mycss_selectors_value_pseudo_class_function_has_destroy(mycss_entry_t* en
|
||||
return mycss_selectors_list_destroy(entry->selectors, value, self_destroy);
|
||||
}
|
||||
|
||||
void * mycss_selectors_value_pseudo_class_function_contains_destroy(mycss_entry_t* entry, void* value, bool self_destroy)
|
||||
{
|
||||
return mycss_selectors_list_destroy(entry->selectors, value, self_destroy);
|
||||
}
|
||||
|
||||
void * mycss_selectors_value_pseudo_class_function_lang_destroy(mycss_entry_t* entry, void* value, bool self_destroy)
|
||||
{
|
||||
if(value == NULL)
|
||||
@ -366,3 +376,4 @@ void * mycss_selectors_value_pseudo_class_function_nth_of_type_destroy(mycss_ent
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -83,6 +83,7 @@ void * mycss_selectors_value_pseudo_class_function_nth_last_child_create(mycss_e
|
||||
void * mycss_selectors_value_pseudo_class_function_nth_last_column_create(mycss_entry_t* entry, bool set_clean);
|
||||
void * mycss_selectors_value_pseudo_class_function_nth_last_of_type_create(mycss_entry_t* entry, bool set_clean);
|
||||
void * mycss_selectors_value_pseudo_class_function_nth_of_type_create(mycss_entry_t* entry, bool set_clean);
|
||||
void * mycss_selectors_value_pseudo_class_function_contains_create(mycss_entry_t* entry, bool set_clean);
|
||||
|
||||
/* pseudo class function destroy */
|
||||
void * mycss_selectors_value_pseudo_class_function_undef_destroy(mycss_entry_t* entry, void* value, bool self_destroy);
|
||||
@ -99,6 +100,7 @@ void * mycss_selectors_value_pseudo_class_function_nth_last_child_destroy(mycss_
|
||||
void * mycss_selectors_value_pseudo_class_function_nth_last_column_destroy(mycss_entry_t* entry, void* value, bool self_destroy);
|
||||
void * mycss_selectors_value_pseudo_class_function_nth_last_of_type_destroy(mycss_entry_t* entry, void* value, bool self_destroy);
|
||||
void * mycss_selectors_value_pseudo_class_function_nth_of_type_destroy(mycss_entry_t* entry, void* value, bool self_destroy);
|
||||
void * mycss_selectors_value_pseudo_class_function_contains_destroy(mycss_entry_t* entry, void* value, bool self_destroy);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -39,6 +39,7 @@ static const mycss_selectors_value_destroy_f mycss_selectors_value_destroy_map[M
|
||||
static const mycss_selectors_value_function_destroy_f mycss_selectors_value_function_destroy_map[MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_LAST_ENTRY] = {
|
||||
mycss_selectors_value_pseudo_class_function_undef_destroy,
|
||||
mycss_selectors_value_pseudo_class_function_undef_destroy,
|
||||
mycss_selectors_value_pseudo_class_function_contains_destroy,
|
||||
mycss_selectors_value_pseudo_class_function_current_destroy,
|
||||
mycss_selectors_value_pseudo_class_function_dir_destroy,
|
||||
mycss_selectors_value_pseudo_class_function_drop_destroy,
|
||||
|
186
test/myhtml/pseudo_class_contains.c
Normal file
186
test/myhtml/pseudo_class_contains.c
Normal file
@ -0,0 +1,186 @@
|
||||
/*
|
||||
Copyright (C) 2016 Alexander Borisov
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Author: lex.borisov@gmail.com (Alexander Borisov)
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <modest/finder/finder.h>
|
||||
#include <myhtml/myhtml.h>
|
||||
#include <myhtml/serialization.h>
|
||||
#include <mycss/mycss.h>
|
||||
#include <mycss/selectors/init.h>
|
||||
#include <mycss/selectors/serialization.h>
|
||||
|
||||
#define DIE(msg, ...) do { fprintf(stderr, msg, ##__VA_ARGS__); exit(EXIT_FAILURE); } while(0)
|
||||
#define CHECK_STATUS(msg, ...) do {if(status) DIE(msg, ##__VA_ARGS__);} while(0)
|
||||
|
||||
mystatus_t serialization_callback(const char* data, size_t len, void* ctx)
|
||||
{
|
||||
printf("%.*s", (int)len, data);
|
||||
return MyCORE_STATUS_OK;
|
||||
}
|
||||
|
||||
mystatus_t serialization_bad_selectors(const char* buffer, size_t size, void* ctx)
|
||||
{
|
||||
printf("%.*s", (int)size, buffer);
|
||||
return MyCORE_STATUS_OK;
|
||||
}
|
||||
|
||||
myhtml_tree_t * parse_html(const char* data, size_t data_size)
|
||||
{
|
||||
myhtml_t* myhtml = myhtml_create();
|
||||
mystatus_t status = myhtml_init(myhtml, MyHTML_OPTIONS_DEFAULT, 1, 0);
|
||||
|
||||
CHECK_STATUS("Can't init MyHTML object\n");
|
||||
|
||||
myhtml_tree_t* tree = myhtml_tree_create();
|
||||
status = myhtml_tree_init(tree, myhtml);
|
||||
|
||||
CHECK_STATUS("Can't init MyHTML Tree object\n");
|
||||
|
||||
status = myhtml_parse(tree, MyENCODING_UTF_8, data, data_size);
|
||||
CHECK_STATUS("Can't parse HTML:\n%s\n", data);
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
mycss_entry_t * create_css_parser(void)
|
||||
{
|
||||
// base init
|
||||
mycss_t *mycss = mycss_create();
|
||||
mystatus_t status = mycss_init(mycss);
|
||||
|
||||
CHECK_STATUS("Can't init MyCSS object\n");
|
||||
|
||||
// currenr entry work init
|
||||
mycss_entry_t *entry = mycss_entry_create();
|
||||
status = mycss_entry_init(mycss, entry);
|
||||
|
||||
CHECK_STATUS("Can't init MyCSS Entry object\n");
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
mycss_selectors_list_t * prepare_selector(mycss_entry_t *css_entry, const char* selector, size_t selector_size)
|
||||
{
|
||||
mystatus_t out_status;
|
||||
mycss_selectors_list_t *list = mycss_selectors_parse(mycss_entry_selectors(css_entry),
|
||||
MyENCODING_UTF_8,
|
||||
selector, selector_size,
|
||||
&out_status);
|
||||
|
||||
// printf("\nprepare_selector()\n");
|
||||
// printf("\t%s\n", (list != NULL)?"has list":"no list");
|
||||
|
||||
/* check parsing errors */
|
||||
if(list == NULL || (list->flags & MyCSS_SELECTORS_FLAGS_SELECTOR_BAD)) {
|
||||
fprintf(stderr, "Bad CSS Selectors\n");
|
||||
|
||||
if(list) {
|
||||
mycss_selectors_serialization_list(mycss_entry_selectors(css_entry), list,
|
||||
serialization_bad_selectors, NULL);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// printf("\treturn list\n");
|
||||
return list;
|
||||
}
|
||||
|
||||
void print_found_result(myhtml_tree_t* html_tree, myhtml_collection_t *collection)
|
||||
{
|
||||
if(collection) {
|
||||
for(size_t i = 0; i < collection->length; i++) {
|
||||
printf("\n\t");
|
||||
myhtml_serialization_node_callback(collection->list[i], serialization_callback, NULL);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
else {
|
||||
printf("empty\n");
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, const char * argv[])
|
||||
{
|
||||
const char *html = "<div>a<p id=\"c d\">c d</p><p id=\"c\">c</p></div>";
|
||||
// const char *selector = ":has(p)";
|
||||
// const char *selector = ":contains(c d)";
|
||||
// const char *selector = ":contains(c)";
|
||||
const char *selector = ":contains(c,d)";
|
||||
// const char *selector = "p:contains('c d')"; // Bad Selector
|
||||
// const char *selector = "p:contains(\"c d\")"; // Bad Selector
|
||||
|
||||
/* init MyHTML and parse HTML */
|
||||
myhtml_tree_t *html_tree = parse_html(html, strlen(html));
|
||||
|
||||
/* create css parser and finder for selectors */
|
||||
mycss_entry_t *css_entry = create_css_parser();
|
||||
modest_finder_t *finder = modest_finder_create_simple();
|
||||
|
||||
/* parse selectors */
|
||||
mycss_selectors_list_t *selectors_list = prepare_selector(css_entry, selector, strlen(selector));
|
||||
|
||||
/* find nodes by selector */
|
||||
myhtml_collection_t *collection = NULL;
|
||||
modest_finder_by_selectors_list(finder, html_tree->node_html, selectors_list, &collection);
|
||||
|
||||
/* print result */
|
||||
/* print selector */
|
||||
printf("Incoming selector:\n\t");
|
||||
mycss_selectors_serialization_list(mycss_entry_selectors(css_entry),
|
||||
selectors_list, serialization_callback, NULL);
|
||||
printf("\n\n");
|
||||
|
||||
/* print tree */
|
||||
printf("Incoming tree:\n\t");
|
||||
myhtml_serialization_tree_callback(html_tree->node_html, serialization_callback, NULL);
|
||||
|
||||
/* print found result */
|
||||
printf("\n\nFound nodes:");
|
||||
print_found_result(html_tree, collection);
|
||||
|
||||
/* destroy all */
|
||||
myhtml_collection_destroy(collection);
|
||||
|
||||
/* destroy selector list */
|
||||
mycss_selectors_list_destroy(mycss_entry_selectors(css_entry), selectors_list, true);
|
||||
|
||||
/* destroy Modest Finder */
|
||||
modest_finder_destroy(finder, true);
|
||||
|
||||
/* destroy MyCSS */
|
||||
mycss_t *mycss = css_entry->mycss;
|
||||
mycss_entry_destroy(css_entry, true);
|
||||
mycss_destroy(mycss, true);
|
||||
|
||||
/* destroy MyHTML */
|
||||
myhtml_t* myhtml = html_tree->myhtml;
|
||||
myhtml_tree_destroy(html_tree);
|
||||
myhtml_destroy(myhtml);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,8 @@ my $func_map = {
|
||||
'nth-of-type' => "",
|
||||
'nth-last-of-type' => "",
|
||||
'nth-column' => "",
|
||||
'nth-last-column' => ""
|
||||
'nth-last-column' => "",
|
||||
'contains' => ""
|
||||
};
|
||||
|
||||
my $INDEX_OF_NAMES = print_functions();
|
||||
|
Loading…
Reference in New Issue
Block a user