Merge pull request #42 from f34nk/support-for-pseudo-class-contains

New CSS selector  ":contains(text)"
This commit is contained in:
Alexander 2018-03-26 16:55:54 +03:00 committed by GitHub
commit 87d75c9585
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 405 additions and 41 deletions

View File

@ -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);

View File

@ -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 */

View File

@ -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);

View File

@ -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);

View File

@ -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},

View File

@ -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;

View File

@ -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" */

View File

@ -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,

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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 */
};

View File

@ -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;

View File

@ -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);

View File

@ -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
//////

View File

@ -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);

View File

@ -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},

View File

@ -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;
}

View File

@ -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;

View File

@ -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:

View File

@ -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
}

View File

@ -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" */

View File

@ -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,

View 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;
}

View File

@ -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();