mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Refactor dom_html_collection_named_item()
This factors out the specific objmap handling to virtual functions. This is the last step in preparation for GH-18550.
This commit is contained in:
parent
a2d65354a0
commit
f11ea2ae13
3 changed files with 45 additions and 27 deletions
|
@ -46,47 +46,35 @@ static dom_named_item dom_html_collection_named_item(zend_string *key, zend_obje
|
||||||
|
|
||||||
/* 2. Return the first element in the collection for which at least one of the following is true: */
|
/* 2. Return the first element in the collection for which at least one of the following is true: */
|
||||||
xmlNodePtr basep = dom_object_get_node(objmap->baseobj);
|
xmlNodePtr basep = dom_object_get_node(objmap->baseobj);
|
||||||
if (basep != NULL) {
|
if (basep != NULL && basep->children != NULL) {
|
||||||
zend_long cur = 0;
|
php_dom_obj_map_collection_iter iter = {0};
|
||||||
zend_long next = cur; /* not +1, otherwise we skip the first candidate */
|
iter.candidate = basep->children;
|
||||||
xmlNodePtr candidate = basep->children;
|
iter.basep = basep;
|
||||||
bool iterate_tag_name = objmap->handler == &php_dom_obj_map_by_tag_name;
|
|
||||||
while (candidate != NULL) {
|
while (true) {
|
||||||
if (iterate_tag_name) {
|
objmap->handler->collection_named_item_iter(objmap, &iter);
|
||||||
candidate = dom_get_elements_by_tag_name_ns_raw(basep, candidate, objmap->ns, objmap->local, objmap->local_lower, &cur, next);
|
if (iter.candidate == NULL) {
|
||||||
if (candidate == NULL) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
next = cur + 1;
|
|
||||||
} else {
|
|
||||||
if (candidate->type != XML_ELEMENT_NODE) {
|
|
||||||
candidate = candidate->next;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ZEND_ASSERT(candidate->type == XML_ELEMENT_NODE);
|
ZEND_ASSERT(iter.candidate->type == XML_ELEMENT_NODE);
|
||||||
|
|
||||||
xmlAttrPtr attr;
|
xmlAttrPtr attr;
|
||||||
|
|
||||||
/* it has an ID which is key; */
|
/* it has an ID which is key; */
|
||||||
if ((attr = xmlHasNsProp(candidate, BAD_CAST "id", NULL)) != NULL && dom_compare_value(attr, BAD_CAST ZSTR_VAL(key))) {
|
if ((attr = xmlHasNsProp(iter.candidate, BAD_CAST "id", NULL)) != NULL && dom_compare_value(attr, BAD_CAST ZSTR_VAL(key))) {
|
||||||
ret.context_intern = objmap->baseobj;
|
ret.context_intern = objmap->baseobj;
|
||||||
ret.node = candidate;
|
ret.node = iter.candidate;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
/* it is in the HTML namespace and has a name attribute whose value is key; */
|
/* it is in the HTML namespace and has a name attribute whose value is key; */
|
||||||
else if (php_dom_ns_is_fast(candidate, php_dom_ns_is_html_magic_token)) {
|
else if (php_dom_ns_is_fast(iter.candidate, php_dom_ns_is_html_magic_token)) {
|
||||||
if ((attr = xmlHasNsProp(candidate, BAD_CAST "name", NULL)) != NULL && dom_compare_value(attr, BAD_CAST ZSTR_VAL(key))) {
|
if ((attr = xmlHasNsProp(iter.candidate, BAD_CAST "name", NULL)) != NULL && dom_compare_value(attr, BAD_CAST ZSTR_VAL(key))) {
|
||||||
ret.context_intern = objmap->baseobj;
|
ret.context_intern = objmap->baseobj;
|
||||||
ret.node = candidate;
|
ret.node = iter.candidate;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!iterate_tag_name) {
|
|
||||||
candidate = candidate->next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -266,6 +266,16 @@ static void dom_map_get_elements_item(dom_nnodemap_object *map, zend_long index,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dom_map_collection_named_item_elements_iter(dom_nnodemap_object *map, php_dom_obj_map_collection_iter *iter)
|
||||||
|
{
|
||||||
|
if (iter->candidate != iter->basep->children) {
|
||||||
|
iter->candidate = iter->candidate->next;
|
||||||
|
}
|
||||||
|
while (iter->candidate && iter->candidate->type != XML_ELEMENT_NODE) {
|
||||||
|
iter->candidate = iter->candidate->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void dom_map_get_by_tag_name_item(dom_nnodemap_object *map, zend_long index, zval *return_value)
|
static void dom_map_get_by_tag_name_item(dom_nnodemap_object *map, zend_long index, zval *return_value)
|
||||||
{
|
{
|
||||||
xmlNodePtr nodep = dom_object_get_node(map->baseobj);
|
xmlNodePtr nodep = dom_object_get_node(map->baseobj);
|
||||||
|
@ -282,6 +292,12 @@ static void dom_map_get_by_tag_name_item(dom_nnodemap_object *map, zend_long ind
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dom_map_collection_named_item_by_tag_name_iter(dom_nnodemap_object *map, php_dom_obj_map_collection_iter *iter)
|
||||||
|
{
|
||||||
|
iter->candidate = dom_get_elements_by_tag_name_ns_raw(iter->basep, iter->candidate, map->ns, map->local, map->local_lower, &iter->cur, iter->next);
|
||||||
|
iter->next = iter->cur + 1;
|
||||||
|
}
|
||||||
|
|
||||||
static void dom_map_get_null_item(dom_nnodemap_object *map, zend_long index, zval *return_value)
|
static void dom_map_get_null_item(dom_nnodemap_object *map, zend_long index, zval *return_value)
|
||||||
{
|
{
|
||||||
RETURN_NULL();
|
RETURN_NULL();
|
||||||
|
@ -447,6 +463,7 @@ const php_dom_obj_map_handler php_dom_obj_map_attributes = {
|
||||||
.get_item = dom_map_get_attributes_item,
|
.get_item = dom_map_get_attributes_item,
|
||||||
.get_ns_named_item = dom_map_get_ns_named_item_prop,
|
.get_ns_named_item = dom_map_get_ns_named_item_prop,
|
||||||
.has_ns_named_item = dom_map_has_ns_named_item_prop,
|
.has_ns_named_item = dom_map_has_ns_named_item_prop,
|
||||||
|
.collection_named_item_iter = NULL,
|
||||||
.use_cache = false,
|
.use_cache = false,
|
||||||
.nameless = false,
|
.nameless = false,
|
||||||
};
|
};
|
||||||
|
@ -456,6 +473,7 @@ const php_dom_obj_map_handler php_dom_obj_map_by_tag_name = {
|
||||||
.get_item = dom_map_get_by_tag_name_item,
|
.get_item = dom_map_get_by_tag_name_item,
|
||||||
.get_ns_named_item = dom_map_get_ns_named_item_null,
|
.get_ns_named_item = dom_map_get_ns_named_item_null,
|
||||||
.has_ns_named_item = dom_map_has_ns_named_item_null,
|
.has_ns_named_item = dom_map_has_ns_named_item_null,
|
||||||
|
.collection_named_item_iter = dom_map_collection_named_item_by_tag_name_iter,
|
||||||
.use_cache = true,
|
.use_cache = true,
|
||||||
.nameless = true,
|
.nameless = true,
|
||||||
};
|
};
|
||||||
|
@ -465,6 +483,7 @@ const php_dom_obj_map_handler php_dom_obj_map_child_nodes = {
|
||||||
.get_item = dom_map_get_nodes_item,
|
.get_item = dom_map_get_nodes_item,
|
||||||
.get_ns_named_item = dom_map_get_ns_named_item_null,
|
.get_ns_named_item = dom_map_get_ns_named_item_null,
|
||||||
.has_ns_named_item = dom_map_has_ns_named_item_null,
|
.has_ns_named_item = dom_map_has_ns_named_item_null,
|
||||||
|
.collection_named_item_iter = NULL,
|
||||||
.use_cache = true,
|
.use_cache = true,
|
||||||
.nameless = true,
|
.nameless = true,
|
||||||
};
|
};
|
||||||
|
@ -474,6 +493,7 @@ const php_dom_obj_map_handler php_dom_obj_map_nodeset = {
|
||||||
.get_item = dom_map_get_nodeset_item,
|
.get_item = dom_map_get_nodeset_item,
|
||||||
.get_ns_named_item = dom_map_get_ns_named_item_null,
|
.get_ns_named_item = dom_map_get_ns_named_item_null,
|
||||||
.has_ns_named_item = dom_map_has_ns_named_item_null,
|
.has_ns_named_item = dom_map_has_ns_named_item_null,
|
||||||
|
.collection_named_item_iter = NULL,
|
||||||
.use_cache = false,
|
.use_cache = false,
|
||||||
.nameless = true,
|
.nameless = true,
|
||||||
};
|
};
|
||||||
|
@ -483,6 +503,7 @@ const php_dom_obj_map_handler php_dom_obj_map_entities = {
|
||||||
.get_item = dom_map_get_entity_item,
|
.get_item = dom_map_get_entity_item,
|
||||||
.get_ns_named_item = dom_map_get_ns_named_item_entity,
|
.get_ns_named_item = dom_map_get_ns_named_item_entity,
|
||||||
.has_ns_named_item = dom_map_has_ns_named_item_xmlht,
|
.has_ns_named_item = dom_map_has_ns_named_item_xmlht,
|
||||||
|
.collection_named_item_iter = NULL,
|
||||||
.use_cache = false,
|
.use_cache = false,
|
||||||
.nameless = false,
|
.nameless = false,
|
||||||
};
|
};
|
||||||
|
@ -492,6 +513,7 @@ const php_dom_obj_map_handler php_dom_obj_map_notations = {
|
||||||
.get_item = dom_map_get_notation_item,
|
.get_item = dom_map_get_notation_item,
|
||||||
.get_ns_named_item = dom_map_get_ns_named_item_notation,
|
.get_ns_named_item = dom_map_get_ns_named_item_notation,
|
||||||
.has_ns_named_item = dom_map_has_ns_named_item_xmlht,
|
.has_ns_named_item = dom_map_has_ns_named_item_xmlht,
|
||||||
|
.collection_named_item_iter = NULL,
|
||||||
.use_cache = false,
|
.use_cache = false,
|
||||||
.nameless = false,
|
.nameless = false,
|
||||||
};
|
};
|
||||||
|
@ -501,6 +523,7 @@ const php_dom_obj_map_handler php_dom_obj_map_child_elements = {
|
||||||
.get_item = dom_map_get_elements_item,
|
.get_item = dom_map_get_elements_item,
|
||||||
.get_ns_named_item = dom_map_get_ns_named_item_null,
|
.get_ns_named_item = dom_map_get_ns_named_item_null,
|
||||||
.has_ns_named_item = dom_map_has_ns_named_item_null,
|
.has_ns_named_item = dom_map_has_ns_named_item_null,
|
||||||
|
.collection_named_item_iter = dom_map_collection_named_item_elements_iter,
|
||||||
.use_cache = true,
|
.use_cache = true,
|
||||||
.nameless = true,
|
.nameless = true,
|
||||||
};
|
};
|
||||||
|
@ -510,6 +533,7 @@ const php_dom_obj_map_handler php_dom_obj_map_noop = {
|
||||||
.get_item = dom_map_get_null_item,
|
.get_item = dom_map_get_null_item,
|
||||||
.get_ns_named_item = dom_map_get_ns_named_item_null,
|
.get_ns_named_item = dom_map_get_ns_named_item_null,
|
||||||
.has_ns_named_item = dom_map_has_ns_named_item_null,
|
.has_ns_named_item = dom_map_has_ns_named_item_null,
|
||||||
|
.collection_named_item_iter = NULL,
|
||||||
.use_cache = false,
|
.use_cache = false,
|
||||||
.nameless = true,
|
.nameless = true,
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,11 +19,17 @@
|
||||||
|
|
||||||
typedef struct dom_nnodemap_object dom_nnodemap_object;
|
typedef struct dom_nnodemap_object dom_nnodemap_object;
|
||||||
|
|
||||||
|
typedef struct php_dom_obj_map_collection_iter {
|
||||||
|
zend_long cur, next;
|
||||||
|
xmlNodePtr candidate, basep;
|
||||||
|
} php_dom_obj_map_collection_iter;
|
||||||
|
|
||||||
typedef struct php_dom_obj_map_handler {
|
typedef struct php_dom_obj_map_handler {
|
||||||
zend_long (*length)(dom_nnodemap_object *);
|
zend_long (*length)(dom_nnodemap_object *);
|
||||||
void (*get_item)(dom_nnodemap_object *, zend_long, zval *);
|
void (*get_item)(dom_nnodemap_object *, zend_long, zval *);
|
||||||
xmlNodePtr (*get_ns_named_item)(dom_nnodemap_object *, const zend_string *, const char *);
|
xmlNodePtr (*get_ns_named_item)(dom_nnodemap_object *, const zend_string *, const char *);
|
||||||
bool (*has_ns_named_item)(dom_nnodemap_object *, const zend_string *, const char *);
|
bool (*has_ns_named_item)(dom_nnodemap_object *, const zend_string *, const char *);
|
||||||
|
void (*collection_named_item_iter)(dom_nnodemap_object *, php_dom_obj_map_collection_iter *);
|
||||||
bool use_cache;
|
bool use_cache;
|
||||||
bool nameless;
|
bool nameless;
|
||||||
} php_dom_obj_map_handler;
|
} php_dom_obj_map_handler;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue