diff options
author | lexborisov <lex.borisov@gmail.com> | 2016-08-29 00:20:40 +0300 |
---|---|---|
committer | lexborisov <lex.borisov@gmail.com> | 2016-08-29 00:20:40 +0300 |
commit | 5afb4ca9b760d62be13b14796a802401d80c7ea4 (patch) | |
tree | 3910ba6eeae279e0bbf148c0ed4ce689a496ad46 /source/modest/finder |
First commit
Diffstat (limited to 'source/modest/finder')
-rw-r--r-- | source/modest/finder/finder.c | 358 | ||||
-rw-r--r-- | source/modest/finder/finder.h | 68 | ||||
-rw-r--r-- | source/modest/finder/match.c | 287 | ||||
-rw-r--r-- | source/modest/finder/match.h | 44 | ||||
-rw-r--r-- | source/modest/finder/myosi.h | 51 | ||||
-rw-r--r-- | source/modest/finder/pseudo_class.c | 832 | ||||
-rw-r--r-- | source/modest/finder/pseudo_class.h | 92 | ||||
-rw-r--r-- | source/modest/finder/resource.h | 125 | ||||
-rw-r--r-- | source/modest/finder/type.c | 126 | ||||
-rw-r--r-- | source/modest/finder/type.h | 54 |
10 files changed, 2037 insertions, 0 deletions
diff --git a/source/modest/finder/finder.c b/source/modest/finder/finder.c new file mode 100644 index 0000000..c57807f --- /dev/null +++ b/source/modest/finder/finder.c @@ -0,0 +1,358 @@ +/* + 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 "modest/finder/finder.h" +#include "modest/finder/resource.h" + +modest_finder_t * modest_finder_create(void) +{ + return (modest_finder_t*)myhtml_calloc(1, sizeof(modest_finder_t)); +} + +modest_status_t modest_finder_init(modest_finder_t* finder, myhtml_tree_t* myhtml_tree, mycss_stylesheet_t *stylesheet) +{ + finder->tree = myhtml_tree; + finder->stylesheet = stylesheet; + + return MODEST_STATUS_OK; +} + +void modest_finder_clean(modest_finder_t* finder) +{ + finder->callback_found = NULL; + finder->callback_found_ctx = NULL; +} + +modest_finder_t * modest_finder_destroy(modest_finder_t* finder, bool self_destroy) +{ + if(finder == NULL) + return NULL; + + if(self_destroy) { + myhtml_free(finder); + return NULL; + } + + return finder; +} + +modest_finder_t * modest_finder_create_simple(myhtml_tree_t* myhtml_tree, mycss_stylesheet_t *stylesheet) +{ + modest_finder_t *finder = modest_finder_create(); + + if(finder == NULL) + return NULL; + + if(modest_finder_init(finder, myhtml_tree, stylesheet) != MyHTML_STATUS_OK) + return modest_finder_destroy(finder, true); + + return finder; +} + +void modest_finder_callback_found_set(modest_finder_t* finder, modest_finder_callback_f callback, void* callback_ctx) +{ + finder->callback_found = callback; + finder->callback_found_ctx = callback_ctx; +} + +void modest_finder_callback_found_with_collection(modest_finder_t* finder, myhtml_tree_node_t* node, void* ctx) +{ + myhtml_collection_t* collection = (myhtml_collection_t*)finder->callback_found_ctx; + + if(myhtml_collection_check_size(collection, 1, 1024) == MyHTML_STATUS_OK) { + collection->list[ collection->length ] = node; + collection->length++; + } +} + +void modest_finder_callback_found_with_bool(modest_finder_t* finder, myhtml_tree_node_t* node, void* ctx) +{ + bool *is = (bool*)ctx; + + if(*is == false) + *is = true; +} + +modest_finder_t * modest_finder_by_stylesheet(myhtml_tree_t* myhtml_tree, mycss_stylesheet_t *stylesheet, myhtml_collection_t** collection, myhtml_tree_node_t* base_node, mycss_selectors_list_t* selector_list) +{ + if(collection == NULL) + return NULL; + + modest_finder_t *finder = modest_finder_create(); + + if(finder == NULL) + return NULL; + + modest_status_t status = modest_finder_init(finder, myhtml_tree, stylesheet); + + if(status != MODEST_STATUS_OK) { + modest_finder_destroy(finder, true); + return NULL; + } + + if(*collection == NULL) { + myhtml_status_t status; + *collection = myhtml_collection_create(4096, &status); + + if(status) { + modest_finder_destroy(finder, true); + return NULL; + } + } + else + myhtml_collection_clean(*collection); + + if(base_node == NULL) { + if(myhtml_tree->node_html) + base_node = myhtml_tree->node_html; + else + return finder; + } + + if(selector_list == NULL) { + if(stylesheet->sel_list_first) + selector_list = stylesheet->sel_list_first; + else + return finder; + } + + modest_finder_callback_found_set(finder, modest_finder_callback_found_with_collection, *collection); + + while(selector_list) { + for(size_t i = 0; i < selector_list->selector_list_length; i++) { + modest_finder_node_combinator_begin(finder, base_node, selector_list->selector_list[i]); + } + + selector_list = selector_list->next; + } + + return finder; +} + +myhtml_collection_t * modest_finder_by_selectors_list(modest_finder_t* finder, mycss_selectors_list_t *sel_list, myhtml_tree_node_t* base_node, myhtml_collection_t* collection) +{ + if(finder == NULL || sel_list == NULL || base_node == NULL) + return NULL; + + if(collection == NULL) { + myhtml_status_t status; + collection = myhtml_collection_create(4096, &status); + + if(status) + return NULL; + } + + modest_finder_callback_found_set(finder, modest_finder_callback_found_with_collection, collection); + + for(size_t i = 0; i < sel_list->selector_list_length; i++) { + modest_finder_node_combinator_begin(finder, base_node, sel_list->selector_list[i]); + } + + return collection; +} + +void modest_finder_begin(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + modest_finder_node_combinator_begin(finder, base_node, selector); +} + +myhtml_tree_node_t * modest_finder_node_combinator_begin(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + myhtml_tree_node_t *node = base_node; + + while(node) { + if(node->tag_id != MyHTML_TAG__TEXT && node->tag_id != MyHTML_TAG__COMMENT && + modest_finder_static_selector_type_map[selector->type](finder, node, selector)) + { + if(selector->next == NULL) { + if(finder->callback_found) + finder->callback_found(finder, node, finder->callback_found_ctx); + } + else { + myhtml_tree_node_t *find_node = modest_finder_static_selector_combinator_map[selector->next->combinator](finder, node, selector->next); + + if(find_node == NULL) { + while(node != base_node && node->next == NULL) + node = node->parent; + + if(node == base_node) + break; + + node = node->next; + continue; + } + } + } + + if(node->child) + node = node->child; + else { + while(node != base_node && node->next == NULL) + node = node->parent; + + if(node == base_node) + break; + + node = node->next; + } + } + + return NULL; +} + +/* some */ +myhtml_tree_node_t * modest_finder_node_combinator_undef(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + if(base_node->tag_id != MyHTML_TAG__TEXT && base_node->tag_id != MyHTML_TAG__COMMENT && + modest_finder_static_selector_type_map[selector->type](finder, base_node, selector)) { + if(selector->next == NULL) { + if(finder->callback_found) + finder->callback_found(finder, base_node, finder->callback_found_ctx); + } + else { + modest_finder_static_selector_combinator_map[selector->next->combinator](finder, base_node, selector->next); + } + } + + return base_node; +} + +/* E F or E >> F */ +myhtml_tree_node_t * modest_finder_node_combinator_descendant(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + myhtml_tree_node_t *node = base_node->child; + + while(node) { + if(node->tag_id != MyHTML_TAG__TEXT && node->tag_id != MyHTML_TAG__COMMENT && + modest_finder_static_selector_type_map[selector->type](finder, node, selector)) + { + if(selector->next == NULL) { + if(finder->callback_found) + finder->callback_found(finder, node, finder->callback_found_ctx); + } + else { + myhtml_tree_node_t *find_node = modest_finder_static_selector_combinator_map[selector->next->combinator](finder, node, selector->next); + + if(find_node == NULL) { + while(node != base_node && node->next == NULL) + node = node->parent; + + if(node == base_node) + break; + + node = node->next; + continue; + } + } + } + + if(node->child) + node = node->child; + else { + while(node != base_node && node->next == NULL) + node = node->parent; + + if(node == base_node) + break; + + node = node->next; + } + } + + return NULL; +} + +/* E > F */ +myhtml_tree_node_t * modest_finder_node_combinator_child(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + myhtml_tree_node_t *node = base_node->child; + + while(node) { + if(node->tag_id != MyHTML_TAG__TEXT && node->tag_id != MyHTML_TAG__COMMENT && + modest_finder_static_selector_type_map[selector->type](finder, node, selector)) + { + if(selector->next == NULL) { + if(finder->callback_found) + finder->callback_found(finder, node, finder->callback_found_ctx); + } + else { + modest_finder_static_selector_combinator_map[selector->next->combinator](finder, node, selector->next); + } + } + + node = node->next; + } + + return base_node; +} + +/* E + F */ +myhtml_tree_node_t * modest_finder_node_combinator_next_sibling(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + myhtml_tree_node_t *node = base_node->next; + + if(base_node->next) { + if(node->tag_id != MyHTML_TAG__TEXT && node->tag_id != MyHTML_TAG__COMMENT && + modest_finder_static_selector_type_map[selector->type](finder, node, selector)) + { + if(selector->next == NULL) { + if(finder->callback_found) + finder->callback_found(finder, node, finder->callback_found_ctx); + } + else { + modest_finder_static_selector_combinator_map[selector->next->combinator](finder, node, selector->next); + } + } + } + + return base_node; +} + +/* E ~ F */ +myhtml_tree_node_t * modest_finder_node_combinator_following_sibling(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + myhtml_tree_node_t *node = base_node->next; + + while(node) { + if(node->tag_id != MyHTML_TAG__TEXT && node->tag_id != MyHTML_TAG__COMMENT && + modest_finder_static_selector_type_map[selector->type](finder, node, selector)) + { + if(selector->next == NULL) { + if(finder->callback_found) + finder->callback_found(finder, node, finder->callback_found_ctx); + } + else { + modest_finder_static_selector_combinator_map[selector->next->combinator](finder, node, selector->next); + } + } + + node = node->next; + } + + return base_node; +} + +/* E || F */ +myhtml_tree_node_t * modest_finder_node_combinator_column(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + return base_node; +} + + diff --git a/source/modest/finder/finder.h b/source/modest/finder/finder.h new file mode 100644 index 0000000..b377393 --- /dev/null +++ b/source/modest/finder/finder.h @@ -0,0 +1,68 @@ +/* + 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) +*/ + +#ifndef MODEST_FINDER_FINDER_H +#define MODEST_FINDER_FINDER_H +#pragma once + +#include "modest/finder/myosi.h" +#include "modest/finder/type.h" +#include "mycss/selectors/myosi.h" +#include "mycss/selectors/list.h" + +#ifdef __cplusplus +//extern "C" { +#endif + +typedef bool (*modest_finder_selector_type_f)(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector); +typedef myhtml_tree_node_t * (*modest_finder_selector_combinator_f)(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector); + +/* init */ +modest_finder_t * modest_finder_create(void); +modest_status_t modest_finder_init(modest_finder_t* finder, myhtml_tree_t* myhtml_tree, mycss_stylesheet_t *stylesheet); +void modest_finder_clean(modest_finder_t* finder); +modest_finder_t * modest_finder_destroy(modest_finder_t* finder, bool self_destroy); + +/* simple api */ +modest_finder_t * modest_finder_create_simple(myhtml_tree_t* myhtml_tree, mycss_stylesheet_t *stylesheet); + +/* callbacks */ +void modest_finder_callback_found_with_collection(modest_finder_t* finder, myhtml_tree_node_t* node, void* ctx); +void modest_finder_callback_found_with_bool(modest_finder_t* finder, myhtml_tree_node_t* node, void* ctx); + +/* base api */ +void modest_finder_begin(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +modest_finder_t * modest_finder_by_stylesheet(myhtml_tree_t* myhtml_tree, mycss_stylesheet_t *stylesheet, myhtml_collection_t** collection, myhtml_tree_node_t* base_node, mycss_selectors_list_t* selector_list); +myhtml_collection_t * modest_finder_by_selectors_list(modest_finder_t* finder, mycss_selectors_list_t *sel_list, myhtml_tree_node_t* base_node, myhtml_collection_t* collection); + +/* process */ +myhtml_tree_node_t * modest_finder_node_combinator_begin(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +myhtml_tree_node_t * modest_finder_node_combinator_undef(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +myhtml_tree_node_t * modest_finder_node_combinator_descendant(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +myhtml_tree_node_t * modest_finder_node_combinator_child(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +myhtml_tree_node_t * modest_finder_node_combinator_next_sibling(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +myhtml_tree_node_t * modest_finder_node_combinator_following_sibling(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +myhtml_tree_node_t * modest_finder_node_combinator_column(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* MODEST_FINDER_FINDER_H */ diff --git a/source/modest/finder/match.c b/source/modest/finder/match.c new file mode 100644 index 0000000..97d5f9d --- /dev/null +++ b/source/modest/finder/match.c @@ -0,0 +1,287 @@ +/* + 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 "modest/finder/match.h" + +bool modest_finder_match_attribute_only_key(myhtml_token_attr_t* attr, const char* key, size_t key_len) +{ + if(key == NULL) + return false; + + while (attr) + { + if(attr->key.length == key_len) { + if(myhtml_strncasecmp(key, attr->key.data, key_len) == 0) + return true; + } + + attr = attr->next; + } + + return false; +} + +bool modest_finder_match_attribute_eq(myhtml_token_attr_t* attr, const char* key, size_t key_len, const char* value, size_t value_len, bool case_sensitive) +{ + if(key == NULL || value == NULL) + return false; + + while (attr) + { + if(attr->key.length == key_len) { + if(myhtml_strncasecmp(key, attr->key.data, key_len) == 0) + { + if(attr->value.length == value_len) { + if(case_sensitive) { + if(strncmp(value, attr->value.data, value_len) == 0) { + return true; + } + } + else { + if(myhtml_strncasecmp(value, attr->value.data, value_len) == 0) { + return true; + } + } + } + + break; + } + } + + attr = attr->next; + } + + return false; +} + +bool modest_finder_match_attribute_ws(myhtml_token_attr_t* attr, const char* key, size_t key_len, const char* value, size_t value_len, bool case_sensitive) +{ + if(key == NULL || value == NULL) + return false; + + while (attr) + { + if(attr->key.length == key_len) { + if(myhtml_strncasecmp(key, attr->key.data, key_len) == 0) + { + size_t i = 0; + + if(attr->value.length >= value_len) { + if(case_sensitive) + { + while(i < attr->value.length) + { + size_t end = i + value_len; + + if(end > attr->value.length) + return false; + + if( + (myhtml_strncmp(value, &attr->value.data[i], value_len) == 0) && + (myhtml_utils_whithspace(attr->value.data[end], ==, ||) || end == attr->value.length)) + { + return true; + } + + i++; + } + } + else { + while(i < attr->value.length) + { + size_t end = i + value_len; + + if(end > attr->value.length) + return false; + + if( + (myhtml_strncasecmp(value, &attr->value.data[i], value_len) == 0) && + (myhtml_utils_whithspace(attr->value.data[end], ==, ||) || end == attr->value.length)) + { + return true; + } + + i++; + } + } + } + + break; + } + } + + attr = attr->next; + } + + return false; +} + +bool modest_finder_match_attribute_begin(myhtml_token_attr_t* attr, const char* key, size_t key_len, const char* value, size_t value_len, bool case_sensitive) +{ + if(key == NULL || value == NULL) + return false; + + while (attr) + { + if(attr->key.length == key_len) { + if(myhtml_strncasecmp(key, attr->key.data, key_len) == 0) + { + if(attr->value.length >= value_len) { + if(case_sensitive) { + if(myhtml_strncmp(value, attr->value.data, value_len) == 0) + return true; + } + else { + if(myhtml_strncasecmp(value, attr->value.data, value_len) == 0) + return true; + } + } + + break; + } + } + + attr = attr->next; + } + + return false; +} + +bool modest_finder_match_attribute_end(myhtml_token_attr_t* attr, const char* key, size_t key_len, const char* value, size_t value_len, bool case_sensitive) +{ + if(key == NULL || value == NULL) + return false; + + while (attr) + { + if(attr->key.length == key_len) { + if(myhtml_strncasecmp(key, attr->key.data, key_len) == 0) + { + if(attr->value.length >= value_len) { + if(case_sensitive) { + if(myhtml_strncmp(value, &attr->value.data[ (attr->value.length - value_len) ], value_len) == 0) + return true; + } + else { + if(myhtml_strncasecmp(value, &attr->value.data[ (attr->value.length - value_len) ], value_len) == 0) + return true; + } + } + + break; + } + } + + attr = attr->next; + } + + return false; +} + +bool modest_finder_match_attribute_sub(myhtml_token_attr_t* attr, const char* key, size_t key_len, const char* value, size_t value_len, bool case_sensitive) +{ + if(key == NULL || value == NULL) + return false; + + while (attr) + { + if(attr->key.length == key_len) { + if(myhtml_strncasecmp(key, attr->key.data, key_len) == 0) + { + if(attr->value.length >= value_len) { + size_t i = 0; + + if(case_sensitive) + { + while ((i + value_len) <= attr->value.length) + { + if(myhtml_strncmp(value, &attr->value.data[i], value_len) == 0) + return true; + + i++; + } + } + else { + while ((i + value_len) <= attr->value.length) + { + if(myhtml_strncasecmp(value, &attr->value.data[i], value_len) == 0) + return true; + + i++; + } + } + } + + break; + } + } + + attr = attr->next; + } + + return false; +} + +bool modest_finder_match_attribute_hsp(myhtml_token_attr_t* attr, const char* key, size_t key_len, const char* value, size_t value_len, bool case_sensitive) +{ + if(key == NULL || value == NULL) + return false; + + while (attr) + { + if(attr->key.length == key_len) { + if(myhtml_strncasecmp(key, attr->key.data, key_len) == 0) + { + if(attr->value.length == value_len) { + if(case_sensitive) { + if(myhtml_strncmp(value, attr->value.data, value_len) == 0) + return true; + } + else { + if(myhtml_strncasecmp(value, attr->value.data, value_len) == 0) + return true; + } + } + else if(attr->value.length > value_len) { + if(case_sensitive) { + if(myhtml_strncmp(value, attr->value.data, value_len) == 0) { + if(attr->value.data[value_len] == '-') + return true; + } + } + else { + if(myhtml_strncasecmp(value, attr->value.data, value_len) == 0) { + if(attr->value.data[value_len] == '-') + return true; + } + } + } + + break; + } + } + + attr = attr->next; + } + + return false; +} + + diff --git a/source/modest/finder/match.h b/source/modest/finder/match.h new file mode 100644 index 0000000..c7ee945 --- /dev/null +++ b/source/modest/finder/match.h @@ -0,0 +1,44 @@ +/* + 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) +*/ + +#ifndef MODEST_FINDER_MATCH_H +#define MODEST_FINDER_MATCH_H +#pragma once + +#include "myhtml/myosi.h" +#include "myhtml/tree.h" + +#ifdef __cplusplus +//extern "C" { +#endif + +bool modest_finder_match_attribute_only_key(myhtml_token_attr_t* attr, const char* key, size_t key_len); +bool modest_finder_match_attribute_eq(myhtml_token_attr_t* attr, const char* key, size_t key_len, const char* value, size_t value_len, bool case_sensitive); +bool modest_finder_match_attribute_ws(myhtml_token_attr_t* attr, const char* key, size_t key_len, const char* value, size_t value_len, bool case_sensitive); +bool modest_finder_match_attribute_begin(myhtml_token_attr_t* attr, const char* key, size_t key_len, const char* value, size_t value_len, bool case_sensitive); +bool modest_finder_match_attribute_end(myhtml_token_attr_t* attr, const char* key, size_t key_len, const char* value, size_t value_len, bool case_sensitive); +bool modest_finder_match_attribute_sub(myhtml_token_attr_t* attr, const char* key, size_t key_len, const char* value, size_t value_len, bool case_sensitive); +bool modest_finder_match_attribute_hsp(myhtml_token_attr_t* attr, const char* key, size_t key_len, const char* value, size_t value_len, bool case_sensitive); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* MODEST_FINDER_MATCH_H */ diff --git a/source/modest/finder/myosi.h b/source/modest/finder/myosi.h new file mode 100644 index 0000000..682e452 --- /dev/null +++ b/source/modest/finder/myosi.h @@ -0,0 +1,51 @@ +/* + 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) +*/ + +#ifndef MODEST_FINDER_MYOSI_H +#define MODEST_FINDER_MYOSI_H +#pragma once + +#include "modest/myosi.h" +#include "myhtml/myosi.h" +#include "mycss/myosi.h" + +#ifdef __cplusplus +//extern "C" { +#endif + +struct modest_finder typedef modest_finder_t; + +typedef void (*modest_finder_callback_f)(modest_finder_t* finder, myhtml_tree_node_t* node, void* ctx); +typedef bool (*modest_finder_match_f)(myhtml_token_attr_t* attr, const char* key, size_t key_len, const char* value, size_t value_len, bool case_sensitive); + +struct modest_finder { + myhtml_tree_t* tree; + mycss_stylesheet_t* stylesheet; + + modest_finder_callback_f callback_found; + void* callback_found_ctx; +}; + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* MODEST_FINDER_MYOSI_H */ diff --git a/source/modest/finder/pseudo_class.c b/source/modest/finder/pseudo_class.c new file mode 100644 index 0000000..9cd9653 --- /dev/null +++ b/source/modest/finder/pseudo_class.c @@ -0,0 +1,832 @@ +/* + 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 "modest/finder/pseudo_class.h" +#include "modest/finder/resource.h" + +bool modest_finder_selector_sub_type_pseudo_class_function_undef(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_function_current(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + mycss_selectors_list_t *list = selector->value; + + modest_finder_callback_f current_callback_found = finder->callback_found; + void *current_ctx = finder->callback_found_ctx; + + bool i_found; + + finder->callback_found = modest_finder_callback_found_with_bool; + finder->callback_found_ctx = &i_found; + + for(size_t i = 0; i < list->selector_list_length; i++) + { + i_found = false; + modest_finder_node_combinator_undef(finder, base_node, list->selector_list[i]); + + if(i_found == true) { + finder->callback_found = current_callback_found; + finder->callback_found_ctx = current_ctx; + + return true; + } + } + + finder->callback_found = current_callback_found; + finder->callback_found_ctx = current_ctx; + + return false; +} + +/* after create render */ +bool modest_finder_selector_sub_type_pseudo_class_function_dir(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_function_drop(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_function_has(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + mycss_selectors_list_t *list = selector->value; + + modest_finder_callback_f current_callback_found = finder->callback_found; + void *current_ctx = finder->callback_found_ctx; + + bool i_found; + + finder->callback_found = modest_finder_callback_found_with_bool; + finder->callback_found_ctx = &i_found; + + for(size_t i = 0; i < list->selector_list_length; i++) + { + i_found = false; + + mycss_selectors_entry_t *sel_entry = list->selector_list[i]; + + if(sel_entry->combinator == MyCSS_SELECTORS_COMBINATOR_UNDEF) + modest_finder_node_combinator_descendant(finder, base_node, sel_entry); + else + modest_finder_static_selector_combinator_map[sel_entry->combinator](finder, base_node, sel_entry); + + if(i_found == true) { + finder->callback_found = current_callback_found; + finder->callback_found_ctx = current_ctx; + + return true; + } + } + + finder->callback_found = current_callback_found; + finder->callback_found_ctx = current_ctx; + + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_function_lang(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector) +{ + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_function_matches(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + mycss_selectors_list_t *list = selector->value; + + modest_finder_callback_f current_callback_found = finder->callback_found; + void *current_ctx = finder->callback_found_ctx; + + bool i_found; + + finder->callback_found = modest_finder_callback_found_with_bool; + finder->callback_found_ctx = &i_found; + + for(size_t i = 0; i < list->selector_list_length; i++) + { + i_found = false; + modest_finder_node_combinator_undef(finder, base_node, list->selector_list[i]); + + if(i_found == true) { + finder->callback_found = current_callback_found; + finder->callback_found_ctx = current_ctx; + + return true; + } + } + + finder->callback_found = current_callback_found; + finder->callback_found_ctx = current_ctx; + + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_function_not(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + mycss_selectors_list_t *list = selector->value; + + modest_finder_callback_f current_callback_found = finder->callback_found; + void *current_ctx = finder->callback_found_ctx; + + bool i_found; + + finder->callback_found = modest_finder_callback_found_with_bool; + finder->callback_found_ctx = &i_found; + + for(size_t i = 0; i < list->selector_list_length; i++) + { + i_found = false; + modest_finder_node_combinator_undef(finder, base_node, list->selector_list[i]); + + if(i_found == true) { + finder->callback_found = current_callback_found; + finder->callback_found_ctx = current_ctx; + + return false; + } + } + + finder->callback_found = current_callback_found; + finder->callback_found_ctx = current_ctx; + + return true; +} + +bool modest_finder_selector_sub_type_pseudo_class_function_nth_child(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + if(selector->value == NULL) + return NULL; + + mycss_an_plus_b_entry_t *anb = mycss_selector_value_an_plus_b(selector->value); + + long node_pos = 0; + myhtml_tree_node_t* node = base_node; + + if(anb->of) { + modest_finder_callback_f current_callback_found = finder->callback_found; + void *current_ctx = finder->callback_found_ctx; + + bool i_found; + + finder->callback_found = modest_finder_callback_found_with_bool; + finder->callback_found_ctx = &i_found; + + mycss_selectors_list_t *list = anb->of; + + while(node) + { + for(size_t i = 0; i < list->selector_list_length; i++) + { + i_found = false; + modest_finder_node_combinator_undef(finder, node, list->selector_list[i]); + + if(i_found == true) { + node_pos++; + break; + } + else if(node_pos == 0) { + finder->callback_found = current_callback_found; + finder->callback_found_ctx = current_ctx; + + return false; + } + } + + node = node->prev; + } + + finder->callback_found = current_callback_found; + finder->callback_found_ctx = current_ctx; + + if(node_pos == 0) + return false; + } + else { + while(node) { + if(node->tag_id != MyHTML_TAG__TEXT && node->tag_id != MyHTML_TAG__COMMENT) + node_pos++; + + node = node->prev; + } + } + + if(anb->a == 0) { + if(anb->b == node_pos) + return true; + } + else { + double n = (double)(node_pos - anb->b) / (double)anb->a; + + if(n >= 0.0f && (n - (double)((long)(n))) == 0.0f) + return true; + } + + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_function_nth_column(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_function_nth_last_child(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + if(selector->value == NULL) + return NULL; + + mycss_an_plus_b_entry_t *anb = mycss_selector_value_an_plus_b(selector->value); + + long node_pos = 0; + myhtml_tree_node_t* node = base_node; + + if(anb->of) { + modest_finder_callback_f current_callback_found = finder->callback_found; + void *current_ctx = finder->callback_found_ctx; + + bool i_found; + + finder->callback_found = modest_finder_callback_found_with_bool; + finder->callback_found_ctx = &i_found; + + mycss_selectors_list_t *list = anb->of; + + while(node) + { + for(size_t i = 0; i < list->selector_list_length; i++) + { + i_found = false; + modest_finder_node_combinator_undef(finder, node, list->selector_list[i]); + + if(i_found == true) { + node_pos++; + break; + } + else if(node_pos == 0) { + finder->callback_found = current_callback_found; + finder->callback_found_ctx = current_ctx; + + return false; + } + } + + node = node->next; + } + + finder->callback_found = current_callback_found; + finder->callback_found_ctx = current_ctx; + + if(node_pos == 0) + return false; + } + else { + while(node) { + if(node->tag_id != MyHTML_TAG__TEXT && node->tag_id != MyHTML_TAG__COMMENT) + node_pos++; + + node = node->next; + } + } + + if(anb->a == 0) { + if(anb->b == node_pos) + return true; + } + else { + double n = (double)(node_pos - anb->b) / (double)anb->a; + + if(n >= 0.0f && (n - (double)((long)(n))) == 0.0f) + return true; + } + + return false; +} + +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) +{ + return false; +} + +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) +{ + if(selector->value == NULL) + return NULL; + + mycss_an_plus_b_entry_t *anb = mycss_selector_value_an_plus_b(selector->value); + + long node_pos = 0; + myhtml_tree_node_t* node = base_node; + + while(node) { + if(node->tag_id == base_node->tag_id && node->ns == base_node->ns) { + node_pos++; + } + + node = node->next; + } + + if(anb->a == 0) { + if(anb->b != node_pos) + return false; + } + else { + double n = (double)(node_pos - anb->b) / (double)anb->a; + + if(n < 0.0f || (n - (double)((long)(n))) != 0.0f) + return false; + } + + return true; +} + +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) +{ + if(selector->value == NULL) + return NULL; + + mycss_an_plus_b_entry_t *anb = mycss_selector_value_an_plus_b(selector->value); + + long node_pos = 0; + myhtml_tree_node_t* node = base_node; + + while(node) { + if(node->tag_id == base_node->tag_id && node->ns == base_node->ns) { + node_pos++; + } + + node = node->prev; + } + + if(anb->a == 0) { + if(anb->b != node_pos) + return false; + } + else { + double n = (double)(node_pos - anb->b) / (double)anb->a; + + if(n < 0.0f || (n - (double)((long)(n))) != 0.0f) + return false; + } + + return true; +} + +/* 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) +{ + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_active(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_any_link(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + if(base_node->tag_id == MyHTML_TAG_A || + base_node->tag_id == MyHTML_TAG_AREA || + base_node->tag_id == MyHTML_TAG_MAP) + { + if(base_node->token) + return modest_finder_match_attribute_only_key(base_node->token->attr_first, "href", 4); + } + + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_blank(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + myhtml_tree_node_t *node = base_node->child; + + while(node) { + if(node->tag_id != MyHTML_TAG__COMMENT) { + if(node->tag_id != MyHTML_TAG__TEXT) + return false; + + if(node->token) { + const char *data = node->token->str.data; + size_t len = node->token->str.length; + + for(size_t i = 0; i < len; i++) { + if(data[i] != ' ' && data[i] != '\t' && data[i] != '\n' && data[i] != '\r') + return false; + } + } + } + + if(node->child) + node = node->child; + else { + while(node != base_node && node->next == NULL) + node = node->parent; + + if(node == base_node) + break; + + node = node->next; + } + } + + return true; +} + +bool modest_finder_selector_sub_type_pseudo_class_checked(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + if(base_node->tag_id == MyHTML_TAG_INPUT || base_node->tag_id == MyHTML_TAG_MENUITEM) + { + myhtml_token_attr_t* attr = base_node->token->attr_first; + + while (attr) + { + if(attr->key.length == 4) { + if(myhtml_strncasecmp("type", attr->key.data, 4) == 0) + { + if(attr->value.length == 8) { + if(myhtml_strncasecmp("checkbox", attr->value.data, 8) == 0) { + return modest_finder_match_attribute_only_key(base_node->token->attr_first, "checked", 7); + } + } + else if(attr->value.length == 5) { + if(myhtml_strncasecmp("radio", attr->value.data, 5) == 0) { + return modest_finder_match_attribute_only_key(base_node->token->attr_first, "checked", 7); + } + } + + break; + } + } + + attr = attr->next; + } + } + else if(base_node->tag_id == MyHTML_TAG_OPTION) { + return modest_finder_match_attribute_only_key(base_node->token->attr_first, "selected", 8); + } + + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_current(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_default(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_disabled(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + if(base_node->token == NULL) + return false; + + if(base_node->tag_id == MyHTML_TAG_BUTTON || + base_node->tag_id == MyHTML_TAG_INPUT || + base_node->tag_id == MyHTML_TAG_SELECT || + base_node->tag_id == MyHTML_TAG_TEXTAREA) + { + if(modest_finder_match_attribute_only_key(base_node->token->attr_first, "disabled", 8)) + return true; + + myhtml_tree_node_t* node = base_node->parent; + + while(node) { + /* oh, see https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled */ + if(node->tag_id == MyHTML_TAG_FIELDSET) { + if(node->child && node->child->tag_id != MyHTML_TAG_LEGEND) { + if(node->token && modest_finder_match_attribute_only_key(node->token->attr_first, "disabled", 8)) + return true; + } + } + + node = node->parent; + } + + return false; + } + + /* see https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled */ + if(base_node->tag_id == MyHTML_TAG_OPTION) { + if(modest_finder_match_attribute_only_key(base_node->token->attr_first, "disabled", 8)) + return true; + + myhtml_tree_node_t* node = base_node->parent; + + while(node) { + if(node->tag_id == MyHTML_TAG_OPTGROUP) { + if(node->token) + return modest_finder_match_attribute_only_key(node->token->attr_first, "disabled", 8); + + return false; + } + + node = node->parent; + } + + return false; + } + + if(base_node->tag_id == MyHTML_TAG_OPTGROUP || + base_node->tag_id == MyHTML_TAG_MENUITEM) { + return modest_finder_match_attribute_only_key(base_node->token->attr_first, "disabled", 8); + } + + if(base_node->tag_id == MyHTML_TAG_FIELDSET) + { + if(modest_finder_match_attribute_only_key(base_node->token->attr_first, "disabled", 8)) + return true; + + myhtml_tree_node_t* node = base_node->parent; + + while(node) { + /* oh, see https://html.spec.whatwg.org/multipage/forms.html#concept-fieldset-disabled */ + if(node->tag_id == MyHTML_TAG_FIELDSET) { + if(node->child && node->child->tag_id != MyHTML_TAG_LEGEND) { + if(node->token && modest_finder_match_attribute_only_key(node->token->attr_first, "disabled", 8)) + return true; + } + } + + node = node->parent; + } + + return false; + } + + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_drop(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_empty(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + myhtml_tree_node_t *node = base_node->child; + + while(node) { + if(node->tag_id != MyHTML_TAG__COMMENT) + return false; + + if(node->child) + node = node->child; + else { + while(node != base_node && node->next == NULL) + node = node->parent; + + if(node == base_node) + break; + + node = node->next; + } + } + + return true; +} + +bool modest_finder_selector_sub_type_pseudo_class_enabled(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + return ~modest_finder_selector_sub_type_pseudo_class_disabled(finder, base_node, selector); +} + +bool modest_finder_selector_sub_type_pseudo_class_first_child(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + myhtml_tree_node_t *node = base_node->prev; + + while(node) { + if(node->tag_id != MyHTML_TAG__TEXT && node->tag_id != MyHTML_TAG__COMMENT) + return false; + + node = node->prev; + } + + return true; +} + +bool modest_finder_selector_sub_type_pseudo_class_first_of_type(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + myhtml_tree_node_t *node = base_node->prev; + + while(node) { + if(node->tag_id == base_node->tag_id && node->ns == base_node->ns) + return false; + + node = node->prev; + } + + return true; +} + +bool modest_finder_selector_sub_type_pseudo_class_focus(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_future(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_hover(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_in_range(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_indeterminate(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_invalid(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_last_child(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + myhtml_tree_node_t *node = base_node->next; + + while(node) { + if(node->tag_id != MyHTML_TAG__TEXT && node->tag_id != MyHTML_TAG__COMMENT) + return false; + + node = node->next; + } + + return true; +} + +bool modest_finder_selector_sub_type_pseudo_class_last_of_type(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + myhtml_tree_node_t *node = base_node->next; + + while(node) { + if(node->tag_id == base_node->tag_id && node->ns == base_node->ns) + return false; + + node = node->next; + } + + return true; +} + +bool modest_finder_selector_sub_type_pseudo_class_link(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + if(base_node->tag_id == MyHTML_TAG_A || + base_node->tag_id == MyHTML_TAG_AREA || + base_node->tag_id == MyHTML_TAG_LINK) + { + if(base_node->token) + return modest_finder_match_attribute_only_key(base_node->token->attr_first, "href", 4); + } + + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_only_child(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + return + modest_finder_selector_sub_type_pseudo_class_first_child(finder, base_node, selector) && + modest_finder_selector_sub_type_pseudo_class_last_child(finder, base_node, selector); +} + +bool modest_finder_selector_sub_type_pseudo_class_only_of_type(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + return + modest_finder_selector_sub_type_pseudo_class_first_of_type(finder, base_node, selector) && + modest_finder_selector_sub_type_pseudo_class_last_of_type(finder, base_node, selector); +} + +bool modest_finder_selector_sub_type_pseudo_class_optional(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + if(base_node->tag_id == MyHTML_TAG_INPUT || + base_node->tag_id == MyHTML_TAG_SELECT || + base_node->tag_id == MyHTML_TAG_TEXTAREA) + { + if(base_node->token) + return ~modest_finder_match_attribute_only_key(base_node->token->attr_first, "required", 8); + else + return true; + } + + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_out_of_range(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_past(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_placeholder_shown(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + if(base_node->tag_id == MyHTML_TAG_INPUT || + base_node->tag_id == MyHTML_TAG_TEXTAREA) + { + if(base_node->token) + return modest_finder_match_attribute_only_key(base_node->token->attr_first, "placeholder", 11); + } + + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_read_only(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + if(modest_finder_selector_sub_type_pseudo_class_read_write(finder, base_node, selector)) + return false; + + return true; +} + +bool modest_finder_selector_sub_type_pseudo_class_read_write(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + if(base_node->tag_id == MyHTML_TAG_INPUT || + base_node->tag_id == MyHTML_TAG_TEXTAREA) + { + if(modest_finder_match_attribute_only_key(base_node->token->attr_first, "readonly", 8)) + return false; + + return ~modest_finder_selector_sub_type_pseudo_class_disabled(finder, base_node, selector); + } + + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_required(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + if(base_node->tag_id == MyHTML_TAG_INPUT || + base_node->tag_id == MyHTML_TAG_SELECT || + base_node->tag_id == MyHTML_TAG_TEXTAREA) + { + if(base_node->token) + return modest_finder_match_attribute_only_key(base_node->token->attr_first, "required", 8); + } + + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_root(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + if(finder->tree->node_html == base_node) + return true; + + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_scope(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_target(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_user_error(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_valid(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + return false; +} + +bool modest_finder_selector_sub_type_pseudo_class_visited(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector) +{ + return false; +} + + diff --git a/source/modest/finder/pseudo_class.h b/source/modest/finder/pseudo_class.h new file mode 100644 index 0000000..23e736b --- /dev/null +++ b/source/modest/finder/pseudo_class.h @@ -0,0 +1,92 @@ +/* + 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) +*/ + +#ifndef MODEST_FINDER_PSEUDO_CLASS_H +#define MODEST_FINDER_PSEUDO_CLASS_H +#pragma once + +#include "modest/finder/myosi.h" +#include "mycss/selectors/myosi.h" +#include "mycss/selectors/value.h" +#include "modest/finder/finder.h" + +#ifdef __cplusplus +//extern "C" { +#endif + +bool modest_finder_selector_sub_type_pseudo_class_function_undef(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_function_current(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_function_dir(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_function_drop(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_function_has(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_function_lang(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_function_matches(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_function_not(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_function_nth_child(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_function_nth_column(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_function_nth_last_child(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_function_nth_last_column(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_function_nth_last_of_type(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_function_nth_of_type(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector); + +/* 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); +bool modest_finder_selector_sub_type_pseudo_class_active(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_any_link(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_blank(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_checked(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_current(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_default(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_disabled(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_drop(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_empty(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_enabled(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_first_child(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_first_of_type(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_focus(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_future(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_hover(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_in_range(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_indeterminate(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_invalid(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_last_child(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_last_of_type(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_link(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_only_child(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_only_of_type(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_optional(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_out_of_range(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_past(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_placeholder_shown(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_read_only(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_read_write(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_required(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_root(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_scope(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_target(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_user_error(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_valid(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_sub_type_pseudo_class_visited(modest_finder_t* finder, myhtml_tree_node_t* base_node, mycss_selectors_entry_t* selector); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* MODEST_FINDER_PSEUDO_CLASS_H */ diff --git a/source/modest/finder/resource.h b/source/modest/finder/resource.h new file mode 100644 index 0000000..839914a --- /dev/null +++ b/source/modest/finder/resource.h @@ -0,0 +1,125 @@ +/* + 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) +*/ + +#ifndef MODEST_FINDER_RESOURCE_H +#define MODEST_FINDER_RESOURCE_H +#pragma once + +/* see enum mycss_selectors_type (mycss_selectors_type_t) on mycss/selectors/myosi.h */ +static const modest_finder_selector_type_f modest_finder_static_selector_type_map[MyCSS_SELECTORS_TYPE_LAST_ENTRY] = +{ + modest_finder_selector_type_undef, /* MyCSS_SELECTORS_TYPE_UNDEF */ + modest_finder_selector_type_element, /* MyCSS_SELECTORS_TYPE_ELEMENT */ + modest_finder_selector_type_id, /* MyCSS_SELECTORS_TYPE_ID */ + modest_finder_selector_type_class, /* MyCSS_SELECTORS_TYPE_CLASS */ + modest_finder_selector_type_attribute, /* MyCSS_SELECTORS_TYPE_ATTRIBUTE */ + modest_finder_selector_type_pseudo_class_function, /* MyCSS_SELECTORS_TYPE_PSEUDO_CLASS_FUNCTION */ + modest_finder_selector_type_pseudo_class, /* MyCSS_SELECTORS_TYPE_PSEUDO_CLASS */ + modest_finder_selector_type_pseudo_element_function, /* MyCSS_SELECTORS_TYPE_PSEUDO_ELEMENT_FUNCTION */ + modest_finder_selector_type_pseudo_element /* MyCSS_SELECTORS_TYPE_PSEUDO_ELEMENT */ +}; + +/* see enum mycss_selectors_sub_type (mycss_selectors_sub_type_t) on mycss/selectors/myosi.h */ +static const modest_finder_selector_type_f modest_finder_static_selector_sub_type_pseudo_class_function_map[MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_LAST_ENTRY] = +{ + 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_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 */ + modest_finder_selector_sub_type_pseudo_class_function_has, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_HAS */ + modest_finder_selector_sub_type_pseudo_class_function_lang, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_LANG */ + modest_finder_selector_sub_type_pseudo_class_function_matches, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_MATCHES */ + modest_finder_selector_sub_type_pseudo_class_function_not, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NOT */ + modest_finder_selector_sub_type_pseudo_class_function_nth_child, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_CHILD */ + modest_finder_selector_sub_type_pseudo_class_function_nth_column, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_COLUMN */ + 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 */ + +}; + +/* see enum mycss_selectors_sub_type (mycss_selectors_sub_type_t) on mycss/selectors/myosi.h */ +static const modest_finder_selector_type_f modest_finder_static_selector_sub_type_pseudo_class_map[MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_LAST_ENTRY] = +{ + modest_finder_selector_sub_type_pseudo_class_undef, /* UNDEF */ + modest_finder_selector_sub_type_pseudo_class_undef, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_UNKNOWN */ + modest_finder_selector_sub_type_pseudo_class_active, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_ACTIVE */ + modest_finder_selector_sub_type_pseudo_class_any_link, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_ANY_LINK */ + modest_finder_selector_sub_type_pseudo_class_blank, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_BLANK */ + modest_finder_selector_sub_type_pseudo_class_checked, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_CHECKED */ + modest_finder_selector_sub_type_pseudo_class_current, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_CURRENT */ + modest_finder_selector_sub_type_pseudo_class_default, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_DEFAULT */ + modest_finder_selector_sub_type_pseudo_class_disabled, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_DISABLED */ + modest_finder_selector_sub_type_pseudo_class_drop, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_DROP */ + modest_finder_selector_sub_type_pseudo_class_empty, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_EMPTY */ + modest_finder_selector_sub_type_pseudo_class_enabled, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_ENABLED */ + modest_finder_selector_sub_type_pseudo_class_first_child, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FIRST_CHILD */ + modest_finder_selector_sub_type_pseudo_class_first_of_type, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FIRST_OF_TYPE */ + modest_finder_selector_sub_type_pseudo_class_focus, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FOCUS */ + modest_finder_selector_sub_type_pseudo_class_future, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUTURE */ + modest_finder_selector_sub_type_pseudo_class_hover, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_HOVER */ + modest_finder_selector_sub_type_pseudo_class_in_range, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_IN_RANGE */ + modest_finder_selector_sub_type_pseudo_class_indeterminate, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_INDETERMINATE */ + modest_finder_selector_sub_type_pseudo_class_invalid, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_INVALID */ + modest_finder_selector_sub_type_pseudo_class_last_child, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_LAST_CHILD */ + modest_finder_selector_sub_type_pseudo_class_last_of_type, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_LAST_OF_TYPE */ + modest_finder_selector_sub_type_pseudo_class_link, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_LINK */ + modest_finder_selector_sub_type_pseudo_class_only_child, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_ONLY_CHILD */ + modest_finder_selector_sub_type_pseudo_class_only_of_type, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_ONLY_OF_TYPE */ + modest_finder_selector_sub_type_pseudo_class_optional, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_OPTIONAL */ + modest_finder_selector_sub_type_pseudo_class_out_of_range, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_OUT_OF_RANGE */ + modest_finder_selector_sub_type_pseudo_class_past, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_PAST */ + modest_finder_selector_sub_type_pseudo_class_placeholder_shown, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_PLACEHOLDER_SHOWN */ + modest_finder_selector_sub_type_pseudo_class_read_only, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_READ_ONLY */ + modest_finder_selector_sub_type_pseudo_class_read_write, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_READ_WRITE */ + modest_finder_selector_sub_type_pseudo_class_required, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_REQUIRED */ + modest_finder_selector_sub_type_pseudo_class_root, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_ROOT */ + modest_finder_selector_sub_type_pseudo_class_scope, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_SCOPE */ + modest_finder_selector_sub_type_pseudo_class_target, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_TARGET */ + modest_finder_selector_sub_type_pseudo_class_user_error, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_USER_ERROR */ + modest_finder_selector_sub_type_pseudo_class_valid, /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_VALID */ + modest_finder_selector_sub_type_pseudo_class_visited /* MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_VISITED */ +}; + +/* see enum mycss_selectors_combinator (mycss_selectors_combinator_t) on mycss/selectors/myosi.h */ +static const modest_finder_selector_combinator_f modest_finder_static_selector_combinator_map[MyCSS_SELECTORS_COMBINATOR_LAST_ENTRY] = +{ + modest_finder_node_combinator_undef, /* MyCSS_SELECTORS_COMBINATOR_UNDEF */ + modest_finder_node_combinator_descendant, /* MyCSS_SELECTORS_COMBINATOR_DESCENDANT */ + modest_finder_node_combinator_child, /* MyCSS_SELECTORS_COMBINATOR_CHILD */ + modest_finder_node_combinator_next_sibling, /* MyCSS_SELECTORS_COMBINATOR_NEXT_SIBLING */ + modest_finder_node_combinator_following_sibling, /* MyCSS_SELECTORS_COMBINATOR_FOLLOWING_SIBLING */ + modest_finder_node_combinator_column /* MyCSS_SELECTORS_COMBINATOR_COLUMN */ +}; + +/* see enum mycss_selectors_match (mycss_selectors_match_t) on mycss/selectors/myosi.h */ +static const modest_finder_match_f modest_finder_static_selector_match_map[MyCSS_SELECTORS_MATCH_LAST_ENTRY] = +{ + modest_finder_match_attribute_eq, /* MyCSS_SELECTORS_MATCH_EQUAL */ + modest_finder_match_attribute_ws, /* MyCSS_SELECTORS_MATCH_INCLUDE */ + modest_finder_match_attribute_hsp, /* MyCSS_SELECTORS_MATCH_DASH */ + modest_finder_match_attribute_begin, /* MyCSS_SELECTORS_MATCH_PREFIX */ + modest_finder_match_attribute_end, /* MyCSS_SELECTORS_MATCH_SUFFIX */ + modest_finder_match_attribute_sub /* MyCSS_SELECTORS_MATCH_SUBSTRING */ +}; + +#endif /* MODEST_FINDER_RESOURCE_H */ diff --git a/source/modest/finder/type.c b/source/modest/finder/type.c new file mode 100644 index 0000000..ad25b9f --- /dev/null +++ b/source/modest/finder/type.c @@ -0,0 +1,126 @@ +/* + 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 "modest/finder/type.h" +#include "modest/finder/resource.h" + +bool modest_finder_selector_type_undef(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector) +{ + return false; +} + +bool modest_finder_selector_type_element(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector) +{ + /* namespace */ + if(selector->ns_entry) { + if(selector->ns_entry->ns_id != MyHTML_NAMESPACE_ANY && selector->ns_entry->ns_id != node->ns) + return false; + } + + /* tag match */ + myhtml_string_t *str = selector->key; + if(str->length == 1 && *str->data == '*') + return true; + + myhtml_tag_id_t tag_id = myhtml_tag_id_by_name(finder->tree, str->data, str->length); + + if(tag_id == node->tag_id) + return true; + + return false; +} + +bool modest_finder_selector_type_id(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector) +{ + if(node->token == NULL) + return false; + + return modest_finder_match_attribute_eq(node->token->attr_first, + "id", 2, + selector->key->data, selector->key->length, + (finder->tree->compat_mode != MyHTML_TREE_COMPAT_MODE_QUIRKS)); +} + +bool modest_finder_selector_type_class(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector) +{ + if(node->token == NULL) + return false; + + return modest_finder_match_attribute_ws(node->token->attr_first, + "class", 5, + selector->key->data, selector->key->length, + (finder->tree->compat_mode != MyHTML_TREE_COMPAT_MODE_QUIRKS)); +} + +bool modest_finder_selector_type_attribute(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector) +{ + /* namespace */ + if(selector->ns_entry) { + if(selector->ns_entry->ns_id != MyHTML_NAMESPACE_ANY && selector->ns_entry->ns_id != node->ns) + return false; + } + + if(node->token == NULL) + return false; + + mycss_selectors_object_attribute_t *sel_attr = mycss_selector_value_attribute(selector->value); + + if(sel_attr) { + if(sel_attr->match < MyCSS_SELECTORS_MATCH_LAST_ENTRY) + return modest_finder_static_selector_match_map[sel_attr->match](node->token->attr_first, + selector->key->data, selector->key->length, + sel_attr->value->data, sel_attr->value->length, + (sel_attr->mod & MyCSS_SELECTORS_MOD_I)); + } + else { + return modest_finder_match_attribute_only_key(node->token->attr_first, + selector->key->data, selector->key->length); + } + + return false; +} + +bool modest_finder_selector_type_pseudo_class_function(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector) +{ + if(selector->sub_type < MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_LAST_ENTRY) + return modest_finder_static_selector_sub_type_pseudo_class_function_map[selector->sub_type](finder, node, selector); + + return false; +} + +bool modest_finder_selector_type_pseudo_class(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector) +{ + if(selector->sub_type < MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_LAST_ENTRY) + return modest_finder_static_selector_sub_type_pseudo_class_map[selector->sub_type](finder, node, selector); + + return false; +} + +bool modest_finder_selector_type_pseudo_element_function(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector) +{ + return false; +} + +bool modest_finder_selector_type_pseudo_element(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector) +{ + return false; +} + + diff --git a/source/modest/finder/type.h b/source/modest/finder/type.h new file mode 100644 index 0000000..7070dea --- /dev/null +++ b/source/modest/finder/type.h @@ -0,0 +1,54 @@ +/* + 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) +*/ + +#ifndef MODEST_FINDER_TYPE_H +#define MODEST_FINDER_TYPE_H +#pragma once + +#include "modest/finder/myosi.h" +#include "modest/finder/finder.h" +#include "modest/finder/pseudo_class.h" +#include "modest/finder/match.h" +#include "myhtml/tree.h" +#include "myhtml/utils.h" +#include "mycss/selectors/myosi.h" +#include "mycss/selectors/list.h" +#include "mycss/selectors/value.h" + +#ifdef __cplusplus +//extern "C" { +#endif + +bool modest_finder_selector_type_undef(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_type_element(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_type_id(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_type_class(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_type_attribute(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_type_pseudo_class_function(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_type_pseudo_class(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_type_pseudo_element_function(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector); +bool modest_finder_selector_type_pseudo_element(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_entry_t* selector); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* MODEST_FINDER_TYPE_H */ |