Skip to content

Commit e1182ae

Browse files
committed
Implement matches() (TODO: tests and cleanup)
1 parent b7717be commit e1182ae

File tree

5 files changed

+67
-1
lines changed

5 files changed

+67
-1
lines changed

ext/dom/element.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1670,4 +1670,20 @@ PHP_METHOD(DOMElement, querySelectorAll)
16701670
php_dom_dispatch_query_selector(INTERNAL_FUNCTION_PARAM_PASSTHRU, true);
16711671
}
16721672

1673+
PHP_METHOD(DOMElement, matches)
1674+
{
1675+
zend_string *selectors_str;
1676+
1677+
ZEND_PARSE_PARAMETERS_START(1, 1)
1678+
Z_PARAM_STR(selectors_str)
1679+
ZEND_PARSE_PARAMETERS_END();
1680+
1681+
xmlNodePtr thisp;
1682+
dom_object *intern;
1683+
zval *id;
1684+
DOM_GET_THIS_OBJ(thisp, id, xmlNodePtr, intern);
1685+
1686+
dom_element_matches(thisp, intern, return_value, selectors_str);
1687+
}
1688+
16731689
#endif

ext/dom/parentnode.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -830,11 +830,18 @@ void dom_parent_node_replace_children(dom_object *context, zval *nodes, uint32_t
830830
* CSS selector implementation below
831831
*/
832832

833+
// TODO: probably best if this is all moved to another file???
834+
833835
typedef struct {
834836
HashTable *list;
835837
dom_object *intern;
836838
} dom_query_selector_all_ctx;
837839

840+
typedef struct {
841+
const xmlNode *reference;
842+
bool result;
843+
} dom_query_selector_matches_ctx;
844+
838845
lxb_status_t php_dom_query_selector_find_single_callback(const xmlNode *node, lxb_css_selector_specificity_t spec, void *ctx)
839846
{
840847
xmlNodePtr *result = (xmlNodePtr *) ctx;
@@ -853,6 +860,16 @@ lxb_status_t php_dom_query_selector_find_array_callback(const xmlNode *node, lxb
853860
return LXB_STATUS_OK;
854861
}
855862

863+
lxb_status_t php_dom_query_selector_find_matches_callback(const xmlNode *node, lxb_css_selector_specificity_t spec, void *ctx)
864+
{
865+
dom_query_selector_matches_ctx *matches_ctx = (dom_query_selector_matches_ctx *) ctx;
866+
if (node == matches_ctx->reference) {
867+
matches_ctx->result = true;
868+
return LXB_STATUS_STOP;
869+
}
870+
return LXB_STATUS_OK;
871+
}
872+
856873
static lxb_status_t php_dom_query_selector_common(zval *return_value, dom_object *intern, const xmlNode *root, zend_string *selectors_str, lxb_selectors_cb_f cb, void *ctx)
857874
{
858875
lxb_status_t status;
@@ -939,4 +956,28 @@ void dom_parent_node_query_selector_all(xmlNodePtr thisp, dom_object *intern, zv
939956
}
940957
}
941958

959+
/* https://dom.spec.whatwg.org/#dom-element-matches */
960+
void dom_element_matches(xmlNodePtr thisp, dom_object *intern, zval *return_value, zend_string *selectors_str)
961+
{
962+
dom_query_selector_matches_ctx ctx = { thisp, false };
963+
964+
const xmlNode *root = thisp;
965+
while (root->parent != NULL) {
966+
root = root->parent;
967+
}
968+
969+
if (php_dom_query_selector_common(
970+
return_value,
971+
intern,
972+
root,
973+
selectors_str,
974+
php_dom_query_selector_find_matches_callback,
975+
&ctx
976+
) != LXB_STATUS_OK) {
977+
RETURN_THROWS();
978+
} else {
979+
RETURN_BOOL(ctx.result);
980+
}
981+
}
982+
942983
#endif

ext/dom/php_dom.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ bool php_dom_pre_insert(php_libxml_ref_obj *document, xmlNodePtr node, xmlNodePt
214214
bool php_dom_pre_insert_is_parent_invalid(xmlNodePtr parent);
215215
void dom_parent_node_query_selector(xmlNodePtr thisp, dom_object *intern, zval *return_value, zend_string *selectors_str);
216216
void dom_parent_node_query_selector_all(xmlNodePtr thisp, dom_object *intern, zval *return_value, zend_string *selectors_str);
217+
void dom_element_matches(xmlNodePtr thisp, dom_object *intern, zval *return_value, zend_string *selectors_str);
217218

218219
/* nodemap and nodelist APIs */
219220
xmlNodePtr php_dom_named_node_map_get_named_item(dom_nnodemap_object *objmap, const zend_string *named, bool may_transform);

ext/dom/php_dom.stub.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,8 @@ public function querySelector(string $selectors): ?DOMElement {}
729729
/** @implementation-alias DOMElement::querySelectorAll */
730730
public function querySelectorAll(string $selectors): DOMNodeList {}
731731

732+
public function matches(string $selectors): bool {}
733+
732734
public function insertAdjacentElement(string $where, DOMElement $element): ?DOMElement {}
733735

734736
public function insertAdjacentText(string $where, string $data): void {}

ext/dom/php_dom_arginfo.h

Lines changed: 7 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)