mirror of
https://github.com/rkd77/elinks.git
synced 2024-11-04 08:17:17 -05:00
match_attribute_value(): Actually do the matching
This is still untested like the last patch.
This commit is contained in:
parent
fc35d9ee33
commit
40ae683bfb
@ -612,42 +612,104 @@ get_child_dom_select_node(struct dom_select_node *selector,
|
||||
static int
|
||||
match_attribute_value(struct dom_select_node *selector, struct dom_node *node)
|
||||
{
|
||||
struct dom_string str;
|
||||
struct dom_string *selvalue = &selector->node.data.attribute.value;
|
||||
struct dom_string *value = &node->data.attribute.value;
|
||||
unsigned char separator;
|
||||
int do_compare;
|
||||
|
||||
assert(selvalue->length);
|
||||
|
||||
/* The attribute selector value should atleast be contained in the
|
||||
* attribute value. */
|
||||
if (value->length < selvalue->length)
|
||||
return 0;
|
||||
|
||||
/* FIXME: Combine the 3 following to use an offset to specify where in
|
||||
* value, selvalue should match. */
|
||||
/* The following three matching methods requires the selector value to
|
||||
* match a substring at a well-defined offset. */
|
||||
|
||||
if (has_attribute_match(selector, DOM_SELECT_ATTRIBUTE_EXACT)
|
||||
&& dom_string_casecmp(value, selvalue))
|
||||
if (has_attribute_match(selector, DOM_SELECT_ATTRIBUTE_EXACT)) {
|
||||
return !dom_string_casecmp(value, selvalue);
|
||||
}
|
||||
|
||||
if (has_attribute_match(selector, DOM_SELECT_ATTRIBUTE_BEGIN)) {
|
||||
set_dom_string(&str, value->string, selvalue->length);
|
||||
|
||||
return !dom_string_casecmp(&str, selvalue);
|
||||
}
|
||||
|
||||
if (has_attribute_match(selector, DOM_SELECT_ATTRIBUTE_END)) {
|
||||
size_t offset = value->length - selvalue->length;
|
||||
|
||||
set_dom_string(&str, value->string + offset, selvalue->length);
|
||||
|
||||
return !dom_string_casecmp(&str, selvalue);
|
||||
}
|
||||
|
||||
/* The 3 following matching methods requires the selector value to be a
|
||||
* substring of the value enclosed in a specific separator (with the
|
||||
* begining and ending of the attribute value both being valid
|
||||
* separators). */
|
||||
|
||||
set_dom_string(&str, value->string, value->length);
|
||||
|
||||
if (has_attribute_match(selector, DOM_SELECT_ATTRIBUTE_HYPHEN_LIST)) {
|
||||
separator = '-';
|
||||
|
||||
} else if (has_attribute_match(selector, DOM_SELECT_ATTRIBUTE_CONTAINS)) {
|
||||
separator = '\0';
|
||||
|
||||
} if (has_attribute_match(selector, DOM_SELECT_ATTRIBUTE_SPACE_LIST)) {
|
||||
separator = ' ';
|
||||
|
||||
} else {
|
||||
INTERNAL("No attribute selector matching method defined");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (has_attribute_match(selector, DOM_SELECT_ATTRIBUTE_BEGIN))
|
||||
return 0;
|
||||
|
||||
if (has_attribute_match(selector, DOM_SELECT_ATTRIBUTE_END))
|
||||
return 0;
|
||||
|
||||
/* FIXME: Combine the 3 following to simply strstr()-search the value
|
||||
* and based on a char group check if it is separated either by
|
||||
* begining, end or the values in the char group: '-' for
|
||||
* DOM_SELECT_ATTRIBUTE_HYPHEN_LIST, etc. */
|
||||
|
||||
if (has_attribute_match(selector, DOM_SELECT_ATTRIBUTE_SPACE_LIST))
|
||||
return 0;
|
||||
|
||||
if (has_attribute_match(selector, DOM_SELECT_ATTRIBUTE_HYPHEN_LIST))
|
||||
return 0;
|
||||
|
||||
if (has_attribute_match(selector, DOM_SELECT_ATTRIBUTE_CONTAINS))
|
||||
return 0;
|
||||
do_compare = 1;
|
||||
|
||||
do {
|
||||
if (do_compare
|
||||
&& !dom_string_ncasecmp(&str, selvalue, selvalue->length)) {
|
||||
/* "Contains" matches no matter what comes after. */
|
||||
if (str.length == selvalue->length)
|
||||
return 1;
|
||||
|
||||
switch (separator) {
|
||||
case '\0':
|
||||
/* "Contains" matches no matter what comes after. */
|
||||
return 1;
|
||||
|
||||
case '-':
|
||||
if (str.string[str.length] == separator)
|
||||
return 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (isspace(str.string[str.length]))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
switch (separator) {
|
||||
case '\0':
|
||||
do_compare = 1;
|
||||
break;
|
||||
|
||||
case '-':
|
||||
do_compare = (str.string[0] == '-');
|
||||
break;
|
||||
|
||||
default:
|
||||
do_compare = isspace(str.string[0]);
|
||||
}
|
||||
|
||||
str.length--, str.string++;
|
||||
|
||||
} while (str.length >= selvalue->length);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Match the attribute of an element @node against attribute selector nodes
|
||||
|
@ -27,6 +27,12 @@ dom_string_casecmp(struct dom_string *string1, struct dom_string *string2)
|
||||
return string_diff ? string_diff : string1->length - string2->length;
|
||||
}
|
||||
|
||||
static inline int
|
||||
dom_string_ncasecmp(struct dom_string *string1, struct dom_string *string2, size_t length)
|
||||
{
|
||||
return strncasecmp(string1->string, string2->string, length);
|
||||
}
|
||||
|
||||
#define is_dom_string_set(str) ((str)->string && (str)->length)
|
||||
|
||||
#define done_dom_string(str) mem_free((str)->string);
|
||||
|
Loading…
Reference in New Issue
Block a user