9#include <libxml/xmlstring.h>
10#include <libxml/dict.h>
24#define CMP_NODE_TYPE(node, ty) ((unsigned char) (node)->type == ty)
38static zend_always_inline bool lxb_selectors_adapted_is_matchable_child(
const xmlNode *node)
43static zend_always_inline bool lxb_selectors_adapted_cmp_local_name_literal(
const xmlNode *node,
const char *
name)
45 return strcmp((
const char *) node->name,
name) == 0;
48static zend_always_inline bool lxb_selectors_adapted_cmp_ns(
const xmlNode *
a,
const xmlNode *b)
51 return a->ns == b->ns || (
a->ns !=
NULL && b->ns !=
NULL && xmlStrEqual(
a->ns->href, b->ns->href));
56 uintptr_t
ptr = (uintptr_t) node->name;
57 if (id->interned && (
ptr & (ZEND_MM_ALIGNMENT - 1)) != 0) {
60 return node->name ==
id->name;
63 return strcmp((
const char *) node->name, (
const char *) id->name) == 0;
72 size_t name_bound =
strlen((
const char *)
name) + 1;
73 for (
const xmlAttr *cur = node->properties; cur !=
NULL; cur = cur->next) {
80 attr = xmlHasProp(node, (
const xmlChar *)
name);
109static bool lxb_selectors_is_lowercased_html_attrib_name(
const lxb_css_selector_t *selector)
111 return lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"accept"))
112 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"accept-charset"))
113 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"align"))
114 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"alink"))
115 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"axis"))
116 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"bgcolor"))
117 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"charset"))
118 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"checked"))
119 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"clear"))
120 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"codetype"))
121 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"color"))
122 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"compact"))
123 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"declare"))
124 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"defer"))
125 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"dir"))
126 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"direction"))
127 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"disabled"))
128 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"enctype"))
129 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"face"))
130 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"frame"))
131 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"hreflang"))
132 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"http-equiv"))
133 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"lang"))
134 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"language"))
135 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"link"))
136 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"media"))
137 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"method"))
138 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"multiple"))
139 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"nohref"))
140 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"noresize"))
141 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"noshade"))
142 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"nowrap"))
143 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"readonly"))
144 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"rel"))
145 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"rev"))
146 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"rules"))
147 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"scope"))
148 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"scrolling"))
149 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"selected"))
150 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"shape"))
151 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"target"))
152 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"text"))
153 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"type"))
154 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"valign"))
155 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"valuetype"))
156 || lxb_selectors_attrib_name_cmp(selector,
ZEND_STRL(
"vlink"));
163 if (node->doc !=
NULL && node->doc->dict !=
NULL) {
164 const xmlChar *interned = xmlDictExists(node->doc->dict, selector->
name.
data, selector->
name.
length);
165 if (interned !=
NULL) {
166 entry->
id.
name = interned;
179 lxb_selectors_adapted_set_entry_id_ex(entry, selector, node);
184lxb_selectors_state_tree(
lxb_selectors_t *selectors,
const xmlNode *root,
188lxb_selectors_state_run(
lxb_selectors_t *selectors,
const xmlNode *node,
196lxb_selectors_state_find_check(
lxb_selectors_t *selectors,
const xmlNode *node,
204static const xmlNode *
207static const xmlNode *
208lxb_selectors_state_has_relative(
const xmlNode *node,
232lxb_selectors_match_id(
const lxb_css_selector_t *selector,
const xmlNode *node,
bool quirks);
244 const xmlNode *node);
248 const xmlNode *node);
252 const xmlNode *node);
255lxb_selectors_pseudo_class_disabled(
const xmlNode *node);
258lxb_selectors_pseudo_class_first_child(
const xmlNode *node);
261lxb_selectors_pseudo_class_first_of_type(
const xmlNode *node);
264lxb_selectors_pseudo_class_last_child(
const xmlNode *node);
267lxb_selectors_pseudo_class_last_of_type(
const xmlNode *node);
270lxb_selectors_pseudo_class_read_write(
const xmlNode *node);
276lxb_selectors_cb_ok(
const xmlNode *node,
280lxb_selectors_cb_not(
const xmlNode *node,
330 while (node !=
NULL) {
332 && lxb_selectors_match(selectors, entry, selector, node))
347 if (lxb_selectors_match(selectors, entry, selector, node)) {
361 && lxb_selectors_match(selectors, entry, selector, root))
375 while (node !=
NULL) {
377 if (lxb_selectors_match(selectors, entry, selector, node)) {
396 while (node !=
NULL) {
398 lxb_selectors_match(selectors, entry, selector, node))
423 nested.
entry = entry;
430 return lxb_selectors_state_tree(selectors, root, list);
452 nested.
entry = entry;
459 status = lxb_selectors_state_run(selectors, node, list);
467lxb_selectors_state_tree(
lxb_selectors_t *selectors,
const xmlNode *root,
479 node = root->children;
485 node = root->children;
497 status = lxb_selectors_state_run(selectors, node, list);
508 if (node->children !=
NULL) {
509 node = node->children;
515 while (node != root && node->next ==
NULL) {
535lxb_selectors_state_run(
lxb_selectors_t *selectors,
const xmlNode *node,
543 selectors->
state = lxb_selectors_state_find;
544 selectors->
first = entry;
549 entry = selectors->
state(selectors, entry);
551 while (entry !=
NULL);
582 switch (pseudo->
type) {
612 selectors->
state = lxb_selectors_state_pseudo_class_function;
627 selector, entry->
node);
632 selector, entry->
node);
637 selector, entry->
node);
642 selector, entry->
node);
647 selector, entry->
node);
656 return lxb_selectors_state_find_check(selectors, node, selector, entry);
660lxb_selectors_state_find_check(
lxb_selectors_t *selectors,
const xmlNode *node,
722 node = entry->
node->parent;
733 node = entry->
node->prev;
748 while (node ==
NULL);
766 entry = selectors->
first;
796 const xmlNode *node, *base;
804 base = lxb_selectors_next_node(
current);
809 pseudo = &
current->parent->last->selector->u.pseudo;
811 switch (pseudo->
type) {
814 node = lxb_selectors_state_has_relative(base, list->
first);
820 selectors->
state = lxb_selectors_state_find;
822 return lxb_selectors_state_find_check(selectors,
NULL,
830 current->return_state = lxb_selectors_state_after_find_has;
831 current->cb = lxb_selectors_cb_ok;
835 selectors->
state = lxb_selectors_state_find;
844 current->return_state = lxb_selectors_state_after_find;
845 current->cb = lxb_selectors_cb_ok;
849 selectors->
state = lxb_selectors_state_find;
856 current->return_state = lxb_selectors_state_after_find;
857 current->cb = lxb_selectors_cb_not;
861 selectors->
state = lxb_selectors_state_find;
871 current->return_state = lxb_selectors_state_after_nth_child;
872 current->cb = lxb_selectors_cb_ok;
878 selectors->
state = lxb_selectors_state_find;
902 selectors->
state = lxb_selectors_state_find;
904 return lxb_selectors_state_find_check(selectors,
NULL,
908static const xmlNode *
911 const xmlNode *node =
main->entry->node;
913 switch (
main->parent->last->combinator) {
916 if (node->parent ==
NULL
936 while (node !=
NULL) {
947static const xmlNode *
948lxb_selectors_state_has_relative(
const xmlNode *node,
951 const xmlNode *root = node;
956 node = node->children;
968 while (node !=
NULL) {
973 while (node != root && node->next ==
NULL && node->parent !=
NULL) {
1001 selectors->
state = lxb_selectors_state_find;
1003 return lxb_selectors_state_find_check(selectors, node,
1004 parent->selector, parent);
1012 if (node->children !=
NULL) {
1013 node = node->children;
1019 while (node !=
current->root && node->next ==
NULL) {
1020 node = node->parent;
1061 selectors->
state = lxb_selectors_state_find;
1070 selectors->
state = lxb_selectors_state_find;
1072 return lxb_selectors_state_find_check(selectors,
NULL,
1073 parent->selector, parent);
1081 const xmlNode *node;
1093 selectors->
state = lxb_selectors_state_find;
1095 return lxb_selectors_state_find_check(selectors, node,
1096 parent->selector, parent);
1101 switch (
current->parent->last->combinator) {
1103 if (node->parent !=
NULL
1106 node = node->parent;
1139 selectors->
state = lxb_selectors_state_find;
1141 return lxb_selectors_state_find_check(selectors, node,
1142 parent->selector, parent);
1146 selectors->
state = lxb_selectors_state_find;
1156 const xmlNode *node;
1163 selector =
current->parent->last->selector;
1171 else if (
current->root == node) {
1179 while (node !=
NULL) {
1190 while (node !=
NULL) {
1205 selectors->
state = lxb_selectors_state_find;
1212 found = lxb_selectors_anb_calc(pseudo->
data,
current->index);
1217 selectors->
state = lxb_selectors_state_find;
1222 return lxb_selectors_state_find_check(selectors, node,
1223 parent->selector, parent);
1230 switch (selector->
type) {
1235 return lxb_selectors_match_element(selector, node, entry);
1241 const xmlAttr *dom_attr = lxb_selectors_adapted_attr(node, (
const lxb_char_t *)
"class");
1242 if (dom_attr ==
NULL) {
1249 dom_lxb_str_wrapper_release(&trg);
1253 bool ret = lxb_selectors_match_class(&trg.
str,
1255 dom_lxb_str_wrapper_release(&trg);
1260 return lxb_selectors_match_attribute(selector, node, entry);
1263 return lxb_selectors_pseudo_class(selector, node);
1266 return lxb_selectors_pseudo_class_function(selector, node);
1269 return lxb_selectors_pseudo_element(selector, node);
1284 lxb_selectors_adapted_set_entry_id(entry, selector, node);
1285 return lxb_selectors_adapted_cmp_local_name_id(node, &entry->
id);
1289lxb_selectors_match_id(
const lxb_css_selector_t *selector,
const xmlNode *node,
bool quirks)
1291 const xmlAttr *dom_attr = lxb_selectors_adapted_attr(node, (
const lxb_char_t *)
"id");
1292 if (dom_attr ==
NULL) {
1306 dom_lxb_str_wrapper_release(&trg);
1317 if (target->length < src->
length) {
1371 switch (
attr->match) {
1386 return lxb_selectors_match_class(trg, src, ins);
1468 lxb_selectors_adapted_set_entry_id(entry, selector, node);
1470 const xmlAttr *dom_attr = lxb_selectors_adapted_attr(node, entry->
id.
name);
1471 if (dom_attr ==
NULL) {
1482 bool res = lxb_selectors_match_attribute_value(
1488 dom_lxb_str_wrapper_release(&trg);
1494 const xmlNode *node)
1498 static const lxb_char_t checkbox[] =
"checkbox";
1499 static const size_t checkbox_length =
sizeof(checkbox) /
sizeof(
lxb_char_t) - 1;
1502 static const size_t radio_length =
sizeof(radio) /
sizeof(
lxb_char_t) - 1;
1504 switch (pseudo->
type) {
1511 && (lxb_selectors_adapted_cmp_local_name_literal(node,
"a")
1512 || lxb_selectors_adapted_cmp_local_name_literal(node,
"area")))
1514 return lxb_selectors_adapted_has_attr(node,
"href");
1530 if (lxb_selectors_adapted_cmp_local_name_literal(node,
"input")) {
1531 const xmlAttr *dom_attr = lxb_selectors_adapted_attr(node, (
const lxb_char_t *)
"type");
1532 if (dom_attr ==
NULL) {
1541 res = lxb_selectors_adapted_has_attr(node,
"checked");
1546 res = lxb_selectors_adapted_has_attr(node,
"checked");
1550 dom_lxb_str_wrapper_release(&str);
1554 else if(lxb_selectors_adapted_cmp_local_name_literal(node,
"option")) {
1555 return lxb_selectors_adapted_has_attr(node,
"selected");
1565 return lxb_selectors_pseudo_class_disabled(node);
1568 node = node->children;
1570 while (node !=
NULL) {
1583 return !lxb_selectors_pseudo_class_disabled(node);
1586 return lxb_selectors_pseudo_class_first_child(node);
1589 return lxb_selectors_pseudo_class_first_of_type(node);
1619 return lxb_selectors_pseudo_class_last_child(node);
1622 return lxb_selectors_pseudo_class_last_of_type(node);
1627 && (lxb_selectors_adapted_cmp_local_name_literal(node,
"a")
1628 || lxb_selectors_adapted_cmp_local_name_literal(node,
"area")))
1630 return lxb_selectors_adapted_has_attr(node,
"href");
1639 return lxb_selectors_pseudo_class_first_child(node)
1640 && lxb_selectors_pseudo_class_last_child(node);
1643 return lxb_selectors_pseudo_class_first_of_type(node)
1644 && lxb_selectors_pseudo_class_last_of_type(node);
1648 && (lxb_selectors_adapted_cmp_local_name_literal(node,
"input")
1649 || lxb_selectors_adapted_cmp_local_name_literal(node,
"select")
1650 || lxb_selectors_adapted_cmp_local_name_literal(node,
"textarea")))
1652 return !lxb_selectors_adapted_has_attr(node,
"required");
1665 && (lxb_selectors_adapted_cmp_local_name_literal(node,
"input")
1666 || lxb_selectors_adapted_cmp_local_name_literal(node,
"textarea")))
1668 return lxb_selectors_adapted_has_attr(node,
"placeholder");
1674 return !lxb_selectors_pseudo_class_read_write(node);
1677 return lxb_selectors_pseudo_class_read_write(node);
1681 && (lxb_selectors_adapted_cmp_local_name_literal(node,
"input")
1682 || lxb_selectors_adapted_cmp_local_name_literal(node,
"select")
1683 || lxb_selectors_adapted_cmp_local_name_literal(node,
"textarea")))
1685 return lxb_selectors_adapted_has_attr(node,
"required");
1691 return node->parent !=
NULL
1722 const xmlNode *node)
1725 const xmlNode *base;
1730 switch (pseudo->
type) {
1736 while (node !=
NULL) {
1737 if (lxb_selectors_adapted_is_matchable_child(node))
1746 while (node !=
NULL) {
1747 if (lxb_selectors_adapted_is_matchable_child(node))
1756 return lxb_selectors_anb_calc(pseudo->
data, index);
1764 while (node !=
NULL) {
1765 if(lxb_selectors_adapted_is_matchable_child(node)
1766 && xmlStrEqual(node->name, base->name)
1767 && lxb_selectors_adapted_cmp_ns(node, base))
1776 while (node !=
NULL) {
1777 if(lxb_selectors_adapted_is_matchable_child(node)
1778 && xmlStrEqual(node->name, base->name)
1779 && lxb_selectors_adapted_cmp_ns(node, base))
1788 return lxb_selectors_anb_calc(pseudo->
data, index);
1803 const xmlNode *node)
1807 switch (pseudo->
type) {
1828lxb_selectors_pseudo_class_disabled(
const xmlNode *node)
1834 if (lxb_selectors_adapted_has_attr(node,
"disabled")
1835 && (lxb_selectors_adapted_cmp_local_name_literal(node,
"button")
1836 || lxb_selectors_adapted_cmp_local_name_literal(node,
"input")
1837 || lxb_selectors_adapted_cmp_local_name_literal(node,
"select")
1838 || lxb_selectors_adapted_cmp_local_name_literal(node,
"textarea")
1839 || lxb_selectors_adapted_cmp_local_name_literal(node,
"optgroup")
1840 || lxb_selectors_adapted_cmp_local_name_literal(node,
"fieldset")))
1845 if (lxb_selectors_adapted_cmp_local_name_literal(node,
"fieldset")) {
1846 const xmlNode *fieldset = node;
1847 node = node->parent;
1849 while (node !=
NULL && lxb_selectors_adapted_is_matchable_child(node)) {
1852 && lxb_selectors_adapted_cmp_local_name_literal(node,
"fieldset")
1853 && lxb_selectors_adapted_has_attr(node,
"disabled"))
1856 const xmlNode *search_current = node->children;
1860 && lxb_selectors_adapted_cmp_local_name_literal(search_current,
"legend")) {
1862 const xmlNode *inner_search_current = fieldset;
1866 if (inner_search_current == search_current) {
1870 inner_search_current = inner_search_current->parent;
1871 }
while (inner_search_current !=
NULL);
1876 search_current = search_current->next;
1877 }
while (search_current !=
NULL);
1880 node = node->parent;
1888lxb_selectors_pseudo_class_first_child(
const xmlNode *node)
1892 while (node !=
NULL) {
1893 if (lxb_selectors_adapted_is_matchable_child(node))
1905lxb_selectors_pseudo_class_first_of_type(
const xmlNode *node)
1907 const xmlNode *root = node;
1911 if (lxb_selectors_adapted_is_matchable_child(node)
1912 && xmlStrEqual(node->name, root->name)
1913 && lxb_selectors_adapted_cmp_ns(node, root))
1925lxb_selectors_pseudo_class_last_child(
const xmlNode *node)
1929 while (node !=
NULL) {
1930 if (lxb_selectors_adapted_is_matchable_child(node))
1942lxb_selectors_pseudo_class_last_of_type(
const xmlNode *node)
1944 const xmlNode *root = node;
1948 if (lxb_selectors_adapted_is_matchable_child(node)
1949 && xmlStrEqual(node->name, root->name)
1950 && lxb_selectors_adapted_cmp_ns(node, root))
1963lxb_selectors_pseudo_class_read_write(
const xmlNode *node)
1966 if (lxb_selectors_adapted_cmp_local_name_literal(node,
"input")
1967 || lxb_selectors_adapted_cmp_local_name_literal(node,
"textarea")) {
1968 return !lxb_selectors_adapted_has_attr(node,
"readonly") && !lxb_selectors_adapted_has_attr(node,
"disabled");
1970 const xmlAttr *
attr = lxb_selectors_adapted_attr(node, (
const lxb_char_t *)
"contenteditable");
1983 if (anb->
anb.
a == 0) {
1984 if (anb->
anb.
b >= 0 && (
size_t) anb->
anb.
b == index) {
1989 num = ((double) index - (double) anb->
anb.
b) / (
double) anb->
anb.
a;
1991 if (num >= 0.0f && (num - trunc(num)) == 0.0f) {
2000lxb_selectors_cb_ok(
const xmlNode *node,
2003 *((
bool *) ctx) =
true;
2008lxb_selectors_cb_not(
const xmlNode *node,
2011 *((
bool *) ctx) =
false;
struct lxb_css_selector lxb_css_selector_t
struct lxb_css_selector_list lxb_css_selector_list_t
void * lexbor_dobject_calloc(lexbor_dobject_t *dobject)
lxb_status_t lexbor_dobject_init(lexbor_dobject_t *dobject, size_t chunk_size, size_t struct_size)
void lexbor_dobject_clean(lexbor_dobject_t *dobject)
lexbor_dobject_t * lexbor_dobject_destroy(lexbor_dobject_t *dobject, bool destroy_self)
lexbor_dobject_t * lexbor_dobject_create(void)
void php_dom_throw_error_with_message(dom_exception_code error_code, const char *error_message, bool strict_error)
int main(int argc, char **argv)
PHP_DOM_EXPORT const php_dom_ns_magic_token * php_dom_ns_is_html_magic_token
PHP_DOM_EXPORT bool php_dom_ns_is_fast(const xmlNode *nodep, const php_dom_ns_magic_token *magic_token)
PHP_DOM_EXPORT bool php_dom_ns_is_html_and_document_is_html(const xmlNode *nodep)
bool dom_compare_value(const xmlAttr *attr, const xmlChar *value)
const XML_HTML_DOCUMENT_NODE
const XML_DOCUMENT_FRAG_NODE
unsigned const char * end
unsigned const char * pos
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_IN_RANGE
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_ACTIVE
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_PAST
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_ENABLED
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_ANY_LINK
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_WARNING
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_TARGET_WITHIN
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_LOCAL_LINK
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_FULLSCREEN
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_CURRENT
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_ROOT
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_LINK
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_VISITED
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_READ_ONLY
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_FOCUS_WITHIN
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_FOCUS
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_INDETERMINATE
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_FUTURE
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_FIRST_CHILD
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_FOCUS_VISIBLE
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_LAST_OF_TYPE
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_USER_INVALID
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_VALID
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_OPTIONAL
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_SCOPE
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_DISABLED
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_EMPTY
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_DEFAULT
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_READ_WRITE
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_PLACEHOLDER_SHOWN
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_ONLY_OF_TYPE
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_FIRST_OF_TYPE
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_INVALID
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_CHECKED
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_BLANK
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_REQUIRED
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_ONLY_CHILD
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_HOVER
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_TARGET
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_OUT_OF_RANGE
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_LAST_CHILD
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_COL
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_OF_TYPE
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_IS
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_DIR
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_HAS
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_COL
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_CURRENT
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_LANG
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_WHERE
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_CHILD
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_OF_TYPE
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NOT
@ LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_CHILD
@ LXB_CSS_SELECTOR_PSEUDO_ELEMENT_SELECTION
@ LXB_CSS_SELECTOR_PSEUDO_ELEMENT_BACKDROP
@ LXB_CSS_SELECTOR_PSEUDO_ELEMENT_AFTER
@ LXB_CSS_SELECTOR_PSEUDO_ELEMENT_GRAMMAR_ERROR
@ LXB_CSS_SELECTOR_PSEUDO_ELEMENT_TARGET_TEXT
@ LXB_CSS_SELECTOR_PSEUDO_ELEMENT_PLACEHOLDER
@ LXB_CSS_SELECTOR_PSEUDO_ELEMENT_FIRST_LINE
@ LXB_CSS_SELECTOR_PSEUDO_ELEMENT_BEFORE
@ LXB_CSS_SELECTOR_PSEUDO_ELEMENT_INACTIVE_SELECTION
@ LXB_CSS_SELECTOR_PSEUDO_ELEMENT_SPELLING_ERROR
@ LXB_CSS_SELECTOR_PSEUDO_ELEMENT_MARKER
@ LXB_CSS_SELECTOR_PSEUDO_ELEMENT_FIRST_LETTER
uint32_t lxb_css_selector_specificity_t
@ LXB_CSS_SELECTOR_COMBINATOR_CELL
@ LXB_CSS_SELECTOR_COMBINATOR_CLOSE
@ LXB_CSS_SELECTOR_COMBINATOR_DESCENDANT
@ LXB_CSS_SELECTOR_COMBINATOR_SIBLING
@ LXB_CSS_SELECTOR_COMBINATOR_CHILD
@ LXB_CSS_SELECTOR_COMBINATOR_FOLLOWING
@ LXB_CSS_SELECTOR_TYPE_ELEMENT
@ LXB_CSS_SELECTOR_TYPE_PSEUDO_CLASS_FUNCTION
@ LXB_CSS_SELECTOR_TYPE_PSEUDO_CLASS
@ LXB_CSS_SELECTOR_TYPE_ATTRIBUTE
@ LXB_CSS_SELECTOR_TYPE_PSEUDO_ELEMENT_FUNCTION
@ LXB_CSS_SELECTOR_TYPE_ID
@ LXB_CSS_SELECTOR_TYPE_CLASS
@ LXB_CSS_SELECTOR_TYPE_PSEUDO_ELEMENT
@ LXB_CSS_SELECTOR_TYPE_ANY
@ LXB_CSS_SELECTOR_MODIFIER_I
@ LXB_CSS_SELECTOR_MATCH_PREFIX
@ LXB_CSS_SELECTOR_MATCH_SUBSTRING
@ LXB_CSS_SELECTOR_MATCH_DASH
@ LXB_CSS_SELECTOR_MATCH_SUFFIX
@ LXB_CSS_SELECTOR_MATCH_INCLUDE
@ LXB_CSS_SELECTOR_MATCH_EQUAL
lxb_status_t lxb_selectors_find(lxb_selectors_t *selectors, const xmlNode *root, const lxb_css_selector_list_t *list, lxb_selectors_cb_f cb, void *ctx)
void lxb_selectors_destroy(lxb_selectors_t *selectors)
#define CMP_NODE_TYPE(node, ty)
lxb_inline const xmlNode * lxb_selectors_close(lxb_selectors_t *selectors, lxb_selectors_entry_t *entry, const lxb_css_selector_t *selector, const xmlNode *node)
lxb_status_t lxb_selectors_init(lxb_selectors_t *selectors)
lxb_inline const xmlNode * lxb_selectors_sibling(lxb_selectors_t *selectors, lxb_selectors_entry_t *entry, const lxb_css_selector_t *selector, const xmlNode *node)
lxb_status_t lxb_selectors_match_node(lxb_selectors_t *selectors, const xmlNode *node, const lxb_css_selector_list_t *list, lxb_selectors_cb_f cb, void *ctx)
void lxb_selectors_clean(lxb_selectors_t *selectors)
lxb_inline const xmlNode * lxb_selectors_child(lxb_selectors_t *selectors, lxb_selectors_entry_t *entry, const lxb_css_selector_t *selector, const xmlNode *root)
lxb_inline const xmlNode * lxb_selectors_following(lxb_selectors_t *selectors, lxb_selectors_entry_t *entry, const lxb_css_selector_t *selector, const xmlNode *node)
lxb_inline const xmlNode * lxb_selectors_descendant(lxb_selectors_t *selectors, lxb_selectors_entry_t *entry, const lxb_css_selector_t *selector, const xmlNode *node)
struct lxb_selectors_entry lxb_selectors_entry_t
struct lxb_selectors lxb_selectors_t
struct lxb_selectors_nested lxb_selectors_nested_t
@ LXB_SELECTORS_OPT_DEFAULT
@ LXB_SELECTORS_OPT_QUIRKS_MODE
@ LXB_SELECTORS_OPT_MATCH_FIRST
@ LXB_SELECTORS_OPT_MATCH_ROOT
lxb_status_t(* lxb_selectors_cb_f)(const xmlNode *node, lxb_css_selector_specificity_t spec, void *ctx)
bool lexbor_str_data_ncmp_contain(const lxb_char_t *where, size_t where_size, const lxb_char_t *what, size_t what_size)
bool lexbor_str_data_ncasecmp(const lxb_char_t *first, const lxb_char_t *sec, size_t size)
bool lexbor_str_data_ncmp(const lxb_char_t *first, const lxb_char_t *sec, size_t size)
bool lexbor_str_data_nlocmp_right(const lxb_char_t *first, const lxb_char_t *sec, size_t size)
bool lexbor_str_data_ncasecmp_contain(const lxb_char_t *where, size_t where_size, const lxb_char_t *what, size_t what_size)
lxb_css_selector_list_t * of
lxb_css_selector_list_t * next
lxb_css_selector_t * last
lxb_css_selector_specificity_t specificity
lxb_css_selector_t * first
lxb_css_selector_type_t type
lxb_css_selector_t * prev
lxb_css_selector_list_t * list
union lxb_css_selector::lxb_css_selector_u u
lxb_css_selector_combinator_t combinator
bool attr_case_insensitive
lxb_selectors_entry_t * following
lxb_selectors_entry_t * prev
lxb_selectors_nested_t * nested
lxb_selectors_adapted_id id
const lxb_css_selector_t * selector
lxb_selectors_entry_t * next
lxb_css_selector_combinator_t combinator
lxb_selectors_state_cb_f return_state
lxb_selectors_nested_t * parent
lxb_selectors_entry_t * entry
lxb_selectors_entry_t * last
lxb_selectors_state_cb_f state
lxb_selectors_opt_t options
lexbor_dobject_t * nested
lxb_selectors_entry_t * first
lxb_selectors_nested_t * current
unsigned int lxb_status_t
lxb_css_selector_attribute_t attribute
lxb_css_selector_pseudo_t pseudo
#define lexbor_utils_whitespace(onechar, action, logic)
strcmp(string $string1, string $string2)
#define zend_always_inline
#define EMPTY_SWITCH_DEFAULT_CASE()