mirror of
https://github.com/php/php-src.git
synced 2025-08-15 13:38:49 +02:00
Implement HTMLCollection::namedItem()
This commit is contained in:
parent
5c69b2e86f
commit
ac039cf716
8 changed files with 137 additions and 4 deletions
|
@ -229,4 +229,15 @@ xmlChar *dom_attr_value(const xmlAttr *attr, bool *free)
|
|||
return value;
|
||||
}
|
||||
|
||||
bool dom_compare_value(const xmlAttr *attr, const xmlChar *value)
|
||||
{
|
||||
bool free;
|
||||
xmlChar *attr_value = dom_attr_value(attr, &free);
|
||||
bool result = xmlStrEqual(attr_value, value);
|
||||
if (free) {
|
||||
xmlFree(attr_value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -32,7 +32,7 @@ if test "$PHP_DOM" != "no"; then
|
|||
documentfragment.c domimplementation.c \
|
||||
element.c node.c characterdata.c \
|
||||
documenttype.c entity.c \
|
||||
nodelist.c text.c comment.c \
|
||||
nodelist.c html_collection.c text.c comment.c \
|
||||
entityreference.c \
|
||||
notation.c xpath.c dom_iterators.c \
|
||||
namednodemap.c xpath_callbacks.c \
|
||||
|
|
|
@ -12,7 +12,7 @@ if (PHP_DOM == "yes") {
|
|||
domexception.c parentnode.c processinginstruction.c \
|
||||
cdatasection.c documentfragment.c domimplementation.c element.c \
|
||||
node.c characterdata.c documenttype.c \
|
||||
entity.c nodelist.c text.c comment.c \
|
||||
entity.c nodelist.c html_collection.c text.c comment.c \
|
||||
entityreference.c \
|
||||
notation.c xpath.c dom_iterators.c \
|
||||
namednodemap.c xpath_callbacks.c", null, "-Iext/dom/lexbor");
|
||||
|
|
74
ext/dom/html_collection.c
Normal file
74
ext/dom/html_collection.c
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| https://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Niels Dossche <nielsdos@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "php.h"
|
||||
#if defined(HAVE_LIBXML) && defined(HAVE_DOM)
|
||||
#include "php_dom.h"
|
||||
#include "namespace_compat.h"
|
||||
|
||||
/* https://dom.spec.whatwg.org/#dom-htmlcollection-nameditem-key */
|
||||
PHP_METHOD(DOM_HTMLCollection, namedItem)
|
||||
{
|
||||
zend_string *key;
|
||||
ZEND_PARSE_PARAMETERS_START(1, 1)
|
||||
Z_PARAM_PATH_STR(key)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
/* 1. If key is the empty string, return null. */
|
||||
if (ZSTR_LEN(key) == 0) {
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
dom_object *intern = Z_DOMOBJ_P(ZEND_THIS);
|
||||
dom_nnodemap_object *objmap = intern->ptr;
|
||||
|
||||
/* 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);
|
||||
if (basep != NULL) {
|
||||
int cur = 0;
|
||||
int next = cur;
|
||||
xmlNodePtr candidate = basep->children;
|
||||
while (candidate != NULL) {
|
||||
candidate = dom_get_elements_by_tag_name_ns_raw(basep, candidate, objmap->ns, objmap->local, objmap->local_lower, &cur, next);
|
||||
if (candidate == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
xmlAttrPtr attr;
|
||||
|
||||
/* 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))) {
|
||||
DOM_RET_OBJ(candidate, objmap->baseobj);
|
||||
return;
|
||||
}
|
||||
/* 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)) {
|
||||
if ((attr = xmlHasNsProp(candidate, BAD_CAST "name", NULL)) != NULL && dom_compare_value(attr, BAD_CAST ZSTR_VAL(key))) {
|
||||
DOM_RET_OBJ(candidate, objmap->baseobj);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
next = cur + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -175,6 +175,7 @@ dom_object *php_dom_instantiate_object_helper(zval *return_value, zend_class_ent
|
|||
xmlDocPtr php_dom_create_html_doc(void);
|
||||
|
||||
xmlChar *dom_attr_value(const xmlAttr *attr, bool *free);
|
||||
bool dom_compare_value(const xmlAttr *attr, const xmlChar *value);
|
||||
|
||||
typedef enum {
|
||||
DOM_LOAD_STRING = 0,
|
||||
|
|
|
@ -1279,7 +1279,7 @@ namespace DOM
|
|||
/** @implementation-alias DOMNodeList::item */
|
||||
public function item(int $index): ?Element {}
|
||||
|
||||
/* TODO: implement namedItem */
|
||||
public function namedItem(string $key): ?Element {}
|
||||
|
||||
/** @implementation-alias DOMNodeList::count */
|
||||
public function count(): int {}
|
||||
|
|
8
ext/dom/php_dom_arginfo.h
generated
8
ext/dom/php_dom_arginfo.h
generated
|
@ -1,5 +1,5 @@
|
|||
/* This is a generated file, edit the .stub.php file instead.
|
||||
* Stub hash: f441c789fdce91e8fc71f450b294c11059999af1 */
|
||||
* Stub hash: 37a1c811bfc8c611d686f0842d06fc327b54511f */
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_dom_import_simplexml, 0, 1, DOMElement, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, node, IS_OBJECT, 0)
|
||||
|
@ -721,6 +721,10 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_HTMLCollection_item, 0,
|
|||
ZEND_ARG_TYPE_INFO(0, index, IS_LONG, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_HTMLCollection_namedItem, 0, 1, DOM\\Element, 1)
|
||||
ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_DOM_HTMLCollection_count arginfo_class_DOM_Node_getLineNo
|
||||
|
||||
#define arginfo_class_DOM_HTMLCollection_getIterator arginfo_class_DOMNodeList_getIterator
|
||||
|
@ -1256,6 +1260,7 @@ ZEND_METHOD(DOM_Node, appendChild);
|
|||
ZEND_METHOD(DOM_Node, replaceChild);
|
||||
ZEND_METHOD(DOM_Node, removeChild);
|
||||
ZEND_METHOD(DOM_Node, getNodePath);
|
||||
ZEND_METHOD(DOM_HTMLCollection, namedItem);
|
||||
ZEND_METHOD(DOM_Element, removeAttribute);
|
||||
ZEND_METHOD(DOM_Element, setAttributeNodeNS);
|
||||
ZEND_METHOD(DOM_Element, removeAttributeNode);
|
||||
|
@ -1620,6 +1625,7 @@ static const zend_function_entry class_DOM_DTDNamedNodeMap_methods[] = {
|
|||
|
||||
static const zend_function_entry class_DOM_HTMLCollection_methods[] = {
|
||||
ZEND_RAW_FENTRY("item", zim_DOMNodeList_item, arginfo_class_DOM_HTMLCollection_item, ZEND_ACC_PUBLIC, NULL, NULL)
|
||||
ZEND_ME(DOM_HTMLCollection, namedItem, arginfo_class_DOM_HTMLCollection_namedItem, ZEND_ACC_PUBLIC)
|
||||
ZEND_RAW_FENTRY("count", zim_DOMNodeList_count, arginfo_class_DOM_HTMLCollection_count, ZEND_ACC_PUBLIC, NULL, NULL)
|
||||
ZEND_RAW_FENTRY("getIterator", zim_DOMNodeList_getIterator, arginfo_class_DOM_HTMLCollection_getIterator, ZEND_ACC_PUBLIC, NULL, NULL)
|
||||
ZEND_FE_END
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
--TEST--
|
||||
HTMLCollection::namedItem() and dimension handling for named accesses
|
||||
--EXTENSIONS--
|
||||
dom
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$xml = <<<XML
|
||||
<!DOCTYPE root [
|
||||
<!ENTITY ent "test">
|
||||
]>
|
||||
<root>
|
||||
<node name="foo">1</node>
|
||||
<x id="foo">2</x>
|
||||
<x id="foo&ent;">2 with entity</x>
|
||||
<node test:id="foo" xmlns:test="http://example.com">3</node>
|
||||
<node id="wrong">4</node>
|
||||
<node id="foo">5</node>
|
||||
<node name="bar">without html ns</node>
|
||||
<node name="bar" xmlns="http://www.w3.org/1999/xhtml">with html ns</node>
|
||||
</root>
|
||||
XML;
|
||||
|
||||
$dom = DOM\XMLDocument::createFromString($xml);
|
||||
var_dump($dom->getElementsByTagName('node')->namedItem('foo')?->textContent);
|
||||
var_dump($dom->getElementsByTagName('node')->namedItem('')?->textContent);
|
||||
var_dump($dom->getElementsByTagName('node')->namedItem('does not exist')?->textContent);
|
||||
var_dump($dom->getElementsByTagName('node')->namedItem('wrong')?->textContent);
|
||||
var_dump($dom->getElementsByTagName('node')->namedItem('bar')?->textContent);
|
||||
var_dump($dom->getElementsByTagName('x')->namedItem('foo')?->textContent);
|
||||
var_dump($dom->getElementsByTagName('x')->namedItem('footest')?->textContent);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
string(1) "5"
|
||||
NULL
|
||||
NULL
|
||||
string(1) "4"
|
||||
string(12) "with html ns"
|
||||
string(1) "2"
|
||||
string(13) "2 with entity"
|
Loading…
Add table
Add a link
Reference in a new issue