mirror of
https://github.com/rkd77/elinks.git
synced 2025-02-02 15:09:23 -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
|
static int
|
||||||
match_attribute_value(struct dom_select_node *selector, struct dom_node *node)
|
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 *selvalue = &selector->node.data.attribute.value;
|
||||||
struct dom_string *value = &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
|
/* The attribute selector value should atleast be contained in the
|
||||||
* attribute value. */
|
* attribute value. */
|
||||||
if (value->length < selvalue->length)
|
if (value->length < selvalue->length)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* FIXME: Combine the 3 following to use an offset to specify where in
|
/* The following three matching methods requires the selector value to
|
||||||
* value, selvalue should match. */
|
* match a substring at a well-defined offset. */
|
||||||
|
|
||||||
if (has_attribute_match(selector, DOM_SELECT_ATTRIBUTE_EXACT)
|
if (has_attribute_match(selector, DOM_SELECT_ATTRIBUTE_EXACT)) {
|
||||||
&& dom_string_casecmp(value, selvalue))
|
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;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (has_attribute_match(selector, DOM_SELECT_ATTRIBUTE_BEGIN))
|
do_compare = 1;
|
||||||
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 {
|
||||||
|
if (do_compare
|
||||||
|
&& !dom_string_ncasecmp(&str, selvalue, selvalue->length)) {
|
||||||
|
/* "Contains" matches no matter what comes after. */
|
||||||
|
if (str.length == selvalue->length)
|
||||||
return 1;
|
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
|
/* 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;
|
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 is_dom_string_set(str) ((str)->string && (str)->length)
|
||||||
|
|
||||||
#define done_dom_string(str) mem_free((str)->string);
|
#define done_dom_string(str) mem_free((str)->string);
|
||||||
|
Loading…
Reference in New Issue
Block a user