php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
html_collection.c
Go to the documentation of this file.
1/*
2 +----------------------------------------------------------------------+
3 | Copyright (c) The PHP Group |
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.01 of the PHP license, |
6 | that is bundled with this package in the file LICENSE, and is |
7 | available through the world-wide-web at the following url: |
8 | https://www.php.net/license/3_01.txt |
9 | If you did not receive a copy of the PHP license and are unable to |
10 | obtain it through the world-wide-web, please send a note to |
11 | license@php.net so we can mail you a copy immediately. |
12 +----------------------------------------------------------------------+
13 | Authors: Niels Dossche <nielsdos@php.net> |
14 +----------------------------------------------------------------------+
15*/
16
17#ifdef HAVE_CONFIG_H
18#include <config.h>
19#endif
20
21#include "php.h"
22#if defined(HAVE_LIBXML) && defined(HAVE_DOM)
23#include "php_dom.h"
24#include "nodelist.h"
25#include "html_collection.h"
26#include "namespace_compat.h"
27
28typedef struct dom_named_item {
29 dom_object *context_intern;
30 xmlNodePtr node;
31} dom_named_item;
32
33/* https://dom.spec.whatwg.org/#dom-htmlcollection-nameditem-key */
34static dom_named_item dom_html_collection_named_item(zend_string *key, zend_object *zobj)
35{
36 dom_named_item ret = {NULL, NULL};
37
38 /* 1. If key is the empty string, return null. */
39 if (ZSTR_LEN(key) == 0) {
40 return ret;
41 }
42
43 dom_object *intern = php_dom_obj_from_obj(zobj);
44 dom_nnodemap_object *objmap = intern->ptr;
45
46 /* 2. Return the first element in the collection for which at least one of the following is true: */
47 xmlNodePtr basep = dom_object_get_node(objmap->baseobj);
48 if (basep != NULL) {
49 zend_long cur = 0;
50 zend_long next = cur; /* not +1, otherwise we skip the first candidate */
51 xmlNodePtr candidate = basep->children;
52 while (candidate != NULL) {
53 candidate = dom_get_elements_by_tag_name_ns_raw(basep, candidate, objmap->ns, objmap->local, objmap->local_lower, &cur, next);
54 if (candidate == NULL) {
55 break;
56 }
57
58 xmlAttrPtr attr;
59
60 /* it has an ID which is key; */
61 if ((attr = xmlHasNsProp(candidate, BAD_CAST "id", NULL)) != NULL && dom_compare_value(attr, BAD_CAST ZSTR_VAL(key))) {
62 ret.context_intern = objmap->baseobj;
63 ret.node = candidate;
64 return ret;
65 }
66 /* it is in the HTML namespace and has a name attribute whose value is key; */
68 if ((attr = xmlHasNsProp(candidate, BAD_CAST "name", NULL)) != NULL && dom_compare_value(attr, BAD_CAST ZSTR_VAL(key))) {
69 ret.context_intern = objmap->baseobj;
70 ret.node = candidate;
71 return ret;
72 }
73 }
74
75 next = cur + 1;
76 }
77 }
78
79 return ret;
80}
81
82static void dom_html_collection_named_item_into_zval(zval *return_value, zend_string *key, zend_object *zobj)
83{
84 dom_named_item named_item = dom_html_collection_named_item(key, zobj);
85 if (named_item.node != NULL) {
86 DOM_RET_OBJ(named_item.node, named_item.context_intern);
87 } else {
89 }
90}
91
92PHP_METHOD(Dom_HTMLCollection, namedItem)
93{
98 dom_html_collection_named_item_into_zval(return_value, key, Z_OBJ_P(ZEND_THIS));
99}
100
102{
103 if (UNEXPECTED(!offset)) {
104 zend_throw_error(NULL, "Cannot append to %s", ZSTR_VAL(object->ce->name));
105 return NULL;
106 }
107
111 return NULL;
112 }
113
114 if (index.type == DOM_NODELIST_DIM_STRING) {
115 dom_html_collection_named_item_into_zval(rv, index.str, object);
116 } else {
118 php_dom_nodelist_get_item_into_zval(php_dom_obj_from_obj(object)->ptr, index.lval, rv);
119 }
120
121 return rv;
122}
123
124int dom_html_collection_has_dimension(zend_object *object, zval *member, int check_empty)
125{
126 /* If it exists, it cannot be empty because nodes aren't empty. */
127 ZEND_IGNORE_VALUE(check_empty);
128
132 return 0;
133 }
134
135 if (index.type == DOM_NODELIST_DIM_STRING) {
136 return dom_html_collection_named_item(index.str, object).node != NULL;
137 } else {
139 return index.lval >= 0 && index.lval < php_dom_get_nodelist_length(php_dom_obj_from_obj(object));
140 }
141}
142
143#endif
zend_ffi_type * type
Definition ffi.c:3812
void * ptr
Definition ffi.c:3814
new_type attr
Definition ffi.c:4364
zend_long offset
#define NULL
Definition gdcache.h:45
zval * dom_html_collection_read_dimension(zend_object *object, zval *offset, int type, zval *rv)
int dom_html_collection_has_dimension(zend_object *object, zval *member, int check_empty)
#define next(ls)
Definition minilua.c:2661
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)
dom_nodelist_dimension_index dom_modern_nodelist_get_index(const zval *offset)
@ DOM_NODELIST_DIM_STRING
Definition nodelist.h:22
@ DOM_NODELIST_DIM_ILLEGAL
Definition nodelist.h:21
@ DOM_NODELIST_DIM_LONG
Definition nodelist.h:23
zend_long php_dom_get_nodelist_length(dom_object *obj)
void php_dom_nodelist_get_item_into_zval(dom_nnodemap_object *objmap, zend_long index, zval *return_value)
#define PHP_METHOD
Definition php.h:365
bool dom_compare_value(const xmlAttr *attr, const xmlChar *value)
xmlNode * dom_get_elements_by_tag_name_ns_raw(xmlNodePtr basep, xmlNodePtr nodep, xmlChar *ns, xmlChar *local, xmlChar *local_lower, zend_long *cur, zend_long index)
unsigned char key[REFLECTION_KEY_LEN]
zval rv
Definition session.c:1024
void * ptr
Definition xml_common.h:26
dom_object * baseobj
Definition php_dom.h:81
xmlChar * local_lower
Definition php_dom.h:86
xmlChar * local
Definition php_dom.h:86
enum dom_nodelist_dimension_index_type type
Definition nodelist.h:31
PHP_DOM_EXPORT xmlNodePtr dom_object_get_node(dom_object *obj)
struct _dom_object dom_object
#define DOM_RET_OBJ(obj, domobject)
Definition xml_common.h:76
ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format,...)
Definition zend.c:1772
ZEND_API ZEND_COLD void zend_illegal_container_offset(const zend_string *container, const zval *offset, int type)
Definition zend.c:1802
#define ZEND_PARSE_PARAMETERS_END()
Definition zend_API.h:1641
#define RETURN_NULL()
Definition zend_API.h:1036
#define Z_PARAM_STR(dest)
Definition zend_API.h:2086
#define ZEND_PARSE_PARAMETERS_START(min_num_args, max_num_args)
Definition zend_API.h:1620
#define ZEND_THIS
Definition zend_API.h:523
struct _zval_struct zval
#define BP_VAR_IS
int32_t zend_long
Definition zend_long.h:42
struct _zend_string zend_string
#define ZEND_IGNORE_VALUE(x)
#define ZEND_ASSERT(c)
#define UNEXPECTED(condition)
struct _zend_object zend_object
#define ZSTR_VAL(zstr)
Definition zend_string.h:68
#define ZSTR_LEN(zstr)
Definition zend_string.h:69
#define Z_OBJ_P(zval_p)
Definition zend_types.h:990
zval * return_value
object
zval * ret
zend_object * zobj