diff --git a/lib/HTMLCollection.php b/lib/HTMLCollection.php index 6ae41f3..eb8aa81 100644 --- a/lib/HTMLCollection.php +++ b/lib/HTMLCollection.php @@ -43,10 +43,43 @@ class HTMLCollection extends Collection { } public function offsetGet($offset): ?Element { - return (is_int($offset)) ? $this->item($offset) : $this->namedItem($offset); + if (is_int($offset)) { + return $this->item($offset); + } + + # The supported property names are the values from the list returned by these + # steps: + # 1. Let result be an empty list. + # 2. For each element represented by the collection, in tree order: + # 1. If element has an ID which is not in result, append element’s ID to + # result. + # 2. If element is in the HTML namespace and has a name attribute whose value is + # neither the empty string nor is in result, append element’s name attribute value + # to result. + # 3. Return result. + // The spec is extremely vague as to what to do here, but it seems to expect + // this to be some sort of live private property that the class will poll to + // check for valid property names when trying to access them. This is + // inefficient. Going to do basically the same thing but not return a list of + // every one. It will just search the list instead using the same process. + + $document = $this->innerDocument->wrapperNode; + foreach ($this->innerCollection as $node) { + if ($node->getAttribute('id') === $offset) { + return $this->innerDocument->getWrapperNode($node); + } + } + + foreach ($this->innerCollection as $node) { + if (!$document instanceof XMLDocument && $node->namespaceURI === null && $node->getAttribute('name') === $offset) { + return $this->innerDocument->getWrapperNode($node); + } + } + + return null; } public function offsetExists($offset): bool { - return (((is_int($offset)) ? $this->item($offset) : $this->namedItem($offset)) !== null); + return ($this->offsetGet($offset) !== null); } } \ No newline at end of file diff --git a/lib/NamedNodeMap.php b/lib/NamedNodeMap.php index bc812d2..19c69f4 100644 --- a/lib/NamedNodeMap.php +++ b/lib/NamedNodeMap.php @@ -56,8 +56,6 @@ class NamedNodeMap extends Collection { # A NamedNodeMap object’s supported property names are the return value of running # these steps: - # 1. Let names be the qualified names of the attributes in this NamedNodeMap object’s - # attribute list, with duplicates omitted, in order. // The spec is extremely vague as to what to do here, but it seems to expect // this to be some sort of live private property that the class will poll to // check for valid property names when trying to access them. This is @@ -65,6 +63,8 @@ class NamedNodeMap extends Collection { // every one. It will just search the element's attribute list instead using the // same process. + # 1. Let names be the qualified names of the attributes in this NamedNodeMap object’s + # attribute list, with duplicates omitted, in order. # 2. If this NamedNodeMap object’s element is in the HTML namespace and its node # document is an HTML document, then for each name in names: # 1. Let lowercaseName be name, in ASCII lowercase. @@ -105,7 +105,7 @@ class NamedNodeMap extends Collection { } public function offsetExists($offset): bool { - return (((is_int($offset)) ? $this->item($offset) : $this->getNamedItem($offset)) !== null); + return ($this->offsetGet($offset) !== null); } public function removeNamedItem(string $qualifiedName): ?Attr { diff --git a/tests/cases/TestHTMLCollection.php b/tests/cases/TestHTMLCollection.php new file mode 100644 index 0000000..a786f6c --- /dev/null +++ b/tests/cases/TestHTMLCollection.php @@ -0,0 +1,126 @@ + + +
+